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.
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 |
Sends error
code when server cannot authenticate client. |
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 / |
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.
Performs creation and registration tasks for the server.
int registerrpc(u_long prognum, u_long versnum, u_long procnum,
u_char *(*procname) (), xdrproc_t inproc, xdrproc_t outproc);
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.
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.
The registerrpc routine returns zero if it succeeds, and -1 if it fails.
Macro that destroys the RPC server handle.
void svc_destroy (SVCXPRT *xprt);
xprt
RPC server handle.
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.
Macro that frees the memory that was allocated when the RPC arguments were decoded.
bool_t svc_freeargs (SVCXPRT *xprt, xdrproc_t xdr_args, char *args_ptr);
xprt, xdr_args, args_ptr
See the Common Arguments table in the RPC RTL Client Routines chapter for a list of these arguments.
The svc_freeargs routine calls the xdr_free routine.
This routine returns TRUE if it succeeds and FALSE if it fails.
Macro that decodes the RPC arguments.
bool_t svc_getargs (SVCXPRT *xprt, xdrproc_t xdr_args, u_char *args_ptr);
xprt, xdr_args, args_ptr
See the Common Arguments table in the RPC RTL Client Routines chapter for a list of these arguments.
This routine returns TRUE if it succeeds and FALSE if it fails.
Reads data for each server connection.
void svc_getreqset (int rdfds);
rdfds
Address of the read socket descriptor array. This array is returned by the select routine.
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.
#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);
}
Adds the specified server to a list of active servers, and registers the service program with the Port Mapper.
bool_t svc_register (SVCXPRT *xprt, u_long prognum, u_long versnum, void (*dispatch) (), u_long protocol);
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.
The svc_register routine returns TRUE if it succeeds and FALSE if it fails.
Waits for RPC requests and calls the svc_getreqset routine to dispatch to the appropriate RPC service program.
void svc_run();
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.
Sends the results of a remote procedure call to the client.
bool_t svc_sendreply (SVCXPRT *xprt, xdrproc_t outproc, caddr_t *out);
xprt, outproc, out
See the Common Arguments table in the RPC RTL Client Routines chapter for a list of these arguments.
The routine sends the results of a remote procedure call to the client.
These routines return TRUE if they succeed and FALSE if they fail.
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.
void svc_unregister (u_long prognum, u_long versnum);
prognum, versnum
See the Common Arguments table in the RPC RTL Client Routines chapter for a list of these arguments.
Sends various error codes to the client process.
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);
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.
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."
Returns the address of a structure containing a server handle for the specified TCP socket.
SVCXPRT *svcfd_create (int sock, u_long sendsize, u_long recvsize);
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.
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.
This routine returns zero if it fails.
Creates a server handle for memory-based Sun RPC for simple testing and timing.
SVCXPRT svcraw_create();
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.
This routine returns NULL if it fails.
Returns the address of a server handle that uses the TCP transport.
SVCXPRT *svctcp_create(int sock, u_long sendsize, u_long recvsize);
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.
The svctcp_create routine returns either the address of the server handle, or zero (if it could not create the server handle).
Returns the address of a server handle that uses the UDP transport.
SVCXPRT *svcudp_create (int sock);
SVCXPRT *svcudp_bufcreate (int sock, u_long sendsize, u_long recvsize);
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.
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.
These routines return either a server handle, or zero (if they could not create the server handle).
Enables the XID cache for the specified UDP transport server.
bool_t svcudp_enablecache (SVCXPRT *xprt, u_long size);
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.
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.
#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");
This routine returns TRUE if it enables the XID cache, and FALSE if the cache was previously enabled or an error occurs.
Adds a TCP or UDP server socket to a list of sockets.
void xprt_register (SVCXPRT *xprt);
xprt
RPC server handle.
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.
Removes a TCP or UDP server socket from a list of sockets.
void xprt_unregister (SVCXPRT *xprt);
xprt
RPC server handle.
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.