static bool_t Svcudp_recv(register SVCXPRT * xprt, struct rpc_msg *msg) { register struct Svcudp_data *su = Su_data(xprt); register XDR *xdrs = &(su->su_xdrs); register int rlen; again: xprt->xp_addrlen = sizeof(struct sockaddr_in); #ifdef _FREEBSD rlen = recvfrom(xprt->xp_fd, rpc_buffer(xprt), (int)su->su_iosz, 0, (struct sockaddr *)&(xprt->xp_raddr), &(xprt->xp_addrlen)); #else rlen = recvfrom(xprt->xp_sock, rpc_buffer(xprt), (int)su->su_iosz, 0, (struct sockaddr *)&(xprt->xp_raddr), &(xprt->xp_addrlen)); #endif if(rlen == -1 && errno == EINTR) goto again; if(rlen == -1 || rlen < 4 * sizeof(u_int32_t)) return (FALSE); xdrs->x_op = XDR_DECODE; XDR_SETPOS(xdrs, 0); if(!xdr_callmsg(xdrs, msg)) return (FALSE); su->su_xid = msg->rm_xid; return (TRUE); }
/* * Usage: * xprt = svcudp_create(sock); * * If sock<0 then a socket is created, else sock is used. * If the socket, sock is not bound to a port then svcudp_create * binds it to an arbitrary port. In any (successful) case, * xprt->xp_sock is the registered socket number and xprt->xp_port is the * associated port number. * Once *xprt is initialized, it is registered as a transporter; * see (svc.h, xprt_register). * The routines returns NULL if a problem occurred. */ SVCXPRT * svcudp_bufcreate( register int sock, unsigned sendsz, unsigned recvsz) { bool_t madesock = FALSE; register SVCXPRT *xprt; register struct svcudp_data *su; struct sockaddr_in addr; socklen_t len = sizeof(struct sockaddr_in); if (sock == RPC_ANYSOCK) { if ((sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) < 0) { perror("svcudp_create: socket creation problem"); return ((SVCXPRT *)NULL); } madesock = TRUE; } bzero((char *)&addr, sizeof (addr)); addr.sin_family = AF_INET; if (bindresvport(sock, &addr)) { addr.sin_port = 0; (void)bind(sock, (struct sockaddr *)&addr, len); } if (getsockname(sock, (struct sockaddr *)&addr, &len) != 0) { perror("svcudp_create - cannot getsockname"); if (madesock) (void)close(sock); return ((SVCXPRT *)NULL); } xprt = (SVCXPRT *)mem_alloc(sizeof(SVCXPRT)); if (xprt == NULL) { (void)fprintf(stderr, "svcudp_create: out of memory\n"); return (NULL); } su = (struct svcudp_data *)mem_alloc(sizeof(*su)); if (su == NULL) { (void)fprintf(stderr, "svcudp_create: out of memory\n"); return (NULL); } su->su_iosz = ((MAX(sendsz, recvsz) + 3) / 4) * 4; if ((rpc_buffer(xprt) = mem_alloc(su->su_iosz)) == NULL) { (void)fprintf(stderr, "svcudp_create: out of memory\n"); return (NULL); } xdrmem_create( &(su->su_xdrs), rpc_buffer(xprt), su->su_iosz, XDR_DECODE); su->su_cache = NULL; xprt->xp_p2 = (char*)su; xprt->xp_verf.oa_base = su->su_verfbody; xprt->xp_ops = &svcudp_op; xprt->xp_port = ntohs(addr.sin_port); xprt->xp_sock = sock; xprt_register(xprt); return (xprt); }
/* * Set an entry in the cache */ static void cache_set(SVCXPRT *xprt, u_long replylen) { cache_ptr victim; cache_ptr *vicp; struct svcudp_data *su = su_data(xprt); struct udp_cache *uc = (struct udp_cache *) su->su_cache; u_int loc; char *newbuf; /* * Find space for the new entry, either by * reusing an old entry, or by mallocing a new one */ victim = uc->uc_fifo[uc->uc_nextvictim]; if (victim != NULL) { loc = CACHE_LOC(xprt, victim->cache_xid); for (vicp = &uc->uc_entries[loc]; *vicp != NULL && *vicp != victim; vicp = &(*vicp)->cache_next) ; if (*vicp == NULL) { return; } *vicp = victim->cache_next; /* remote from cache */ newbuf = victim->cache_reply; } else { victim = malloc(sizeof(struct cache_node)); if (victim == NULL) { return; } newbuf = malloc(su->su_iosz); if (newbuf == NULL) { free(victim); return; } } /* * Store it away */ victim->cache_replylen = replylen; victim->cache_reply = rpc_buffer(xprt); rpc_buffer(xprt) = newbuf; xdrmem_create(&(su->su_xdrs), rpc_buffer(xprt), su->su_iosz, XDR_ENCODE); victim->cache_xid = su->su_xid; victim->cache_proc = uc->uc_proc; victim->cache_vers = uc->uc_vers; victim->cache_prog = uc->uc_prog; victim->cache_addr = uc->uc_addr; loc = CACHE_LOC(xprt, victim->cache_xid); victim->cache_next = uc->uc_entries[loc]; uc->uc_entries[loc] = victim; uc->uc_fifo[uc->uc_nextvictim++] = victim; uc->uc_nextvictim %= uc->uc_size; }
static bool_t svcudp_recv( SVCXPRT *xprt, struct rpc_msg *msg) { struct msghdr dummy; struct iovec dummy_iov[1]; struct svcudp_data *su = su_data(xprt); XDR *xdrs = &su->su_xdrs; int rlen; char *reply; uint32_t replylen; socklen_t addrlen; again: memset(&dummy, 0, sizeof(dummy)); dummy_iov[0].iov_base = rpc_buffer(xprt); dummy_iov[0].iov_len = (int) su->su_iosz; dummy.msg_iov = dummy_iov; dummy.msg_iovlen = 1; dummy.msg_namelen = xprt->xp_laddrlen = sizeof(struct sockaddr_in); dummy.msg_name = (char *) &xprt->xp_laddr; rlen = recvmsg(xprt->xp_sock, &dummy, MSG_PEEK); if (rlen == -1) { if (errno == EINTR) goto again; else return (FALSE); } addrlen = sizeof(struct sockaddr_in); rlen = recvfrom(xprt->xp_sock, rpc_buffer(xprt), (int) su->su_iosz, 0, (struct sockaddr *)&(xprt->xp_raddr), &addrlen); if (rlen == -1 && errno == EINTR) goto again; if (rlen < (int) (4*sizeof(uint32_t))) return (FALSE); xprt->xp_addrlen = addrlen; xdrs->x_op = XDR_DECODE; XDR_SETPOS(xdrs, 0); if (! xdr_callmsg(xdrs, msg)) return (FALSE); su->su_xid = msg->rm_xid; if (su->su_cache != NULL) { if (cache_get(xprt, msg, &reply, &replylen)) { (void) sendto(xprt->xp_sock, reply, (int) replylen, 0, (struct sockaddr *) &xprt->xp_raddr, xprt->xp_addrlen); return (TRUE); } } return (TRUE); }
static bool_t svcudp_reply( register SVCXPRT *xprt, struct rpc_msg *msg) { register struct svcudp_data *su = su_data(xprt); register XDR *xdrs = &(su->su_xdrs); register int slen; register bool_t stat = FALSE; xdrs->x_op = XDR_ENCODE; XDR_SETPOS(xdrs, 0); msg->rm_xid = su->su_xid; if (xdr_replymsg(xdrs, msg)) { slen = (int)XDR_GETPOS(xdrs); if (sendto(xprt->xp_sock, rpc_buffer(xprt), slen, 0, (struct sockaddr *)&(xprt->xp_raddr), xprt->xp_addrlen) == (ssize_t)slen) { stat = TRUE; if (su->su_cache) { cache_set(xprt, (unsigned long) slen); } } } return (stat); }
static bool_t svcudp_recv( register SVCXPRT *xprt, struct rpc_msg *msg) { register struct svcudp_data *su = su_data(xprt); register XDR *xdrs = &(su->su_xdrs); register ssize_t rlen; char *reply; unsigned long replylen; socklen_t len; again: len = xprt->xp_addrlen = sizeof(struct sockaddr_in); rlen = recvfrom(xprt->xp_sock, rpc_buffer(xprt), (int) su->su_iosz, 0, (struct sockaddr *)&(xprt->xp_raddr), &len); if (rlen == -1 && errno == EINTR) goto again; if (rlen < 4*sizeof(uint32_t)) return (FALSE); xprt->xp_addrlen = len; xdrs->x_op = XDR_DECODE; XDR_SETPOS(xdrs, 0); if (! xdr_callmsg(xdrs, msg)) return (FALSE); su->su_xid = msg->rm_xid; if (su->su_cache != NULL) { if (cache_get(xprt, msg, &reply, &replylen)) { (void) sendto(xprt->xp_sock, reply, replylen, 0, (struct sockaddr *) &xprt->xp_raddr, xprt->xp_addrlen); return (TRUE); } } return (TRUE); }
static bool_t svc_dg_reply(SVCXPRT *xprt, struct rpc_msg *msg) { struct svc_dg_data *su; XDR *xdrs; bool_t stat = FALSE; size_t slen; _DIAGASSERT(xprt != NULL); _DIAGASSERT(msg != NULL); su = su_data(xprt); xdrs = &(su->su_xdrs); xdrs->x_op = XDR_ENCODE; XDR_SETPOS(xdrs, 0); msg->rm_xid = su->su_xid; if (xdr_replymsg(xdrs, msg)) { slen = XDR_GETPOS(xdrs); if (sendto(xprt->xp_fd, rpc_buffer(xprt), slen, 0, (struct sockaddr *)xprt->xp_rtaddr.buf, (socklen_t)xprt->xp_rtaddr.len) == (ssize_t) slen) { stat = TRUE; if (su->su_cache) cache_set(xprt, slen); } } return (stat); }
void Svcudp_soft_destroy(register SVCXPRT * xprt) { register struct Svcudp_data *su = Su_data(xprt); //XDR_DESTROY(&(su->su_xdrs)); Mem_Free(rpc_buffer(xprt)); Mem_Free((caddr_t) su); Mem_Free((caddr_t) xprt); }
static void Svcudp_destroy(register SVCXPRT * xprt) { register struct Svcudp_data *su = Su_data(xprt); Xprt_unregister(xprt); (void)close(xprt->XP_SOCK); XDR_DESTROY(&(su->su_xdrs)); Mem_Free(rpc_buffer(xprt)); Mem_Free((caddr_t) su); Mem_Free((caddr_t) xprt); }
static bool_t svc_dg_recv(SVCXPRT *xprt, struct rpc_msg *msg) { struct svc_dg_data *su; XDR *xdrs; char *reply; struct sockaddr_storage ss; socklen_t alen; size_t replylen; ssize_t rlen; _DIAGASSERT(xprt != NULL); _DIAGASSERT(msg != NULL); su = su_data(xprt); xdrs = &(su->su_xdrs); again: alen = sizeof (struct sockaddr_storage); rlen = recvfrom(xprt->xp_fd, rpc_buffer(xprt), su->su_iosz, 0, (struct sockaddr *)(void *)&ss, &alen); if (rlen == -1 && errno == EINTR) goto again; if (rlen == -1 || (rlen < (ssize_t)(4 * sizeof (u_int32_t)))) return (FALSE); if (xprt->xp_rtaddr.len < alen) { if (xprt->xp_rtaddr.len != 0) mem_free(xprt->xp_rtaddr.buf, xprt->xp_rtaddr.len); xprt->xp_rtaddr.buf = mem_alloc(alen); xprt->xp_rtaddr.len = alen; } memcpy(xprt->xp_rtaddr.buf, &ss, alen); #ifdef PORTMAP if (ss.ss_family == AF_INET) { xprt->xp_raddr = *(struct sockaddr_in *)xprt->xp_rtaddr.buf; xprt->xp_addrlen = sizeof (struct sockaddr_in); } #endif xdrs->x_op = XDR_DECODE; XDR_SETPOS(xdrs, 0); if (! xdr_callmsg(xdrs, msg)) { return (FALSE); } su->su_xid = msg->rm_xid; if (su->su_cache != NULL) { if (cache_get(xprt, msg, &reply, &replylen)) { (void)sendto(xprt->xp_fd, reply, replylen, 0, (struct sockaddr *)(void *)&ss, alen); return (FALSE); } } return (TRUE); }
static void svcudp_destroy( register SVCXPRT *xprt) { register struct svcudp_data *su = su_data(xprt); xprt_unregister(xprt); (void)close(xprt->xp_sock); XDR_DESTROY(&(su->su_xdrs)); mem_free(rpc_buffer(xprt), su->su_iosz); mem_free((char*)su, sizeof(struct svcudp_data)); mem_free((char*)xprt, sizeof(SVCXPRT)); }
static void svcudp_destroy(SVCXPRT *xprt) { struct svcudp_data *su = su_data(xprt); xprt_unregister(xprt); if (xprt->xp_sock != -1) (void)close(xprt->xp_sock); xprt->xp_sock = -1; XDR_DESTROY(&(su->su_xdrs)); mem_free(rpc_buffer(xprt), su->su_iosz); mem_free((caddr_t)su, sizeof(struct svcudp_data)); mem_free((caddr_t)xprt, sizeof(SVCXPRT)); }
static void Svcudp_destroy(register SVCXPRT * xprt) { register struct Svcudp_data *su = Su_data(xprt); Xprt_unregister(xprt); #ifdef _FREEBSD (void)close(xprt->xp_fd); #else (void)close(xprt->xp_sock); #endif XDR_DESTROY(&(su->su_xdrs)); Mem_Free(rpc_buffer(xprt)); Mem_Free((caddr_t) su); Mem_Free((caddr_t) xprt); }
static void svcudp_destroy(register SVCXPRT *xprt) { register struct svcudp_data *su = su_data(xprt); xprt_unregister(xprt); if (xprt->xp_sock != INVALID_SOCKET) (void)closesocket(xprt->xp_sock); xprt->xp_sock = INVALID_SOCKET; if (xprt->xp_auth != NULL) { SVCAUTH_DESTROY(xprt->xp_auth); xprt->xp_auth = NULL; } XDR_DESTROY(&(su->su_xdrs)); mem_free(rpc_buffer(xprt), su->su_iosz); mem_free((caddr_t)su, sizeof(struct svcudp_data)); mem_free((caddr_t)xprt, sizeof(SVCXPRT)); }
static bool_t svcudp_reply( register SVCXPRT *xprt, struct rpc_msg *msg) { register struct svcudp_data *su = su_data(xprt); register XDR *xdrs = &(su->su_xdrs); register int slen; register bool_t stat = FALSE; xdrproc_t xdr_results; caddr_t xdr_location; bool_t has_args; if (msg->rm_reply.rp_stat == MSG_ACCEPTED && msg->rm_reply.rp_acpt.ar_stat == SUCCESS) { has_args = TRUE; xdr_results = msg->acpted_rply.ar_results.proc; xdr_location = msg->acpted_rply.ar_results.where; msg->acpted_rply.ar_results.proc = xdr_void; msg->acpted_rply.ar_results.where = NULL; } else has_args = FALSE; xdrs->x_op = XDR_ENCODE; XDR_SETPOS(xdrs, 0); msg->rm_xid = su->su_xid; if (xdr_replymsg(xdrs, msg) && (!has_args || (SVCAUTH_WRAP(xprt->xp_auth, xdrs, xdr_results, xdr_location)))) { slen = (int)XDR_GETPOS(xdrs); if (sendto(xprt->xp_sock, rpc_buffer(xprt), slen, 0, (struct sockaddr *)&(xprt->xp_raddr), xprt->xp_addrlen) == slen) { stat = TRUE; if (su->su_cache && slen >= 0) { cache_set(xprt, (uint32_t) slen); } } } return (stat); }
static bool_t Svcudp_reply(register SVCXPRT * xprt, struct rpc_msg *msg) { register struct Svcudp_data *su = Su_data(xprt); register XDR *xdrs = &(su->su_xdrs); register int slen; xdrproc_t xdr_proc; caddr_t xdr_where; xdrs->x_op = XDR_ENCODE; XDR_SETPOS(xdrs, 0); msg->rm_xid = su->su_xid; if(msg->rm_reply.rp_stat == MSG_ACCEPTED && msg->rm_reply.rp_acpt.ar_stat == SUCCESS) { xdr_proc = msg->acpted_rply.ar_results.proc; xdr_where = msg->acpted_rply.ar_results.where; msg->acpted_rply.ar_results.proc = (xdrproc_t) xdr_void; msg->acpted_rply.ar_results.where = NULL; if(!xdr_replymsg(xdrs, msg) || !SVCAUTH_WRAP(xprt->xp_auth, xdrs, xdr_proc, xdr_where)) return (FALSE); } else if(!xdr_replymsg(xdrs, msg)) { return (FALSE); } slen = (int)XDR_GETPOS(xdrs); #ifdef _FREEBSD if(sendto(xprt->xp_fd, #else if(sendto(xprt->xp_sock, #endif rpc_buffer(xprt), slen, 0, (struct sockaddr *)&(xprt->xp_raddr), xprt->xp_addrlen) != slen) { return (FALSE); } return (TRUE); }
static bool_t Svcudp_reply(register SVCXPRT * xprt, struct rpc_msg *msg) { register struct Svcudp_data *su = Su_data(xprt); register XDR *xdrs = &(su->su_xdrs); register int slen; xdrproc_t xdr_proc; caddr_t xdr_where; xdrs->x_op = XDR_ENCODE; XDR_SETPOS(xdrs, 0); msg->rm_xid = su->su_xid; if(msg->rm_reply.rp_stat == MSG_ACCEPTED && msg->rm_reply.rp_acpt.ar_stat == SUCCESS) { xdr_proc = msg->acpted_rply.ar_results.proc; xdr_where = msg->acpted_rply.ar_results.where; msg->acpted_rply.ar_results.proc = (xdrproc_t) xdr_void; msg->acpted_rply.ar_results.where = NULL; if(!xdr_replymsg(xdrs, msg) || !SVCAUTH_WRAP(xprt->xp_auth, xdrs, xdr_proc, xdr_where)) return (FALSE); } else if(!xdr_replymsg(xdrs, msg)) { return (FALSE); } slen = (int)XDR_GETPOS(xdrs); if(sendto(xprt->XP_SOCK, rpc_buffer(xprt), slen, 0, (struct sockaddr *)&(xprt->xp_raddr), xprt->xp_addrlen) != slen) { LogInfo(COMPONENT_DISPATCH, "EAGAIN indicates UDP buffer is full and not" " allowed to block. sendto() returned %s", strerror(errno)); return (FALSE); } return (TRUE); }
static void svc_dg_destroy(SVCXPRT *xprt) { struct svc_dg_data *su; _DIAGASSERT(xprt != NULL); su = su_data(xprt); xprt_unregister(xprt); if (xprt->xp_fd != -1) (void)close(xprt->xp_fd); XDR_DESTROY(&(su->su_xdrs)); (void) mem_free(rpc_buffer(xprt), su->su_iosz); (void) mem_free(su, sizeof (*su)); if (xprt->xp_rtaddr.buf) (void) mem_free(xprt->xp_rtaddr.buf, xprt->xp_rtaddr.maxlen); if (xprt->xp_ltaddr.buf) (void) mem_free(xprt->xp_ltaddr.buf, xprt->xp_ltaddr.maxlen); if (xprt->xp_tp) (void) free(xprt->xp_tp); (void) mem_free(xprt, sizeof (SVCXPRT)); }
void FreeXprt(SVCXPRT *xprt) { if(!xprt) { LogFullDebug(COMPONENT_RPC, "Attempt to free NULL xprt"); return; } LogFullDebug(COMPONENT_RPC, "FreeXprt xprt=%p", xprt); if(xprt->xp_ops == &Svcudp_op) { xp_free(Su_data(xprt)); xp_free(rpc_buffer(xprt)); } else if (xprt->xp_ops == &Svctcp_op) { struct tcp_conn *cd = (struct tcp_conn *)xprt->xp_p1; XDR_DESTROY(&(cd->xdrs)); xp_free(xprt->xp_p1); /* cd */ } else if (xprt->xp_ops == &Svctcp_rendezvous_op) { xp_free(xprt->xp_p1); /* r */ } else { LogCrit(COMPONENT_RPC, "Attempt to free unknown xprt %p", xprt); return; } Mem_Free(xprt); }
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 *Svcudp_bufcreate(register int sock, u_int sendsz, u_int recvsz) { bool_t madesock = FALSE; register SVCXPRT *xprt; register struct Svcudp_data *su; struct sockaddr_in addr; unsigned long len = sizeof(struct sockaddr_in); if(sock == RPC_ANYSOCK) { if((sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) < 0) { perror("Svcudp_create: socket creation problem"); return ((SVCXPRT *) NULL); } madesock = TRUE; } memset(&addr, 0, sizeof(addr)); addr.sin_family = AF_INET; if(bindresvport(sock, &addr)) { addr.sin_port = 0; (void)bind(sock, (struct sockaddr *)&addr, len); } if(getsockname(sock, (struct sockaddr *)&addr, (socklen_t *) & len) != 0) { perror("Svcudp_create - cannot getsockname"); if(madesock) (void)close(sock); return ((SVCXPRT *) NULL); } xprt = (SVCXPRT *) Mem_Alloc(sizeof(SVCXPRT)); if(xprt == NULL) { return (NULL); } su = (struct Svcudp_data *)Mem_Alloc(sizeof(*su)); if(su == NULL) { return (NULL); } su->su_iosz = ((MAX(sendsz, recvsz) + 3) / 4) * 4; if((rpc_buffer(xprt) = Mem_Alloc(su->su_iosz)) == NULL) { return (NULL); } xdrmem_create(&(su->su_xdrs), rpc_buffer(xprt), su->su_iosz, XDR_DECODE); xprt->xp_p2 = (caddr_t) su; xprt->xp_verf.oa_base = su->su_verfbody; xprt->xp_ops = &Svcudp_op; xprt->xp_port = ntohs(addr.sin_port); #ifdef _FREEBSD xprt->xp_fd = sock; #else xprt->xp_sock = sock; #endif Xprt_register(xprt); return (xprt); }
/* * Usage: * xprt = svcudp_create(sock); * * If sock<0 then a socket is created, else sock is used. * If the socket, sock is not bound to a port then svcudp_create * binds it to an arbitrary port. In any (successful) case, * xprt->xp_sock is the registered socket number and xprt->xp_port is the * associated port number. * Once *xprt is initialized, it is registered as a transporter; * see (svc.h, xprt_register). * The routines returns NULL if a problem occurred. */ SVCXPRT * svcudp_bufcreate(int sock, u_int sendsz, u_int recvsz) { bool_t madesock = FALSE; SVCXPRT *xprt; struct svcudp_data *su; struct sockaddr_in addr; socklen_t len = sizeof(struct sockaddr_in); if (sock == RPC_ANYSOCK) { if ((sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) < 0) return (NULL); madesock = TRUE; } memset(&addr, 0, sizeof (addr)); addr.sin_len = sizeof(struct sockaddr_in); addr.sin_family = AF_INET; if (bindresvport(sock, &addr)) { addr.sin_port = 0; (void)bind(sock, (struct sockaddr *)&addr, len); } if (getsockname(sock, (struct sockaddr *)&addr, &len) != 0) { if (madesock) (void)close(sock); return (NULL); } xprt = malloc(sizeof(SVCXPRT)); if (xprt == NULL) { if (madesock) (void)close(sock); return (NULL); } su = malloc(sizeof(*su)); if (su == NULL) { if (madesock) (void)close(sock); free(xprt); return (NULL); } su->su_iosz = ((MAX(sendsz, recvsz) + 3) / 4) * 4; if ((rpc_buffer(xprt) = malloc(su->su_iosz)) == NULL) { if (madesock) (void)close(sock); free(xprt); free(su); return (NULL); } xdrmem_create(&(su->su_xdrs), rpc_buffer(xprt), su->su_iosz, XDR_DECODE); su->su_cache = NULL; xprt->xp_p2 = (caddr_t)su; xprt->xp_verf.oa_base = su->su_verfbody; xprt->xp_ops = &svcudp_op; xprt->xp_port = ntohs(addr.sin_port); xprt->xp_sock = sock; if (__xprt_register(xprt) == 0) { if (madesock) (void)close(sock); free(rpc_buffer(xprt)); free(xprt); free(su); return (NULL); } return (xprt); }
/* * Usage: * xprt = svcudp_create(sock); * * If sock<0 then a socket is created, else sock is used. * If the socket, sock is not bound to a port then svcudp_create * binds it to an arbitrary port. In any (successful) case, * xprt->xp_sock is the registered socket number and xprt->xp_port is the * associated port number. * Once *xprt is initialized, it is registered as a transporter; * see (svc.h, xprt_register). * The routines returns NULL if a problem occurred. */ SVCXPRT * svcudp_bufcreate (int sock, u_int sendsz, u_int recvsz) { bool_t madesock = FALSE; SVCXPRT *xprt; struct svcudp_data *su; struct sockaddr_in addr; socklen_t len = sizeof (struct sockaddr_in); int pad; void *buf; if (sock == RPC_ANYSOCK) { if ((sock = socket (AF_INET, SOCK_DGRAM, IPPROTO_UDP)) < 0) { perror (_("svcudp_create: socket creation problem")); return (SVCXPRT *) NULL; } madesock = TRUE; } memset ((char *) &addr, 0, sizeof (addr)); addr.sin_family = AF_INET; if (bindresvport (sock, &addr)) { addr.sin_port = 0; (void) bind (sock, (struct sockaddr *) &addr, len); } if (getsockname (sock, (struct sockaddr *) &addr, &len) != 0) { perror (_("svcudp_create - cannot getsockname")); if (madesock) (void) close (sock); return (SVCXPRT *) NULL; } xprt = (SVCXPRT *) mem_alloc (sizeof (SVCXPRT)); su = (struct svcudp_data *) mem_alloc (sizeof (*su)); buf = mem_alloc (((MAX (sendsz, recvsz) + 3) / 4) * 4); if (xprt == NULL || su == NULL || buf == NULL) { #ifdef USE_IN_LIBIO if (_IO_fwide (stderr, 0) > 0) (void) fwprintf (stderr, L"%s", _("svcudp_create: out of memory\n")); else #endif (void) fputs (_("svcudp_create: out of memory\n"), stderr); mem_free (xprt, sizeof (SVCXPRT)); mem_free (su, sizeof (*su)); mem_free (buf, ((MAX (sendsz, recvsz) + 3) / 4) * 4); return NULL; } su->su_iosz = ((MAX (sendsz, recvsz) + 3) / 4) * 4; rpc_buffer (xprt) = buf; xdrmem_create (&(su->su_xdrs), rpc_buffer (xprt), su->su_iosz, XDR_DECODE); su->su_cache = NULL; xprt->xp_p2 = (caddr_t) su; xprt->xp_verf.oa_base = su->su_verfbody; xprt->xp_ops = &svcudp_op; xprt->xp_port = ntohs (addr.sin_port); xprt->xp_sock = sock; #ifdef IP_PKTINFO if ((sizeof (struct iovec) + sizeof (struct msghdr) + sizeof(struct cmsghdr) + sizeof (struct in_pktinfo)) > sizeof (xprt->xp_pad)) { # ifdef USE_IN_LIBIO if (_IO_fwide (stderr, 0) > 0) (void) fwprintf (stderr, L"%s", _("svcudp_create: xp_pad is too small for IP_PKTINFO\n")); else # endif (void) fputs (_("svcudp_create: xp_pad is too small for IP_PKTINFO\n"), stderr); return NULL; } pad = 1; if (setsockopt (sock, SOL_IP, IP_PKTINFO, (void *) &pad, sizeof (pad)) == 0) /* Set the padding to all 1s. */ pad = 0xff; else #endif /* Clear the padding. */ pad = 0; memset (&xprt->xp_pad [0], pad, sizeof (xprt->xp_pad)); xprt_register (xprt); return xprt; }
/* * Usage: * xprt = svcudp_create(sock); * * If sock<0 then a socket is created, else sock is used. * If the socket, sock is not bound to a port then svcudp_create * binds it to an arbitrary port. In any (successful) case, * xprt->xp_sock is the registered socket number and xprt->xp_port is the * associated port number. * Once *xprt is initialized, it is registered as a transporter; * see (svc.h, xprt_register). * The routines returns NULL if a problem occurred. */ SVCXPRT * svcudp_bufcreate( int sock, u_int sendsz, u_int recvsz) { bool_t madesock = FALSE; SVCXPRT *xprt; struct svcudp_data *su; struct sockaddr_storage ss; struct sockaddr *sa = (struct sockaddr *)&ss; socklen_t len; if (sock == RPC_ANYSOCK) { if ((sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) < 0) { perror("svcudp_create: socket creation problem"); return ((SVCXPRT *)NULL); } set_cloexec_fd(sock); madesock = TRUE; memset(&ss, 0, sizeof(ss)); sa->sa_family = AF_INET; } else { len = sizeof(struct sockaddr_storage); if (getsockname(sock, sa, &len) < 0) { perror("svcudp_create - cannot getsockname"); return ((SVCXPRT *)NULL); } } if (bindresvport_sa(sock, sa)) { sa_setport(sa, 0); (void)bind(sock, sa, sa_socklen(sa)); } len = sizeof(struct sockaddr_storage); if (getsockname(sock, sa, &len) != 0) { perror("svcudp_create - cannot getsockname"); if (madesock) (void)close(sock); return ((SVCXPRT *)NULL); } xprt = (SVCXPRT *)mem_alloc(sizeof(SVCXPRT)); if (xprt == NULL) { (void)fprintf(stderr, "svcudp_create: out of memory\n"); return (NULL); } su = (struct svcudp_data *)mem_alloc(sizeof(*su)); if (su == NULL) { (void)fprintf(stderr, "svcudp_create: out of memory\n"); return (NULL); } su->su_iosz = ((MAX(sendsz, recvsz) + 3) / 4) * 4; if ((rpc_buffer(xprt) = mem_alloc(su->su_iosz)) == NULL) { (void)fprintf(stderr, "svcudp_create: out of memory\n"); return (NULL); } xdrmem_create( &(su->su_xdrs), rpc_buffer(xprt), su->su_iosz, XDR_DECODE); su->su_cache = NULL; xprt->xp_p2 = (caddr_t)su; xprt->xp_auth = NULL; xprt->xp_verf.oa_base = su->su_verfbody; xprt->xp_ops = &svcudp_op; xprt->xp_port = sa_getport(sa); xprt->xp_sock = sock; xprt_register(xprt); return (xprt); }
/* * Duplicate xprt from original to copy. */ SVCXPRT *Svcxprt_copy(SVCXPRT *xprt_copy, SVCXPRT *xprt_orig) { if(xprt_copy) FreeXprt(xprt_copy); xprt_copy = (SVCXPRT *) Mem_Alloc(sizeof(SVCXPRT)); if(xprt_copy == NULL) goto fail_no_xprt; LogFullDebug(COMPONENT_RPC, "Svcxprt_copy copying xprt_orig=%p to xprt_copy=%p", xprt_orig, xprt_copy); memcpy(xprt_copy, xprt_orig, sizeof(SVCXPRT)); xprt_copy->xp_p1 = NULL; xprt_copy->xp_p2 = NULL; if(xprt_orig->xp_ops == &Svcudp_op) { if(Su_data(xprt_orig)) { struct Svcudp_data *su_o = Su_data(xprt_orig), *su_c; su_c = (struct Svcudp_data *) Mem_Alloc(sizeof(*su_c)); if(!su_c) goto fail; Su_data_set(xprt_copy) = (void *) su_c; memcpy(su_c, su_o, sizeof(*su_c)); rpc_buffer(xprt_copy) = Mem_Alloc_Label(su_c->su_iosz, "UDP IO Buffer"); if(!rpc_buffer(xprt_copy)) goto fail; xdrmem_create(&(su_c->su_xdrs), rpc_buffer(xprt_copy), su_c->su_iosz, XDR_DECODE); if(xprt_orig->xp_verf.oa_base == su_o->su_verfbody) xprt_copy->xp_verf.oa_base = su_c->su_verfbody; else xprt_copy->xp_verf.oa_base = xprt_orig->xp_verf.oa_base; xprt_copy->xp_verf.oa_flavor = xprt_orig->xp_verf.oa_flavor; xprt_copy->xp_verf.oa_length = xprt_orig->xp_verf.oa_length; } else goto fail; } else if (xprt_orig->xp_ops == &Svctcp_op) { struct tcp_conn *cd_o = (struct tcp_conn *)xprt_orig->xp_p1, *cd_c; cd_c = (struct tcp_conn *) Mem_Alloc(sizeof(*cd_c)); if(!cd_c) goto fail; memcpy(cd_c, cd_o, sizeof(*cd_c)); xprt_copy->xp_p1 = (void *) cd_c; xdrrec_create(&(cd_c->xdrs), 32768, 32768, (caddr_t) xprt_copy, Readtcp, Writetcp); if(xprt_orig->xp_verf.oa_base == cd_o->verf_body) xprt_copy->xp_verf.oa_base = cd_c->verf_body; else xprt_copy->xp_verf.oa_base = xprt_orig->xp_verf.oa_base; xprt_copy->xp_verf.oa_flavor = xprt_orig->xp_verf.oa_flavor; xprt_copy->xp_verf.oa_length = xprt_orig->xp_verf.oa_length; } else if (xprt_orig->xp_ops == &Svctcp_rendezvous_op) { goto fail; } else { LogDebug(COMPONENT_RPC, "Attempt to copy unknown xprt %p", xprt_orig); Mem_Free(xprt_copy); goto fail_no_xprt; } return xprt_copy; fail: FreeXprt(xprt_copy); fail_no_xprt: /* Let caller know about failure */ LogCrit(COMPONENT_RPC, "Failed to copy xprt"); svcerr_systemerr(xprt_orig); 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); }