예제 #1
0
파일: clnt_tcp.c 프로젝트: Julia117/embox
static enum clnt_stat clnttcp_call(struct client *clnt, uint32_t procnum,
		xdrproc_t inproc, char *in, xdrproc_t outproc, char *out,
		struct timeval timeout) {
	struct xdr xstream;
	struct rpc_msg msg_reply, msg_call;

	assert((clnt != NULL) && (inproc != NULL));

	msg_call.xid = (uint32_t)rand();
	msg_call.type = CALL;
	msg_call.b.call.rpcvers = RPC_VERSION;
	msg_call.b.call.prog = clnt->prognum;
	msg_call.b.call.vers = clnt->versnum;
	msg_call.b.call.proc = procnum;
	memcpy(&msg_call.b.call.cred, &clnt->ath->cred, sizeof clnt->ath->cred);
	memcpy(&msg_call.b.call.verf, &clnt->ath->verf, sizeof clnt->ath->verf);

	if (-1 == setsockopt(clnt->sock, SOL_SOCKET, SO_RCVTIMEO,
				&timeout, sizeof timeout)) {
		LOG_ERROR("clnttcp_call", "setsockopt error");
		clnt->err.extra.error = errno;
		return clnt->err.status = RPC_SYSTEMERROR;
	}

	xdrrec_create(&xstream, clnt->extra.tcp.sendsz, clnt->extra.tcp.recvsz,
			(char *)clnt, (xdrrec_hnd_t)readtcp, (xdrrec_hnd_t)writetcp);

	xstream.oper = XDR_ENCODE;

	clnt->err.status = RPC_SUCCESS;
	if (!xdr_rpc_msg(&xstream, &msg_call)
			|| !(*inproc)(&xstream, in)) {
		if (clnt->err.status == RPC_SUCCESS) {
			clnt->err.status = RPC_CANTENCODEARGS;
		}
		goto exit_with_status;
	}

	if (!xdrrec_endofrecord(&xstream, 1)) {
		clnt->err.status = RPC_CANTSEND;
		goto exit_with_status;
	}

	xstream.oper = XDR_DECODE;

	msg_reply.b.reply.r.accepted.d.result.decoder = outproc;
	msg_reply.b.reply.r.accepted.d.result.param = out;
	assert(clnt->err.status == RPC_SUCCESS);
	if (!xdr_rpc_msg(&xstream, &msg_reply)) {
		if (clnt->err.status == RPC_SUCCESS) {
			clnt->err.status = RPC_CANTDECODERES;
		}
		goto exit_with_status;
	}

	assert(clnt->err.status == RPC_SUCCESS);
exit_with_status:
	xdr_destroy(&xstream);
	return clnt->err.status;
}
예제 #2
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);
}
예제 #3
0
/*
 * ndmp_send_response
 *
 * Send an NDMP reply message.
 *
 * Parameters:
 *   connection_handle  (input)  - connection pointer.
 *   err	       (input)  - error code to place in header.
 *   reply	     (input)  - reply message body.
 *
 * Returns:
 *   0 - successful send.
 *  -1 - error.
 *
 * Notes:
 *   - The body is only sent if the error code is NDMP_NO_ERR.
 */
