void rpc_dplx_ruf(int fd) { uint32_t oflags; struct rpc_dplx_rec *rec = rpc_dplx_lookup_rec(fd, RPC_DPLX_FLAG_NONE, &oflags); /* assert: initialized */ mutex_unlock(&rec->recv.lock.we.mtx); }
void rpc_dplx_rlfi(int fd, const char *func, int line) { uint32_t oflags; struct rpc_dplx_rec *rec = rpc_dplx_lookup_rec(fd, RPC_DPLX_FLAG_NONE, &oflags); rpc_dplx_lock_t *lk = &rec->recv.lock; mutex_lock(&lk->we.mtx); if (__pkg_params.debug_flags & TIRPC_DEBUG_FLAG_LOCK) { lk->locktrace.func = (char*) func; lk->locktrace.line = line; } }
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); }
/* * Connection less client creation returns with client handle parameters. * Default options are set, which the user can change using clnt_control(). * fd should be open and bound. * * sendsz and recvsz are the maximum allowable packet sizes that can be * sent and received. Normally they are the same, but they can be * changed to improve the program efficiency and buffer allocation. * If they are 0, use the transport default. * * If svcaddr is NULL, returns NULL. */ CLIENT * clnt_dg_ncreate(int fd, /* open file descriptor */ const struct netbuf *svcaddr, /* servers address */ rpcprog_t program, /* program number */ rpcvers_t version, /* version number */ u_int sendsz, /* buffer recv size */ u_int recvsz /* buffer send size */) { CLIENT *clnt = NULL; /* client handle */ struct cx_data *cx = NULL; /* private data */ struct cu_data *cu = NULL; struct timespec now; struct rpc_msg call_msg; struct __rpc_sockinfo si; uint32_t oflags; int one = 1; if (svcaddr == NULL) { rpc_createerr.cf_stat = RPC_UNKNOWNADDR; return (NULL); } if (!__rpc_fd2sockinfo(fd, &si)) { rpc_createerr.cf_stat = RPC_TLIERROR; rpc_createerr.cf_error.re_errno = 0; return (NULL); } /* * Find the receive and the send size */ sendsz = __rpc_get_t_size(si.si_af, si.si_proto, (int)sendsz); recvsz = __rpc_get_t_size(si.si_af, si.si_proto, (int)recvsz); if ((sendsz == 0) || (recvsz == 0)) { rpc_createerr.cf_stat = RPC_TLIERROR; /* XXX */ rpc_createerr.cf_error.re_errno = 0; return (NULL); } clnt = mem_alloc(sizeof(CLIENT)); if (clnt == NULL) goto err1; mutex_init(&clnt->cl_lock, NULL); clnt->cl_flags = CLNT_FLAG_NONE; /* * Should be multiple of 4 for XDR. */ sendsz = ((sendsz + 3) / 4) * 4; recvsz = ((recvsz + 3) / 4) * 4; cx = alloc_cx_data(CX_DG_DATA, sendsz, recvsz); if (cx == NULL) goto err1; cu = CU_DATA(cx); (void)memcpy(&cu->cu_raddr, svcaddr->buf, (size_t) svcaddr->len); cu->cu_rlen = svcaddr->len; /* Other values can also be set through clnt_control() */ cu->cu_wait.tv_sec = 15; /* heuristically chosen */ cu->cu_wait.tv_usec = 0; cu->cu_total.tv_sec = -1; cu->cu_total.tv_usec = -1; cu->cu_sendsz = sendsz; cu->cu_recvsz = recvsz; cu->cu_async = false; cu->cu_connect = false; cu->cu_connected = false; (void)clock_gettime(CLOCK_MONOTONIC_FAST, &now); call_msg.rm_xid = __RPC_GETXID(&now); /* XXX? */ call_msg.rm_call.cb_prog = program; call_msg.rm_call.cb_vers = version; xdrmem_create(&(cu->cu_outxdrs), cu->cu_outbuf, sendsz, XDR_ENCODE); if (!xdr_callhdr(&(cu->cu_outxdrs), &call_msg)) { rpc_createerr.cf_stat = RPC_CANTENCODEARGS; /* XXX */ rpc_createerr.cf_error.re_errno = 0; goto err2; } cu->cu_xdrpos = XDR_GETPOS(&(cu->cu_outxdrs)); /* XXX fvdl - do we still want this? */ #if 0 (void)bindresvport_sa(fd, (struct sockaddr *)svcaddr->buf); #endif #ifdef IP_RECVERR { int on = 1; (void) setsockopt(fd, SOL_IP, IP_RECVERR, &on, sizeof(on)); } #endif ioctl(fd, FIONBIO, (char *)(void *)&one); /* * By default, closeit is always false. It is users responsibility * to do a close on it, else the user may use clnt_control * to let clnt_destroy do it for him/her. */ cu->cu_closeit = false; cu->cu_fd = fd; clnt->cl_ops = clnt_dg_ops(); clnt->cl_p1 = cx; clnt->cl_p2 = rpc_dplx_lookup_rec(fd, RPC_DPLX_LKP_FLAG_NONE, &oflags); /* ref+1 */ clnt->cl_tp = NULL; clnt->cl_netid = NULL; return (clnt); err1: __warnx(TIRPC_DEBUG_FLAG_CLNT_DG, mem_err_clnt_dg); rpc_createerr.cf_stat = RPC_SYSTEMERROR; rpc_createerr.cf_error.re_errno = errno; err2: if (clnt) { mem_free(clnt, sizeof(CLIENT)); if (cx) free_cx_data(cx); } return (NULL); }