ControlBlock.Send refused any outgoing segment carrying data in
FIN-WAIT-1, citing RFC 9293's "no further SENDs from the user will be
accepted by the TCP implementation". That rule bounds what the
application may queue, which Handler.Write already enforces, and not the
retransmission of data the connection has already accepted from it.
The consequence is that write-then-close, which is what nearly every
server does with a response, cannot recover from losing its last data
segment. The FIN occupies a sequence number above that data, so the peer
cannot cross the gap to process the close: it waits for bytes that are
never resent while the sender waits for an ACK that cannot arrive.
Neither side times out at the TCP layer.
FIN-WAIT-2 keeps the restriction and gains the reasoning: it is reached
by our FIN being acknowledged, which acknowledges everything below it, so
no unacknowledged data can remain there.
PendingSegment needs the same distinction, since it decides whether to
offer send-buffer data at all; it gets an unexported State predicate
rather than a new exported one.
Two tests, the second red before the change:
- retransmission after RTO expiry, covering the Handler/LossRecovery
seam that the RTO unit tests do not reach (they exercise the state
machine in isolation, where it behaves correctly).
- retransmission after a close with unacknowledged data.
Co-authored-by: Derek den Haas <i.pestano@easyflor.nl>
* fix for #50
* fix remaining test
* revert changes and instead approach problem on full-duplex case
* fix merge messup
* fix @MDr164 note and upgrade documentation while at it
* gate full buffer exit on rx shutdown since no risk of full buffer error
* add log line to note issue is hit
* document CloseRead relationship with Close
* add ipv6 to xnet.StackAsync
* dns improvements
* improve DNS workings of StackAsync
* add tentative ICMPv6
* work on prefixes and fix some small bugs, plan UDP/TCP6
* fix bugs in StackAsync and ipv4.Prefix.Contains
* update arpsubtable
* completely remove legacy internet.StackIP for StackIPv4/v6
* ipv4/ipv6 tcp/udp
* add TCP6/UDP6 dialing APIs
* add xnet.Stack6 interface
* more ipv6 integration into StackAsync; various tweaks to lneto and documentation+TODOs
* add stack6 tests
* replace netip.Prefix with ipv4.Prefix where it makes sense
* remove old fuzz corpus and stick to using PCG for seeding fuzz test
* polish up drain logic and reduce action search space
* improve fuzzing debug prints
* more fuzz fixes also formatter capture printer fixes
* refactor StackSeeded test
* fix challenge ack infinite packet bug
* more expressive challenge satisfy
* remove printing
* tcp: remove retransmit logic entirely; add duplicate ack counting to ControlBlock
* retransmit implemented in nice simple straightforward way
* narrow down retransmission cases
* remove old timing tests
* add ControlBlock retransmit test
* add failing handler test
* reworking payload length semantic meaning in code
* fix establish conn logic
* clean up tests and add TCB dupack generation and test it
* catch pending retransmit satisfy in test
* add fuzz test for control block
* bugfix: be more strict in what is considered dupack
* add IncomingIsDupACK docs
* limit queue of retransmits
* protect retransmit overflow from incorrectly updating nxt
* fix for #58
* add fixes for both retransmit and fuzz failure found
* fix infinite challenge ack due to RST+SYN+FIN corrupt packet in SYNRCV state
* fuzz: previous recovery ack path led to infinite transmit
* fuzz: calculate CRCs when fuzzing to reduce search space to non-CRC error cases
* add local fuzz corpus to tests
* add more cases to fuzz corpus
* tcp: bugfix for seq not in snd/rcv.wnd error
* accept dupe ACKs for window updates and prevent decrement of UNA
* add fixes for incorrect tcp functioning
* remove Conn.Available* methods in favor of Conn.Free* methods due to ambiguous name
* tcp: mss honoring; accept syn with ECE/CWR flags; add RSTQueue type
* tcp: move option logic to own file
* remove prints in pcap
* add MSS send threshold inspired by linux/freebsd/lwip thresh
* claude suggests a way forward
* add timing to capture printer
* add pcap.Flags
* fix ICMP CRC calculation and add test
* bugfix: still send data on half-close state(close-wait)
* fix pcap test
* begin reviewing TCP listener
* begin adding listener tests
* adding TestExchange implementation
* split out legacy and Step tests
* move listener to tcp package
* fix up tcp tests taking very long
* add xnet.TCPPool and work on TCPPool semantics
* xnet: TCPPool only accepts established connections
* xnet: getting to bottom of panic in xnet.Listener
* xnet: improve listener tests
* fix several data races in testing fixtures
* fix more synchronization things in listener test
* finalize tcplistener test