mirror of
https://github.com/soypat/lneto.git
synced 2026-09-08 07:49:05 +00:00
tcp: simplified Policy implementation based on @MDr164 (#190)
* begin prepping policy refactor manually * implement tcp.Policy and refactor rto to use it * fix CI * chatting with claude gave me idea to reformulate Policy * tcp.Policy: add newTransmitLimit output * merge with main and fix failing tests * remove fix.patch * answer my own comments
This commit is contained in:
+29
-3
@@ -95,6 +95,12 @@ func (tcb *ControlBlock) RecvWindow() Size { return tcb.rcv.WND }
|
||||
// ISS returns the initial sequence number of the connection that was defined on a call to Open by user.
|
||||
func (tcb *ControlBlock) ISS() Value { return tcb.snd.ISS }
|
||||
|
||||
// SendUNA returns snd.UNA, the oldest sequence number not yet acked by the remote.
|
||||
func (tcb *ControlBlock) SendUNA() Value { return tcb.snd.UNA }
|
||||
|
||||
// SendNext returns snd.NXT, one past the highest sequence number sent.
|
||||
func (tcb *ControlBlock) SendNext() Value { return tcb.snd.NXT }
|
||||
|
||||
// MaxInFlightData returns the maximum size of a segment that can be sent by taking into account
|
||||
// the send window size and the unacked data. Returns 0 before StateSynRcvd.
|
||||
func (tcb *ControlBlock) MaxInFlightData() Size {
|
||||
@@ -257,14 +263,34 @@ func (tcb *ControlBlock) HasPendingRetransmit() bool {
|
||||
return tcb._state.TxDataOpen() && tcb.dupack >= retransmitAfterDupacks && tcb.nRetransmit <= tcb.dupack-retransmitAfterDupacks
|
||||
}
|
||||
|
||||
// RetransmitFrom rewinds snd.NXT back to newNxt so the next PendingSegment and
|
||||
// Send calls retransmit unacknowledged data from that sequence number onwards.
|
||||
// It must be paired with ringTx.RetransmitFrom to rewind the transmit buffer to
|
||||
// the same point. Implements RFC 9293 §3.10.8 (RETRANSMISSION TIMEOUT).
|
||||
//
|
||||
// It reports false and changes nothing when newNxt falls outside the
|
||||
// unacknowledged range [snd.UNA, snd.NXT] or the connection cannot send data, so
|
||||
// a misbehaving [Policy] cannot corrupt the send sequence space.
|
||||
func (tcb *ControlBlock) RetransmitFrom(newNxt Value) bool {
|
||||
if !tcb._state.txQueuedDataOpen() {
|
||||
// Matches [State.TxDataOpen] and other states that may have data queued to make progress.
|
||||
// Matches [ControlBlock.PendingSegment] gate (RFC 9293 §3.10.8).
|
||||
return false
|
||||
} else if newNxt.LessThan(tcb.snd.UNA) || tcb.snd.NXT.LessThan(newNxt) {
|
||||
return false
|
||||
}
|
||||
tcb.snd.NXT = newNxt
|
||||
tcb.dupack = 0
|
||||
tcb.nRetransmit = 0
|
||||
return true
|
||||
}
|
||||
|
||||
// RetransmitAll rewinds snd.NXT back to snd.UNA so the next PendingSegment and
|
||||
// Send calls retransmit all unacknowledged data from the oldest sequence number
|
||||
// (go-back-N). It must be paired with ringTx.RetransmitFromUNA to rewind the
|
||||
// transmit buffer. Implements RFC 9293 §3.10.8 (RETRANSMISSION TIMEOUT).
|
||||
func (tcb *ControlBlock) RetransmitAll() {
|
||||
tcb.snd.NXT = tcb.snd.UNA
|
||||
tcb.dupack = 0
|
||||
tcb.nRetransmit = 0
|
||||
tcb.RetransmitFrom(tcb.snd.UNA)
|
||||
}
|
||||
|
||||
// PendingSegment calculates a suitable next segment to send from a payload length.
|
||||
|
||||
Reference in New Issue
Block a user