Connected: An Internet Encyclopedia
8. THE RPC MESSAGE PROTOCOL

Up: Connected: An Internet Encyclopedia
Up: Requests For Comments
Up: RFC 1831
Prev: 7.4.2 Broadcast Remote Procedure Calls
Next: 9. AUTHENTICATION PROTOCOLS

8. THE RPC MESSAGE PROTOCOL

8. THE RPC MESSAGE PROTOCOL

This section defines the RPC message protocol in the XDR data description language [9].

      enum msg_type {
         CALL  = 0,
         REPLY = 1
      };

A reply to a call message can take on two forms: The message was either accepted or rejected.

      enum reply_stat {
         MSG_ACCEPTED = 0,
         MSG_DENIED   = 1
      };

Given that a call message was accepted, the following is the status of an attempt to call a remote procedure.

      enum accept_stat {
         SUCCESS       = 0, /* RPC executed successfully             */
         PROG_UNAVAIL  = 1, /* remote hasn't exported program        */
         PROG_MISMATCH = 2, /* remote can't support version #        */
         PROC_UNAVAIL  = 3, /* program can't support procedure       */
         GARBAGE_ARGS  = 4, /* procedure can't decode params         */
         SYSTEM_ERR    = 5  /* errors like memory allocation failure */
      };

Reasons why a call message was rejected:

      enum reject_stat {
         RPC_MISMATCH = 0, /* RPC version number != 2          */
         AUTH_ERROR = 1    /* remote can't authenticate caller */
      };

Why authentication failed:

      enum auth_stat {
         AUTH_OK           = 0,  /* success                          */
         /*
          * failed at remote end
          */
         AUTH_BADCRED      = 1,  /* bad credential (seal broken)     */
         AUTH_REJECTEDCRED = 2,  /* client must begin new session    */
         AUTH_BADVERF      = 3,  /* bad verifier (seal broken)       */
         AUTH_REJECTEDVERF = 4,  /* verifier expired or replayed     */
         AUTH_TOOWEAK      = 5,  /* rejected for security reasons    */
         /*
          * failed locally
          */
         AUTH_INVALIDRESP  = 6,  /* bogus response verifier          */
         AUTH_FAILED       = 7   /* reason unknown                   */
      };

The RPC message:

All messages start with a transaction identifier, xid, followed by a two-armed discriminated union. The union's discriminant is a msg_type which switches to one of the two types of the message. The xid of a REPLY message always matches that of the initiating CALL message. NB: The xid field is only used for clients matching reply messages with call messages or for servers detecting retransmissions; the service side cannot treat this id as any type of sequence number.

      struct rpc_msg {
         unsigned int xid;
         union switch (msg_type mtype) {
         case CALL:
            call_body cbody;
         case REPLY:
            reply_body rbody;
         } body;
      };

Body of an RPC call:

In version 2 of the RPC protocol specification, rpcvers must be equal to 2. The fields prog, vers, and proc specify the remote program, its version number, and the procedure within the remote program to be called. After these fields are two authentication parameters: cred (authentication credential) and verf (authentication verifier). The two authentication parameters are followed by the parameters to the remote procedure, which are specified by the specific program protocol.

The purpose of the authentication verifier is to validate the authentication credential. Note that these two items are historically separate, but are always used together as one logical entity.

      struct call_body {
         unsigned int rpcvers;       /* must be equal to two (2) */
         unsigned int prog;
         unsigned int vers;
         unsigned int proc;
         opaque_auth  cred;
         opaque_auth  verf;
         /* procedure specific parameters start here */
      };

Body of a reply to an RPC call:

      union reply_body switch (reply_stat stat) {
      case MSG_ACCEPTED:
         accepted_reply areply;
      case MSG_DENIED:
         rejected_reply rreply;
      } reply;

Reply to an RPC call that was accepted by the server:

There could be an error even though the call was accepted. The first field is an authentication verifier that the server generates in order to validate itself to the client. It is followed by a union whose discriminant is an enum accept_stat. The SUCCESS arm of the union is protocol specific. The PROG_UNAVAIL, PROC_UNAVAIL, GARBAGE_ARGS, and SYSTEM_ERR arms of the union are void. The PROG_MISMATCH arm specifies the lowest and highest version numbers of the remote program supported by the server.

      struct accepted_reply {
         opaque_auth verf;
         union switch (accept_stat stat) {
         case SUCCESS:
            opaque results[0];
            /*
             * procedure-specific results start here
             */
          case PROG_MISMATCH:
             struct {
                unsigned int low;
                unsigned int high;
             } mismatch_info;
          default:
             /*
              * Void.  Cases include PROG_UNAVAIL, PROC_UNAVAIL,
              * GARBAGE_ARGS, and SYSTEM_ERR.
              */
             void;
          } reply_data;
      };

Reply to an RPC call that was rejected by the server:

The call can be rejected for two reasons: either the server is not running a compatible version of the RPC protocol (RPC_MISMATCH), or the server rejects the identity of the caller (AUTH_ERROR). In case of an RPC version mismatch, the server returns the lowest and highest supported RPC version numbers. In case of invalid authentication, failure status is returned.

      union rejected_reply switch (reject_stat stat) {
      case RPC_MISMATCH:
         struct {
            unsigned int low;
            unsigned int high;
         } mismatch_info;
      case AUTH_ERROR:
         auth_stat stat;
      };


Next: 9. AUTHENTICATION PROTOCOLS

Connected: An Internet Encyclopedia
8. THE RPC MESSAGE PROTOCOL