Tech-invite3GPPspaceIETFspace
96959493929190898887868584838281807978777675747372717069686766656463626160595857565554535251504948474645444342414039383736353433323130292827262524232221201918171615141312111009080706050403020100
in Index   Prev   Next

RFC 1045

VMTP: Versatile Message Transaction Protocol: Protocol specification

Pages: 128
Experimental
Part 3 of 4 – Pages 54 to 88
First   Prev   Next

Top   ToC   RFC1045 - Page 54   prevText
4. Client Protocol Operation

This chapter describes the operation of the client portion of VMTP in
terms of the procedures for handling VMTP user events, packet reception
events, management operations and timeout events.  Note that the client
portion of VMTP is separable from the server portion.  It is feasible to
have a node that only implements the client end of VMTP.

To simplify the description, we define a client state record (CSR) plus
some standard utility routines.


4.1. Client State Record Fields

In the following protocol description, there is one client state record
(CSR) per (client,transaction) outstanding message transaction.  Here is
a suggested set of fields.

Link            Link to next CSR when queued in one of the transmission,
                timeout or message queues.

QueuePtr        Pointer to queue head in which this CSR is contained or
                NULL if none.  Queue could be one of transmission queue,
                timeout queue, server queue or response queue.

ProcessIdentification
                The process identification and address space.

Priority        Priority for processing, network service, etc.

State           One of the client states described below.

FinishupFunc    Procedure to be executed on the CSR when it is completes
                its processing in transmission or timeout queues.

TimeoutCount    Time to remain in timeout queue.

TimeoutLimit    User-specified time after which the message transaction
                is aborted. The timeout is infinite if set to zero.

RetransCount    Number of retransmissions since last hearing from the
                Server.

LastTransmitTime
                The time at which the last packet was sent.  This field
                is used to calculate roundtrip times, using the
                RetransmitCount to match the responding packet to a
Top   ToC   RFC1045 - Page 55
                particular transmission.  I.e. Response or management
                NotifyVmtpClient operation to Request and a management
                NotifyVmtpServer operation to a Response.

TimetoLive      Time to live to be used on transmission of IP packets.

TransmissionMask
                Bit mask indicating the portions of the segment to
                transmit.  Set before entering the transmission queue
                and cleared incrementally as the 512-byte segment blocks
                of the segment are transmitted.

LocalClientLink Link to next CSR hashing to same hash index in the
                ClientMap.

LocalClient     Entity identifier for client when this CSR is used to
                send a Request packet.

LocalTransaction
                Transaction identifier for current message transaction
                the local client has outstanding.

LocalPrincipal  Account identification, possibly including key and key
                timeout.

LocalDelivery   Bit mask of segment blocks that have not been
                acknowledged in the Request or have been received in the
                Response, depending on the state.

ResponseQueue   Queue of CSR's representing the queued Responses for
                this entity.

VMTP Header     Prototype VMTP header, used to generate and store the
                header portion of a Request for transmission and
                retransmission on timeout.

SegmentDesc     Description of the segment data associated with the CSR,
                either the area storing the original Request data, the
                area for receiving Request data, or the area storing the
                Response data that is returned.

HostAddr        The network or internetwork host address to which the
                Client last transmitted.  This field also indicates the
                type of the address, e.g. IP, Ethernet, etc.

Note: the CSR can be combined with a light-weight process descriptor
with considerable benefit if the process is designed to block when it
Top   ToC   RFC1045 - Page 56
issues a message transaction.  In particular, by combining the two
descriptors, the implementation saves time because it only needs to
locate and queue one descriptor with various operations (rather than
having to locate two descriptors).  It also saves space, given that the
VMTP header prototype provides space such as the user data field which
may serve to store processor state for when the process is preempted.
Non-preemptive blocking can use the process stack to store the processor
state so only a program counter and stack pointer may be required in the
process descriptor beyond what we have described.  (This is the approach
used in the V kernel.)


4.2. Client Protocol States

A Client State Record records the state of message transaction generated
by this host, identified by the (Client, Transaction) values in the CSR.
As a client originating a transaction, it is in one of the following
states.

AwaitingResponse
                Waiting for a Response packet group to arrive with the
                same (Client,Transaction) identification.

ReceivingResponse
                Waiting for additional packets in the Response packet
                group it is currently receiving.

"Other"         Not waiting for a response, which can be Processing or
                some other operating system state, or one of the Server
                states if it also acts as a server.

This covers all the states for a client.


4.3. State Transition Diagrams

The client state transitions are illustrated in Figure 4-1.  The client
goes into the state AwaitingResponse on sending a request unless it is a
datagram request.  In the AwaitingResponse state, it can timeout and
retry and eventually give up and return to the processing state unless
it receives a Response.  (A NotifyVmtpClient operation resets the
timeout but does not change the state.)  On receipt of a single packet
response, it returns to the processing state.  Otherwise, it goes to
ReceivingResponse state.  After timeout or final response packet is
received, the client returns to the processing state.  The processing
state also includes any other state besides those associated with
issuing a message transaction.
Top   ToC   RFC1045 - Page 57
   +------------+
   | Processing |<--------------------|
   |            |<-------------|      |
   |            |<---|         |      |
   +|------^--^-+  Single    Last     |
 Transmit  |  |    Packet    Response |
    |      |  |    Response  Packet   |
    |      |  |      |         |      |
    +-DGM->+ Timeout |         |   Final timeout
    |         |      |         |      |
   +V-----------+    |       +-----------+
   |  Awaiting  |----+       | Receiving |->Response-+
   |  Response  |->Response->| Response  |           |
   |            |  (multi-   |           |<----------+
   +-|--------^-+   packet)  +----------^+
     V        |                |        |
     +-Timeout+                +>Timeout+

                 Figure 4-1:   Client State Transitions


4.4. User Interface

The RPC or user interface to VMTP is implementation-dependent and may
use systems calls, functions or some other mechanism.  The list of
requests that follow is intended to suggest the basic functionality that
should be available.

