AUUGN on the Web - Volume 16, Number 1:

Transparency and Performance Issues in Sun RPC

David Purdue < davidp@knowledge.com.au >


ABSTRACT

Sun RPC is an important implementation of a Remote Procedure Call mechanism, because it is included in almost all UNIX versions. This paper uses the construction of a sample Sun RPC program to examine issues of transparency and performance in Sun RPC.


1. Introduction

Sun RPC (Sun, 1990) is Sun Microsystems Computer Corporation's implementation of a Remote Procedure Call mechanism. It is an important example of RPC because it is used on almost all UNIX systems, (Black, 1992:281)the source code is available, (Comp.Sys.Research Group, 1994) it is used to implement Sun's Network File System (NFS), which is itself a widely used distributed file system, and it has been recommended as an Internet standard. (Sun, 1988) (Sun, 1987)

In this paper I shall provide an assessment of Sun RPC in terms of how well it provides a transparent remote procedure call mechanism, and in how much use of Sun RPC affects performance as opposed to using lower level network programming primitives.

1.1. An Example

In this paper I will be illustrating the points I make with an example. The example service is a function that provides an arbitrary number of random numbers. It is conceivable that this may be a desired distributed service, as mathematical calculation or simulation programs may need a source of truly random numbers, and there may be a machine on the network that is attached to an atomic source, or some other source of truly random numbers. It is a useful example for this project, because it allows me to construct messages of different sizes, for use in evaluating performance.

Having written a random number generating function and a program that uses it, I altered the program so that it would access the random number function over the network. Two such versions of the server and client were produced, one that uses Sun RPC, and another that uses the BSD socket interface to TCP (Stevens, 1990). Thus a comparison can be made in terms of transparency in the programmer's interface (going from local procedure call to RPC), and ease of programming (RPC versus socket programming).

The source code for these examples can be obtained from auug.org.au's ftp site.

2. An Overview of Sun RPC

The Sun RPC package consists of four components:

RPC and XDR protocols
The protocols used for client/server communication, and a language for describing the client/server interface;

rpcgen
A program that translates the description of the client/server interface into server and client stub routines;

a runtime library
to make it all work; and

the portmapper
a Sun RPC program that handles some transparency issues.

These elements are examined in more detail below.

2.1. RPC and XDR protocols

The XDR protocol (Sun, 1987) is a mechanism for encoding arbitrary data structures into a byte stream in a machine independent manner. The protocol also defines a language used to describe data structures that are to be sent with the XDR protocol.

At its simplest, XDR described issues such as byte ordering for integers [1] and the format for floating point numbers.[2] Character strings are sent with an ASCII encoding.[3] The standard goes on to describe how arrays, variable length arrays, structures and unions can be encoded. Although there is no direct support for pointers (as noted in Tanenbaum (1992:425) modern pointers only really make sense in the address space of the caller) XDR does support encoding for the recursive data structures they are often used to construct, such as linked lists or trees. This uses the "Optional-data" construct, and the syntax for describing it looks like the C syntax for pointers. This construct, however, does not support data structures of arbitrary complexity, for example it is not trivial to encode doubly linked lists.

XDR is an implicit encoding, that is, the encoded byte stream contains no explicit data typing information. In the context of remote procedure calls this makes sense, as the lack of type information reduces the overhead of the protocol, and the procedure caller and the procedure being called should agree on the number and type of arguments, so that there is no ambiguity in how to the byte stream should be interpreted.

RPC (Sun, 1988) extends the XDR protocol and language by adding messages that represent procedure calls and replies. Individual procedures are identified by three numbers: the program number, used to identify a service; the version number, so that changes to the interface for a particular service can be recognised; and a procedure number identifying the required procedure in that service.

The RPC language allows a programmer to define the interface to the service offered by assigning program, version and procedure numbers and describing the arguments and results for each procedure.

The RPC protocol provides messages for procedure calls and server replies, and includes the option of an authentication mechanism. There are fours authentication mechanisms defined in the protocol standard (Null, UNIX, Short and DES), but the protocol is open ended so other mechanisms can be defined.

RPC can be implemented over any transport layer protocol, but the lower protocol may affect the semantics of RPC, for example by imposing a maximum message size.

In my example, the RPC description of the random number service is shown in the file random.x.

2.2. rpcgen

The rpcgen program takes the RPC description of a service interface and produces four files: a client stub, a server stub, a file of functions for converting data structures to and from their XDR format, and a header file that describes the functions and data types described.

It is instructional for the programmer to examine the generated header file, as the data structures that rpcgen generates from the XDR description may not be exactly what the programmer expected. For example, look at random.h.

2.3. Runtime Library

As many operations in implementing a remote procedure call are identical from procedure to procedure, and as the stubs generated by rpcgen do not provide full transparency, there are a number of library routines used to support access by user programs to the RPC protocol. The programmer can use these, for example, to control which protocol RPC will be layered over, or adjust the timeout used by the call, or get more detail on an error condition.

2.4. The Portmapper

