11. RPC RTL Server Routines

Introduction

This chapter is for RPC programmers. It documents the server routines in the RPC Run-Time Library (RTL). These routines are the programming interface to RPC.

Server Routines

The server routines are called by the server program or the server stub procedures. The below table lists each server routine and summarizes its purpose.

Routine

Purpose

registerrpc

Performs creation and registration tasks for server.

svc_destroy

Macro that destroys RPC server handle.

svc_freeargs

Macro that frees memory allocated when RPC arguments were decoded.

svc_getargs

Macro that decodes RPC arguments.

svc_getreqset

Reads data for each server connection.

svc_register

Adds specified server to list of active servers, and registers service program with Port Mapper.

svc_run

Waits for RPC requests and calls svc_getreqset routine to dispatch to appropriate RPC service program.

svc_sendreply

Sends results of remote procedure call to client.

svc_unregister

Calls Port Mapper to unregister specified program and version for all protocols.

svcerr_auth

svcerr_decode

svcerr_noproc


svcerr_noprog


svcerr_progvers


svcerr_systemerr


svcerr_weakauth

Sends error code when server cannot authenticate client.

Sends error code to client if server cannot decode arguments.

Sends error code to client if server cannot implement requested procedure.

Sends error code to client when requested program is not registered with Port Mapper.

Sends error code to client when requested program is registered with Port Mapper, but requested version is not registered.

Sends error code to client when server encounters error not handled by particular protocol.

Sends error code to client when server cannot perform remote procedure call because it received insufficient (but correct) authentication parameters.

svcfd_create

Returns address of structure containing server handle for specified TCP socket.

svctcp_create

Returns address of server handle that uses TCP transport.

svcudp_bufcreate /
svcudp_create

Returns address of server handle that uses UDP transport. For procedures that pass messages longer than 8Kbytes.

svcudp_enablecache

Enables XID cache for specified UDP transport server.

xprt_register

Adds UDP or TCP server socket to list of sockets.

xprt_unregister

Removes UDP or TCP server socket from list of sockets.

 

The following sections describe each server routine in detail.


 

registerrpc

Performs creation and registration tasks for the server.

 

Format

int registerrpc(u_long prognum, u_long versnum, u_long procnum,
u_char *(*procname) (), xdrproc_t inproc, xdrproc_t outproc);

 

Arguments

prognum, versnum, procnum, inproc, outproc

See the Common Arguments table in the RPC RTL Client Routines chapter for a list of these arguments.

procname

Address of the routine that implements the service procedure. The routine uses the following format:

u_char *procname(u_char *out);

out is the address of the data decoded by outproc.

 

Description

The registerrpc routine performs the following tasks for a server:

·         Creates a UDP server handle.

·         Calls the svc_register routine to register the program with the Port Mapper.

·         Adds prognum, versnum, and procnum to an internal list of registered procedures. When the server receives a request, it uses this list to determine which routine to call.

A server should call registerrpc for every procedure it implements, except for the NULL procedure.

 

Returns

The registerrpc routine returns zero if it succeeds, and -1 if it fails.

 

 

 

 


 

svc_destroy

Macro that destroys the RPC server handle.

 

Format

void svc_destroy (SVCXPRT *xprt);

 

Argument

xprt

RPC server handle.

 

Description

The svc_destroy routine destroys xprt by deallocating private data structures. After this call, xprt is undefined.

If the server creation routine received RPC_ANYSOCK as the socket, svc_destroy closes the socket. Otherwise, you must close the socket.

 

 

 

 


 

svc_freeargs

Macro that frees the memory that was allocated when the RPC arguments were decoded.

 

Format

bool_t svc_freeargs (SVCXPRT *xprt, xdrproc_t xdr_args, char *args_ptr);

 

Arguments

xprt, xdr_args, args_ptr

See the Common Arguments table in the RPC RTL Client Routines chapter for a list of these arguments.

 

Description

The svc_freeargs routine calls the xdr_free routine.

 

Returns

This routine returns TRUE if it succeeds and FALSE if it fails.

 

 

 

 


 