Send( mcb, timeout, segptr, segsize )
                Initiate a message transaction to the server and request
                message specified by mcb and return a response in mcb,
                if it is received within the specified timeout period
                (or else return USER_TIMEOUT in the Code field).  The
                segptr parameter specifies the location from which the
                segment data is sent and the location into which the
                response data is to be delivered.  The segsize field
                indicates the maximum length of this area.

GetResponse( responsemcb, timeout, segptr, segsize )
                Get the next response sent to this client as part of the
                current message transaction, returning the segment data,
                if any, into the memory specified by segptr and segsize.

This interface assumes that there is a client entity associated with the
invoking process that is to be used with these operations.  Otherwise,
the client entity must be specified as an additional parameter.
Top   ToC   RFC1045 - Page 58
4.5. Event Processing

The following events may occur in the VMTP client:

   - User Requests

        * Send

        * GetResponse

   - Packet Arrival

        * Response Packet

        * Request

     The minimal Client implementation handles Request packets for
     its VMTP management (server) module and sends NotifyVmtpClient
     requests in response to others, indicating the specified
     server does not exist.

   - Management Operation - NotifyVmtpClient

   - Timeouts

        * Client Retransmission Timeout

The handling of these events is described in detail in the following
subsections.

We first describe some conventions and procedures used in the
description.  A field of the received packet is indicated as (for
example) p.Transaction, for the Transaction field.  Optional portions of
the code, such as the streaming handling code are prefixed with a "|" in
the first column.

MapClient( client )
                Return pointer to CSR for client with the specified
                clientId, else NULL.

SendPacketGroup( csr )
                Send the packet group (Request, Response) according to
                that specified by the CSR.

NotifyClient( csr, p, code )
                Invoke the NotifyVmtpClient operation with the
                parameters csr.RemoteClient, p.control,
Top   ToC   RFC1045 - Page 59
                csr.ReceiveSeqNumber, csr.RemoteTransaction and
                csr.RemoteDelivery, and code.  If csr is NULL, use
                p.Client, p.Transaction and p.PacketDelivery instead and
                the global ReceiveSequenceNumber, if supported.  This
                function simplifies the description over calling
                NotifyVmtpClient directly in the procedural
                specification below.  (See Appendix III.)

NotifyServer( csr, p, code )
                Invoke the NotifyVmtpServer operation with the
                parameters p.Server, csr.LocalClient,
                csr.LocalTransaction, csr.LocalDelivery and code.  Use
                p.Client, P.Transaction and 0 for the clientId, transact
                and delivery parameters if csr is NULL.  This function
                simplifies the description over calling NotifyVmtpServer
                directly in the procedural specification below.  (See
                Appendix III.)

DGMset(p)       True if DGM bit set in packet (or csr) else False.
                (Similar functions are used for other bits.)

Timeout( csr, timeperiod, func )
                Set or reset timer on csr record for timeperiod later
                and invoke func if the timeout expires.


4.6. Client User-invoked Events

A user event occurs when a VMTP user application invokes one of the VMTP
interface procedures.


4.6.1. Send

Send( mcb, timeout, segptr, segsize )
    map to main CSR for this client.
    increment csr.LocalTransaction
    Init csr and check parameters and segment if any.
    Set SDA if sending appended data.
    Flush queued replies from previous transaction, if any.
    if local non-group server then
        deliver locally
        await response
        return
    if GroupId(server) then
        Check for and deliver to local members.
        if CRE request and non-group local CR entity then
Top   ToC   RFC1045 - Page 60
           await response
           return
        endif
        set MDG if member of this group.
    endif
    clear csr.RetransCount
    set csr.TransmissionMask
    set csr.TimeLimit to timeout
    set csr.HostAddr for csr.Server
    SendPacketGroup( csr )
    if DGMset(csr) then
       return
    endif
    set csr.State to AwaitingResponse
    Timeout( rootcsr, TC1(csr.Server), LocalClientTimeout )
    return
end Send

Notes:

   1. Normally, the HostAddr is extracted from the ServerHost
      cache, which maps server entity identifiers to host
      addresses.  However, on cache miss, the client first queries
      the network using the ProbeEntity operation, as specified in
      Appendix III, determining the host address from the Response.
      The ProbeEntity operation is handled as a separate message
      transaction by the Client.

The stream interface incorporates a parameter to pass a responseHandler
procedure that is invoked when the message transaction completes.

StreamSend( mcb, timeout, segptr, segsize, responseHandler )
    map to main CSR for this client.
|   Allocate a new csr if root in use.
|   lastcsr := First csr for last request.
|   if STIset(lastcsr)
|       csr.LocalTransaction := lastcsr.LocalTransaction + 256
|   else
|       csr.LocalTransaction := lastcsr.LocalTransaction + 1
    Init csr and check parameters and segment if any.
    . . . ( rest is the same as for the normal Send)

Notes:

   1. Each outstanding message transaction is represented by a CSR
      queued on the root CSR for this client entity.  The root CSR
      is used to handle timeouts, etc.  On timeout, the last packet
Top   ToC   RFC1045 - Page 61
      from the last packet group is retransmitted (with or without
      the segment data).


4.6.2. GetResponse

GetResponse( req, timeout, segptr, segsize )
    csr := CurrentCSR;
    if responses queued then return next response
      (in req, segptr to max of segsize )
    if timeout is zero then return KERNEL_TIMEOUT error
    set state to AWAITING_RESPONSE
    Timeout( csr, timeout, ReturnKernelTimeout );
end GetResponse

Notes:

   1. GetResponse is only used with multicast Requests, which is
      the only case in which multiple (different) Responses should
      be received.

   2. A response must remain queued until the next message
      transaction is invoked to filter out duplicates of this
      response.

   3. If the response is incomplete (only relevant if a
      multi-packet response), then the client may wait for the
      response to be fully received, including issuing requests for
      retransmission (using NotifyVmtpServer operations) before
      returning the response.

   4. As an optimization, a response may be stored in the CSR of
      the client.  In this case, the response must be transferred
      to a separate buffer (for duplicate suppression) before
      waiting for another response.  Using this optimization, a
      response buffer is not allocated in the common case of the
      client receiving only one response.


4.7. Packet Arrival

