Network Interfaces Programmer's Guide
  Buscar sólo este libro
Descargar este libro en PDF

Introduction to Remote Procedure Call (RPC)

2

This manual addresses the C interface to RPC, and the way RPC is used to communicate between processes on same or different hosts. Other language bindings are not available in Solaris.
This chapter contains capsule overviews of the key components and leading characteristics of RPC. See "RPC Programming Terms" on page 449 for the definition of the terms used in this chapter.
What Is RPCpage 12
RPC Versions and Numberspage 14
Network Selectionpage 14
Transport Selectionpage 17
Address Lookup Using rpcbindpage 18

RPC Server Is Multithread Safe

In SunOS 5.3 client-side interfaces were made MT safe. SunOS 5.4 now provides MT-safe server-side interfaces that can be used freely in a multithreaded application. For more information on these interfaces, refer to "MT Server Issues" on page 118."

What Is RPC

RPC is a high-level network applications model. 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 allows the application to use a variety of transports.
RPC specifically supports network applications. It runs on available networking mechanisms such as TCP/IP. Generic facilities, such as rpcbind, associate network services with universal network addresses where they may be accessed. In RPC programming, the term network is frequently used as a synonym for transport or transport type.

Gráfico

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 it 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 programs follow the client/server model of distributed programming. RPC programs provide network services to callers without requiring any awareness of the underlying network. For example, a program can call rusers(), a routine in the librpcsvc library that returns the number of users on a remote host. The caller is not explicitly aware of using the network. The call to rusers() is as simple as a call to a standard system service call like malloc().

RPC Levels

You can use the RPC services at a number of levels, from the simplified level to the lower level. The levels are described in detail in "Introduction to RPC Interface Levels" on page 60." Understanding the lower levels of RPC is helpful but not necessary when you use the rpcgen tool to generate your RPC applications. For use of rpcgen, see Chapter 3, "rpcgen Programming Guide."

External Data Representation (XDR)

For RPC to function on a variety of system architectures requires a standard data representation. 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 different hosts' byte orders or structure layout conventions. For a detailed discussion of XDR, see Appendix A, "XDR Protocol Specification," and Appendix B, "XDR Technical Note."

RPC Versions and Numbers

Each RPC procedure is uniquely identified by a program number, version number, and procedure number.
The program number identifies a group of related remote procedures, each of which has a unique procedure number. Each program also has a version number, so when a change is made to a remote service (such as adding a new procedure), a new program number does not have to be assigned.
Changes in a program, such as adding a new procedure, changing the arguments or return value of a procedure, or changing the side effects of the procedure require that the version number be changed.
Appendix C, "RPC Protocol and Language Specification," tells you how to assign a program number to an RPC program.

Network Selection

You can write programs to run on a specific transport or transport type, or to operate on a system- or user-chosen transport. It uses two mechanisms, the /etc/netconfig database and the environmental variable NETPATH. /etc/netconfig lists the transports available to the host and identifies them by type. NETPATH is optional and allows a user to specify a transport or selection of transports from the list in /etc/netconfig.
The major features of /etc/netconfig are:
  • The first field of each entry is the network identifier of the transport.
  • Each entry contains a flag or set of flags (the third field) that identifies the transport type -- the v flag, for example, identifies a transport that can be selected ("visible").
  • The second field identifies the transport type. Connectionless transports are identified by tpi_clts. Connection oriented transports are identified by tpi_cots. Connection oriented transports with orderly release are identified by tpi_cots_ord.
  • The last field names one or more run-time linkable modules that contain the name-to-address translation routines associated with the transport.
  • The loopback transports are used to register services with rpcbind. They are local transports, available only to local clients and servers, and are more secure than other transports.
The /etc/netconfig file contains several lines, each of which corresponds to an available transport. Code Example 2-1 shows some possible entries.
Code Example 2-1 Sample /etc/netconfig File
# The Network Configuration File.
#
# Each entry is of the form:
#
# network_id semantics: flags protofamily protocol device_name
# nametoaddr_libs
#
tcp tpi_cots_ord v inet tcp /dev/tcp tcpip.so
#
udp tpi_clts v inet udp /dev/udp tcpip.so
#
icmp tpi_raw - inet icmp /dev/icmp tcpip.so
#
rawip tpi_raw - inet - /dev/rawip tcpip.so
#
ticlts tpi_clts v loopback - /dev/ticlts straddr.so
#
ticots tpi_cots v loopback - /dev/ticots straddr.so
#
ticotsord tpi_cots_ord v loopback - /dev/ticotsord straddr.so
#
#   end of netconfig file

For the details of /etc/netconfig and the application interface to it, see the getnetconfig(3N) and netconfig(4) manpages and the TCP/IP Network Administration Guide.
NETPATH is an environment variable. Its format is a simple ordered list of network identifiers separated by colons (:). An example is: udp:tcp.
By setting NETPATH, the user specifies 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 they appear in that file.
An application can ignore a user's NETPATH and set its own transport-selection order. The ability to make a predetermined choice of transport is a convenience to the developer but is not mandatory.
RPC divides selectable transports into the following types:
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_nUses the connection-oriented transports chosen in the order defined in NETPATH.
datagram_nUses the connectionless transports chosen in the
udpSpecifies Internet user datagram protocol (UDP).
tcpSpecifies Internet transport control protocol (TCP).
A transport-aware application starts by calling setnetconfig(3N), getnetconfig(3N), and endnetconfig(3N) to search /etc/netconfig for the right type of transport. The data are stored in local netconfig data structures for later use.
These mechanisms allow a fine degree of control over network selection: a user can specify a preferred transport, and if it can, an application uses it. If the specified transport is inappropriate, the application automatically tries others with the right characteristics.

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.
A datagram transport is the transport of choice 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.
A circuit-oriented transport is the transport of choice if the application has any of the following characteristics:
  • The application can tolerate or amortize 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 exceed the maximum size of a datagram packet.

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 run-time linkable library that contains the name-to-address translation routines is associated with each transport. Table 2-1 shows the main translation routines.
For more details on these routines, see the netdir(3N) manpage and Chapter 5, "Transport Selection and Name-to-Address Mapping." Note that the netconfig structure in each case provides the context for name-to-address translations.
Table 2-1
netdir_getbynameTranslates from host/service pairs (e.g. 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 run-time.
netdir_getbyaddrTranslates from netbuf addresses and a netconfig structure to host/service pairs.
uaddr2taddrTranslates from universal addresses and a netconfig
structure to netbuf addresses.
taddr2uaddrTranslates from netbuf addresses and a netconfig structure to universal addresses.

Address Lookup Using rpcbind

Transport services do not provide address-lookup services. They provide only message transfer across a network. A client program needs a way to obtain the address of its server program. In earlier system releases this service was performed by portmap. rpcbind replaces the portmap utility.
RPC makes no assumption about the structure of a network address. It deals with 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(3N) and rpcbind(3N)manpages.
rpcbind provides the operations:
  • Add a registration
  • 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
  • Return the time

Address Registration

rpcbind maps RPC services to their addresses, so its 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(3N) manpage. 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 lets a client 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 Appendix C, "RPC Protocol and Language Specification."

The rpcinfo Utility

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. It can call a specific version of a specific program on a specific host and report whether a response is received. It can also delete registrations. For details, see the rpcinfo(1M) manpage.