static bool_t Svctcp_reply(SVCXPRT * xprt, register struct rpc_msg *msg) { register struct tcp_conn *cd = (struct tcp_conn *)(xprt->xp_p1); register XDR *xdrs = &(cd->xdrs); xdrproc_t xdr_proc; caddr_t xdr_where; xdrs->x_op = XDR_ENCODE; msg->rm_xid = cd->x_id; 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(NULL, xdrs, xdr_proc, xdr_where)) return (FALSE); } else if(!xdr_replymsg(xdrs, msg)) { return (FALSE); } (void)xdrrec_endofrecord(xdrs, TRUE); return (TRUE); }
static bool svc_rdma_reply(SVCXPRT *xprt, struct svc_req *req, struct rpc_msg *msg) { struct rpc_rdma_cbc *cbc = req->rq_context; XDR *xdrs = cbc->holdq.xdrs; xdrproc_t proc; void *where; bool has_args; __warnx(TIRPC_DEBUG_FLAG_SVC_RDMA, "%s() xprt %p cbc %p outgoing xdr %p\n", __func__, xprt, cbc, xdrs); if (msg->rm_reply.rp_stat == MSG_ACCEPTED && msg->rm_reply.rp_acpt.ar_stat == SUCCESS) { has_args = TRUE; proc = msg->acpted_rply.ar_results.proc; where = msg->acpted_rply.ar_results.where; msg->acpted_rply.ar_results.proc = (xdrproc_t)xdr_void; msg->acpted_rply.ar_results.where = NULL; } else { has_args = FALSE; proc = NULL; where = NULL; } if (!xdr_rdma_svc_reply(cbc, 0)){ __warnx(TIRPC_DEBUG_FLAG_SVC_RDMA, "%s: xdr_rdma_svc_reply failed (will set dead)", __func__); return (FALSE); } xdrs->x_op = XDR_ENCODE; if (!xdr_reply_encode(xdrs, msg)) { __warnx(TIRPC_DEBUG_FLAG_SVC_RDMA, "%s: xdr_reply_encode failed (will set dead)", __func__); return (FALSE); } xdr_tail_update(xdrs); if (has_args && req->rq_auth && !SVCAUTH_WRAP(req->rq_auth, req, xdrs, proc, where)) { __warnx(TIRPC_DEBUG_FLAG_SVC_RDMA, "%s: SVCAUTH_WRAP failed (will set dead)", __func__); return (FALSE); } xdr_tail_update(xdrs); return xdr_rdma_svc_flushout(cbc); }
static enum xprt_stat svc_dg_reply(struct svc_req *req) { SVCXPRT *xprt = req->rq_xprt; struct rpc_dplx_rec *rec = REC_XPRT(xprt); XDR *xdrs = rec->ioq.xdrs; struct svc_dg_xprt *su = DG_DR(rec); struct msghdr *msg = &su->su_msghdr; struct iovec iov; size_t slen; if (!xprt->xp_remote.nb.len) { __warnx(TIRPC_DEBUG_FLAG_WARN, "%s: %p fd %d has no remote address", __func__, xprt, xprt->xp_fd); return (XPRT_IDLE); } xdrs->x_op = XDR_ENCODE; XDR_SETPOS(xdrs, 0); if (!xdr_reply_encode(xdrs, &req->rq_msg)) { __warnx(TIRPC_DEBUG_FLAG_ERROR, "%s: %p fd %d xdr_reply_encode failed (will set dead)", __func__, xprt, xprt->xp_fd); return (XPRT_DIED); } if (req->rq_msg.rm_reply.rp_stat == MSG_ACCEPTED && req->rq_msg.rm_reply.rp_acpt.ar_stat == SUCCESS && req->rq_auth && !SVCAUTH_WRAP(req, xdrs)) { __warnx(TIRPC_DEBUG_FLAG_ERROR, "%s: %p fd %d SVCAUTH_WRAP failed (will set dead)", __func__, xprt, xprt->xp_fd); return (XPRT_DIED); } iov.iov_base = &su[1]; iov.iov_len = slen = XDR_GETPOS(xdrs); msg->msg_iov = &iov; msg->msg_iovlen = 1; msg->msg_name = (struct sockaddr *)&xprt->xp_remote.ss; msg->msg_namelen = xprt->xp_remote.nb.len; /* cmsg already set in svc_dg_rendezvous */ if (sendmsg(xprt->xp_fd, msg, 0) != (ssize_t) slen) { __warnx(TIRPC_DEBUG_FLAG_ERROR, "%s: %p fd %d sendmsg failed (will set dead)", __func__, xprt, xprt->xp_fd); return (XPRT_DIED); } return (XPRT_IDLE); }
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); }
/* * Send rpc reply. * Serialize the reply packet into the output buffer then * call t_ksndudata to send it. */ static bool_t svc_clts_ksend(SVCXPRT *clone_xprt, struct rpc_msg *msg) { /* LINTED pointer alignment */ struct udp_data *ud = (struct udp_data *)clone_xprt->xp_p2buf; XDR *xdrs = &clone_xprt->xp_xdrout; int stat = FALSE; mblk_t *mp; int msgsz; struct T_unitdata_req *udreq; xdrproc_t xdr_results; caddr_t xdr_location; bool_t has_args; TRACE_0(TR_FAC_KRPC, TR_SVC_CLTS_KSEND_START, "svc_clts_ksend_start:"); ASSERT(ud->ud_resp != NULL); /* * If there is a result procedure specified in the reply message, * it will be processed in the xdr_replymsg and SVCAUTH_WRAP. * We need to make sure it won't be processed twice, so we null * it for xdr_replymsg here. */ has_args = FALSE; if (msg->rm_reply.rp_stat == MSG_ACCEPTED && msg->rm_reply.rp_acpt.ar_stat == SUCCESS) { if ((xdr_results = msg->acpted_rply.ar_results.proc) != NULL) { has_args = TRUE; xdr_location = msg->acpted_rply.ar_results.where; msg->acpted_rply.ar_results.proc = xdr_void; msg->acpted_rply.ar_results.where = NULL; } } if (ud->ud_resp->b_cont == NULL) { /* * Allocate an initial mblk for the response data. */ while ((mp = allocb(UD_INITSIZE, BPRI_LO)) == NULL) { if (strwaitbuf(UD_INITSIZE, BPRI_LO)) { TRACE_1(TR_FAC_KRPC, TR_SVC_CLTS_KSEND_END, "svc_clts_ksend_end:(%S)", "strwaitbuf"); return (FALSE); } } /* * Initialize the XDR decode stream. Additional mblks * will be allocated if necessary. They will be UD_MAXSIZE * sized. */ xdrmblk_init(xdrs, mp, XDR_ENCODE, UD_MAXSIZE); /* * Leave some space for protocol headers. */ (void) XDR_SETPOS(xdrs, 512); mp->b_rptr += 512; msg->rm_xid = clone_xprt->xp_xid; ud->ud_resp->b_cont = mp; TRACE_0(TR_FAC_KRPC, TR_XDR_REPLYMSG_START, "xdr_replymsg_start:"); if (!(xdr_replymsg(xdrs, msg) && (!has_args || SVCAUTH_WRAP(&clone_xprt->xp_auth, xdrs, xdr_results, xdr_location)))) { TRACE_1(TR_FAC_KRPC, TR_XDR_REPLYMSG_END, "xdr_replymsg_end:(%S)", "bad"); RPCLOG0(1, "xdr_replymsg/SVCAUTH_WRAP failed\n"); goto out; } TRACE_1(TR_FAC_KRPC, TR_XDR_REPLYMSG_END, "xdr_replymsg_end:(%S)", "good"); } else if (!(xdr_replymsg_body(xdrs, msg) && (!has_args || SVCAUTH_WRAP(&clone_xprt->xp_auth, xdrs, xdr_results, xdr_location)))) { RPCLOG0(1, "xdr_replymsg_body/SVCAUTH_WRAP failed\n"); goto out; } msgsz = (int)xmsgsize(ud->ud_resp->b_cont); if (msgsz <= 0 || (clone_xprt->xp_msg_size != -1 && msgsz > clone_xprt->xp_msg_size)) { #ifdef DEBUG cmn_err(CE_NOTE, "KRPC: server response message of %d bytes; transport limits are [0, %d]", msgsz, clone_xprt->xp_msg_size); #endif goto out; } /* * Construct the T_unitdata_req. We take advantage * of the fact that T_unitdata_ind looks just like * T_unitdata_req, except for the primitive type. */ udreq = (struct T_unitdata_req *)ud->ud_resp->b_rptr; udreq->PRIM_type = T_UNITDATA_REQ; put(clone_xprt->xp_wq, ud->ud_resp); stat = TRUE; ud->ud_resp = NULL; out: if (stat == FALSE) { freemsg(ud->ud_resp); ud->ud_resp = NULL; } /* * This is completely disgusting. If public is set it is * a pointer to a structure whose first field is the address * of the function to free that structure and any related * stuff. (see rrokfree in nfs_xdr.c). */ if (xdrs->x_public) { /* LINTED pointer alignment */ (**((int (**)())xdrs->x_public))(xdrs->x_public); } TRACE_1(TR_FAC_KRPC, TR_SVC_CLTS_KSEND_END, "svc_clts_ksend_end:(%S)", "done"); return (stat); }