Sun Microsystems, Inc.
spacerspacer
spacer www.sun.com docs.sun.com |
spacer
black dot
 
 
4.  Programmer's Interface to RPC Standard Interfaces Bottom-Level Interface Client Side of the Bottom-Level Interface  Previous   Contents   Next 
   
 

Server Side of the Bottom-Level Interface

The following code example is an example of creating a bottom-level server.


Example 4-15 Server for Bottom Level

/*
 * variables are:
 * xprt: SVCXPRT *
 */
switch(tinfo.servtype) {
	case T_COTS_ORD:
	case T_COTS:
		xprt = svc_vc_create(fd, sendsz, recvsz);

		break;
	case T_CLTS:
		xprt = svc_dg_create(fd, sendsz, recvsz);

		break;
	default:
		goto err;
}

Server Caching

svc_dg_enablecache() initiates service caching for datagram transports. Caching should be used only in cases where a server procedure is a "once only" kind of operation. Executing a cached server procedure multiple times yields different results.

svc_dg_enablecache(xprt, cache_size)
    SVCXPRT *xprt;
    unsigned int cache_size;

This function allocates a duplicate request cache for the service endpoint xprt, large enough to hold cache_size entries. A duplicate request cache is needed if the service contains procedures with varying results. After caching is enabled, it cannot be disabled.

Low-Level Data Structures

The following data structure information is for reference only. The implementation might change.

The first structure is the client RPC handle, defined in <rpc/clnt.h>. Low-level implementations must provide and initialize one handle per connection, as shown in the following code example.


Example 4-16 RPC Client Handle Structure

typedef struct {
	AUTH *cl_auth;								/* authenticator */
	struct clnt_ops {
		enum clnt_stat	(*cl_call)();		/* call remote procedure */
		void			(*cl_abort)();			/* abort a call */
		void			(*cl_geterr)();		/* get specific error code */
		bool_t			(*cl_freeres)();	/* frees results */
		void			(*cl_destroy)();		/* destroy this structure */
		bool_t			(*cl_control)();	/* the ioctl() of rpc */
	} *cl_ops;
	caddrt_t			cl_private;				/* private stuff */
	char			*cl_netid;					/* network token */
	char			*cl_tp;						/* device name */
} CLIENT;

The first field of the client-side handle is an authentication structure, defined in <rpc/auth.h>. By default, this field is set to AUTH_NONE. A client program must initialize cl_auth appropriately, as shown in the following code example.


Example 4-17 Client Authentication Handle

typedef struct {
	struct			opaque_auth  ah_cred;
	struct			opaque_auth  ah_verf;
	union			des_block    ah_key;
	struct auth_ops {
		void		(*ah_nextverf)();
		int		(*ah_marshal)();			/* nextverf & serialize */
		int		(*ah_validate)();			/* validate varifier */
		int		(*ah_refresh)();			/* refresh credentials */
		void		(*ah_destroy)();			/* destroy this structure */
	} *ah_ops;
	caddr_t ah_private;
} AUTH;

In the AUTH structure, ah_cred contains the caller's credentials, and ah_verf contains the data to verify the credentials. See "Authentication" for details.

The following code example shows the server transport handle.


Example 4-18 Server Transport Handle

typedef struct {
	int			xp_fd;
#define xp_sock					xp_fd
	u_short xp_port;		/* associated port number. Obsoleted */
	struct xp_ops {
	    bool_t		(*xp_recv)();		/* receive incoming requests */
	   enum xprt_stat (*xp_stat)();			/* get transport status */
	    bool_t				(*xp_getargs)();	/* get arguments */
	    bool_t				(*xp_reply)();		/* send reply */
	    bool_t		(*xp_freeargs)();		/* free mem alloc for args */
	    void			 *xp_destroy)();		/* destroy this struct */
	} *xp_ops;
	int		xp_addrlen;			/* length of remote addr. Obsolete */
	char		*xp_tp;				/* transport provider device name */
	char		*xp_netid;			/* network token */
	struct netbuf  xp_ltaddr;		/* local transport address */
	struct netbuf  xp_rtaddr;		/* remote transport address */
	char				xp_raddr[16];	/* remote address. Now obsoleted */
	struct opaque_auth xp_verf;	/* raw response verifier */
	caddr_t				xp_p1;		/* private: for use by svc ops */
	caddr_t				xp_p2;		/* private: for use by svc ops */
	caddr_t				xp_p3;		/* private: for use by svc lib */
} SVCXPRT;

The following table shows the fields for the server transport handle.

xp_fd

The file descriptor associated with the handle. Two or more server handles can share the same file descriptor.

xp_netid

The network identifier (for example, udp) of the transport on which the handle is created and xp_tp is the device name associated with that transport.

xp_ltaddr

The server's own bind address.

xp_rtaddr

The address of the remote caller (and so can change from call to call).

xp_netid xp_tp xp_ltaddr

Initialized by svc_tli_create() and other expert-level routines.

The rest of the fields are initialized by the bottom-level server routines svc_dg_create() and svc_vc_create().

For connection-oriented endpoints, the following fields are not valid until a connection has been requested and accepted for the server:

xp_fd
xp_ops()
xp_p1()
xp_p2
xp_verf()
xp_tp()
xp_ltaddr
xp_rtaddr()
xp_netid()

 
 
 
  Previous   Contents   Next