int
ndmp_send_response(ndmp_connection_t *connection_handle, ndmp_error err,
    void *reply)
{
	ndmp_connection_t *connection = (ndmp_connection_t *)connection_handle;
	ndmp_header header;
	struct timeval time;

	(void) gettimeofday(&time, 0);

	header.sequence = ++(connection->conn_my_sequence);
	header.time_stamp = time.tv_sec;
	header.message_type = NDMP_MESSAGE_REPLY;
	header.message = connection->conn_msginfo.mi_hdr.message;
	header.reply_sequence = connection->conn_msginfo.mi_hdr.sequence;
	header.error = err;

	connection->conn_xdrs.x_op = XDR_ENCODE;
	if (!xdr_ndmp_header(&connection->conn_xdrs, &header)) {
		NDMP_LOG(LOG_DEBUG, "Sending message 0x%x: "
		    "encoding reply header",
		    header.message);
		(void) xdrrec_endofrecord(&connection->conn_xdrs, 1);
		return (-1);
	}
	if (err == NDMP_NO_ERR &&
	    connection->conn_msginfo.mi_handler->mh_xdr_reply &&
	    reply) {
		if (!(*connection->conn_msginfo.mi_handler->mh_xdr_reply)(
		    &connection->conn_xdrs, reply)) {
			NDMP_LOG(LOG_DEBUG,
			    "Sending message 0x%x: encoding reply body",
			    header.message);
			(void) xdrrec_endofrecord(&connection->conn_xdrs, 1);
			return (-1);
	}
	}
	(void) xdrrec_endofrecord(&connection->conn_xdrs, 1);
	return (0);
}
예제 #4
0
static bool_t
svctcp_reply (SVCXPRT *xprt, struct rpc_msg *msg)
{
  struct tcp_conn *cd = (struct tcp_conn *) (xprt->xp_p1);
  XDR *xdrs = &(cd->xdrs);
  bool_t stat;

  xdrs->x_op = XDR_ENCODE;
  msg->rm_xid = cd->x_id;
  stat = xdr_replymsg (xdrs, msg);
  (void) xdrrec_endofrecord (xdrs, TRUE);
  return stat;
}
예제 #5
0
int CMSendMessage(int communicationDescriptor, void *message) {
	if ( message == NULL ) return  errno = EINVAL, -1;
	if ( CMInternalData.capacity < UINT_MAX && (unsigned int)communicationDescriptor >= CMInternalData.capacity) return errno = EINVAL, -1;
	
	CMCommunicationDescriptionContext *communicationContexts = CMInternalData.CMCommunicationContexts;
	CMCommunicationDescriptionContext *context = &(communicationContexts[communicationDescriptor]);
	
	if (context->communicationDescriptor != communicationDescriptor) return errno = EINVAL, -1;
	if (context->socket == -1) return errno = EINVAL, -1;
	if (context->converterf == NULL) return errno = EINVAL, -1;

//	CC_SHA1((const unsigned char *)line->content, size, line->id);
//	SHA1((const unsigned char *)line->content, size, line->id);
	
	XDR *xdrs = &(context->xdrs);
	xdrs->x_op = XDR_ENCODE;
	bool_t result = context->converterf(xdrs, message, 0);
	if ( result == (TRUE) )
		return (xdrrec_endofrecord(xdrs, (TRUE) ) == 1) ? 0 : (errno = EINVAL, -1);
	return -1;
}
예제 #6
0
static enum clnt_stat
clnt_vc_call(CLIENT *cl, rpcproc_t proc, xdrproc_t xdr_args, void *args_ptr,
    xdrproc_t xdr_results, void *results_ptr, struct timeval timeout)
{
	struct ct_data *ct = (struct ct_data *) cl->cl_private;
	XDR *xdrs = &(ct->ct_xdrs);
	struct rpc_msg reply_msg;
	u_int32_t x_id;
	u_int32_t *msg_x_id = &ct->ct_u.ct_mcalli;    /* yuk */
	bool_t shipnow;
	int refreshes = 2;
	sigset_t mask, newmask;
	int rpc_lock_value;
	bool_t reply_stat;

	assert(cl != NULL);

	sigfillset(&newmask);
	thr_sigsetmask(SIG_SETMASK, &newmask, &mask);
	mutex_lock(&clnt_fd_lock);
	while (vc_fd_locks[ct->ct_fd])
		cond_wait(&vc_cv[ct->ct_fd], &clnt_fd_lock);
	if (__isthreaded)
                rpc_lock_value = 1;
        else
                rpc_lock_value = 0;
	vc_fd_locks[ct->ct_fd] = rpc_lock_value;
	mutex_unlock(&clnt_fd_lock);
	if (!ct->ct_waitset) {
		/* If time is not within limits, we ignore it. */
		if (time_not_ok(&timeout) == FALSE)
			ct->ct_wait = timeout;
	}

	shipnow =
	    (xdr_results == NULL && timeout.tv_sec == 0
	    && timeout.tv_usec == 0) ? FALSE : TRUE;

call_again:
	xdrs->x_op = XDR_ENCODE;
	ct->ct_error.re_status = RPC_SUCCESS;
	x_id = ntohl(--(*msg_x_id));

	if (cl->cl_auth->ah_cred.oa_flavor != RPCSEC_GSS) {
		if ((! XDR_PUTBYTES(xdrs, ct->ct_u.ct_mcallc, ct->ct_mpos)) ||
		    (! XDR_PUTINT32(xdrs, &proc)) ||
		    (! AUTH_MARSHALL(cl->cl_auth, xdrs)) ||
		    (! (*xdr_args)(xdrs, args_ptr))) {
			if (ct->ct_error.re_status == RPC_SUCCESS)
				ct->ct_error.re_status = RPC_CANTENCODEARGS;
			(void)xdrrec_endofrecord(xdrs, TRUE);
			release_fd_lock(ct->ct_fd, mask);
			return (ct->ct_error.re_status);
		}
	} else {
		*(uint32_t *) &ct->ct_u.ct_mcallc[ct->ct_mpos] = htonl(proc);
		if (! __rpc_gss_wrap(cl->cl_auth, ct->ct_u.ct_mcallc,
			ct->ct_mpos + sizeof(uint32_t),
			xdrs, xdr_args, args_ptr)) {
			if (ct->ct_error.re_status == RPC_SUCCESS)
				ct->ct_error.re_status = RPC_CANTENCODEARGS;
			(void)xdrrec_endofrecord(xdrs, TRUE);
			release_fd_lock(ct->ct_fd, mask);
			return (ct->ct_error.re_status);
		}
	}
	if (! xdrrec_endofrecord(xdrs, shipnow)) {
		release_fd_lock(ct->ct_fd, mask);
		return (ct->ct_error.re_status = RPC_CANTSEND);
	}
	if (! shipnow) {
		release_fd_lock(ct->ct_fd, mask);
		return (RPC_SUCCESS);
	}
	/*
	 * Hack to provide rpc-based message passing
	 */
	if (timeout.tv_sec == 0 && timeout.tv_usec == 0) {
		release_fd_lock(ct->ct_fd, mask);
		return(ct->ct_error.re_status = RPC_TIMEDOUT);
	}


	/*
	 * Keep receiving until we get a valid transaction id
	 */
	xdrs->x_op = XDR_DECODE;
	while (TRUE) {
		reply_msg.acpted_rply.ar_verf = _null_auth;
		reply_msg.acpted_rply.ar_results.where = NULL;
		reply_msg.acpted_rply.ar_results.proc = (xdrproc_t)xdr_void;
		if (! xdrrec_skiprecord(xdrs)) {
			release_fd_lock(ct->ct_fd, mask);
			return (ct->ct_error.re_status);
		}
		/* now decode and validate the response header */
		if (! xdr_replymsg(xdrs, &reply_msg)) {
			if (ct->ct_error.re_status == RPC_SUCCESS)
				continue;
			release_fd_lock(ct->ct_fd, mask);
			return (ct->ct_error.re_status);
		}
		if (reply_msg.rm_xid == x_id)
			break;
	}

	/*
	 * process header
	 */
	_seterr_reply(&reply_msg, &(ct->ct_error));
	if (ct->ct_error.re_status == RPC_SUCCESS) {
		if (! AUTH_VALIDATE(cl->cl_auth,
		    &reply_msg.acpted_rply.ar_verf)) {
			ct->ct_error.re_status = RPC_AUTHERROR;
			ct->ct_error.re_why = AUTH_INVALIDRESP;
		} else {
			if (cl->cl_auth->ah_cred.oa_flavor != RPCSEC_GSS) {
				reply_stat = (*xdr_results)(xdrs, results_ptr);
			} else {
				reply_stat = __rpc_gss_unwrap(cl->cl_auth,
				    xdrs, xdr_results, results_ptr);
			}
			if (! reply_stat) {
				if (ct->ct_error.re_status == RPC_SUCCESS)
					ct->ct_error.re_status =
						RPC_CANTDECODERES;
			}
		}
		/* free verifier ... */
		if (reply_msg.acpted_rply.ar_verf.oa_base != NULL) {
			xdrs->x_op = XDR_FREE;
			(void)xdr_opaque_auth(xdrs,
			    &(reply_msg.acpted_rply.ar_verf));
		}
	}  /* end successful completion */
	else {
		/* maybe our credentials need to be refreshed ... */
		if (refreshes-- && AUTH_REFRESH(cl->cl_auth, &reply_msg))
			goto call_again;
	}  /* end of unsuccessful completion */
	release_fd_lock(ct->ct_fd, mask);
	return (ct->ct_error.re_status);
}
예제 #7
0
static enum clnt_stat
clnttcp_call(CLIENT *h, u_long proc, xdrproc_t xdr_args, caddr_t args_ptr,
    xdrproc_t xdr_results, caddr_t results_ptr, struct timeval timeout)
{
	struct ct_data *ct = (struct ct_data *) h->cl_private;
	XDR *xdrs = &(ct->ct_xdrs);
	struct rpc_msg reply_msg;
	u_long x_id;
	u_int32_t *msg_x_id = (u_int32_t *)(ct->ct_mcall);	/* yuk */
	bool_t shipnow;
	int refreshes = 2;

	if (!ct->ct_waitset) {
		ct->ct_wait = timeout;
	}

	shipnow =
	    (xdr_results == NULL && timeout.tv_sec == 0
	    && timeout.tv_usec == 0) ? FALSE : TRUE;

call_again:
	xdrs->x_op = XDR_ENCODE;
	ct->ct_error.re_status = RPC_SUCCESS;
	x_id = ntohl(--(*msg_x_id));
	if ((! XDR_PUTBYTES(xdrs, ct->ct_mcall, ct->ct_mpos)) ||
	    (! XDR_PUTLONG(xdrs, (long *)&proc)) ||
	    (! AUTH_MARSHALL(h->cl_auth, xdrs)) ||
	    (! (*xdr_args)(xdrs, args_ptr))) {
		if (ct->ct_error.re_status == RPC_SUCCESS)
			ct->ct_error.re_status = RPC_CANTENCODEARGS;
		(void)xdrrec_endofrecord(xdrs, TRUE);
		return (ct->ct_error.re_status);
	}
	if (! xdrrec_endofrecord(xdrs, shipnow))
		return (ct->ct_error.re_status = RPC_CANTSEND);
	if (! shipnow)
		return (RPC_SUCCESS);
	/*
	 * Hack to provide rpc-based message passing
	 */
	if (timeout.tv_sec == 0 && timeout.tv_usec == 0) {
		return(ct->ct_error.re_status = RPC_TIMEDOUT);
	}


	/*
	 * Keep receiving until we get a valid transaction id
	 */
	xdrs->x_op = XDR_DECODE;
	while (TRUE) {
		reply_msg.acpted_rply.ar_verf = _null_auth;
		reply_msg.acpted_rply.ar_results.where = NULL;
		reply_msg.acpted_rply.ar_results.proc = xdr_void;
		if (! xdrrec_skiprecord(xdrs))
			return (ct->ct_error.re_status);
		/* now decode and validate the response header */
		if (! xdr_replymsg(xdrs, &reply_msg)) {
			if (ct->ct_error.re_status == RPC_SUCCESS)
				continue;
			return (ct->ct_error.re_status);
		}
		if (reply_msg.rm_xid == x_id)
			break;
	}

	/*
	 * process header
	 */
	_seterr_reply(&reply_msg, &(ct->ct_error));
	if (ct->ct_error.re_status == RPC_SUCCESS) {
		if (! AUTH_VALIDATE(h->cl_auth, &reply_msg.acpted_rply.ar_verf)) {
			ct->ct_error.re_status = RPC_AUTHERROR;
			ct->ct_error.re_why = AUTH_INVALIDRESP;
		} else if (! (*xdr_results)(xdrs, results_ptr)) {
			if (ct->ct_error.re_status == RPC_SUCCESS)
				ct->ct_error.re_status = RPC_CANTDECODERES;
		}
		/* free verifier ... */
		if (reply_msg.acpted_rply.ar_verf.oa_base != NULL) {
			xdrs->x_op = XDR_FREE;
			(void)xdr_opaque_auth(xdrs, &(reply_msg.acpted_rply.ar_verf));
		}
	}  /* end successful completion */
	else {
		/* maybe our credentials need to be refreshed ... */
		if (refreshes-- && AUTH_REFRESH(h->cl_auth))
			goto call_again;
	}  /* end of unsuccessful completion */
	return (ct->ct_error.re_status);
}
예제 #8
0
static enum clnt_stat
clnt_vc_call(
	CLIENT *h,
	rpcproc_t proc,
	xdrproc_t xdr_args,
	const char *args_ptr,
	xdrproc_t xdr_results,
	caddr_t results_ptr,
	struct timeval timeout
)
{
	struct ct_data *ct;
	XDR *xdrs;
	struct rpc_msg reply_msg;
	u_int32_t x_id;
	u_int32_t *msg_x_id;
	bool_t shipnow;
	int refreshes = 2;
#ifdef _REENTRANT
	sigset_t mask, newmask;
#endif

	_DIAGASSERT(h != NULL);

	ct = (struct ct_data *) h->cl_private;

#ifdef _REENTRANT
	__clnt_sigfillset(&newmask);
	thr_sigsetmask(SIG_SETMASK, &newmask, &mask);
	mutex_lock(&clnt_fd_lock);
	while (vc_fd_locks[ct->ct_fd])
		cond_wait(&vc_cv[ct->ct_fd], &clnt_fd_lock);
	vc_fd_locks[ct->ct_fd] = __rpc_lock_value;
	mutex_unlock(&clnt_fd_lock);
#endif

	xdrs = &(ct->ct_xdrs);
	msg_x_id = &ct->ct_u.ct_mcalli;

	if (!ct->ct_waitset) {
		if (time_not_ok(&timeout) == FALSE)
		ct->ct_wait = timeout;
	}

	shipnow =
	    (xdr_results == NULL && timeout.tv_sec == 0
	    && timeout.tv_usec == 0) ? FALSE : TRUE;

call_again:
	xdrs->x_op = XDR_ENCODE;
	ct->ct_error.re_status = RPC_SUCCESS;
	x_id = ntohl(--(*msg_x_id));
	if ((! XDR_PUTBYTES(xdrs, ct->ct_u.ct_mcallc, ct->ct_mpos)) ||
	    (! XDR_PUTINT32(xdrs, (int32_t *)&proc)) ||
	    (! AUTH_MARSHALL(h->cl_auth, xdrs)) ||
	    (! (*xdr_args)(xdrs, __UNCONST(args_ptr)))) {
		if (ct->ct_error.re_status == RPC_SUCCESS)
			ct->ct_error.re_status = RPC_CANTENCODEARGS;
		(void)xdrrec_endofrecord(xdrs, TRUE);
		release_fd_lock(ct->ct_fd, mask);
		return (ct->ct_error.re_status);
	}
	if (! xdrrec_endofrecord(xdrs, shipnow)) {
		release_fd_lock(ct->ct_fd, mask);
		return (ct->ct_error.re_status = RPC_CANTSEND);
	}
	if (! shipnow) {
		release_fd_lock(ct->ct_fd, mask);
		return (RPC_SUCCESS);
	}
	/*
	 * Hack to provide rpc-based message passing
	 */
	if (timeout.tv_sec == 0 && timeout.tv_usec == 0) {
		release_fd_lock(ct->ct_fd, mask);
		return(ct->ct_error.re_status = RPC_TIMEDOUT);
	}


	/*
	 * Keep receiving until we get a valid transaction id
	 */
	xdrs->x_op = XDR_DECODE;
	for (;;) {
		reply_msg.acpted_rply.ar_verf = _null_auth;
		reply_msg.acpted_rply.ar_results.where = NULL;
		reply_msg.acpted_rply.ar_results.proc = (xdrproc_t)xdr_void;
		if (! xdrrec_skiprecord(xdrs)) {
			release_fd_lock(ct->ct_fd, mask);
			return (ct->ct_error.re_status);
		}
		/* now decode and validate the response header */
		if (! xdr_replymsg(xdrs, &reply_msg)) {
			if (ct->ct_error.re_status == RPC_SUCCESS)
				continue;
			release_fd_lock(ct->ct_fd, mask);
			return (ct->ct_error.re_status);
		}
		if (reply_msg.rm_xid == x_id)
			break;
	}

	/*
	 * process header
	 */
	_seterr_reply(&reply_msg, &(ct->ct_error));
	if (ct->ct_error.re_status == RPC_SUCCESS) {
		if (! AUTH_VALIDATE(h->cl_auth,
		    &reply_msg.acpted_rply.ar_verf)) {
			ct->ct_error.re_status = RPC_AUTHERROR;
			ct->ct_error.re_why = AUTH_INVALIDRESP;
		} else if (! (*xdr_results)(xdrs, results_ptr)) {
			if (ct->ct_error.re_status == RPC_SUCCESS)
				ct->ct_error.re_status = RPC_CANTDECODERES;
		}
		/* free verifier ... */
		if (reply_msg.acpted_rply.ar_verf.oa_base != NULL) {
			xdrs->x_op = XDR_FREE;
			(void)xdr_opaque_auth(xdrs,
			    &(reply_msg.acpted_rply.ar_verf));
		}
	}  /* end successful completion */
	else {
		/* maybe our credentials need to be refreshed ... */
		if (refreshes-- && AUTH_REFRESH(h->cl_auth))
			goto call_again;
	}  /* end of unsuccessful completion */
	release_fd_lock(ct->ct_fd, mask);
	return (ct->ct_error.re_status);
}
예제 #9
0
/*
 * ndmp_send_request
 *
 * Send an NDMP request message.
 *
 * Parameters:
 *   connection_handle (input) - connection pointer.
 *   message (input) - message number.
 *   err (input)  - error code to place in header.
 *   request_data (input) - message body.
 *   reply (output) - reply message. If 0, reply will be
 *				discarded.
 *
 * Returns:
 *   0	- successful send.
 *  -1	- error.
 *   otherwise - error from reply header.
 *
 * Notes:
 *   - The reply body is only returned if the error code is NDMP_NO_ERR.
 */
