This section provides an overview of TI-RPC, also known as Sun RPC. The information presented is most useful to someone new to RPC. See the Glossary for the definition of the terms used in this guide.
Topics covered in this chapter include:
TI-RPC is a powerful technique for constructing distributed, client-server based applications. It is based on extending the notion of conventional, or local, procedure calling so that the called procedure need not exist in the same address space as the calling procedure. The two processes might be on the same system, or they might be on different systems with a network connecting them.
By using RPC, programmers of distributed applications avoid the details of the interface with the network. The transport independence of RPC isolates the application from the physical and logical elements of the data communications mechanism and enables the application to use a variety of transports.
An RPC is analogous to a function call. Like a function call, when an RPC is made, the calling arguments are passed to the remote procedure and the caller waits for a response to be returned from the remote procedure.
Figure 2–1 shows the flow of activity that takes place during an RPC call between two networked systems. The client makes a procedure call that sends a request to the server and waits. The thread is blocked from processing until either a reply is received, or the request times out. When the request arrives, the server calls a dispatch routine that performs the requested service, and sends the reply to the client. After the RPC call is completed, the client program continues.
RPC specifically supports network applications. TI-RPC runs on available networking mechanisms such as TCP/IP. Other RPC standards are OSF DCE (based on Apollo's NCS system), Xerox Courier, and Netwise.
A number of issues help to characterize a particular RPC implementation.
How are parameters and results passed?
How is binding carried out?
How are transport protocols dealt with?
What are the call semantics?
What data representation is used?
TI-RPC allows a single parameter to be passed from client to server. If more than one parameter is required, the components can be combined into a structure that is counted as a single element. Information passed from server to client is passed as the function's return value. Information cannot be passed back from server to client through the parameter list.
The client must know how to contact the service. The two necessary aspects are finding out which host the server is on, and then connecting to the actual server process. On each host, a service called rpcbind manages RPC services. TI-RPC uses the available host-naming services, such as the hosts and ipnodes file, NIS+, and DNS, to locate a host.
The transport protocol specifies how the call message and the reply message are transmitted between client and server. TS-RPC used TCP and UDP as transport protocols, but the current version of TI-RPC is transport independent, so it works with any transport protocol.
Call semantics define what the client can assume about the execution of the remote procedure; in particular, how many times the procedure was executed. These semantics are important in dealing with error conditions. The three alternatives are exactly once, at most once, and at least once. ONC+ provides at least once semantics. Procedures called remotely are idempotent: they should return the same result each time they are called, even through several iterations.
Data representation describes the format used for parameters and results as they are passed between processes. To function on a variety of system architectures, RPC requires a standard data representation. TI-RPC uses external data representation (XDR). XDR is a machine-independent data description and encoding protocol. Using XDR, RPC can handle arbitrary data structures, regardless of the byte orders or structure layout conventions of the different hosts. For a detailed discussion of XDR, see Appendix A, XDR Technical Note and Appendix C, XDR Protocol Specification.
A remote procedure is uniquely identified by the triple:
Program number
Version number
Procedure number
The program number identifies a group of related remote procedures, each of which has a unique procedure number.
A program can consist of one or more versions. Each version consists of a collection of procedures that are available to be called remotely. Version numbers enable multiple versions of an RPC protocol to be available simultaneously.
Each version contains a number of procedures that can be called remotely. Each procedure has a procedure number.
Program and Procedure Numbers lists the range of values and their significance and tells you how to have a program number assigned to your RPC program. A list of mappings of RPC service name to program number is available in the RPC network database /etc/rpc.
RPC has multiple levels of application interface to its services. These levels provide different degrees of control balanced with different amounts of interface code to implement, in order of increasing control and complexity. This section gives a summary of the routines available at each level.
The simplified interfaces are used to make remote procedure calls to routines on other machines, and specify only the type of transport to use. The routines at this level are used for most applications. Descriptions and code samples are in the section Simplified Interface.
Table 2–1 RPC Routines—Simplified Level
Routine |
Function |
---|---|
Registers a procedure as an RPC program on all transports of the specified type |
|
rpc_call() |
Remotely calls the specified procedure on the specified remote host |
Broadcasts a call message across all transports of the specified type |
The standard interfaces are divided into top level, intermediate level, expert level, and bottom level. These interfaces give a programmer much greater control over communication parameters such as the transport being used, how long to wait before responding to errors and retransmitting requests, and so on.
At the top level, the interface is still simple, but the program has to create a client handle before making a call or create a server handle before receiving calls. If you want the application to run on all transports, use this interface. You can find the use of these routines and code samples in Top-Level Interface.
Table 2–2 RPC Routines—Top Level
Routine |
Description |
---|---|
Generic client creation. The program tells clnt_create() where the server is located and the type of transport to use. |
|
Similar to clnt_create() but enables the programmer to specify the maximum time allowed for each type of transport tried during the creation attempt. |
|
Creates server handles for all transports of the specified type. The program tells svc_create() which dispatch function to use. |
|
clnt_call() () |
Client calls a procedure to send a request to the server. |
The intermediate level interface of RPC enables you to you control details. Programs written at these lower levels are more complicated but run more efficiently. The intermediate level enables you to specify the transport to use. Intermediate-Level Interface describes the use of these routines and code samples.
Table 2–3 RPC Routines—Intermediate Level
Routine |
Description |
---|---|
Creates a client handle for the specified transport |
|
Similar to clnt_tp_create() but enables the programmer to specify the maximum time allowed |
|
Creates a server handle for the specified transport |
|
clnt_call() () |
Client calls a procedure to send a request to the server |
The expert level contains a larger set of routines with which to specify transport-related parameters. Expert-Level Interface describes the use of these routines and code samples.
Table 2–4 RPC Routines—Expert Level
Routine |
Description |
---|---|
Creates a client handle for the specified transport |
|
svc_tli_create() |
Creates a server handle for the specified transport |
Calls rpcbind to set a map between an RPC service and a network address |
|
Deletes a mapping set by rpcb_set() |
|
Calls rpcbind() to get the transport addresses of specified RPC services |
|
svc_reg() |
Associates the specified program and version number pair with the specified dispatch routine |
Deletes an association set by svc_reg() |
|
clnt_call()() |
Client calls a procedure to send a request to the server |
The bottom level contains routines used for full control of transport options. Bottom-Level Interface describes these routines.
Table 2–5 RPC Routines—Bottom Level
Routine |
Description |
---|---|
Creates an RPC client handle for the specified remote program using a connectionless transport |
|
Creates an RPC server handle using a connectionless transport |
|
Creates an RPC client handle for the specified remote program using a connection-oriented transport |
|
Creates an RPC server handle using a connection-oriented transport |
|
clnt_call()() |
Client calls a procedure to send a request to the server |
You can write programs to run on a specific transport or transport type, or to operate on a system-chosen or user-chosen transport. Two mechanisms for network selection are the /etc/netconfig database and the environmental variable NETPATH. These mechanisms enable a fine degree of control over network selection: a user can specify a preferred transport and an application will use it if it can. If the specified transport is inappropriate, the application automatically tries other transports with the right characteristics.
/etc/netconfig lists the transports available to the host and identifies them by type. NETPATH is optional and enables you to specify a transport or selection of transports from the list in /etc/netconfig. By setting the NETPATH, you specify the order in which the application tries the available transports. If NETPATH is not set, the system defaults to all visible transports specified in /etc/netconfig, in the order that they appear in that file.
For more details on network selection, see the getnetconfig(3NSL) and netconfig(4) man pages.
RPC divides selectable transports into the types described in the following table:
Table 2–6 nettype Parameters
Value |
Meaning |
---|---|
Same as selecting netpath. |
|
Uses the transports chosen with the visible flag (`v') set in their /etc/netconfig entries. |
|
Same as visible, but restricted to connection-oriented transports. Transports are selected in the order listed in /etc/netconfig. |
|
Same as visible, but restricted to connectionless transports. |
|
circuit_n |
Uses the connection-oriented transports chosen in the order defined in NETPATH. |
Uses the connectionless transports chosen in the order defined in NETPATH. |
|
Specifies Internet User Datagram Protocol (UDP). |
|
Specifies Internet Transport Control Protocol (TCP). |
RPC services are supported on both circuit-oriented and datagram transports. The selection of the transport depends on the requirements of the application.
Choose a datagram transport if the application has all of the following characteristics:
Calls to the procedures do not change the state of the procedure or of associated data.
The size of both the arguments and results is smaller than the transport packet size.
The server is required to handle hundreds of clients. A datagram server does not keep any state data on clients, so it can potentially handle many clients. A circuit-oriented server keeps state data on each open client connection, so the number of clients is limited by the host resources.
Choose a circuit-oriented transport if the application has any of the following characteristics:
The application can tolerate or justify the higher cost of connection setup compared to datagram transports.
Calls to the procedures can change the state of the procedure or of associated data.
The size of either the arguments or the results exceeds the maximum size of a datagram packet.
Each transport has an associated set of routines that translate between universal network addresses (string representations of transport addresses) and the local address representation. These universal addresses are passed around within the RPC system (for example, between rpcbind and a client). A runtime linkable library that contains the name-to-address translation routines is associated with each transport. Table 2–7 shows the main translation routines.
For more details on these routines, see the netdir(3NSL) man page. Note that the netconfig structure in each case provides the context for name-to-address translations.
Table 2–7 Name-to-Address Translation Routines
netdir_getbyname() |
Translates from host or service pairs (for example server1, rpcbind) and a netconfig structure to a set of netbuf addresses. netbufs are Transport Level Interface (TLI) structures that contain transport-specific addresses at runtime. |
|
Translates from netbuf() addresses and a netconfig structure to host or service pairs. |
uaddr2taddr() |
Translates from universal addresses and a netconfig() structure to netbuf addresses. |
taddr2uaddr () |
Translates from netbuf addresses and a netconfig structure to universal addresses. |
Transport services do not provide address look-up services. They provide only message transfer across a network. A client program needs a way to obtain the address of its server program. In previous system releases this service was performed by portmap. In this release, rpcbind replaces the portmap utility.
RPC makes no assumption about the structure of a network address. It handles universal addresses specified only as null-terminated strings of ASCII characters. RPC translates universal addresses into local transport addresses by using routines specific to the transport. For more details on these routines, see the netdir(3NSL) and rpcbind(3NSL) man pages.
rpcbind enables you to perform the following operations:
Delete a registration
Get address of a specified program number, version number, and transport
Get the complete registration list
Perform a remote call for a client
rpcbind maps RPC services to their addresses, so rpcbind's address must be known. The name-to-address translation routines must reserve a known address for each type of transport used. For example, in the Internet domain, rpcbind has port number 111 on both TCP and UDP. When rpcbind is started, it registers its location on each of the transports supported by the host. rpcbind is the only RPC service that must have a known address.
For each supported transport, rpcbind registers the addresses of RPC services and makes the addresses available to clients. A service makes its address available to clients by registering the address with the rpcbind daemon. The address of the service is then available to rpcinfo(1M) and to programs using library routines named in the rpcbind(3NSL) man page. No client or server can assume the network address of an RPC service.
Client and server programs and client and server hosts are usually distinct but they need not be. A server program can also be a client program. When one server calls another rpcbind server it makes the call as a client.
To find a remote program's address, a client sends an RPC message to a host's rpcbind daemon. If the service is on the host, the daemon returns the address in an RPC reply message. The client program can then send RPC messages to the server's address. A client program can minimize its calls to rpcbind by storing the network addresses of recently called remote programs.
The RPCBPROC_CALLIT procedure of rpcbind enables a client to make a remote procedure call without knowing the address of the server. The client passes the target procedure's program number, version number, procedure number, and calling arguments in an RPC call message. rpcbind looks up the target procedure's address in the address map and sends an RPC call message, including the arguments received from the client, to the target procedure.
When the target procedure returns results, RPCBPROC_CALLIT passes them to the client program. It also returns the target procedure's universal address so that the client can later call it directly.
The RPC library provides an interface to all rpcbind procedures. Some of the RPC library procedures also call rpcbind automatically for client and server programs. For details, see RPC Language Specification.
rpcinfo is a utility that reports current RPC information registered with rpcbind. rpcinfo, with either rpcbind or the portmap utility, reports the universal addresses and the transports for all registered RPC services on a specified host. rpcinfo can call a specific version of a specific program on a specific host and report whether a response is received. rpcinfo can also delete registrations. For details, see the rpcinfo(1M) man page.