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:
Pat Whittingslow
2026-09-07 10:46:24 -03:00
committed by GitHub
parent d7f3924489
commit 07afcfd924
14 changed files with 1518 additions and 806 deletions
+30
View File
@@ -0,0 +1,30 @@
package tcp
// TransmitUnlimited size returned by [Policy.PreTx] to signal no new data transmit limit (no congestion control).
const TransmitUnlimited = ^Size(0)
// Policy observes segment traffic and steers transmit behaviour: RTO,
// congestion control and the like (discussion #157). The tcp package holds no
// clock, so a Policy needing time carries its own (issue #140).
type Policy interface {
// Reset returns the Policy to its pre-connection state. Should be called on every
// Open/Listen on connection creation. Configuration like clock setting and fine tuning
// should persist throughout the Policy lifetime after Reset calls.
Reset()
// PreTx is called before writing to a frame.
// The outgoing frame options can be set by the Policy and will be respected if Frame offset >5.
// retransmitFrom is ignored unless within [snd.UNA, snd.NXT] and returned retransmit==true.
// newTransmitLimit sets the maximum number of new bytes to send over the wire (congestion control).
// If not implementing congestion control then newTransmitLimit=[TransmitUnlimited].
PreTx(h *Handler, outgoingOpts Frame) (newTransmitLimit Size, retransmitFrom Value, retransmit bool)
// PostTx called on leaving the transmit path with the fully written frame.
PostTx(h *Handler, outgoing Frame)
// PreRx is called by [Handler] on every incoming segment.
// PreRx can choose to drop segment if it returns keep=false.
PreRx(h *Handler, incoming Frame) (keep bool)
// PostRx is called by [Handler] after accepting an incoming segment.
// To access [ControlBlock.SendUNA] before incoming frame was processed save UNA in PreRx.
PostRx(h *Handler, prevState State, accepted Frame)
}