int
ndmp_send_request(ndmp_connection_t *connection_handle, ndmp_message message,
    ndmp_error err, void *request_data, void **reply)
{
	ndmp_connection_t *connection = (ndmp_connection_t *)connection_handle;
	ndmp_header header;
	ndmp_msg_handler_t *handler;
	int r;
	struct timeval time;

	/* Lookup info necessary for processing this request. */
	if (!(handler = ndmp_get_handler(connection, message))) {
		NDMP_LOG(LOG_DEBUG, "Sending message 0x%x: not supported",
		    message);
		return (-1);
	}
	(void) gettimeofday(&time, 0);

	header.sequence = ++(connection->conn_my_sequence);
	header.time_stamp = time.tv_sec;
	header.message_type = NDMP_MESSAGE_REQUEST;
	header.message = message;
	header.reply_sequence = 0;
	header.error = err;

	connection->conn_xdrs.x_op = XDR_ENCODE;
	if (!xdr_ndmp_header(&connection->conn_xdrs, &header)) {
		NDMP_LOG(LOG_DEBUG,
		    "Sending message 0x%x: encoding request header", message);
		(void) xdrrec_endofrecord(&connection->conn_xdrs, 1);
		return (-1);
	}
	if (err == NDMP_NO_ERR && handler->mh_xdr_request && request_data) {
		if (!(*handler->mh_xdr_request)(&connection->conn_xdrs,
		    request_data)) {
			NDMP_LOG(LOG_DEBUG,
			    "Sending message 0x%x: encoding request body",
			    message);
			(void) xdrrec_endofrecord(&connection->conn_xdrs, 1);
			return (-1);
		}
	}
	(void) xdrrec_endofrecord(&connection->conn_xdrs, 1);

	if (handler->mh_xdr_reply == 0) {
		NDMP_LOG(LOG_DEBUG, "handler->mh_xdr_reply == 0");
		return (0);
	}

	/*
	 * Process messages until the reply to this request has been
	 * processed.
	 */
	for (; ; ) {
		r = ndmp_process_messages(connection, TRUE);

		/* connection error? */
		if (r < 0)
			return (-1);

		/* no reply received? */
		if (r == 0)
			continue;

		/* reply received? */
		if (r == 1) {
			if (message !=
			    connection->conn_msginfo.mi_hdr.message) {
				NDMP_LOG(LOG_DEBUG,
				    "Received unexpected reply 0x%x",
				    connection->conn_msginfo.mi_hdr.message);
				ndmp_free_message(connection_handle);
				return (-1);
			}
			if (reply != NULL)
				*reply = connection->conn_msginfo.mi_body;
			else
				ndmp_free_message(connection_handle);

			return (connection->conn_msginfo.mi_hdr.error);
		}
		/* error handling reply */

		return (-1);
	}
}
예제 #10
0
bool_t P_xdrrec_endofrecord(XDR *x, int now) {return (xdrrec_endofrecord(x, now));}
예제 #11
0
파일: clnt_tcp.c 프로젝트: PADL/krb5
static enum clnt_stat
clnttcp_call(
	CLIENT *h,
	rpcproc_t proc,
	xdrproc_t xdr_args,
	void * args_ptr,
	xdrproc_t xdr_results,
	void * results_ptr,
	struct timeval timeout)
{
	struct ct_data *ct = h->cl_private;
	XDR *xdrs = &ct->ct_xdrs;
	struct rpc_msg reply_msg;
	uint32_t x_id;
	uint32_t *msg_x_id = &ct->ct_u.ct_mcalli;	/* yuk */
	bool_t shipnow;
	int refreshes = 2;
	long procl = proc;