In general, on packet reception, a packet is mapped to the client state
record, decrypted if necessary using the key in the CSR.  It then has
its checksum verified and then is transformed to the right byte order.
The packet is then processed fully relative to its packet function code.
It is discarded immediately if it is addressed to a different domain
than the domain(s) in which the receiving host participates.
Top   ToC   RFC1045 - Page 62
For each of the 2 packet types, we assume a procedure called with a
pointer p to the VMTP packet and psize, the size of the packet in
octets.  Thus, generic packet reception is:

if not LocalDomain(p.Domain) then return;

csr := MapClient( p.Client )

if csr is NULL then
    HandleNoCsr( p, psize )
    return

if Secure(p) then
    if SecureVMTP not supported then
        { Assume a Request. }
        if not Multicast(p) then
            NotifyClient(NULL, p, SECURITY_NOT_SUPPORTED )
        return
    endif
|   Decrypt( csr.Key, p, psize )

if p.Checksum not null then
    if not VerifyChecksum(p, psize) then return;
if OppositeByteOrder(p) then ByteSwap( p, psize )
if psize not equal sizeof(VmtpHeader) + 4*p.Length then
    NotifyClient(NULL, p, VMTP_ERROR )
    return
Invoke Procedure[p.FuncCode]( csr, p, psize )
Discard packet and return

Notes:

   1. The Procedure[p.FuncCode] refers to one of the 2 procedures
      corresponding to the two different packet types of VMTP,
      Requests and Responses.

   2. In all the following descriptions, a packet is discarded on
      "return" unless otherwise stated.

   3. The procedure HandleNoCSR is a management routine that
      allocates and initializes a CSR and processes the packet or
      else sends an error indication to the sender of the packet.
      This procedure is described in greater detail in Section
      4.8.1.
Top   ToC   RFC1045 - Page 63
4.7.1. Response

This procedure handles incoming Response packets.

HandleResponse( csr, p, psize )
    if not LocalClient( csr ) then
        if Multicast then return
|       if Migrated( p.Client ) then
|           NotifyServer(csr, p ENTITY_MIGRATED )
|       else
            NotifyServer(csr, p, ENTITY_NOT_HERE )
        return
    endif

    if NSRset(p) then
        if Streaming not supported then
            NotifyServer(csr, p, STREAMING_NOT_SUPPORTED )
            return STREAMED_RESPONSE
|       Find csr corresponding to p.Transaction
|       if none found then
|           NotifyServer(csr, p, BAD_TRANSACTION_ID )
|           return
     else
      if csr.LocalTransaction not equal p.Transaction then
        NotifyServer(csr, p, BAD_TRANSACTION_ID )
        return
    endif
    Locate reply buffer rb for this p.Server
    if found then
        if rb.State is not ReceivingResponse then
          { Duplicate }
            if APGset(p) or NERset(p) then
                { Send Response to stop response packets. }
                NotifyServer(csr, p, RESPONSE_DISCARDED )
            endif
            return
         endif
         { rb.State is ReceivingRequest}
         if new segment data then retain in CSR segment area.
         if packetgroup not complete then
             Timeout( rb, TC3(p.Server), LocalClientTimeout )
             return;
          endif
          goto EndPacketGroup
    endif
    { Otherwise, a new response message. }
Top   ToC   RFC1045 - Page 64
    if (NSRset(p) or NERset(p)) and NoStreaming then
        NotifyServer(csr, p, VMTP_ERROR )
        return
|    if NSRset(p) then
|      { Check consecutive with previous packet group }
|       Find last packet group CSR from p.Server.
|       if p.Transaction not
|             lastcsr.RemoteTransaction+1 mod 2**32 then
|         { Out of order packet group }
|            NotifyServer(csr, p, BAD_TRANSACTION_ID)
|           return
|       endif
|       if lastcsr not completed then
|           NotifyServer(lastcsr, p, RETRY )
|       endif
|       if CMG(lastcsr) then
|           Add segment data to lastcsr Response
|           Notify lastcsr with new packet group.
|           Clear lastcsr.VerifyInterval
|       else
|           if lastcsr available then
|                 use it for this packet group
|           else allocate and initialize new CSR
|           Save message and segment data in new CSR area.
|       endif
|   else { First packet group }
        Allocate and init reply buffer rb for this response.
        if allocation fails then
            NotifyServer(csr, p, BUSY )
            return
        Set rb.State to ReceivingResponse
        Copy message and segment data to rb's segment area
         and set rb.PacketDelivery to that delivered.
        Save p.Server host address in ServerHost cache.
    endif
    if packetgroup not complete then
        Timeout( rb, TS1(p.Client), LocalClientTimeout )
        return;
    endif
endPacketGroup:
    { We have received last packet in packet group. }
    if APGset(p) then NotifyServer(csr, p, OK )
|   if NERset(p) and CMGset(p) then
|       Queue waiting for continuation packet group.
|       Timeout( rb, TC2(rb.Server), LocalClientTimeout )
|       return
|   endif
Top   ToC   RFC1045 - Page 65
    { Deliver response message. }
    Deliver response to Client, or queue as appropriate.
end HandleResponse

Notes:

   1. The mechanism for handling streaming is optional and can be
      replaced with the tests for use of streaming.  Note that the
      server should never stream at the Client unless the Client
      has streamed at the Server or has used the STI control bit.
      Otherwise, streamed Responses are a protocol error.

   2. As an optimization, a Response can be stored into the CSR for
      the Client rather than allocating a separate CSR for a
      response buffer.  However, if multiple responses are handled,
      the code must be careful to perform duplicate detection on
      the Response stored there as well as those queued.  In
      addition, GetResponse must create a queued version of this
      Response before allowing it to be overwritten.

   3. The handling of Group Responses has been omitted for brevity.
      Basically, a Response is accepted if there has been a Request
      received locally from the same Client and same Transaction
      that has not been responded to.  In this case, the Response
      is delivered to the Server or queued.
Top   ToC   RFC1045 - Page 66
4.8. Management Operations

VMTP uses management operations (invoked as remote procedure calls) to
effectively acknowledge packet groups and request retransmissions.  The
following routine is invoked by the Client's management module on
request from the Server.

