mirror of
https://github.com/soypat/lneto.git
synced 2026-08-19 14:14:07 +00:00
78 lines
3.4 KiB
Go
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.
|
|
}
|