fix(xnet): install a retransmission timer on TCP connections

No connection created through x/xnet had one. Neither NewTCPPool nor the
dial path in StackGo set ConnConfig.LossRecovery and ConnConfig.Nanotime,
so tcp.Handler ran with loss recovery disabled: nothing noticed a lost
segment, and the connection simply stopped: the sender waiting for an
ACK that cannot arrive, the receiver for data nobody will resend.

TCPPoolConfig.NanoTime already documents itself as "passed to each
tcp.Conn for retransmission timing (RFC 6298)", including the
time.Now fallback when it is nil; this makes that true. Each connection
gets its own tcp.RTO, which shadows that connection's send sequence space
and so cannot be shared. That is 80 bytes per connection, allocated once
at pool construction, against buffers measured in kilobytes.

The test drops exactly one data segment and requires the byte to arrive
anyway. It depends on the FIN-WAIT-1 retransmission fix, since the server
closes after writing.
This commit is contained in:
Derek den Haas
2026-08-10 20:18:44 +02:00
committed by soypat
parent 3eb1f39f1d
commit 2dda96b610
3 changed files with 164 additions and 0 deletions
+4
View File
@@ -182,6 +182,10 @@ func (s StackGo) SocketNetip(ctx context.Context, network string, family, sotype
RxBuf: make([]byte, s.plcfg.RxBufSize),
TxPacketQueueSize: s.plcfg.QueueSize,
RWBackoff: s.plcfg.NewBackoff(),
// A dialed connection needs a retransmission timer as much as a
// pooled one. See [NewTCPPool].
LossRecovery: new(tcp.RTO),
Nanotime: s.blk.nanotime,
})
if err != nil {
return nil, err