NotifyVmtpClient( clientId,ctrl,receiveSeqNumber,transact,delivery,code)
    Get csr for clientId
    if none then return
    if RemoteClient( csr ) and not NotifyVmtpRemoteClient then
       return
|   else (for streaming)
|      Find csr with same LocalTransaction as transact
|      if csr is NULL then return
    if csr.State not AwaitingResponse then return
    if ctrl.PGcount then ack previous packet groups.
    select on code
      case OK:
        Notify ack'ed segment blocks from delivery
        Clear csr.RetransCount;
        Timeout( csr, TC1(csr.Server), LocalClientTimeout )
        return
      case RETRY:
        Set csr.TransmissionMask to missing segment blocks,
            as specified by delivery
        SendPacketGroup( csr )
        Timeout( csr, TC1(csr.Server), LocalClientTimeout )
      case RETRY_ALL
        Set csr.TransmissionMask to retransmit all blocks.
        SendPacketGroup( csr )
        Timeout( csr, TC1(csr.Server), LocalClientTimeout )
|       if streaming then
|          Restart transmission of packet groups,
|                starting from transact+1
         return
      case BUSY:
         if csr.TimeLimit exceeded then
             Set csr.Code to USER_TIMEOUT
             return Response to application
             return;
        Set csr.TransmissionMask for full retransmission
        Clear csr.RetransCount
        Timeout( csr, TC1(csr.Server), LocalClientTimeout )
        return
      case ENTITY_MIGRATED:
        Get new host address for entity
Top   ToC   RFC1045 - Page 67
        Set csr.TransmissionMask for full retransmission
        Clear csr.RetransCount
        SendPacketGroup( csr )
        Timeout( csr, TC1(csr.Server), LocalClientTimeout )
        return

      case STREAMING_NOT_SUPPORTED:
        Record that server does not support streaming
        if CMG(csr) then forget this packet group
        else resend Request as separate packet group.
        return
      default:
         Set csr.Code to code
         return Response to application
         return;
    endselect
end NotifyVmtpClient

Notes:

   1. The delivery parameter indicates the segment blocks received
      by the Server.  That is, a 1 bit in the i-th position
      indicates that the i-th segment block in the segment data of
      the Request was received.  All subsequent NotifyVmtpClient
      operations for this transaction should be set to acknowledge
      a superset of the segment blocks in this packet.  In
      particular, the Client need not be prepared to retransmit the
      segment data once it has been acknowledged by a Notify
      operation.


4.8.1. HandleNoCSR

HandleNoCSR is called when a packet arrives for which there is no CSR
matching the client field of the packet.

HandleNoCSR( p, psize )
    if Secure(p) then
        if SecureVMTP not supported then
            { Assume a Request }
            if not Multicast(p) then
                NotifyClient(NULL,p,SECURITY_NOT_SUPPORTED)
            return
        endif
        HandleRequestNoCSR( p, psize )
        return
    endif
Top   ToC   RFC1045 - Page 68
    if p.Checksum not null then
        if not VerifyChecksum(p, psize) then return;
    if OppositeByteOrder(p) then ByteSwap( p, psize )
    if psize not equal sizeof(VmtpHeader) + 4*p.Length then
        NotifyClient(NULL, p, VMTP_ERROR )
        return

    if p.FuncCode is Response then
|        if Migrated( p.Client ) then
|           NotifyServer(csr, p ENTITY_MIGRATED )
|       else
            NotifyServer(csr, p, NONEXISTENT_ENTITY )
        return
    endif

    if p.FuncCode is Request then
       HandleRequestNoCSR( p, psize )
    return
end HandleNoCSR

Notes:

   1. The node need only check to see if the client entity has
      migrated if in fact it supports migration of entities.

   2. The procedure HandleRequestNoCSR is specified in Section
      5.8.1.  In the minimal client version, it need only handle
      Probe requests and can do so directly without allocating a
      new CSR.
Top   ToC   RFC1045 - Page 69
4.9. Timeouts

A client with a message transaction in progress has a single timer
corresponding to the first unacknowledged request message.  (In the
absence of streaming, this request is also the last request sent.)  This
timeout is handled as follows:

LocalClientTimeout( csr )
  select on csr.State
    case AwaitingResponse:
      if csr.RetransCount > MaxRetrans(csr.Server) then
             terminate Client's message transactions up to
             and including the current message transaction.
             set return code to KERNEL_TIMEOUT
          return
      increment csr.RetransCount
      Resend current packet group with APG set.
      Timeout( csr, TC2(csr.Server), LocalClientTimeout )
      return
    case ReceivingResponse:
      if DGMset(csr) or csr.RetransCount > Max then
         if MDMset(csr) then
            Set MCB.MsgDeliveryMask to blocks received.
         else
            Set csr.Code to BAD_REPLY_SEGMENT
         return to user Client
      endif
      increment csr.RetransCount
      NotifyServer with RETRY
      Timeout( csr, TC3(csr.Server), LocalClientTimeout )
      return
  end select
end LocalClientTimeout

Notes:

   1. A Client can only request retransmission of a Response if the
      Response is not idempotent.  If idempotent, it must
      retransmit the Request.  The Server should generally support
      the MsgDeliveryMask for Requests that it treats as idempotent
      and that require multi-packet Responses.  Otherwise, there is
      no selective retransmission for idempotent message
      transactions.

   2. The current packet group is the last one transmitted.  Thus,
      with streaming, there may be several packet groups
      outstanding that precede the current packet group.
Top   ToC   RFC1045 - Page 70
   3. The Request packet group should be retransmitted without the
      segment data, resulting in a single short packet in the
      retransmission.  The Server must then send a
      NotifyVmtpClient with a RETRY or RETRY_ALL code to get the
      segment data transmitted as needed.  This strategy minimizes
      the overhead on the network and the server(s) for
      retransmissions.
Top   ToC   RFC1045 - Page 71
5. Server Protocol Operation

This section describes the operation of the server portion of the
protocol in terms of the procedures for handling VMTP user events,
packet reception events and timeout events.  Each server is assumed to
implement the client procedures described in the previous chapter.
(This is not strictly necessary but it simplifies the exposition.)


