10.5. Remote Procedure Call
The general mechanism for
client-server applications is provided by the
Remote Procedure
Call (RPC) package. RPC was developed by Sun
Microsystems and is a collection of tools and library functions. An
important application built on top of RPC is NFS.
An RPC server consists of a collection of
procedures that a client can call by sending an RPC request to the
server along with the procedure parameters. The server will invoke
the indicated procedure on behalf of the client, handing back the
return value, if there is any. In order to be machine-independent,
all data exchanged between client and server is converted to the
External Data
Representation format (XDR) by the sender, and
converted back to the machine-local representation by the receiver.
RPC relies on standard UDP and TCP sockets to transport the XDR
formatted data to the remote host. Sun has graciously placed RPC in
the public domain; it is described in a series of RFCs. Sometimes improvements to an RPC
application introduce incompatible changes in the procedure call
interface. Of course, simply changing the server would crash all
applications that still expect the original behavior. Therefore, RPC
programs have version numbers assigned to them, usually starting with
1, and with each new version of the RPC interface, this counter will
be bumped up. Often, a server may offer several versions
simultaneously; clients then indicate by the version number in their
requests which implementation of the service they want to use.
The communication between RPC servers and
clients is somewhat peculiar. An RPC server offers one or more
collections of procedures; each set is called a
program and is uniquely identified by a
program number. A list that
maps service names to program numbers is usually kept in
/etc/rpc, an excerpt of which is shown in Example 10-4.
Example 10-4. A sample /etc/rpc file
#In TCP/IP networks, the authors of RPC
# /etc/rpc - miscellaneous RPC-based services
#
portmapper 100000 portmap sunrpc
rstatd 100001 rstat rstat_svc rup perfmeter
rusersd 100002 rusers
nfs 100003 nfsprog
ypserv 100004 ypprog
mountd 100005 mount showmount
ypbind 100007
walld 100008 rwall shutdown
yppasswdd 100009 yppasswd
bootparam 100026
ypupdated 100028 ypupdate
faced the problem of mapping program numbers to generic network
services. They designed each server to provide both a TCP and a UDP
port for each program and each version. Generally, RPC applications
use UDP when sending data and fall back to TCP only when the data to
be transferred doesn't fit into a single UDP
datagram.Of course, client programs need to
find out to which port a program number maps. Using a configuration
file for this would be too inflexible; since RPC applications
don't use reserved ports, there's
no guarantee that a port originally meant to be used by our database
application hasn't been taken by some other process.
Therefore, RPC applications pick any available port and register it
with a special program called the portmapper
daemon. The portmapper acts as a service broker
for all RPC servers running on its machine. A client that wishes to
contact a service with a given program number first queries the
portmapper on the server's host, which returns the
TCP and UDP port numbers the service can be reached at.This method introduces a single point of failure, much like the
inetd daemon does for the standard Berkeley
services. However, this case is even a little worse because when the
portmapper dies, all RPC port information is lost; this usually means
that you have to restart all RPC servers manually or reboot the
entire machine.
On Linux, the portmapper is called
/sbin/portmap, or sometimes
/usr/sbin/rpc.portmap. Other than making sure it
is started from your network boot scripts, the portmapper
doesn't require any configuration.