	if (!ct->ct_waitset) {
		ct->ct_wait = timeout;
	}

	shipnow =
	    (xdr_results == (xdrproc_t)0 && timeout.tv_sec == 0
	    && timeout.tv_usec == 0) ? FALSE : TRUE;

call_again:
	xdrs->x_op = XDR_ENCODE;
	ct->ct_error.re_status = RPC_SUCCESS;
	x_id = ntohl(--(*msg_x_id));
	if ((! XDR_PUTBYTES(xdrs, ct->ct_u.ct_mcall, ct->ct_mpos)) ||
	    (! XDR_PUTLONG(xdrs, &procl)) ||
	    (! AUTH_MARSHALL(h->cl_auth, xdrs)) ||
	    (! AUTH_WRAP(h->cl_auth, xdrs, xdr_args, args_ptr))) {
		if (ct->ct_error.re_status == RPC_SUCCESS)
			ct->ct_error.re_status = RPC_CANTENCODEARGS;
		(void)xdrrec_endofrecord(xdrs, TRUE);
		return (ct->ct_error.re_status);
	}
	if (! xdrrec_endofrecord(xdrs, shipnow))
		return (ct->ct_error.re_status = RPC_CANTSEND);
	if (! shipnow)
		return (RPC_SUCCESS);
	/*
	 * Hack to provide rpc-based message passing
	 */
	if (timeout.tv_sec == 0 && timeout.tv_usec == 0) {
		return(ct->ct_error.re_status = RPC_TIMEDOUT);
	}