5.1. Remote Client State Record Fields

The CSR for a server is extended with the following fields, in addition
to the ones listed for the client version.

RemoteClient    Identifier for remote client that sent the Request that
                this CSR is handling.

RemoteClientLink
                Link to next CSR hashing to same hash index in the
                ClientMap.

RemoteTransaction
                Transaction identifier for Request from remote client.

RemoteDelivery  The segment blocks received so far as part of a Request
                or yet to be acknowledged as part of a Response.

VerifyInterval  Time interval since there was confirmation that the
                remote Client was still valid.

RemotePrincipal Account identification, possibly including key and key
                timeout for secure communication.


5.2. Remote Client Protocol States

A CSR in the server end is in one of the following states.

AwaitingRequest Waiting for a Request packet group.  It may be marked as
                waiting on a specific Client, or on any Client.

ReceivingRequest
                Waiting to receive additional Request packets in a
                multi-packet group Request.

Responded       The Response has been sent and the CSR is timing out,
                providing duplicate suppression and retransmission (if
Top   ToC   RFC1045 - Page 72
                the Response was not idempotent).

ResponseDiscarded
                Response has been acknowledged or has timed out so
                cannot be retransmitted.  However, duplicates are still
                filtered and CSR can be reused for new message
                transaction.

Processing      Executing on behalf of the Client.

Forwarded       The message transaction has been forwarded to another
                Server that is to respond directly to the Client.


5.3. State Transition Diagrams

The CSR state transitions in the server are illustrated in Figure 5-1.
The CSR generally starts in the AwaitingRequest state.  On receipt of a
Request, the Server either has an up-to-date CSR for the Client or else
it sends a Probe request (as a separate VMTP message transaction) to the
VMTP management module associated with the Client.  In the latter case,
the processing of the Request is delayed until a Response to the Probe
request is received.  At that time, the CSR information is brought up to
date and the Request is processed.  If the Request is a single-packet
request, the CSR is then set in the Processing state to handle the
request.  Otherwise (a multi-packet Request), the CSR is put into the
ReceivingResponse state, waiting to receive subsequent Request packets
that constitute the Request message.  It exits the ReceivingRequest
state on timeout or on receiving the last Request packet.  In the former
case, the request is delivered with an indication of the portion
received, using the MsgDelivery field if MDM is set.  After request
processing is complete, either the Response is sent and the CSR enters
the Responded state or the message transaction is forwarded and the CSR
enters the Forwarded state.

In the Responded state, if the Response is not marked as idempotent, the
Response is retransmitted on receipt of a retransmission of the
corresponding Request, on receipt of a NotifyVmtpServer operation
requesting retransmission or on timeout at which time APG is set,
requesting an acknowledgment from the Client.  The Response is
retransmitted some maximum number of times at which time the Response is
discarded and the CSR is marked accordingly.  If a Request or a
NotifyVmtpServer operation is received expecting retransmission of the
Response after the CSR has entered the ResponseDiscarded state, a
NotifyVmtpClient operation is sent back (or invoked in the Client
management module) indicating that the response was discarded unless the
Request was multicast, in which case no action is taken.  After a
Top   ToC   RFC1045 - Page 73
     (Retransmit Forwarded Request and NotifyVmtpClient)
                    Request/
                    Ack/
                   +Timeout+
                   V       |
                 +-|-------^-+
                 |           |
          +-Time-| Forwarded |<-------------+
          |  out +-----------+              |
          |                                 |
          |          (Retransmit Response)  |
          |                      Request    |
          V                      Ack        |
          |                    +-Timeout-+  |
          |                    V         |  |
        +---------+ Ack/ +|---------^+ |
 +-Time-|Response |<-Timeout--| Responded | |
 |  out |Discarded|           +----^------+ |
 |      +---------+                |        |
 |  +------------+                 |        |
 |  |            |->-Send Response-+        |
 |  |            |->-forward Request--------+
 +->| Processing |<----------------------+
 |  |            |<----------------+     |
 |  |            |<---|            |     |
 |  +-|--------^-+    |          Last    |
 | Receive     |      |          Request |
 |    |   Timeout   Single       Packet  |
 |    |        |    Packet         |   Timeout
 |    |        |    Request        ^     ^
 |    |        |      ^           +|-----|--+
 |  +-V--------|-+    |           |Receiving|<-+Time
 +->|  Awaiting  |->--+->Request->| Request |--+ out
    |  Request   |    |  (multi-  +---------+
    +------|-----+    ^  packet)
        Request       |
           |        Response
      Send Probe     to
           |        Probe
       +---V----+     |
       |Awaiting|     ^
       |Response|-->--+
       |to Probe|
       +--------+

             Figure 5-1:   Remote Client State Transitions

timeout corresponding to the time required to filter out duplicates, the
Top   ToC   RFC1045 - Page 74
CSR returns either to the AwaitingRequest state or to the Processing
state.  Note that "Ack" refers to acknowledgment by a Notify operation.

A Request that is forwarded leaves the CSR in the Forwarded state.  In
the Forwarded state, the forwarded Request is retransmitted
periodically, expecting NotifyRemoteClient operations back from the
Server to which the Request was forwarded, analogous to the Client
behavior in the AwaitingResponse state.  In this state, a
NotifyRemoteClient from this Server acknowledges the Request or asks
that it be retransmitted or reports an error.  A retransmission of the
Request from the Client causes a NotifyVmtpClient to be returned to the
Client if APG is set.  The CSR leaves the Forwarded state after timing
out in the absence of NotifyRemoteClient operations from the forward
Server or on receipt of a NotifyRemoteClient operation indicating the
forward Server has sent a Response and received an acknowledgement.  It
then enters the ResponseDiscarded state.

Receipt of a new Request from the same Client aborts the current
transaction, independent of its state, and initiates a new transaction
unless the new Request is part of a run of message transactions.  If it
is part of a run of message transactions, the handling follows the state
diagram except the new Request is not Processed until there has been a
response sent to the previous transaction.


5.4. User Interface

The RPC or user interface to VMTP is implementation-dependent and may
use systems calls, functions or some other mechanism.  The list of
requests that follow is intended to suggest the basic functionality that
should be available.