svc_getargs

Macro that decodes the RPC arguments.

 

Format

bool_t svc_getargs (SVCXPRT *xprt, xdrproc_t xdr_args, u_char *args_ptr);

 

Arguments

xprt, xdr_args, args_ptr

See the Common Arguments table in the RPC RTL Client Routines chapter for a list of these arguments.

 

Returns

This routine returns TRUE if it succeeds and FALSE if it fails.

 

 

 

 


 

svc_getreqset

Reads data for each server connection.

 

Format

void svc_getreqset (int rdfds);

 

Argument

rdfds

Address of the read socket descriptor array. This array is returned by the select routine.

 

Description

The server calls svc_getreqset when it receives an RPC request. The svc_getreqset routine reads in data for each server connection, then calls the server program to handle the data.

The svc_getreqset routine does not return a value. It finishes executing after all rdfds sockets have been serviced.

You are unlikely to call this routine directly, because the svc_run routine calls it. However, there are times when you cannot call svc_run. For example, suppose a program services RPC requests and reads or writes to another socket at the same time. The program cannot call svc_run. It must call select and svc_getreqset.

The svc_getreqset routine is for servers that implement custom asynchronous event processing, do not use the svc_run routine.

You may use the global variable svc_fdset with svc_getreqset. The svc_fdset variable lists all sockets the server is using. It contains an array of structures, where each element is a socket pointer and a service handle. It uses the following format:

struct sockarr svc_fdset [MAXSOCK +1];

This is how to use svc_fdset: first, copy the socket handles from svc_fdset into a temporary array that ends with a zero. Pass the array to the select() routine. The select() routine overwrites the array and returns it. Pass this array to the svc_getreqset routine.

You may use svc_fdset when the server does not use svc_run.

The svc_fdset variable is not compatible with UNIX.

 

Example

#define MAXSOCK         10

int readfds[ MAXSOCK+1],    /* sockets to select from */
    i, j;

for (i = 0, j = 0; i < MAXSOCK; i++)
  if ((svc_fdset[i].sockname != 0) && (svc_fdset[i].sockname != 1))
    readfds[j++] = svc_fdset[i].sockname;


readfds[j] = 0;  

              /* list of sockets ends w/ a zero */
switch (select(0, readfds, 0, 0, 0))

{
  case -1:      /* an error happened */
  case 0:       /* time out */
           break;
  default:      /* 1 or more sockets ready for reading */
           errno = 0;
           ONCRPC_SVC_GET_REQSET(readfds);
           if (errno == ENETDOWN || errno == ENOTCONN)
             sys$exit(SS$_THIRDPARTY);
}

 

 

 

 


 

svc_register

Adds the specified server to a list of active servers, and registers the service program with the Port Mapper.

 

Format

bool_t svc_register (SVCXPRT *xprt, u_long prognum, u_long versnum, void (*dispatch) (), u_long protocol);

 

Arguments

xprt, prognum, versnum

See the Common Arguments table in the RPC RTL Client Routines chapter for a list of these arguments.

 

dispatch

Routine that svc_register calls when the server receives a request for prognum, versnum. This routine determines which routine to call for each server procedure. This routine uses the following form:

void dispatch(struct svc_req *request, SVCXPRT *xprt);

The svc_getreqset and svc_run routines call dispatch.

 

protocol

Must be IPPROTO_UDP, IPPROTO_TCP, or zero. Zero indicates that you do not want to register the server with the Port Mapper.

 

Returns

The svc_register routine returns TRUE if it succeeds and FALSE if it fails.

 

 

 

 


 

svc_run

Waits for RPC requests and calls the svc_getreqset routine to dispatch to the appropriate RPC service program.

 

Format

void svc_run();

 

Description

The svc_run routine calls the select() routine to wait for RPC requests. When a request arrives, svc_run calls the svc_getreqset routine. Then svc_run calls select() again.

The svc_run routine never returns.

You may use the global variable svc_fdset with svc_run. See the svc_getreqset routine for more information on svc_fdset.

 

 

 

 


 

