Transport Control Protocol (TCP)
Overview: The Empire’s Telegraph Office
Imagine a vast, bustling telegraph office in the heart of a sprawling Victorian empire. This is not a chaotic operation of haphazardly transmitted messages, but a meticulously organized system dedicated to the reliable delivery of every dispatch. This is the world of the Transmission Control Protocol (TCP) in SVR4. Where the underlying postal service (the Internet Protocol) offers no guarantees—letters may be lost, arrive out of order, or be duplicated—the TCP Telegraph Office takes upon itself the solemn duty of ensuring that every word, every sentence, every message arrives at its destination precisely as it was sent.
Each conversation is a dedicated correspondence between two parties, managed by a senior clerk who maintains a detailed ledger. This ledger, the TCP Control Block, tracks every byte sent and received, ensuring that lost packets are retransmitted, duplicates are discarded, and a constant, orderly flow of information is maintained. The office operates under a strict set of rules—the TCP Finite State Machine—governing the lifecycle of each connection, from the formal three-way handshake that initiates a conversation to the final, four-part farewell that concludes it. This is a world of sequence numbers, acknowledgements, windows, and timers, all working in concert to create a reliable stream of communication over an inherently unreliable medium.
The Clerk’s Ledger: The TCP Control Block
At the heart of every TCP connection is the tcpcb, the TCP Control Block. This structure is the clerk’s master ledger for a single conversation, a comprehensive record of everything needed to maintain a reliable, ordered stream of data.
/*
* Kernel variables for tcp.
*/
/*
* Tcp control block, one per tcp; fields:
*/
struct tcpcb {
struct tcpiphdr *seg_next; /* sequencing queue */
short t_state; /* state of this connection */
short t_timer[TCPT_NTIMERS]; /* tcp timers */
short t_rxtshift; /* log(2) of rexmt exp. backoff */
short t_rxtcur; /* current retransmit value */
u_short t_maxseg; /* maximum segment size */
char t_force; /* 1 if forcing out a byte */
u_short t_flags;
/* send sequence variables */
tcp_seq snd_una; /* send unacknowledged */
tcp_seq snd_nxt; /* send next */
tcp_seq snd_up; /* send urgent pointer */
tcp_seq snd_wl1; /* window update seg seq number */
tcp_seq snd_wl2; /* window update seg ack number */
tcp_seq iss; /* initial send sequence number */
u_long snd_wnd; /* send window */
/* receive sequence variables */
u_long rcv_wnd; /* receive window */
tcp_seq rcv_nxt; /* receive next */
tcp_seq rcv_up; /* receive urgent pointer */
tcp_seq irs; /* initial receive sequence number */
};
(netinet/tcp_var.h)
Key fields in this ledger include:
t_state: The current state of the connection, drawn from the finite state machine.snd_una,snd_nxt: Sequence numbers that track the bytes that have been sent and acknowledged.rcv_nxt: The sequence number of the next byte the receiver expects to receive.snd_wnd,rcv_wnd: The send and receive windows, which manage flow control.t_timer: An array of timers for retransmissions, keep-alives, and other time-based events.t_maxseg: The maximum segment size, negotiated during the handshake, to avoid IP-level fragmentation.
The Rulebook: The TCP Finite State Machine
The life of a TCP connection is governed by a strict set of rules known as the Finite State Machine. Each state represents a distinct phase in the conversation, and the transitions between states are triggered by specific events, such as the arrival of a particular type of segment or a request from the user application.
Figure 4.6.1: The TCP State Machine
The primary states and their roles:
CLOSED: The beginning and end. No connection exists.LISTEN: A server waiting for a connection request from a client.SYN_SENT: A client has sent a connection request (aSYNsegment) and is waiting for a reply.SYN_RECEIVED: A server has received aSYNand sent its ownSYN-ACK, and is now waiting for the finalACKfrom the client.ESTABLISHED: The connection is active. Data can be transferred freely in both directions. This is the main state for a healthy, active connection.FIN_WAIT_1/FIN_WAIT_2: The local application has closed the connection, and the TCP module has sent aFINsegment. It is waiting for anACKand then aFINfrom the remote party.CLOSE_WAIT: The local TCP has received aFINfrom the remote party and is waiting for the local application to close its end of the connection.LAST_ACK: Both sides have sentFINs, and the TCP is waiting for the finalACKof its ownFIN.TIME_WAIT: The “2MSL Wait” state. The connection is closed, but the control block is kept around for a short period to catch any stray, late-arriving packets from the now-defunct connection, preventing them from being misinterpreted as belonging to a new connection.
Opening the Line: The Three-Way Handshake
A TCP connection is established through a precise, three-step process known as the three-way handshake. This ensures that both parties are ready to communicate and have agreed upon the initial sequence numbers.
Figure 4.6.2: The Three-Way Handshake
- SYN: The client, wishing to start a conversation, sends a
SYN(synchronize) segment to the server. This segment includes the client’s initial sequence number (SEQ=x). - SYN-ACK: The server, having received the
SYN, responds with aSYN-ACKsegment. This segment contains the server’s own initial sequence number (SEQ=y) and an acknowledgement of the client’s sequence number (ACK=x+1). - ACK: Finally, the client sends an
ACKsegment back to the server, acknowledging the server’s sequence number (ACK=y+1).
Upon completion of this exchange, the connection is ESTABLISHED, and data transfer can begin. The SVR4 implementation of this logic is primarily handled in tcp_input.c, within the tcp_uinput function, which processes incoming segments and drives state transitions.
The Ghost of SVR4:
“Ah, the simple, elegant dance of the three-way handshake. It was a robust and reliable method in its day, and remains the foundation of TCP connections even now, in your far-flung future of 2026. But the world has grown so much faster, so much more concerned with latency. Your modern TCP stacks have learned new tricks. ‘TCP Fast Open’ (TFO), for instance, allows data to be sent in the very first
SYNpacket, a brazen violation of the old etiquette, all in the name of shaving off a few precious milliseconds. We, in our time, valued correctness and a clear separation of concerns above all. The handshake was for synchronization, and only once the line was declared open would data ever be transmitted. A more civilized age, perhaps.”
TCP - Telegraph Office
Reliable Delivery and Flow Control
TCP’s primary mandate is reliability. It achieves this through several key mechanisms:
- Sequence Numbers: Every byte of data is assigned a unique sequence number. The
snd_nxtandrcv_nxtfields in thetcpcbtrack the progress of this byte stream. - Acknowledgements (ACKs): The receiver sends
ACKsegments back to the sender to confirm receipt of data. If the sender does not receive anACKfor a segment within a certain time (the retransmission timeout, or RTO), it assumes the segment was lost and sends it again. The SVR4 kernel manages this with a set of timers, handled intcp_timer.c. - Sliding Window: The
snd_wndandrcv_wndfields implement a “sliding window” for flow control. The receiver advertises itsrcv_wnd—the amount of buffer space it has available. The sender is not allowed to send more data than the advertised window, preventing the receiver from being overwhelmed. The logic for sending data, respecting the window, and handling retransmissions is found intcp_output.c.
Conclusion
The SVR4 TCP implementation, a faithful rendition of the classic protocol, is a testament to the enduring principles of reliable network design. Like a well-run telegraph office, it is a system of immense complexity, with clerks, rules, and ledgers all working in harmony. It imposes order on the chaos of the underlying network, providing applications with the simple, reassuring abstraction of a reliable, unbroken stream of data. While the speeds and latencies of the networks have changed beyond recognition, the fundamental challenges of reliability that TCP was designed to solve remain, and its core principles, as implemented in SVR4, endure.