AcceptMessage( reqmcb, segptr, segsize, client, transid, timeout ) 
                Accept a new Request message in the specified reqmcb
                area, placing the segment data, if any, in the area
                described by segptr and segsize.  This returns the
                Server in the entityId field of the reqmcb and actual
                segment size in the segsize parameters.  It also returns
                the Client and Transaction for this message transaction
                in the corresponding parameters.  This procedure
                supports message semantics for request processing.  When
                a server process executes this call, it blocks until a
                Request message has been queued for the server.
                AcceptMessage returns after the specified timeout period
                if a message has not been received by that time.

RespondMessage( responsemcb, client, transid, segptr ) 
Top   ToC   RFC1045 - Page 75
                Respond to the client with the specified response
                message and segment, again with message semantics.

RespondCall( responsemcb, segptr ) 
                Respond to the client with the specified response
                message and segment, with remote procedure call
                semantics.  This procedure does not return.  The
                lightweight process that executes this procedure is
                matched to a stack, program counter, segment area and
                priority from the information provided in a
                ModifyService call, as specified in Appendix III.

ForwardMessage( requestmcb, transid, segptr, segsize, forwardserver ) 
                Forward the client to the specified forwardserver with
                the request specified in mcb.

ForwardCall( requestmcb, segptr, segsize, forwardserver ) 
                Forward the client transaction to the specified
                forwardserver with the request specified by requestmcb.
                This procedure does not return.

GetRemoteClientId()
                Return the entityId for the remote client on whose
                behave the process is executing.  This is only
                applicable in the procedure call model of request
                handling.

GetForwarder( client )
                Return the entity that forwarded this Request, if any.

GetProcess( client )
                Return an identifier for the process associated with
                this client entity-id.

GetPrincipal( client )
                Return the principal associated with this client
                entity-id.


5.5. Event Processing

The following events may occur in VMTP servers.

   - User Requests

        * Receive
Top   ToC   RFC1045 - Page 76
        * Respond

        * Forward

        * GetForwarder

        * GetProcess

        * GetPrincipal

   - Packet Arrival

        * Request Packet

   - Management Operations

        * NotifyVmtpServer

   - Timeouts

        * Client State Record Timeout

The handling of these events is described in detail in the following
subsections.  The conventions of the previous chapter are followed,
including the use of the various subroutines in the description.


5.6. Server User-invoked Events

A user event occurs when a VMTP server invokes one of the VMTP interface
procedures.


5.6.1. Receive

AcceptMessage(reqmcb, segptr, segsize, client, transid, timeout)
    Locate server's request queue.
    if request is queued then
        Remember CSR associated with this Request.
        return Request in reqmcb, segptr and segsize
               and client and transaction id.
    Wait on server's request queue for next request
    up time timeout seconds.
end ReceiveCall

Notes:
Top   ToC   RFC1045 - Page 77
   1. If a multi-packet Request is partially received at the time
      of the AcceptMessage, the process waits until it completes.

   2. The behavior of a process accepting a Request as a
      lightweight thread is similar except that the process
      executes using the Request data logically as part of the
      requesting Client process.


5.6.2. Respond

RespondCall is described as one case of the Respond transmission
procedure; RespondMessage is similar.

RespondCall( responsemcb, responsesegptr )
    Locate csr for this client.
    Check segment data accessible, if any
    if local client then
        Handle locally
        return
    endif
    if responsemcb.Code is RESPONSE_DISCARDED then
        Mark as RESPONSE_DISCARDED
        return
    SendPacketGroup( csr )
    set csr.State to Responded.
    if DGM reply then { Idempotent }
        release segment data
        Timeout( csr, TS4(csr.Client), FreeCsr );
    else { Await acknowledgement or new Request else ask for ack. }
        Timeout( csr, TS5(csr.Client), RemoteClientTimeout )
end RespondCall

Notes:

   1. RespondMessage is similar except the Server process must be
      synchronized with the release of the segment data (if any).

   2. The non-idempotent Response with segment data is sent first
      without a request for an acknowledgement.  The Response is
      retransmitted after time TS5(client) if no acknowledgment or
      new Request is received from the client in the meantime.  At
      this point, the APG bit is sent.

   3. The MCB of the Response is buffered in the client CSR, which
      remains for TS4 seconds, sufficient to filter old duplicates.
      The segment data (if any) must be retained intact until:  (1)
Top   ToC   RFC1045 - Page 78
      after transmission if idempotent or (2) after acknowledged or
      timeout has occurred if not idempotent.  Techniques such as
      copy-on-write might be used to keep a copy of the Response
      segment data without incurring the cost of a copy.


5.6.3. Forward

Forwarding is logically initiating a new message transaction between the
Server (now acting as a Client) and the server to which the Request is
forwarded.  When the second server returns a Response, the same Response
is immediately returned to the Client.  The forwarding support in VMTP
preserves these semantics while providing some performance optimizations
in some cases.

ForwardCall( req, segptr, segsize, forwardserver )
    Locate csr for this client.
    Check segment data accessible, if any

    if local client or Request was multicast or secure
       or csr.ForwardCount == 15 then
        Handle as a new Send operation
        return
    if forwardserver is local then
        Handle locally
        return
    Set csr.funccode to Request
    Increment csr.ForwardCount
    Set csr.State to Responded
    SendPacketGroup( csr ) { To ForwardServer }
    Timeout( csr, TS4(csr.Client), FreeAlien )
end ForwardCall

Notes:

   1. A Forward is logically a new call or message transaction.  It
      must be really implemented as a new message transaction if
      the original Request was multicast or secure (with the
      optional further refinement that it can be used with a secure
      message transaction when the Server and ForwardServer are the
      same principal and the Request was not multicast).

   2. A Forward operation is never handled as an idempotent
      operation because it requires knowledge that the
      ForwardServer will treat the forwarded operation as
      idempotent as well.  Thus, a Forward operation that includes
      a segment should set APG on the first transmission of the
Top   ToC   RFC1045 - Page 79
      forwarded Request to get an acknowledgement for this data.
      Once the acknowledgement is received, the forwarding Server
      can discard the segment data, leaving only the basic CSR to
      handle retransmissions from the Client.