The RPC protocol describes a message format, but leaves the delivery of these messages to whatever lower level protocol RPC is layered on. In the case of the TCP/IP suite of protocols, an RPC server must listen on a UDP or TCP port. The information the caller provides - namely program, version and procedure numbers - is not sufficient to locate the server. This is listed as a virtue in the the protocol specification (Sun, 1988) as it allows independence from the binding software.

A standard piece of binding software supplied with Sun RPC is the portmapper. The portmapper is itself an RPC service (program number 100000, version 2) that listens on a well known port (port 111 for TCP and UDP). When RPC server programs start, they register their existence with the portmapper. Client programs tell the portmapper what program number, version and protocol (TCP or UDP) they want, and the portmapper replies with the port number that the server is listening on. The client can then use the protocol specified to contact that port.

3. Transparency Issues

In an ideal world, we should simply be able to replace our local procedure call with a client stub on the client end and a server stub on the server end, as shown in figure 1. In practise this is not possible, and in this section I examine some of the reasons for this. Many of the issues I examine here are raised in references. (Tanenbaum, 1992) (Stevens, 1990) (APM Ltd., 1989)

Figure 1 - Ideal local to distributed
progression.

On the server side, it was sufficient to wrap the service procedure with another function to interface it the server stub generated by rpcgen. This wrapper is shown in rpc_server_wrap.c. On the client side, however, some more significant changes were required because RPC needs some initialisation before the service can be called. These changes are highlighted with "#ifdef RPC_CLIENT" in rpc_client.c.

3.1. Service Numbering

When programmers specify the RPC interface, they assign a service number to the service they create. Thus it is the programmer's responsibility to ensure that the number he or she uses does not clash with numbers being used by any other service on that machine (or, potentially, any other machine in the network).

It should really be the system's responsibility to ensure unique numbers are assigned, if numbers are used at all. In the ANSA system for example, a service registers its properties with a trader, and clients look for servers with the required properties.

3.2. Transport Protocol

In theory, Sun RPC could be layered over any transport protocol; but in practice the run time libraries supplied only support TCP and UDP. A particular protocol must be chosen by the programmer, and the choice of protocol can affect the semantics of the call.

If UDP is chosen, then total size of arguments and the total size of results must each be less than the maximum UDP packet size, which in most implementations is 8192 bytes. TCP has no size restriction on parameters or results.

The RPC library supports a broadcast procedure call, so any server on the local network can reply, but only for RPC over UDP.

3.3. Parameter Passing

Sun RPC supports the passing of only a single parameter and the return of only a single result, though these parameters and results could be structures containing several data items. The only parameter passing model supported is call by value.

Of course, remote procedures cannot have side effects - they cannot access global variables.

3.4. Data Representation

The XDR protocol and XDR functions generated by rpcgen handle any differences in data representation from machine to machine. The client and server stubs automatically use these routines to encode and decode parameters and results. But, as noted in section 2.1, there are limits on the data structures that can be represented in XDR.

Note that the representation chosen in XDR mainly suits Sun machines, so that XDR is inefficient when used to transmit data between two machines that, for example, both use little endian integers.

3.5. Binding and Location Transparency

In the local case, the caller knows which procedure it is using as they were bound together at compile time.[4] In a remote procedure call, the caller must find the process providing the service it desires.

In Sun RPC this is accomplished by calling the portmapper service. The RPC library contains functions that will do a lookup on the portmapper when the client is initialised, so the client can then send its RPC requests to the appropriate TCP or UDP port.

Note, however, that the caller must specify which machine it wants to connect to to find the service. If it is not known in advance which machine the service will be on, then the programmer must include code to send a broadcast RPC to the portmapper on all machines.[5]

3.6. Replication Transparency

A system designer may choose to have several replicated server instances for reasons of performance or reliability. The Sun RPC protocol provides no direct support for this. The system designer will have to ensure clients broadcast when looking for a service (see last section), and will have to come up with a way for the replicated servers to stay in step with each other.

3.7. Failure Handling

In the local case, the client need only examine the return code to determine the success of the operation. In the RPC case, as can be seen in rpc_client.c, the return status of the RPC library function must be examined to determine if a return code was even received from the server. Thus a whole extra layer of error checking and response must be added in on the client side.

If TCP is used as the transport protocol, then the client will get an error return if the server breaks its connection (crashes). The client has no way of knowing if the crash occurred before or after the request was executed. The TCP protocol handles time-outs and retransmissions.

If the UDP protocol is used, then the client stub automatically provides timeout and retransmission (the client programmer can set the value of the timeout). The RPC protocol includes a transaction identifier, and the server stub can be instructed to remember responses sent and to send a cached response again if it receives a request it has seen before. This implements an at-most-once semantics in place of the default at-least-once semantics.

The SunRPC implementation is not resilient to failures of the portmapper. If the portmapper fails, new servers will not be able to register themselves, and clients will not be able to find running servers, so all RPC's will time out unsatisfied. In practice, even if the portmapper was restarted, all running servers would have to be restarted so they could register themselves with the new portmapper, so the only way to recover properly is to reboot the system.

