Next: , Previous: Building an RPC Server, Up: Implementation of ONC RPC

4.3.3 ONC RPC Message Types

The (rpc rpc types) module provides a representation of the various XDR types defined in the standard to represent RPC messages (see References). We only describe the most important ones as well as procedures from the (rpc rpc) module that help use it.

— Scheme Variable: rpc-message

This variable contains a XDR struct type representing all possible RPC messages—the rpc_msg struct type defined in RFC 1831. By “rpc message” we mean the header that is transmitted before the actual procedure argument to describe the procedure call being made.

Roughly, this header contains a transaction ID allowing clients to match call/reply pairs, plus information describing either the call or the reply being made. Calls essentially contain a program, version and procedure numbers. Replies, on the other hand, can be more complex since they can describe a large class of errors.

— Scheme Variable: rpc-message-type

This variable is bound to an XDR enumeration. Its two possible values are CALL and REPLY (both represented in Scheme using symbols), denoting a procedure call and a reply to a procedure call, respectively.

— Scheme Procedure: make-rpc-message xid type args ...

Return an rpc-message datum. type should be either CALL or REPLY (the two values of the rpc-message-type enumeration). The arguments args are message-type-specific. For example, a message denoting a procedure call to procedure number 5 of version 1 of program 77 can be created as follows:

          (define my-call-msg
            (make-rpc-message #x123 ;; the transaction ID
                              'CALL ;; the message type
                              77 1 5))

It can then be encoded in the usual way (see XDR Encoding and Decoding):

          (let* ((size (xdr-type-size rpc-message my-call-msg))
                 (bv   (make-bytevector size)))
            (xdr-encode! bv 0 rpc-message my-call-msg)
            ;;; ...

Likewise, a reply message denoting a successful RPC call can be produced as follows:

          (make-rpc-message xid 'REPLY 'MSG_ACCEPTED 'SUCCESS)

It is worth noting that in practice, “messages” of type rpc-message are followed by additional data representing either the procedure call arguments (if the message is a CALL message) or the procedure return value (if the message is a REPLY message).

— Scheme Procedure: assert-successful-reply rpc-msg xid

Return true if rpc-msg (an RPC message as returned by a previous (xdr-decode rpc-message port) call) is a valid reply for the invocation labeled with transaction ID xid indicating that it was accepted. If xid is #t, any reply transaction ID is accepted and it is returned (provided the rest of the message denotes an accepted message). On failure, an appropriate error condition is raised.

The error conditions that may be raised obey rpc-error? and rpc-call-error?. More precisely, error conditions include the following:

If rpc-msg denotes the fact that the program requested by the corresponding RPC call is not available.
If the corresponding RPC call requested a program version that is not available. The procedures rpc-program-mismatch-error:low-version and rpc-program-mismatch-error:high-version return, respectively, the lowest and highest version numbers supported by the remote server.
If the corresponding RPC call requested a procedure that is not available.
If the remote server failed to decode the procedure arguments.
If the remote server failed to allocate enough memory for argument decoding, for instance.