Example #1
0
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);
}
Example #2
0
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);
}
Example #3
0
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);
}
Example #4
0
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);
}
Example #5
0
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);
}
Example #6
0
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);
}
Example #7
0
/*
 * 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);
}