svc_sendreply

Sends the results of a remote procedure call to the client.

 

Format

bool_t svc_sendreply (SVCXPRT *xprt, xdrproc_t outproc, caddr_t *out);

 

Arguments

xprt, outproc, out

See the Common Arguments table in the RPC RTL Client Routines chapter for a list of these arguments.

 

Description

The routine sends the results of a remote procedure call to the client.

 

Returns

These routines return TRUE if they succeed and FALSE if they fail.

 

 

 

 


 

svc_unregister

Calls the Port Mapper to unregister the specified program and version for all protocols. The program and version are removed from the list of active servers.

 

Format

void svc_unregister (u_long prognum, u_long versnum);

 

Arguments

prognum, versnum

See the Common Arguments table in the RPC RTL Client Routines chapter for a list of these arguments.

 

 

 

 

 


 

svcerr_auth / svcerr_decode / svcerr_noproc / svcerr_noprog / svcerr_progvers / svcerr_systemerr / svcerr_weakauth

Sends various error codes to the client process.

 

Format

void svcerr_auth (SVCXPRT *xprt, enum auth_stat why);
void svcerr_decode (SVCXPRT *xprt);
void svcerr_noproc (SVCXPRT *xprt);
void svcerr_noprog (SVCXPRT *xprt);
void svcerr_progvers (SVCXPRT *xprt, u_long low-vers, u_long high-vers);
void svcerr_systemerr (SVCXPRT *xprt);
void svcerr_weakauth (SVCXPRT *xprt);

 

Arguments

xprt

RPC server handle.

 

why

Error code defined in the AUTH.H file.

 

low-vers

Lowest version number in the range of versions that the server supports.

 

high-vers

Highest version in the range of versions that the server supports.

 

Description

svcerr_auth

See svc_getreqset. Calls svcerr_auth when it cannot authenticate a client. The svcerr_auth routine returns an error code (why) to the caller.

svcerr_decode

Sends an error code to the client if the server cannot decode the arguments.

svcerr_noproc

Sends an error code to the client if the server does not implement the requested procedure.

svcerr_noprog

Sends an error code to the client when the requested program is not registered with the port mapper. Generally, the port mapper informs the client when a server is not registered. Therefore, the server is not expected to use this routine.

svcerr_progvers

Sends an error code to the client when the requested program is registered with the Port Mapper, but the requested version is not registered.

svcerr_systemerr

Sends an error code to the client when the server encounters an error that is not handled by a particular protocol.

svcerr_weakauth

Sends an error code to the client when the server cannot perform a remote procedure call because it received insufficient (but correct) authentication parameters. This routine calls the svcerr_auth routine. The value of why is AUTH_TOOWEAK, which means "access permission denied."

 

 

 

 


 

svcfd_create

Returns the address of a structure containing a server handle for the specified TCP socket.

 

Format

SVCXPRT *svcfd_create (int sock, u_long sendsize, u_long recvsize);

 

Arguments

sock

Socket number. Do not specify a file descriptor.

 

sendsize

Size of the send buffer. If you enter a value less than 100, then 4000 is used as the default.

 

recvsize

Size of the receive buffer. If you enter a value less than 100, then 4000 is used as the default.

 

Description

The svcfd_create routine returns the address of a server handle for the specified TCP socket. This handle cannot use a file. The server calls the svcfd_create routine after it accepts a TCP connection.

 

Returns

This routine returns zero if it fails.

 

 

 

 

 


 

svcraw_create

Creates a server handle for memory-based Sun RPC for simple testing and timing.

 

Format

SVCXPRT svcraw_create();

 

Description

The svcraw_create routine creates a toy Sun RPC service transport, to which it returns a pointer. The transport is really a buffer within the process's address space, so the corresponding client should live in the same address space.

This routine allows simulation of and acquisition of Sun RPC overheads (such as round-trip times) without any kernel interference.

 

Returns

This routine returns NULL if it fails.

 

 

 

 

 


 

svctcp_create

