示例#1
0
void
rpc_dplx_ruf(int fd)
{
    uint32_t oflags;
    struct rpc_dplx_rec *rec =
        rpc_dplx_lookup_rec(fd, RPC_DPLX_FLAG_NONE, &oflags);
    /* assert: initialized */
    mutex_unlock(&rec->recv.lock.we.mtx);
}
示例#2
0
void
rpc_dplx_rlfi(int fd, const char *func, int line)
{
    uint32_t oflags;
    struct rpc_dplx_rec *rec =
        rpc_dplx_lookup_rec(fd, RPC_DPLX_FLAG_NONE, &oflags);
    rpc_dplx_lock_t *lk = &rec->recv.lock;

    mutex_lock(&lk->we.mtx);
    if (__pkg_params.debug_flags & TIRPC_DEBUG_FLAG_LOCK) {
        lk->locktrace.func = (char*) func;
        lk->locktrace.line = line;
    }

}
示例#3
0
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);
}
示例#4
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);
}