ONC+ Developer's Guide

Chapter 2 Introduction to TI-RPC

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:

What Is TI-RPC?

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.

Figure 2–1 How RPC Works

Text describes graphic.

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.

TI-RPC Issues

A number of issues help to characterize a particular RPC implementation.

Parameter Passing

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.

Binding

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.

Transport Protocol

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

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

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.

Program, Version, and Procedure Numbers

A remote procedure is uniquely identified by the triple:

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.

Overview of Interface Routines

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.

Simplified Interface Routines

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 

rpc_reg()

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 

rpc_broadcast()

Broadcasts a call message across all transports of the specified type 

Standard Interface Routines

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.

Top-Level Routines

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 

clnt_create()

Generic client creation. The program tells clnt_create() where the server is located and the type of transport to use.

clnt_create_timed()

Similar to clnt_create() but enables the programmer to specify the maximum time allowed for each type of transport tried during the creation attempt.

svc_create()

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. 

Intermediate-Level Routines

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 

clnt_tp_create()

Creates a client handle for the specified transport  

clnt_tp_create_timed()

Similar to clnt_tp_create() but enables the programmer to specify the maximum time allowed

svc_tp_create()

Creates a server handle for the specified transport 

clnt_call() ()

Client calls a procedure to send a request to the server 

Expert-Level Routines

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 

clnt_tli_create()

Creates a client handle for the specified transport 

svc_tli_create()

Creates a server handle for the specified transport 

rpcb_set()

Calls rpcbind to set a map between an RPC service and a network address

rpcb_unset()

Deletes a mapping set by rpcb_set()

rpcb_getaddr()

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 

svc_unreg()

Deletes an association set by svc_reg()

clnt_call()()

Client calls a procedure to send a request to the server 

Bottom-Level Routines

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 

clnt_dg_create()

Creates an RPC client handle for the specified remote program using a connectionless transport  

svc_dg_create()

Creates an RPC server handle using a connectionless transport 

clnt_vc_create()

Creates an RPC client handle for the specified remote program using a connection-oriented transport 

svc_vc_create()

Creates an RPC server handle using a connection-oriented transport 

clnt_call()()

Client calls a procedure to send a request to the server  

Network Selection

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 

NULL

Same as selecting netpath.

visible

Uses the transports chosen with the visible flag (`v') set in their /etc/netconfig entries.

circuit_v

Same as visible, but restricted to connection-oriented transports. Transports are selected in the order listed in /etc/netconfig.

datagram_v

Same as visible, but restricted to connectionless transports.

circuit_n

Uses the connection-oriented transports chosen in the order defined in NETPATH.

datagram_n

Uses the connectionless transports chosen in the order defined in NETPATH.

udp

Specifies Internet User Datagram Protocol (UDP). 

tcp

Specifies Internet Transport Control Protocol (TCP). 

Transport Selection

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:

Choose a circuit-oriented transport if the application has any of the following characteristics:

Name-to-Address Translation

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.

Address Look-up Services

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:

Registering Addresses

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.

Reporting RPC Information

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.