Section 8. Event Processing

This section describes how DCCP connections move between states and
   which packets are sent when.  Note that feature negotiation takes
   place in parallel with the connection-wide state transitions
   described here.
8.1.  Connection Establishment
   DCCP connections' initiation phase consists of a three-way handshake:
   an initial DCCP-Request packet sent by the client, a DCCP-Response
   sent by the server in reply, and finally an acknowledgement from the
   client, usually via a DCCP-Ack or DCCP-DataAck packet.  The client
   moves from the REQUEST state to PARTOPEN, and finally to OPEN; the
   server moves from LISTEN to RESPOND, and finally to OPEN.
     Client State                             Server State
        CLOSED                                   LISTEN
   1.   REQUEST   -->       Request        -->
   2.             <--       Response       <--   RESPOND
   3.   PARTOPEN  -->     Ack, DataAck     -->
   4.             <--  Data, Ack, DataAck  <--   OPEN
   5.   OPEN      <->  Data, Ack, DataAck  <->   OPEN
8.1.1.  Client Request
   When a client decides to initiate a connection, it enters the REQUEST
   state, chooses an initial sequence number (Section 7.2), and sends a
   DCCP-Request packet using that sequence number to the intended
   server.
   DCCP-Request packets will commonly carry feature negotiation options
   that open negotiations for various connection parameters, such as
   preferred congestion control IDs for each half-connection.  They may
   also carry application data, but the client should be aware that the
   server may not accept such data.
   A client in the REQUEST state SHOULD use an exponential-backoff timer
   to send new DCCP-Request packets if no response is received.  The
   first retransmission should occur after approximately one second,
   backing off to not less than one packet every 64 seconds; or the
   endpoint can use whatever retransmission strategy is followed for
   retransmitting TCP SYNs.  Each new DCCP-Request MUST increment the
   Sequence Number by one and MUST contain the same Service Code and
   application data as the original DCCP-Request.
   A client MAY give up on its DCCP-Requests after some time (3 minutes,
   for example).  When it does, it SHOULD send a DCCP-Reset packet to
   the server with Reset Code 2, "Aborted", to clean up state in case
   one or more of the Requests actually arrived.  A client in REQUEST
   state has never received an initial sequence number from its peer, so
   the DCCP-Reset's Acknowledgement Number MUST be set to zero.
   The client leaves the REQUEST state for PARTOPEN when it receives a
   DCCP-Response from the server.
