FreeBSD/sys/rpc/svc_vc.c
/*
 * Usage:
 *	xprt = svc_vc_create(sock, send_buf_size, recv_buf_size);
 *
 * Creates, registers, and returns a (rpc) tcp based transporter.
 * Once *xprt is initialized, it is registered as a transporter
 * see (svc.h, xprt_register).  This routine returns
 * a NULL if a problem occurred.
 *
 * The filedescriptor passed in is expected to refer to a bound, but
 * not yet connected socket.
 *
 * Since streams do buffered io similar to stdio, the caller can specify
 * how big the send and receive buffers are via the second and third parms;
 * 0 => use the system default.
 */


Creates, registers, and returns a (rpc) tcp based transporter.
Once *xprt is initialized, it is registered as a transporter
see (svc.h, xprt_register).  This routine returns
a NULL if a problem occurred.

The filedescriptor passed in is expected to refer to a bound, but
not yet connected socket.

Since streams do buffered io similar to stdio, the caller can specify
how big the send and receive buffers are via the second and third parms;
0 => use the system default.
Creates registers and returns a ( rpc ) tcp based transporter . Once * xprt is initialized it is registered as a transporter see ( svc . h xprt_register ) . This routine returns a NULL if a problem occurred . The filedescriptor passed in is expected to refer to a bound but not yet connected socket . Since streams do buffered io similar to stdio the caller can specify how big the send and receive buffers are via the second and third parms ; 0 = > use the system default .
SVCXPRT *
svc_vc_create(SVCPOOL *pool, struct socket *so, size_t sendsize,
    size_t recvsize)
{
	SVCXPRT *xprt;
	struct sockaddr* sa;
	int error;
	SOCK_LOCK(so);
	if (so->so_state & (SS_ISCONNECTED|SS_ISDISCONNECTED)) {
		SOCK_UNLOCK(so);
		CURVNET_SET(so->so_vnet);
		error = so->so_proto->pr_usrreqs->pru_peeraddr(so, &sa);
		CURVNET_RESTORE();
		if (error)
			return (NULL);
		xprt = svc_vc_create_conn(pool, so, sa);
		free(sa, M_SONAME);
		return (xprt);
	}
	SOCK_UNLOCK(so);
	xprt = svc_xprt_alloc();
	sx_init(&xprt->xp_lock, "xprt->xp_lock");
	xprt->xp_pool = pool;
	xprt->xp_socket = so;
	xprt->xp_p1 = NULL;
	xprt->xp_p2 = NULL;
	xprt->xp_ops = &svc_vc_rendezvous_ops;
	CURVNET_SET(so->so_vnet);
	error = so->so_proto->pr_usrreqs->pru_sockaddr(so, &sa);
	CURVNET_RESTORE();
	if (error) {
		goto cleanup_svc_vc_create;
	}
	memcpy(&xprt->xp_ltaddr, sa, sa->sa_len);
	free(sa, M_SONAME);
	xprt_register(xprt);
	solisten(so, -1, curthread);
	SOCKBUF_LOCK(&so->so_rcv);
	xprt->xp_upcallset = 1;
	soupcall_set(so, SO_RCV, svc_vc_soupcall, xprt);
	SOCKBUF_UNLOCK(&so->so_rcv);
	return (xprt);
cleanup_svc_vc_create:
	sx_destroy(&xprt->xp_lock);
	svc_xprt_free(xprt);
	return (NULL);
}
SVCXPRT * svc_vc_create ( SVCPOOL * pool , struct socket * so , size_t sendsize , size_t recvsize ) { SVCXPRT * xprt ; struct sockaddr * sa ; int error ; SOCK_LOCK ( so ) ; if ( so -> so_state & ( SS_ISCONNECTED | SS_ISDISCONNECTED ) ) { SOCK_UNLOCK ( so ) ; CURVNET_SET ( so -> so_vnet ) ; error = so -> so_proto -> pr_usrreqs -> pru_peeraddr ( so , & sa ) ; CURVNET_RESTORE ( ) ; if ( error ) return ( NULL ) ; xprt = svc_vc_create_conn ( pool , so , sa ) ; free ( sa , M_SONAME ) ; return ( xprt ) ; } SOCK_UNLOCK ( so ) ; xprt = svc_xprt_alloc ( ) ; sx_init ( & xprt -> xp_lock , " " ) ; xprt -> xp_pool = pool ; xprt -> xp_socket = so ; xprt -> xp_p1 = NULL ; xprt -> xp_p2 = NULL ; xprt -> xp_ops = & svc_vc_rendezvous_ops ; CURVNET_SET ( so -> so_vnet ) ; error = so -> so_proto -> pr_usrreqs -> pru_sockaddr ( so , & sa ) ; CURVNET_RESTORE ( ) ; if ( error ) { goto cleanup_svc_vc_create ; } memcpy ( & xprt -> xp_ltaddr , sa , sa -> sa_len ) ; free ( sa , M_SONAME ) ; xprt_register ( xprt ) ; solisten ( so , -1 , curthread ) ; SOCKBUF_LOCK ( & so -> so_rcv ) ; xprt -> xp_upcallset = 1 ; soupcall_set ( so , SO_RCV , svc_vc_soupcall , xprt ) ; SOCKBUF_UNLOCK ( & so -> so_rcv ) ; return ( xprt ) ; cleanup_svc_vc_create : sx_destroy ( & xprt -> xp_lock ) ; svc_xprt_free ( xprt ) ; return ( NULL ) ; }
Usage:
      xprt = svc_vc_create(sock, send_buf_size, recv_buf_size);
Usage : xprt = svc_vc_create ( sock send_buf_size recv_buf_size ) ;