Returns the address of a server handle that uses the TCP transport.

 

Format

SVCXPRT *svctcp_create(int sock, u_long sendsize, u_long recvsize);

 

Arguments

sock

Socket for this service. The svctcp_create routine creates a new socket if you enter RPC_ANYSOCK. If the socket is not bound to a TCP port, svctcp_create binds it to an arbitrary port.

 

sendsize

Size of the send buffer. If you enter a value less than 100, then 4000 bytes is used as the default.

 

recvsize

Size of the receive buffer. If you enter a value less than 100, then 4000 bytes is used as the default.

 

Returns

The svctcp_create routine returns either the address of the server handle, or zero (if it could not create the server handle).

 

 

 

 

 


 

svcudp_create / svcudp_bufcreate

Returns the address of a server handle that uses the UDP transport.

 

Format

SVCXPRT *svcudp_create (int sock);

SVCXPRT *svcudp_bufcreate (int sock, u_long sendsize, u_long recvsize);

 

Arguments

sock

Socket for this service. These routines create a new socket if you enter RPC_ANYSOCK. If the socket is not bound to a UDP port, the routines bind it to an arbitrary port.

 

sendsize

Size of the send buffer. The minimum size is 100 bytes. The maximum size is 65468, the maximum UDP packet size. If you enter a value less than 100, then 4000 is used as the default.

 

recvsize

Size of the receive buffer. The minimum size is 100 bytes. The maximum size is 65000, the maximum UDP packet size. If you enter a value less than 100, then 4000 is used as the default.

 

Description

Use the svc_create routine only for procedures that pass messages shorter than 8Kbytes long. Use the svcudp_bufcreate routine for procedures that pass messages longer than 8Kbytes.

 

Returns

These routines return either a server handle, or zero (if they could not create the server handle).

 

 

 

 

 


 

svcudp_enablecache

Enables the XID cache for the specified UDP transport server.

 

Format

bool_t svcudp_enablecache (SVCXPRT *xprt, u_long size);

 

Arguments

xprt

RPC server handle.

 

size

Number of entries permitted in the XID cache. You may estimate this number based on how active the server is, and on how long you want to retain old replies.

 

Description

Use the svcudp_enablecache routine after a UDP server handle is created. The server places all outgoing responses in the XID cache. The cache can be used to improve the performance of the server, for example, by preventing the server from recalculating the results or sending incorrect results.

You cannot disable the XID cache for UDP servers.

The RPC Fundamentals, Chapter 6, provides more information on the XID cache.

 

Example

#define FALSE   0
#define UDP_CACHE_SIZE  10

SVCXPRT *udp_xprt;

udp_xprt = svcudp_create(RPC_ANYSOCK);


if (svcudp_enablecache(udp_xprts, UDP_CACHE_SIZE) == FALSE)
  printf("XID cache was not enabled");
else
  printf("XID cache was enabled");

Returns

This routine returns TRUE if it enables the XID cache, and FALSE if the cache was previously enabled or an error occurs.

 

 

 

 


 

xprt_register

Adds a TCP or UDP server socket to a list of sockets.

 

Format

void xprt_register (SVCXPRT *xprt);

 

Argument

xprt

RPC server handle.

 

Description

The xprt_register and xprt_unregister routines maintain a list of sockets. This list ensures that the correct server is called to process the request. The xprt_register routine adds the server socket to the svc_fdset variable, which also stores the server handle that is associated with the socket. The svc_run routine passes the list of sockets to the select() routine. The select() routine returns to svc_run a list of sockets that have outstanding requests.

You are unlikely to call this routine directly because svc_register calls it.

 

 

 

 

 


 

xprt_unregister

Removes a TCP or UDP server socket from a list of sockets.

 

Format

void xprt_unregister (SVCXPRT *xprt);

 

Argument

xprt

RPC server handle.

 

Description

This list of sockets ensures that the correct server is called to process the request. See the xprt_unregister routine for a description of how this list is maintained.

You are unlikely to call this routine directly because svc_unregister calls it.