	/*
	 * Keep receiving until we get a valid transaction id
	 */
	xdrs->x_op = XDR_DECODE;
	while (TRUE) {
		reply_msg.acpted_rply.ar_verf = gssrpc__null_auth;
		reply_msg.acpted_rply.ar_results.where = NULL;
		reply_msg.acpted_rply.ar_results.proc = xdr_void;
		if (! xdrrec_skiprecord(xdrs))
			return (ct->ct_error.re_status);
		/* now decode and validate the response header */
		if (! xdr_replymsg(xdrs, &reply_msg)) {
			/*
			 * Free some stuff allocated by xdr_replymsg()
			 * to avoid leaks, since it may allocate
			 * memory from partially successful decodes.
			 */
			enum xdr_op op = xdrs->x_op;
			xdrs->x_op = XDR_FREE;
			xdr_replymsg(xdrs, &reply_msg);
			xdrs->x_op = op;
			if (ct->ct_error.re_status == RPC_SUCCESS)
				continue;
			return (ct->ct_error.re_status);
		}
		if (reply_msg.rm_xid == x_id)
			break;
	}

	/*
	 * process header
	 */
	gssrpc__seterr_reply(&reply_msg, &(ct->ct_error));
	if (ct->ct_error.re_status == RPC_SUCCESS) {
		if (! AUTH_VALIDATE(h->cl_auth, &reply_msg.acpted_rply.ar_verf)) {
			ct->ct_error.re_status = RPC_AUTHERROR;
			ct->ct_error.re_why = AUTH_INVALIDRESP;
		} else if (! AUTH_UNWRAP(h->cl_auth, xdrs,
					 xdr_results, results_ptr)) {
			if (ct->ct_error.re_status == RPC_SUCCESS)
				ct->ct_error.re_status = RPC_CANTDECODERES;
		}
	}  /* end successful completion */
	else {
		/* maybe our credentials need to be refreshed ... */
		if (refreshes-- && AUTH_REFRESH(h->cl_auth, &reply_msg))
			goto call_again;
	}  /* end of unsuccessful completion */
	/* free verifier ... */
	if ((reply_msg.rm_reply.rp_stat == MSG_ACCEPTED) &&
	    (reply_msg.acpted_rply.ar_verf.oa_base != NULL)) {
	    xdrs->x_op = XDR_FREE;
	    (void)xdr_opaque_auth(xdrs, &(reply_msg.acpted_rply.ar_verf));
	}
	return (ct->ct_error.re_status);
}