Files
lneto/lneto/tcp/control.go
T
2024-12-24 14:02:25 -03:00

78 lines
3.4 KiB
Go

package tcp
import "log/slog"
// ControlBlock is a partial Transmission Control Block (TCB) implementation as
// per RFC 9293 in section 3.3.1. In contrast with the description in RFC9293,
// this implementation is limited to receiving only sequential segments.
// This means buffer management is left up entirely to the user of the ControlBlock.
// Use ControlBlock as the building block that solves Sequence Number calculation
// and validation in a full TCP implementation.
//
// A ControlBlock's internal state is modified by the available "System Calls" as defined in
// RFC9293, such as Close, Listen/Open, Send, and Receive.
// Sent and received data is represented with the [Segment] struct type.
type ControlBlock struct {
// # Send Sequence Space
//
// 'Send' sequence numbers correspond to local data being sent.
//
// 1 2 3 4
// ----------|----------|----------|----------
// SND.UNA SND.NXT SND.UNA
// +SND.WND
// 1. old sequence numbers which have been acknowledged
// 2. sequence numbers of unacknowledged data
// 3. sequence numbers allowed for new data transmission
// 4. future sequence numbers which are not yet allowed
snd sendSpace
// # Receive Sequence Space
//
// 'Receive' sequence numbers correspond to remote data being received.
//
// 1 2 3
// ----------|----------|----------
// RCV.NXT RCV.NXT
// +RCV.WND
// 1 - old sequence numbers which have been acknowledged
// 2 - sequence numbers allowed for new reception
// 3 - future sequence numbers which are not yet allowed
rcv recvSpace
// When FlagRST is set in pending flags rstPtr will contain the sequence number of the RST segment to make it "believable" (See RFC9293)
rstPtr Value
// pending is the queue of pending flags to be sent in the next 2 segments.
// On a call to Send the queue is advanced and flags set in the segment are unset.
// The second position of the queue is used for FIN segments.
pending [2]Flags
state State
challengeAck bool
log *slog.Logger
}
// sendSpace contains Send Sequence Space data. Its sequence numbers correspond to local data.
type sendSpace struct {
ISS Value // initial send sequence number, defined locally on connection start
UNA Value // send unacknowledged. Seqs equal to UNA and above have NOT been acked by remote. Corresponds to local data.
NXT Value // send next. This seq and up to UNA+WND-1 are allowed to be sent. Corresponds to local data.
WND Size // send window defined by remote. Permitted number of local unacked octets in flight.
// WL1 Value // segment sequence number used for last window update
// WL2 Value // segment acknowledgment number used for last window update
}
// inFlight returns amount of unacked bytes sent out.
func (snd *sendSpace) inFlight() Size {
return Sizeof(snd.UNA, snd.NXT)
}
// maxSend returns maximum segment datalength receivable by remote peer.
func (snd *sendSpace) maxSend() Size {
return snd.WND - snd.inFlight()
}
// recvSpace contains Receive Sequence Space data. Its sequence numbers correspond to remote data.
type recvSpace struct {
IRS Value // initial receive sequence number, defined by remote in SYN segment received.
NXT Value // receive next. seqs before this have been acked. this seq and up to NXT+WND-1 are allowed to be sent. Corresponds to remote data.
WND Size // receive window defined by local. Permitted number of remote unacked octets in flight.
}