8.1.2.  Service Codes
   Each DCCP-Request contains a 32-bit Service Code, which identifies
   the application-level service to which the client application is
   trying to connect.  Service Codes should correspond to application
   services and protocols.  For example, there might be a Service Code
   for SIP control connections and one for RTP audio connections.
   Middleboxes, such as firewalls, can use the Service Code to identify
   the application running on a nonstandard port (assuming the DCCP
   header has not been encrypted).
   Endpoints MUST associate a Service Code with every DCCP socket, both
   actively and passively opened.  The application will generally supply
   this Service Code.  Each active socket MUST have exactly one Service
   Code.  Passive sockets MAY, at the implementation's discretion, be
   associated with more than one Service Code; this might let multiple
   applications, or multiple versions of the same application, listen on
   the same port, differentiated by Service Code.  If the DCCP-Request's
   Service Code doesn't equal any of the server's Service Codes for the
   given port, the server MUST reject the request by sending a DCCP-
   Reset packet with Reset Code 8, "Bad Service Code".  A middlebox MAY
   also send such a DCCP-Reset in response to packets whose Service Code
   is considered unsuitable.
   Service Codes are not intended to be DCCP-specific and are allocated
   by IANA.  Following the policies outlined in [RFC2434], most Service
   Codes are allocated First Come First Served, subject to the following
   guidelines.
   o  Service Codes are allocated one at a time, or in small blocks.  A
      short English description of the intended service is REQUIRED to
      obtain a Service Code assignment, but no specification, standards
      track or otherwise, is necessary.  IANA maintains an association
      of Service Codes to the corresponding phrases.
   o  Users request specific Service Code values.  We suggest that users
      request Service Codes that can be represented using the "SC:"
      formatting convention described below.  Thus, the "Frobodyne Plotz
      Protocol" might correspond to Service Code 17178548426 or,
      equivalently, "SC:fdpz".  The canonical interpretation of a
      Service Code field is numeric.
   o  Service Codes whose bytes each have values in the set {32, 45-57,
      65-90} use a Specification Required allocation policy.  That is,
      these Service Codes are used for international standard or
      standards-track specifications, IETF or otherwise.  (This set
      consists of the ASCII digits, uppercase letters, and characters
      space, '-', '.', and '/'.)
   o  Service Codes whose high-order byte equals 63 (ASCII '?') are
      reserved for Private Use.
   o  Service Code 0 represents the absence of a meaningful Service Code
      and MUST NOT be allocated.
   o  The value 4294967295 is an invalid Service Code.  Servers MUST
      reject any DCCP-Request with this Service Code value by sending a
      DCCP-Reset packet with Reset Code 8, "Bad Service Code".
   This design for Service Code allocation is based on the allocation of
   4-byte identifiers for Macintosh resources, PNG chunks, and TrueType
   and OpenType tables.
   In text settings, we recommend that Service Codes be written in one
   of three forms, prefixed by the ASCII letters SC and either a colon
   ":" or equals sign "=".  These forms are interpreted as follows.
   SC:     Indicates a Service Code representable using a subset of the
           ASCII characters.  The colon is followed by one to four
           characters taken from the following set: letters, digits, and
           the characters in "-_+.*/?@" (not including quotes).
           Numerically, these characters have values in {42-43, 45-57,
           63-90, 95, 97-122}.  The Service Code is calculated by
           padding the string on the right with spaces (value 32) and
           intepreting the four-character result as a 32-bit big-endian
           number.
   SC=     Indicates a decimal Service Code.  The equals sign is
           followed by any number of decimal digits, which specify the
           Service Code.  Values above 4294967294 are illegal.
   SC=x or SC=X
           Indicates a hexadecimal Service Code.  The "x" or "X" is
           followed by any number of hexadecimal digits (upper or lower
           case), which specify the Service Code.  Values above
           4294967294 are illegal.
   Thus, the Service Code 1717858426 might be represented in text as
   either SC:fdpz, SC=1717858426, or SC=x6664707A.
8.1.3.  Server Response
   In the second phase of the three-way handshake, the server moves from
   the LISTEN state to RESPOND and sends a DCCP-Response message to the
   client.  In this phase, a server will often specify the features it
   would like to use, either from among those the client requested or in
   addition to those.  Among these options is the congestion control
   mechanism the server expects to use.
   The server MAY respond to a DCCP-Request packet with a DCCP-Reset
   packet to refuse the connection.  Relevant Reset Codes for refusing a
   connection include 7, "Connection Refused", when the DCCP-Request's
   Destination Port did not correspond to a DCCP port open for
   listening; 8, "Bad Service Code", when the DCCP-Request's Service
   Code did not correspond to the service code registered with the
   Destination Port; and 9, "Too Busy", when the server is currently too
   busy to respond to requests.  The server SHOULD limit the rate at
   which it generates these resets; for example, to not more than 1024
   per second.
   The server SHOULD NOT retransmit DCCP-Response packets; the client
   will retransmit the DCCP-Request if necessary.  (Note that the
   "retransmitted" DCCP-Request will have, at least, a different
   sequence number from the "original" DCCP-Request.  The server can
   thus distinguish true retransmissions from network duplicates.)  The
   server will detect that the retransmitted DCCP-Request applies to an
   existing connection because of its Source and Destination Ports.
   Every valid DCCP-Request received while the server is in the RESPOND
   state MUST elicit a new DCCP-Response.  Each new DCCP-Response MUST
   increment the server's Sequence Number by one and MUST include the
   same application data, if any, as the original DCCP-Response.
   The server MUST NOT accept more than one piece of DCCP-Request
   application data per connection.  In particular, the DCCP-Response
   sent in reply to a retransmitted DCCP-Request with application data
   SHOULD contain a Data Dropped option, in which the retransmitted
   DCCP-Request data is reported with Drop Code 0, Protocol Constraints.
   The original DCCP-Request SHOULD also be reported in the Data Dropped
   option, either in a Normal Block (if the server accepted the data or
   there was no data) or in a Drop Code 0 Drop Block (if the server
   refused the data the first time as well).
   The Data Dropped and Init Cookie options are particularly useful for
   DCCP-Response packets (Sections 11.7 and 8.1.4).
   The server leaves the RESPOND state for OPEN when it receives a valid
   DCCP-Ack from the client, completing the three-way handshake.  It MAY
   also leave the RESPOND state for CLOSED after a timeout of not less
   than 4MSL (8 minutes); when doing so, it SHOULD send a DCCP-Reset
   with Reset Code 2, "Aborted", to clean up state at the client.
