예제 #1
0
파일: clnt_dg.c 프로젝트: hkoehler/ntirpc
static void
clnt_dg_destroy(CLIENT *clnt)
{
	struct cx_data *cx = (struct cx_data *)clnt->cl_p1;
	struct rpc_dplx_rec *rec = (struct rpc_dplx_rec *)clnt->cl_p2;
	int cu_fd = CU_DATA(cx)->cu_fd;
	sigset_t mask, newmask;

	/* Handle our own signal mask here, the signal section is
	 * larger than the wait (not 100% clear why) */
	sigfillset(&newmask);
	thr_sigsetmask(SIG_SETMASK, &newmask, &mask);

	/* barrier both channels */
	rpc_dplx_swc(clnt, rpc_flag_clear);
	rpc_dplx_rwc(clnt, rpc_flag_clear);

	if (CU_DATA(cx)->cu_closeit)
		(void)close(cu_fd);
	XDR_DESTROY(&(CU_DATA(cx)->cu_outxdrs));

	/* signal both channels */
	rpc_dplx_ssc(clnt, RPC_DPLX_FLAG_NONE);
	rpc_dplx_rsc(clnt, RPC_DPLX_FLAG_NONE);

	/* release */
	rpc_dplx_unref(rec, RPC_DPLX_FLAG_NONE);
	free_cx_data(cx);

	if (clnt->cl_netid && clnt->cl_netid[0])
		mem_free(clnt->cl_netid, strlen(clnt->cl_netid) + 1);
	if (clnt->cl_tp && clnt->cl_tp[0])
		mem_free(clnt->cl_tp, strlen(clnt->cl_tp) + 1);
	mem_free(clnt, sizeof(CLIENT));
	thr_sigsetmask(SIG_SETMASK, &mask, NULL);
}
예제 #2
0
파일: clnt_dg.c 프로젝트: hkoehler/ntirpc
/*
 * 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);
}
예제 #3
0
/*
 * client mooshika create
 */
CLIENT *
clnt_msk_create(msk_trans_t *trans,	        /* init but NOT connect()ed descriptor */
                rpcprog_t program,		/* program number */
                rpcvers_t version,		/* version number */
                u_int credits)			/* credits = number of parallel messages */
{
	CLIENT *cl = NULL;		/* client handle */
	struct cx_data *cx = NULL;	/* private data */
        struct cm_data *cm = NULL;
	struct timeval now;

	if (!trans || trans->state != MSK_INIT) {
		rpc_createerr.cf_stat = RPC_UNKNOWNADDR; /* FIXME, add a warnx? */
		rpc_createerr.cf_error.re_errno = 0;
		return (NULL);
	}

	/*
	 * Find the receive and the send size
	 */
//	u_int sendsz = 8*1024;
//	u_int recvsz = 4*8*1024;
	u_int sendsz = 1024;
	u_int recvsz = 1024;

	if (credits == 0)
		credits = 10;


	if ((cl = mem_alloc(sizeof (CLIENT))) == NULL)
		goto err1;
	/*
	 * Should be multiple of 4 for XDR.
	 */
        cx = alloc_cx_data(CX_MSK_DATA, sendsz, recvsz);
	if (cx == NULL)
		goto err1;
        cm = CM_DATA(cx);
	/* Other values can also be set through clnt_control() */
	cm->trans = trans;
	cm->cm_wait.tv_sec = 15; /* heuristically chosen */
	cm->cm_wait.tv_usec = 0;

	(void) gettimeofday(&now, NULL);
	cm->call_msg.rm_xid = __RPC_GETXID(&now);
	cm->call_msg.rm_call.cb_prog = program;
	cm->call_msg.rm_call.cb_vers = version;

	msk_connect(trans);

	xdrmsk_create(&cm->cm_xdrs, trans, sendsz, recvsz, credits, NULL, NULL);

	msk_finalize_connect(trans);


	/*
	 * 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.
	 */
	cm->cm_closeit = FALSE;
	cl->cl_ops = clnt_msk_ops();
	cl->cl_private = (caddr_t)(void *) cx;
	cl->cl_auth = authnone_create();
	cl->cl_tp = NULL;
	cl->cl_netid = NULL;
	
	return (cl);
err1:
	__warnx("clnt_msk_create: out of memory");
	rpc_createerr.cf_stat = RPC_SYSTEMERROR;
	rpc_createerr.cf_error.re_errno = errno;
	if (cl) {
		mem_free(cl, sizeof (CLIENT));
		if (cx)
                    free_cx_data(cx);
	}
	return (NULL);
}