5.6.4. Other Functions

GetRemoteClient is a simple local query of the CSR.  GetProcess and
GetPrincipal also extract this information from the CSR.  A server
module may defer the Probe callback to the Client to get that
information until it is requested by the Server (assuming it is not
using secure communication and duplicate suppression is adequate without
callback.)  GetForwarder is implemented as a callback to the Client,
using a GetRequestForwarder VMTP management operation.  Additional
management procedures for VMTP are described in Appendix III.


5.7. Request Packet Arrival

The basic packet reception follows that described for the Client
routines.  A Request packet is handled by the procedure HandleRequest.

HandleRequest( csr, p, psize )

    if LocalClient(csr) then
        { Forwarded Request on local Client }
        if csr.LocalTransaction != p.Transaction then return
        if csr.State != AwaitingResponse then return
        if p.ForwardCount < csr.ForwardCount then
           Discard Request and return.
        Find a CSR for Client as a remote Client.
        if not found then
            if packet group complete then
                handle as a local message transaction
                return
            Allocate and init CSR
            goto newTransaction
        { Otherwise part of current transaction }
        { Handle directly below. }n
    if csr.RemoteTransaction = p.Transaction then
      { Matches current transaction }
        if OldForward(p.ForwardCount,csr.ForwardCount) then
            return
        if p.ForwardCount > csr.ForwardCount then
          { New forwarded transaction }
            goto newTransaction
Top   ToC   RFC1045 - Page 80
        { Otherwise part of current transaction }
        if csr.State = ReceivingRequest then
            if new segment data then retain in CSR segment area.
            if Request not complete then
               Timeout( csr, TS1(p.Client), RemoteClientTimeout )
               return;
            endif
            goto endPacketGroup
        endif
        if csr.State is Responded then
          { Duplicate }
            if csr.Code is RESPONSE_DISCARDED
               and Multicast(p) then
                return
            endif
            if not DGM(csr) then { Not idempotent }
                if SegmentData(csr) then set APG
                { Resend Response or Request, if Forwarded }
                SendPacketGroup( csr )
                timeout=if SegmentData(csr) then TS5(csr.Client)
                          else TS4(csr.Client)
                Timeout( csr, timeout, RemoteClientTimeout )
                return
            { Else idempotent - fall thru to newTransaction }
        else { Presume it is a retransmission }
            NotifyClient( csr, p, OK )
            return
   else if OldTransaction(csr.RemoteTransact,p.Transaction) then
        return
    { Otherwise, a new message transaction. }
newTransaction:
    Abort handling of previous transactions for this Client.

    if (NSRset(p) or NERset(p)) and NoStreaming then
        NotifyClient( csr, p, STREAMING_NOT_SUPPORTED )
        return
|   if NSRset(p) then { Streaming }
|     { Check that consecutive with previous packet group }
|       Find last packet group CSR from this client.
|      if p.Transaction not lastcsr.RemoteTransaction+1 mod 2**32
|         and not STIset(lastcsr) or
|        p.Transaction not lastcsr.RemoteTransaction+256 mod **32
|        then
|         { Out of order packet group }
|         NotifyClient(csr, p, BAD_TRANSACTION_ID )
|         return
|       endif
Top   ToC   RFC1045 - Page 81
|       if lastcsr not completed then
|           NotifyClient( lastcsr, p, RETRY )
|       endif
|       if lastcsr available then use it for this packet group
|       else allocate and initialize new CSR
|       if CMG(lastcsr) then
|          Add segment data to lastcsr Request
|          Keep csr as record of this packet group.
|          Clear lastcsr.VerifyInterval
|      endif
|   else { First packet group }
        if MultipleRemoteClients(csr) then ScavengeCsrs(p.Client)
        Set csr.RemoteTransaction, csr.Priority
        Copy message and segment data to csr's segment area
         and set csr.PacketDelivery to that delivered.
        Clear csr.PacketDelivery
        Clear csr.VerifyInterval
        SaveNetworkAddress( csr, p )
    endif
    if packetgroup not complete then
        Timeout( csr, TS3(p.Client), RemoteClientTimeout )
        return;
    endif
endPacketGroup:
    { We have received complete packet group. }
    if APG(p) then NotifyClient( csr, p, OK )
    endif
|   if NERset(p) and CMG(p) then
|       Queue waiting for continuation packet group.
|       Timeout( csr, TS3(csr.Client), RemoteClientTimeout )
|       return
|   endif
    { Deliver request message. }
    if GroupId(csr.Server) then
        For each server identified by csr.Server
            Replicate csr and associated data segment.
            if CMDset(csr) and Server busy then
               Discard csr and data
            else
               Deliver or invoke csr for each Server.
            if not DGMset(csr) then queue for Response
            else Timeout( csr, TS4(csr.Client), FreeCsr )
        endfor
     else
       if CMDset(csr) and Server busy then
           Discard csr and data
        else
Top   ToC   RFC1045 - Page 82
           Deliver or invoke csr for this server.
        if not DGMset(csr) then queue for Response
        else Timeout( csr, TS4(csr.Client), FreeCsr )
     endif
end HandleRequest

Notes:

   1. A Request received that specifies a Client that is a local
      entity should be a Request forwarded by a remote server to a
      local Server.

   2. An alternative structure for handling a Request sent to a
      group when there are multiple local group members is to
      create a remote CSR for each group member on reception of the
      first packet and deliver a copy of each packet to each such
      remote CSR as each packet arrives.
Top   ToC   RFC1045 - Page 83
5.8. Management Operations

VMTP uses management operations (invoked as remote procedure calls) to
effectively acknowledge packet groups and request retransmissions.  The
following routine is invoked by the Server's management module on
request from the Client.

NotifyVmtpServer(server,clientId,transact,delivery,code)
    Find csr with same RemoteTransaction and RemoteClient
    as clientId and transact.
    if not found or csr.State not Responded then return
    if DGMset(csr) then
        if transmission of Response in progress then
            Abort transmission
            if code is migrated then
               restart transmission with new host addr.
        if Retry then Report protocol error
        return
    endif
    select on code
      case RETRY:
        if csr.RetransCount > MaxRetrans(clientId) then
             if response data segment then
                 Discard data and mark as RESPONSE_DISCARDED
