ONC+ Developer's Guide

Using Transient RPC Program Numbers

Occasionally, it is useful for an application to use RPC program numbers that are generated dynamically. This could be used for implementing callback procedures, for example. In the callback example, a client program typically registers an RPC service using a dynamically generated, or transient, RPC program number and passes this on to a server along with a request. The server will then call back the client program using the transient RPC program number in order to supply the results. Such a mechanism may be necessary if processing the client's request will take a huge amount of time and the client cannot block (assuming it is single-threaded); in this case, the server will acknowledge the client's request, and call back later with the results. Another use of callbacks is to generate periodic reports from a server; the client makes an RPC call to start the reporting, and the server periodically calls back the client with reports using the transient RPC program number supplied by the client program.

Dynamically generated, or transient, RPC program numbers are in the transient range, 0x40000000 - 0x5fffffff. The following routine creates a service based on a transient RPC program for a given transport type. The service handle and the transient rpc program number are returned. The caller supplies the service dispatch routine, the version, and the transport type.


Example 4-37 Transient RPC Program--Server Side

SVCXPRT *register_transient_prog(dispatch, program, version, netid)
	void (*dispatch)(); /* service dispatch routine */
	rpcproc_t *program;    /* returned transient RPC number */
	rpcvers_t version;     /* program version */
	char *netid;        /* transport id */
{
	SVCXPRT  *transp;
	struct netconfig *nconf;
	rpcprog_t prognum;
	if ((nconf = getnetconfigent(netid)) == (struct netconfig
*)NULL)
		return ((SVCXPRT *)NULL);
	if ((transp = svc_tli_create(RPC_ANYFD, nconf,
				(struct t_bind *)NULL, 0, 0)) == (SVCXPRT *)NULL) {
		freenetconfigent(nconf);
		return ((SVCXPRT *)NULL);
	}
	prognum = 0x40000000;
	while (prognum < 0x60000000 && svc_reg(transp, prognum,
version,
									dispatch, nconf) == 0) {
		prognum++;
	}
	freenetconfigent(nconf);
	if (prognum >= 0x60000000) {
		svc_destroy(transp);
		return ((SVCXPRT *)NULL);
	}
	*program = prognum;
	return (transp);
}