SVCXPRT * svc_dg_ncreate(int fd, u_int sendsize, u_int recvsize) { SVCXPRT *xprt; struct svc_dg_data *su = NULL; struct __rpc_sockinfo si; struct sockaddr_storage ss; socklen_t slen; uint32_t oflags; if (!__rpc_fd2sockinfo(fd, &si)) { __warnx(TIRPC_DEBUG_FLAG_SVC_DG, svc_dg_str, svc_dg_err1); return (NULL); } /* * Find the receive and the send size */ sendsize = __rpc_get_t_size(si.si_af, si.si_proto, (int)sendsize); recvsize = __rpc_get_t_size(si.si_af, si.si_proto, (int)recvsize); if ((sendsize == 0) || (recvsize == 0)) { __warnx(TIRPC_DEBUG_FLAG_SVC_DG, svc_dg_str, svc_dg_err2); return (NULL); } xprt = mem_alloc(sizeof (SVCXPRT)); if (xprt == NULL) goto freedata; memset(xprt, 0, sizeof (SVCXPRT)); /* Init SVCXPRT locks, etc */ mutex_init(&xprt->xp_lock, NULL); mutex_init(&xprt->xp_auth_lock, NULL); su = mem_alloc(sizeof (*su)); if (su == NULL) goto freedata; su->su_iosz = ((MAX(sendsize, recvsize) + 3) / 4) * 4; if ((rpc_buffer(xprt) = mem_alloc(su->su_iosz)) == NULL) goto freedata; xdrmem_create(&(su->su_xdrs), rpc_buffer(xprt), su->su_iosz, XDR_DECODE); su->su_cache = NULL; xprt->xp_flags = SVC_XPRT_FLAG_NONE; xprt->xp_refcnt = 1; xprt->xp_fd = fd; xprt->xp_p2 = su; svc_dg_ops(xprt); xprt->xp_rtaddr.maxlen = sizeof (struct sockaddr_storage); slen = sizeof ss; if (getsockname(fd, (struct sockaddr *)(void *)&ss, &slen) < 0) goto freedata; __rpc_set_netbuf(&xprt->xp_ltaddr, &ss, slen); switch (ss.ss_family) { case AF_INET: xprt->xp_port = ntohs(((struct sockaddr_in *) &ss)->sin_port); break; #ifdef INET6 case AF_INET6: xprt->xp_port = ntohs(((struct sockaddr_in6 *) &ss)->sin6_port); break; #endif case AF_LOCAL: /* no port */ break; default: break; } /* Enable reception of IP*_PKTINFO control msgs */ svc_dg_enable_pktinfo(fd, &si); /* Make reachable */ xprt->xp_p5 = rpc_dplx_lookup_rec(xprt->xp_fd, RPC_DPLX_FLAG_NONE, &oflags); /* ref+1 */ svc_rqst_init_xprt(xprt); /* Conditional xprt_register */ if (! (__svc_params->flags & SVC_FLAG_NOREG_XPRTS)) xprt_register(xprt); return (xprt); freedata: __warnx(TIRPC_DEBUG_FLAG_SVC_DG, svc_dg_str, __no_mem_str); if (xprt) { if (su) (void) mem_free(su, sizeof (*su)); svc_rqst_finalize_xprt(xprt, SVC_RQST_FLAG_NONE); (void) mem_free(xprt, sizeof (SVCXPRT)); } return (NULL); }
SVCXPRT * svc_dg_create(int fd, u_int sendsize, u_int recvsize) { SVCXPRT *xprt; struct svc_dg_data *su = NULL; struct __rpc_sockinfo si; struct sockaddr_storage ss; socklen_t slen; if (!__rpc_fd2sockinfo(fd, &si)) { warnx(svc_dg_str, svc_dg_err1); return (NULL); } /* * Find the receive and the send size */ sendsize = __rpc_get_t_size(si.si_af, si.si_proto, (int)sendsize); recvsize = __rpc_get_t_size(si.si_af, si.si_proto, (int)recvsize); if ((sendsize == 0) || (recvsize == 0)) { warnx(svc_dg_str, svc_dg_err2); return (NULL); } xprt = mem_alloc(sizeof (SVCXPRT)); if (xprt == NULL) goto freedata; memset(xprt, 0, sizeof (SVCXPRT)); su = mem_alloc(sizeof (*su)); if (su == NULL) goto freedata; su->su_iosz = ((MAX(sendsize, recvsize) + 3) / 4) * 4; if ((rpc_buffer(xprt) = malloc(su->su_iosz)) == NULL) goto freedata; _DIAGASSERT(__type_fit(u_int, su->su_iosz)); xdrmem_create(&(su->su_xdrs), rpc_buffer(xprt), (u_int)su->su_iosz, XDR_DECODE); su->su_cache = NULL; xprt->xp_fd = fd; xprt->xp_p2 = (caddr_t)(void *)su; xprt->xp_verf.oa_base = su->su_verfbody; svc_dg_ops(xprt); xprt->xp_rtaddr.maxlen = sizeof (struct sockaddr_storage); slen = sizeof ss; if (getsockname(fd, (struct sockaddr *)(void *)&ss, &slen) < 0) goto freedata; xprt->xp_ltaddr.buf = mem_alloc(sizeof (struct sockaddr_storage)); xprt->xp_ltaddr.maxlen = sizeof (struct sockaddr_storage); xprt->xp_ltaddr.len = slen; memcpy(xprt->xp_ltaddr.buf, &ss, slen); xprt_register(xprt); return (xprt); freedata: (void) warnx(svc_dg_str, __no_mem_str); if (xprt) { if (su) (void) mem_free(su, sizeof (*su)); (void) mem_free(xprt, sizeof (SVCXPRT)); } return (NULL); }