3.8. Security

In the local case the caller of a function can be sure that it is calling an authorised provider of the service, and the procedure can be sure it is called by an authorised user, because they are linked together at compile time. With a remote call, neither party can be sure.[6]

To assure clients and server that they are talking to authorised servers and clients, Sun RPC includes an authentication mechanism. The client sends its credentials and a verifier to the server with its RPC call, the server returns its own verifier with the results. The standard authentication methods provided by the library are Null, UNIX, Short[7] and DES, but it is easy to add new methods.

Using the authentication mechanisms is not transparent; it requires some extra programming on the client and server sides.

In addition, the poertmapper introduces security risks as it can be used, in certain circumstances, to spoof the origin of a request (Cheswick, 1994:35). It is recommended that firewalls should block packets sent to the portmapper.

4. Performance

Each of the client/server combinations - the local case, the Sun RPC version and a version that uses TCP sockets - were run. The clients were all run on a Sun 2 workstation, the servers on a Sun IPX, and the two were connected with a thin wire Ethernet.

The tests were run at night, so both machines and the network had no other significant load. This helps to reduce the variance between runs. Each run of the program requested 1,048,576 random numbers in total, meaning 4 Mbytes of data was transferred between the server and the client. Each program was run ten times, with requests for blocks of 32, 128, 512, 1024 and 4096 bytes of random numbers to be sent, and the execution time for each of these was averaged. The results of this experiment appear in table 1 below. By noting that in all cases 4 megabytes of useful data were transferred, we can work out effective transfer rates in kilobytes per second, these are shown in table 2.

Table 1 - Run times for different procedure
link methods.

Table 2 - Transfer rates for different procedure
link methods.

These results are illustrated graphically in figures 2. Figure 3 compares the transfer rates for tcp and Sun RPC.

Figure 2 - Run time versus packet size.

Figure 3 - Transfer rate versus packet
size.

As can be seen from figure 3, using Sun RPC gives approximately a 50% penalty in data transfer rates. This runs contrary to expectation, as the RPC and XDR protocols should not introduce that much extra traffic, and there should not be excessive amounts of processing on either side to convert formats, so I would expect the transfer rates for TCP and RPC to converge for large message sizes.

An examination of the RPC implementation is required to explain this, and this goes beyond the time I can devote to this paper. However, profiling suggests that the reason for the extra time taken by the RPC version is due to the number of calls made on XDR routines to encode and decode the integers sent.

5. Conclusions

The Sun RPC mechanism makes network programming easier, however it falls far short of making remote procedure calls transparent to the programmer.

Due to the performance penalty, Sun RPC should not be used in applications that require large amounts of data transfer between clients and servers.


Footnotes

[1] Big-endian, which happens to be the same as most Sun machines.

[2] IEEE Standard 754-1985, another coincidence?

[3] You get the message. :-)

[4] Shared libraries are the exception to this. The functions in the shared library are bound at run time. However, you can trust the contents of a shared library as much as you trust the binary you are running, as they are just as easy to replace. You may not have control over the remote server that your RPC's bind to.

[5] Although the portmapper does have a procedure to automatically handle broadcast RPC (it looks up the server the RPC is destined for and sends it to that server itself if the server is registered, and drops the request if it is not) this only works for RPC over UDP. In the general case, the programmer must do a broadcast RPC to find which machine can provide the service, then initialise the client to talk to that machine.

[6] In fact, many classic attacks on networks of Sun systems relied on providing a false RPC service.

[7] Short is a shorthand version of UNIX, used as short cut when the client has already identified itself using UNIX authentication.


Bibliography

Architecture Projects Management Ltd
ANSA: An Engineer's Introduction to the Architecture
TR.03.02
Cambridge UK, November 1989

Ulysses Black
TCP/IP And Related Protocols
McGraw-Hill Incorporated
New York, NY, USA, 1992

William R. Cheswick & Steven M. Bellovin
Firewalls and Internet Security
Addison-Wesley
Reading, MA, USA, 1994

Computer Systems Research Group, University of California at Berkeley
4.4BSD-Lite Source CD-ROM
O'Reilly & Associates, Incorporated
Sebastopol, CA, USA, April 1994

W. Richard Stevens
UNIX Network Programming
Pretice-Hall Incorporated
Englewood Cliffs, NJ, USA, 1990

Sun Microsystems
XDR: External Data Representation Standard
Internet Network Working Group
RFC1014 Internet Request For Comments, June 1987

Sun Microsystems
RPC: Remote Procedure Call Protocol Specification Version 2
Internet Network Working Group
RFC1057 Internet Request For Comments, June 1988

Sun Microsystems
Network Programming Guide
Part Number: 800-3850-10
Manual set for SunOS 4.1.x
Sun Microsystems Incorporated
Mountain View, CA, USA, March 1990

Andrew S. Tanenbaum
Modern Operating Systems
Prentice-Hall International Incorporated
Englewood Cliffs, NJ, USA, 1992


[Previous
article] [Contents] [Next article]

[Home
page]