8.1.4.  Init Cookie Option
   +--------+--------+--------+--------+--------+--------
   |00100100| Length |         Init Cookie Value   ...
   +--------+--------+--------+--------+--------+--------
    Type=36
   The Init Cookie option lets a DCCP server avoid having to hold any
   state until the three-way connection setup handshake has completed,
   in a similar fashion as for TCP SYN cookies [SYNCOOKIES].  The server
   wraps up the Service Code, server port, and any options it cares
   about from both the DCCP-Request and DCCP-Response in an opaque
   cookie.  Typically the cookie will be encrypted using a secret known
   only to the server and will include a cryptographic checksum or magic
   value so that correct decryption can be verified.  When the server
   receives the cookie back in the response, it can decrypt the cookie
   and instantiate all the state it avoided keeping.  In the meantime,
   it need not move from the LISTEN state.
   The Init Cookie option MUST NOT be sent on DCCP-Request or DCCP-Data
   packets.  Any Init Cookie options received on DCCP-Request or DCCP-
   Data packets, or after the connection has been established (when the
   connection's state is >= OPEN), MUST be ignored.  The server MAY
   include Init Cookie options in its DCCP-Response.  If so, then the
   client MUST echo the same Init Cookie options, in the same order, in
   each succeeding DCCP packet until one of those packets is
   acknowledged (showing that the three-way handshake has completed) or
   the connection is reset.  As a result, the client MUST NOT use DCCP-
   Data packets until the three-way handshake completes or the
   connection is reset.  The Init Cookie options on a client packet MUST
   equal those received on the DCCP-Request indicated by the client
   packet's Acknowledgement Number.  The server SHOULD design its Init
   Cookie format so that Init Cookies can be checked for tampering; it
   SHOULD respond to a tampered Init Cookie option by resetting the
   connection with Reset Code 10, "Bad Init Cookie".
   Init Cookie's precise implementation need not be specified here;
   since Init Cookies are opaque to the client, there are no
   interoperability concerns.  An example cookie format might encrypt
   (using a secret key) the connection's initial sequence and
   acknowledgement numbers, ports, Service Code, any options included on
   the DCCP-Request packet and the corresponding DCCP-Response, a random
   salt, and a magic number.  On receiving a reflected Init Cookie, the
   server would decrypt the cookie, validate it by checking its magic
   number, sequence numbers, and ports, and, if valid, create a
   corresponding socket using the options.
   Each individual Init Cookie option can hold at most 253 bytes of
   data, but a server can send multiple Init Cookie options to gain more
   space.
8.1.5.  Handshake Completion
   When the client receives a DCCP-Response from the server, it moves
   from the REQUEST state to PARTOPEN and completes the three-way
   handshake by sending a DCCP-Ack packet to the server.  The client
   remains in PARTOPEN until it can be sure that the server has received
   some packet the client sent from PARTOPEN (either the initial DCCP-
   Ack or a later packet).  Clients in the PARTOPEN state that want to
   send data MUST do so using DCCP-DataAck packets, not DCCP-Data
   packets.  This is because DCCP-Data packets lack Acknowledgement
   Numbers, so the server can't tell from a DCCP-Data packet whether the
   client saw its DCCP-Response.  Furthermore, if the DCCP-Response
   included an Init Cookie, that Init Cookie MUST be included on every
   packet sent in PARTOPEN.
   The single DCCP-Ack sent when entering the PARTOPEN state might, of
   course, be dropped by the network.  The client SHOULD ensure that
   some packet gets through eventually.  The preferred mechanism would
   be a roughly 200-millisecond timer, set every time a packet is
   transmitted in PARTOPEN.  If this timer goes off and the client is
   still in PARTOPEN, the client generates another DCCP-Ack and backs
   off the timer.  If the client remains in PARTOPEN for more than 4MSL
   (8 minutes), it SHOULD reset the connection with Reset Code 2,
   "Aborted".
   The client leaves the PARTOPEN state for OPEN when it receives a
   valid packet other than DCCP-Response, DCCP-Reset, or DCCP-Sync from
   the server.
8.2.  Data Transfer
   In the central data transfer phase of the connection, both server and
   client are in the OPEN state.
   DCCP A sends DCCP-Data and DCCP-DataAck packets to DCCP B due to
   application events on host A.  These packets are congestion-
   controlled by the CCID for the A-to-B half-connection.  In contrast,
   DCCP-Ack packets sent by DCCP A are controlled by the CCID for the
   B-to-A half-connection.  Generally, DCCP A will piggyback
   acknowledgement information on DCCP-Data packets when acceptable,
   creating DCCP-DataAck packets.  DCCP-Ack packets are used when there
   is no data to send from DCCP A to DCCP B, or when the congestion
   state of the A-to-B CCID will not allow data to be sent.
   DCCP-Sync and DCCP-SyncAck packets may also occur in the data
   transfer phase.  Some cases causing DCCP-Sync generation are
   discussed in Section 7.5.  One important distinction between DCCP-
   Sync packets and other packet types is that DCCP-Sync elicits an
   immediate acknowledgement.  On receiving a valid DCCP-Sync packet, a
   DCCP endpoint MUST immediately generate and send a DCCP-SyncAck
   response (subject to any implementation rate limits); the
   Acknowledgement Number on that DCCP-SyncAck MUST equal the Sequence
   Number of the DCCP-Sync.
   A particular DCCP implementation might decide to initiate feature
   negotiation only once the OPEN state was reached, in which case it
   might not allow data transfer until some time later.  Data received
   during that time SHOULD be rejected and reported using a Data Dropped
   Drop Block with Drop Code 0, Protocol Constraints (see Section 11.7).
8.3.  Termination
   DCCP connection termination uses a handshake consisting of an
   optional DCCP-CloseReq packet, a DCCP-Close packet, and a DCCP-Reset
   packet.  The server moves from the OPEN state, possibly through the
   CLOSEREQ state, to CLOSED; the client moves from OPEN through CLOSING
   to TIMEWAIT, and after 2MSL wait time (4 minutes) to CLOSED.
   The sequence DCCP-CloseReq, DCCP-Close, DCCP-Reset is used when the
   server decides to close the connection but doesn't want to hold
   TIMEWAIT state:
     Client State                             Server State
        OPEN                                     OPEN
   1.             <--       CloseReq       <--   CLOSEREQ
   2.   CLOSING   -->        Close         -->
   3.             <--        Reset         <--   CLOSED (LISTEN)
   4.   TIMEWAIT
   5.   CLOSED
   A shorter sequence occurs when the client decides to close the
   connection.
     Client State                             Server State
        OPEN                                     OPEN
   1.   CLOSING   -->        Close         -->
   2.             <--        Reset         <--   CLOSED (LISTEN)
   3.   TIMEWAIT
   4.   CLOSED
   Finally, the server can decide to hold TIMEWAIT state:
     Client State                             Server State
        OPEN                                     OPEN
   1.             <--        Close         <--   CLOSING
   2.   CLOSED    -->        Reset         -->
   3.                                            TIMEWAIT
   4.                                            CLOSED (LISTEN)
   In all cases, the receiver of the DCCP-Reset packet holds TIMEWAIT
   state for the connection.  As in TCP, TIMEWAIT state, where an
   endpoint quietly preserves a socket for 2MSL (4 minutes) after its
   connection has closed, ensures that no connection duplicating the
   current connection's source and destination addresses and ports can
   start up while old packets might remain in the network.
   The termination handshake proceeds as follows.  The receiver of a
   valid DCCP-CloseReq packet MUST respond with a DCCP-Close packet.
   The receiver of a valid DCCP-Close packet MUST respond with a DCCP-
   Reset packet with Reset Code 1, "Closed".  The receiver of a valid
   DCCP-Reset packet -- which is also the sender of the DCCP-Close
   packet (and possibly the receiver of the DCCP-CloseReq packet) --
   will hold TIMEWAIT state for the connection.
   A DCCP-Reset packet completes every DCCP connection, whether the
   termination is clean (due to application close; Reset Code 1,
   "Closed") or unclean.  Unlike TCP, which has two distinct termination
   mechanisms (FIN and RST), DCCP ends all connections in a uniform
   manner.  This is justified because some aspects of connection
   termination are the same independent of whether termination was
   clean.  For instance, the endpoint that receives a valid DCCP-Reset
   SHOULD hold TIMEWAIT state for the connection.  Processors that must
   distinguish between clean and unclean termination can examine the
   Reset Code.  DCCP implementations generally transition to the CLOSED
   state after sending a DCCP-Reset packet.
   Endpoints in the CLOSEREQ and CLOSING states MUST retransmit DCCP-
   CloseReq and DCCP-Close packets, respectively, until leaving those
   states.  The retransmission timer should initially be set to go off
   in two round-trip times and should back off to not less than once
   every 64 seconds if no relevant response is received.
   Only the server can send a DCCP-CloseReq packet or enter the CLOSEREQ
   state.  A server receiving a sequence-valid DCCP-CloseReq packet MUST
   respond with a DCCP-Sync packet and otherwise ignore the DCCP-
   CloseReq.
   DCCP-Data, DCCP-DataAck, and DCCP-Ack packets received in CLOSEREQ or
   CLOSING states MAY be either processed or ignored.
8.3.1.  Abnormal Termination
   DCCP endpoints generate DCCP-Reset packets to terminate connections
   abnormally; a DCCP-Reset packet may be generated from any state.
   Resets sent in the CLOSED, LISTEN, and TIMEWAIT states use Reset Code
   3, "No Connection", unless otherwise specified.  Resets sent in the
   REQUEST or RESPOND states use Reset Code 4, "Packet Error", unless
   otherwise specified.
   DCCP endpoints in CLOSED, LISTEN, or TIMEWAIT state may need to
   generate a DCCP-Reset packet in response to a packet received from a
   peer.  Since these states have no associated sequence number
   variables, the Sequence and Acknowledgement Numbers on the DCCP-Reset
   packet R are taken from the received packet P, as follows.
   1. If P.ackno exists, then set R.seqno := P.ackno + 1.  Otherwise,
      set R.seqno := 0.
   2. Set R.ackno := P.seqno.
   3. If the packet used short sequence numbers (P.X == 0), then set the
      upper 24 bits of R.seqno and R.ackno to 0.
8.4.  DCCP State Diagram
   The most common state transitions discussed above can be summarized
   in the following state diagram.  The diagram is illustrative; the
   text in Section 8.5 and elsewhere should be considered definitive.
   For example, there are arcs (not shown) from every state except
   CLOSED to TIMEWAIT, contingent on the receipt of a valid DCCP-Reset.
   +---------------------------+    +---------------------------+
   |                           v    v                           |
   |                        +----------+                        |
   |          +-------------+  CLOSED  +------------+           |
   |          | passive     +----------+  active    |           |
   |          |  open                      open     |           |
   |          |                         snd Request |           |
   |          v                                     v           |
   |     +----------+                          +----------+     |
   |     |  LISTEN  |                          | REQUEST  |     |
   |     +----+-----+                          +----+-----+     |
   |          | rcv Request            rcv Response |           |
   |          | snd Response             snd Ack    |           |
   |          v                                     v           |
   |     +----------+                          +----------+     |
   |     | RESPOND  |                          | PARTOPEN |     |
   |     +----+-----+                          +----+-----+     |
   |          | rcv Ack/DataAck         rcv packet  |           |
   |          |                                     |           |
   |          |             +----------+            |           |
   |          +------------>|   OPEN   |<-----------+           |
   |                        +--+-+--+--+                        |
   |       server active close | |  |   active close            |
   |           snd CloseReq    | |  | or rcv CloseReq           |
   |                           | |  |    snd Close              |
   |                           | |  |                           |
   |     +----------+          | |  |          +----------+     |
   |     | CLOSEREQ |<---------+ |  +--------->| CLOSING  |     |
   |     +----+-----+            |             +----+-----+     |
   |          | rcv Close        |        rcv Reset |           |
   |          | snd Reset        |                  |           |
   |<---------+                  |                  v           |
   |                             |             +----+-----+     |
   |                   rcv Close |             | TIMEWAIT |     |
   |                   snd Reset |             +----+-----+     |
   +-----------------------------+                  |           |
                                                    +-----------+
                                                 2MSL timer expires
8.5.  Pseudocode
   This section presents an algorithm describing the processing steps a
   DCCP endpoint must go through when it receives a packet.  A DCCP
   implementation need not implement the algorithm as it is described
   here, but any implementation MUST generate observable effects exactly
   as indicated by this pseudocode, except where allowed otherwise by
   another part of this document.
   The received packet is written as P, the socket as S.  Socket
   variables are:
   S.SWL - sequence number window low
   S.SWH - sequence number window high
   S.AWL - acknowledgement number window low
   S.AWH - acknowledgement number window high
   S.ISS - initial sequence number sent
   S.ISR - initial sequence number received
   S.OSR - first OPEN sequence number received
   S.GSS - greatest sequence number sent
   S.GSR - greatest valid sequence number received
   S.GAR - greatest valid acknowledgement number received on a
           non-Sync; initialized to S.ISS
   "Send packet" actions always use, and increment, S.GSS.
   Step 1: Check header basics
      /* This step checks for malformed packets.  Packets that fail
         these checks are ignored -- they do not receive Resets in
         response */
      If the packet is shorter than 12 bytes, drop packet and return
      If P.type is not understood, drop packet and return
      If P.Data Offset is smaller than the given packet type's
            fixed header length or larger than the packet's length,
            drop packet and return
      If P.type is not Data, Ack, or DataAck and P.X == 0 (the packet
            has short sequence numbers), drop packet and return
      If the header checksum is incorrect, drop packet and return
      If P.CsCov is too large for the packet size, drop packet and
            return
   Step 2: Check ports and process TIMEWAIT state
      /* Flow ID is <src addr, src port, dst addr, dst port> 4-tuple */
      Look up flow ID in table and get corresponding socket
      If no socket, or S.state == TIMEWAIT,
         /* The following Reset's Sequence and Acknowledgement Numbers
            are taken from the input packet; see Section 8.3.1. */
         Generate Reset(No Connection) unless P.type == Reset
         Drop packet and return
   Step 3: Process LISTEN state
      If S.state == LISTEN,
         If P.type == Request or P contains a valid Init Cookie option,
            /* Must scan the packet's options to check for Init
               Cookies.  Only Init Cookies are processed here,
               however; other options are processed in Step 8.  This
               scan need only be performed if the endpoint uses Init
               Cookies */
            /* Generate a new socket and switch to that socket */
            Set S := new socket for this port pair
            S.state = RESPOND
            Choose S.ISS (initial seqno) or set from Init Cookies
            Initialize S.GAR := S.ISS
            Set S.ISR, S.GSR, S.SWL, S.SWH from packet or Init Cookies
            Continue with S.state == RESPOND
            /* A Response packet will be generated in Step 11 */
         Otherwise,
            Generate Reset(No Connection) unless P.type == Reset
            Drop packet and return
   Step 4: Prepare sequence numbers in REQUEST
      If S.state == REQUEST,
         If (P.type == Response or P.type == Reset)
               and S.AWL <= P.ackno <= S.AWH,
            /* Set sequence number variables corresponding to the
               other endpoint, so P will pass the tests in Step 6 */
            Set S.GSR, S.ISR, S.SWL, S.SWH
            /* Response processing continues in Step 10; Reset
               processing continues in Step 9 */
         Otherwise,
            /* Only Response and Reset are valid in REQUEST state */
            Generate Reset(Packet Error)
            Drop packet and return
   Step 5: Prepare sequence numbers for Sync
      If P.type == Sync or P.type == SyncAck,
         If S.AWL <= P.ackno <= S.AWH and P.seqno >= S.SWL,
            /* P is valid, so update sequence number variables
               accordingly.  After this update, P will pass the tests
               in Step 6.  A SyncAck is generated if necessary in
               Step 15 */
            Update S.GSR, S.SWL, S.SWH
         Otherwise,
            Drop packet and return
   Step 6: Check sequence numbers
      If P.X == 0 and the relevant Allow Short Seqnos feature is 0,
         /* Packet has short seqnos, but short seqnos not allowed */
         Drop packet and return
      Otherwise, if P.X == 0,
         Extend P.seqno and P.ackno to 48 bits using the procedure
         in Section 7.6
      Let LSWL = S.SWL and LAWL = S.AWL
      If P.type == CloseReq or P.type == Close or P.type == Reset,
         LSWL := S.GSR + 1, LAWL := S.GAR
      If LSWL <= P.seqno <= S.SWH
            and (P.ackno does not exist or LAWL <= P.ackno <= S.AWH),
         Update S.GSR, S.SWL, S.SWH
         If P.type != Sync,
            Update S.GAR
      Otherwise,
         If P.type == Reset,
            Send Sync packet acknowledging S.GSR
         Otherwise,
            Send Sync packet acknowledging P.seqno
         Drop packet and return
   Step 7: Check for unexpected packet types
      If (S.is_server and P.type == CloseReq)
           or (S.is_server and P.type == Response)
           or (S.is_client and P.type == Request)
           or (S.state >= OPEN and P.type == Request
               and P.seqno >= S.OSR)
           or (S.state >= OPEN and P.type == Response
               and P.seqno >= S.OSR)
           or (S.state == RESPOND and P.type == Data),
         Send Sync packet acknowledging P.seqno
         Drop packet and return
   Step 8: Process options and mark acknowledgeable
      /* Option processing is not specifically described here.
         Certain options, such as Mandatory, may cause the connection
         to be reset, in which case Steps 9 and on are not executed */
      Mark packet as acknowledgeable (in Ack Vector terms, Received
           or Received ECN Marked)
   Step 9: Process Reset
      If P.type == Reset,
         Tear down connection
         S.state := TIMEWAIT
         Set TIMEWAIT timer
         Drop packet and return
   Step 10: Process REQUEST state (second part)
      If S.state == REQUEST,
         /* If we get here, P is a valid Response from the server (see
            Step 4), and we should move to PARTOPEN state.  PARTOPEN
            means send an Ack, don't send Data packets, retransmit
            Acks periodically, and always include any Init Cookie from
            the Response */
         S.state := PARTOPEN
         Set PARTOPEN timer
         Continue with S.state == PARTOPEN
         /* Step 12 will send the Ack completing the three-way
            handshake */
   Step 11: Process RESPOND state
      If S.state == RESPOND,
         If P.type == Request,
            Send Response, possibly containing Init Cookie
            If Init Cookie was sent,
               Destroy S and return
               /* Step 3 will create another socket when the client
                  completes the three-way handshake */
         Otherwise,
            S.OSR := P.seqno
            S.state := OPEN
   Step 12: Process PARTOPEN state
      If S.state == PARTOPEN,
         If P.type == Response,
            Send Ack
         Otherwise, if P.type != Sync,
            S.OSR := P.seqno
            S.state := OPEN
   Step 13: Process CloseReq
      If P.type == CloseReq and S.state < CLOSEREQ,
         Generate Close
         S.state := CLOSING
         Set CLOSING timer
   Step 14: Process Close
      If P.type == Close,
         Generate Reset(Closed)
         Tear down connection
         Drop packet and return
   Step 15: Process Sync
      If P.type == Sync,
         Generate SyncAck
   Step 16: Process data
      /* At this point any application data on P can be passed to the
         application, except that the application MUST NOT receive
         data from more than one Request or Response */