• David Howells's avatar
    rxrpc: Call channels should have separate call number spaces · a1399f8b
    David Howells authored
    Each channel on a connection has a separate, independent number space from
    which to allocate callNumber values.  It is entirely possible, for example,
    to have a connection with four active calls, each with call number 1.
    
    Note that the callNumber values for any particular channel don't have to
    start at 1, but they are supposed to increment monotonically for that
    channel from a client's perspective and may not be reused once the call
    number is transmitted (until the epoch cycles all the way back round).
    
    Currently, however, call numbers are allocated on a per-connection basis
    and, further, are held in an rb-tree.  The rb-tree is redundant as the four
    channel pointers in the rxrpc_connection struct are entirely capable of
    pointing to all the calls currently in progress on a connection.
    
    To this end, make the following changes:
    
     (1) Handle call number allocation independently per channel.
    
     (2) Get rid of the conn->calls rb-tree.  This is overkill as a connection
         may have a maximum of four calls in progress at any one time.  Use the
         pointers in the channels[] array instead, indexed by the channel
         number from the packet.
    
     (3) For each channel, save the result of the last call that was in
         progress on that channel in conn->channels[] so that the final ACK or
         ABORT packet can be replayed if necessary.  Any call earlier than that
         is just ignored.  If we've seen the next call number in a packet, the
         last one is most definitely defunct.
    
     (4) When generating a RESPONSE packet for a connection, the call number
         counter for each channel must be included in it.
    
     (5) When parsing a RESPONSE packet for a connection, the call number
         counters contained therein should be used to set the minimum expected
         call numbers on each channel.
    
    To do in future commits:
    
     (1) Replay terminal packets based on the last call stored in
         conn->channels[].
    
     (2) Connections should be retired before the callNumber space on any
         channel runs out.
    
     (3) A server is expected to disregard or reject any new incoming call that
         has a call number less than the current call number counter.  The call
         number counter for that channel must be advanced to the new call
         number.
    
         Note that the server cannot just require that the next call that it
         sees on a channel be exactly the call number counter + 1 because then
         there's a scenario that could cause a problem: The client transmits a
         packet to initiate a connection, the network goes out, the server
         sends an ACK (which gets lost), the client sends an ABORT (which also
         gets lost); the network then reconnects, the client then reuses the
         call number for the next call (it doesn't know the server already saw
         the call number), but the server thinks it already has the first
         packet of this call (it doesn't know that the client doesn't know that
         it saw the call number the first time).
    Signed-off-by: default avatarDavid Howells <dhowells@redhat.com>
    a1399f8b
ar-internal.h 29.7 KB