|                if NERset(csr) and subsequent csr then
|                    Deallocate csr and use later csr for
|                    future duplicate suppression
|                endif
             return
        endif
        increment csr.RetransCount
        Set csr.TransmissionMask to missing segment blocks,
            as specified by delivery
        SendPacketGroup( csr )
        Timeout( csr, TS3(csr.Client), RemoteClientTimeout )
      case BUSY:
        if csr.TimeLimit exceeded then
            if response data segment then
                Discard data and mark as RESPONSE_DISCARDED
|               if NERset(csr) and subsequent csr then
|                   Deallocate csr and use later csr for
|                   future duplicate suppression
|               endif
             endif
        endif
        Set csr.TransmissionMask for full retransmission
        Clear csr.RetransCount
Top   ToC   RFC1045 - Page 84
        Timeout( csr, TS3(csr.Server), RemoteClientTimeout )
        return

      case ENTITY_MIGRATED:
        Get new host address for entity
        Set csr.TransmissionMask for full retransmission
        Clear csr.RetransCount
        SendPacketGroup( csr )
        Timeout( csr, TS3(csr.Server), RemoteClientTimeout )
        return

      case default:
        Abort transmission of Response if in progress.
        if response data segment then
           Discard data and mark as RESPONSE_DISCARDED
           if NERset(csr) and subsequent csr then
               Deallocate csr and use later csr for
               future duplicate suppression
           endif
        return
    endselect
end NotifyVmtpServer

Notes:

   1. A NotifyVmtpServer operation requesting retransmission of
      the Response is acceptable only if the Response was not
      idempotent.  When the Response is idempotent, the Client must
      be prepared to retransmit the Request to effectively request
      retransmission of the Response.

   2. A NotifyVmtpServer operation may be received while the
      Response is being transmitted.  If an error return, as an
      efficiency, the transmission should be aborted, as suggested
      when the Response is a datagram.

   3. A NotifyVmtpServer operation indicating OK or an error
      allows the Server to discard segment data and not provide for
      subsequent retransmission of the Response.


5.8.1. HandleRequestNoCSR

When a Request is received from a Client for which the node has no CSR,
the node allocates and initializes a CSR for this Client and does a
callback to the Client's VMTP management module to get the Principal,
Process and other information associated with this Client.  It also
Top   ToC   RFC1045 - Page 85
checks that the TransactionId is correct in order to filter out
duplicates.

HandleRequestNoCSR( p, psize )
|   if Secure(p) then
|       Allocate and init CSR
|       SaveSourceHostAddr( csr, p )
|       ProbeRemoteClient( csr, p, AUTH_PROBE )
|       if no response or error then
|          delete CSR
|          return
|       Decrypt( csr.Key, p, psize )
|        if p.Checksum not null then
|       if not VerifyChecksum(p, psize) then return;
|       if OppositeByteOrder(p) then ByteSwap( p, psize )
|       if psize not equal sizeof(VmtpHeader) + 4*p.Length then
|          NotifyClient(NULL, p, VMTP_ERROR )
|          return
|       HandleRequest( csr, p, psize )
|       return
    if Server does not exist then
        NotifyClient( csr, p, NONEXISTENT_ENTITY )
        return
    endif
    if security required by server then
        NotifyClient(csr, p, SECURITY_REQUIRED )
        return
    endif
    Allocate and init CSR
    SaveSourceHostAddr( csr, p );
    if server requires Authentication then
        ProbeRemoteClient( csr, p, AUTH_PROBE )
        if no response or error then
           delete CSR
           return
    endif
    { Setup immediately as a new message transaction }
    set csr.Server to p.Server
    set csr.RemoteTransaction to p.Transaction-1

    HandleRequest( csr, p, psize )
    endif

Notes:

   1. A Probe request is always handled as a Request not requiring
      authentication so it never generates a callback Probe to the
Top   ToC   RFC1045 - Page 86
      Client.

   2. If the Server host retains remote client CSR's for longer
      than the maximum packet lifetime and the Request
      retransmission time, and the host has been running for at
      least that long, then it is not necessary to do a Probe
      callback unless the Request is secure.  A Probe callback can
      take place when the Server asks for the Process or
      PrincipalId associated with the Client.
Top   ToC   RFC1045 - Page 87
5.9. Timeouts

The server must implement a timeout for remote client CSRs.  There is a
timeout for each CSR in the server.

RemoteClientTimeout( csr )
  select on csr.State
    case Responded:
        if RESPONSE_DISCARDED then
            mark as timed out
            Make a candidate for reuse.
            return
        if csr.RetransCount > MaxRetrans(Client) then
            discard Response
            mark CSR as RESPONSE_DISCARDED
            Timeout(csr, TS4(Client), RemoteClientTimeout)
            return
        increment csr.RetransCount
        { Retransmit Response or forwarded Request }
        Set APG to get acknowledgement.
        SendPacketGroup( csr )
        Timeout( csr, TS3(Client), RemoteClientTimeout )
        return
    case ReceivingRequest:
      if csr.RetransCount > MaxRetrans(csr.Client)
         or DGMset(csr) or NRTset(csr) then
          Modify csr.segmentSize and csr.MsgDelivery
          to indicate packets received.
          if MDMset(csr) then
              Invoke processing on Request
              return
          else
              discard Request and reuse CSR
              (Note: Need not remember Request discarded.)
              return
      increment csr.RetransCount
      NotifyClient( csr, p, RETRY )
      Timeout( csr, TS3(Client), RemoteClientTimeout )
      return
    default:
        Report error - invalid state for RemoteClientTimeout
    endselect
end RemoteClientTimeout

Notes:

   1. When a CSR in the Responded state times out after discarding
Top   ToC   RFC1045 - Page 88
      the Response, it can be made available for reuse, either by
      the same Client or a different one.  The CSR should be kept
      available for reuse by the Client for as long as possible to
      avoid unnecessary callback Probes.


(next page on part 4)

Next Section