fix: correlate base answers and bind peer identity in sm and peer
Merged
GO
14d ago+1688+1688+0123456789012345678901234567890123456789-92-92-01234567890123456789
Part 1 of the protocol contract decided in #108. sm.StateMachine,
sm.Client and peer.Manager differed in how strictly they matched base
answers to their requests and in which peer they accepted watchdog and
disconnect requests from.
- CEA: the CER is tracked per connection generation with its Hop-by-Hop
and End-to-End identifiers. A CEA that does not match, malformed or
not, is discarded with a Warn record and a notification, and the
handshake keeps waiting until its original deadline; the Manager no
longer fails the connection on an identifier mismatch, and the Client
learns the peer's identity from the matching CEA (RFC 6733 §§3, 5.3,
6.2.1). - DPA: an answer completes a disconnect only if a DPR is pending on that
generation and the command, both identifiers and the bound peer host
match, checked before its Result-Code is read (§§5.4.2, 6.2.1). - StateMachine no longer answers DWR or DPR from a host other than the
admitted peer, and such a DPR does not start Closing, as in the
Manager (§6.3). - DWA: StateMachine validates a successful DWA as the Manager does
(single identities and Result-Code, bound host and realm). Received
traffic resets Tw, but an invalid, rejected or mismatched DWA neither
clears the pending probe nor restores health (RFC 3539 §3.4.1,
Appendix A).
Refs #108
Validation
make checkpasses locally for all modules: format, test (Go 1.27.2 and
1.26.9), race, vet, lint, vuln, windows, secrets and codeql.- Wire tests over TCP, written to fail on main first, cover each row:
identifier and host mismatches, a malformed uncorrelated CEA followed by the
right one or by nothing, duplicate and stale answers, wrong-host DWR and DPR,
and invalid, rejected or mismatched DWAs while SUSPECT. Captures show the
wrong-host requests answered on main and unanswered here. - An independent review found one major gap (the malformed-CEA path) and a
missing log record; both are fixed with their own tests, and mutating any
row fails a named test.
Summary by cubic
Correlates base protocol answers in sm and peer so a peer cannot consume a pending request with an unrelated or malformed answer, and binds watchdog and disconnect requests to the admitted peer identity.
- CEA must match the CER's identifiers on the same connection generation; mismatched or malformed CEAs are discarded with a Warn record and notification, and the handshake keeps its original deadline instead of failing (RFC 6733 §§3, 5.3, 6.2.1). The
Clientnow learns the peer identity from the matching CEA. - DPA completes a disconnect only when a DPR is pending for that generation and command, both identifiers match, and Origin-Host matches the bound peer — all checked before the Result-Code (RFC 6733 §§5.4.2, 6.2.1).
StateMachinemirrors theManagerin rejecting DWR and DPR from a non-admitted host; such DPR also no longer enters Closing (RFC 6733 §6.3).- The
StateMachinevalidates successful DWAs like theManager(single Result-Code and identities bound to the peer), and while received traffic still resets Tw, an invalid, rejected, or mismatched DWA neither clears the pending probe nor restores health (RFC 3539 §3.4.1, Appendix A).
Refs #108.