fix: give StateMachine, Client and Manager one protocol policy

Merged
GO
11d ago
+1277-555

Since the three front ends moved onto the shared protocol core, fifteen
Manager-only core options and two Manager adapter remaps kept Manager's
older error and correlation policies where StateMachine and Client did
something else. Twelve options and both remaps are gone, so
each input now gets one disposition in every front end. The three
options that remain decide who closes the connection after a message
error: the core for natively admitted StateMachine and Client
connections, the reader for Manager and externally admitted ones. The
core's own phase and timers follow from that choice: one decision marks
the connection terminal and selects whether a required reply closes it
once written, and the write's completion then terminates it. The core
options are now documented that way.

Behaviour changes, by the front end whose users see them:

  • StateMachine and Client answer a repeated CER that carries a fatal
    decoding error, such as an invalid AVP length, with an error CEA
    before they close, as Manager did, so the peer learns why the
    connection ends (RFC 6733 section 7). Settings.OnCEA runs for that
    error CEA. A repeated CER without a fatal decoding error is still
    ignored.
  • StateMachine and Client keep a fatal decoder error fatal when a base
    header error decides the Result-Code: they send the answer a request
    requires, report Closing and close, as for every other fatal message
    error.
  • StateMachine and Client report a fatal error received during Closing
    as fatal; Closing timers, replies and the connection are unchanged.
  • StateMachine and Client check a DWA's Origin-Host and Origin-Realm
    before its Result-Code, as DPA matching does, so an unsuccessful DWA
    from the wrong peer is reported as invalid, not as a rejected probe.
  • StateMachine, Client and Manager report a well-formed DWA that answers
    no outstanding DWR as an unexpected message with Result-Code 0 and the
    correlation detail (RFC 6733 section 3). StateMachine and Client log
    it as "sm: DWA identifiers mismatch; answer discarded" and no longer
    call the invalid-answer watchdog hook for it.
  • Client and dialed Manager discard a CEA whose identifiers do not match
    the pending CER as an unexpected message (RFC 6733 section 3). Manager
    no longer fails the handshake with a CEA rejection for it. If the CEA
    also carries a fatal decoding error, the connection still ends:
    Client's core fails the handshake and closes, Manager's reader closes,
    and both report Closing. Without a fatal error the pending CER keeps
    its deadline.
  • Dialed Manager discards a CEA that arrives after the handshake by
    ownership, silently for an exact duplicate, instead of validating it.
  • Manager reports a DPA that answers no outstanding DPR during Closing
    as an unexpected message rather than InvalidDPA, as StateMachine and
    Client do.
  • Manager derives the header Result-Code for a decoded first message
    that is not a CER, and keeps the decoder's code for a reported
    decoding error.
  • Manager classifies an invalid-header request during Closing as
    InvalidHeader rather than MalformedMessage.
  • Manager resets Tw when it receives a message with a valid header and a
    fatal body error, without watchdog credit (RFC 3539 section 3.4.1).
  • Manager.Close rejects a Disconnect-Cause outside 0-2 (RFC 6733 section
    5.4.3) before any shutdown step, also on a Manager that is already
    closed, with the error StateMachine.Disconnect returns.
  • StateMachine and Client keep the standard fmt wrapper around a failed
    error-answer build in the error they record.

New TCP parity tests cover each change through StateMachine (accepted
and Client) and Manager (accepted and dialed). A run of 6,100 shared
scenarios against main differs only where listed above, and bytes and
allocations per exchange are at or below main.

Closes #143.


Summary by cubic

Consolidates the error and correlation policy across StateMachine, Client, and Manager by removing fifteen Manager-only core options and two adapter remaps; each input now gets one disposition in every frontend. Only the ownership of connection closure after a message error still differs: the core for natively admitted StateMachine and Client connections, the reader for Manager and externally admitted ones.

Behavior changes users will see

  • StateMachine and Client answer a repeated CER carrying a fatal decoding error with an error CEA before closing, as Manager did, so the peer learns why the connection ends.
  • StateMachine and Client now report fatal errors received during Closing as fatal and preserve decoder fatality when a base header error sets the Result-Code.
  • A well-formed DWA or DPA that answers no outstanding request is now an unexpected message with Result-Code 0 in all frontends; StateMachine and Client no longer call the invalid-answer watchdog hook for it.
  • Client and dialed Manager discard a CEA whose identifiers do not match the pending CER as an unexpected message instead of failing the handshake; a fatal decoding error still ends the connection.
  • Manager.Close rejects a Disconnect-Cause outside 0–2 before any shutdown step, also on a Manager that is already closed.

New TCP parity tests cover each change; a run of 6,100 shared scenarios differs from main only in the listed behavior, at or below main's bytes and allocations per exchange.

Closes #143.