RFC 761
DoD standard Transmission Control Protocol
RFC 761 and IEN 129 โจ
- Title: DOD STANDARD TRANSMISSION CONTROL PROTOCOL ๐
- Date: January 1980 ๐
- Editor: Jon Postel ๐
- Prepared for: Defense Advanced Research Projects Agency, Information Processing Techniques Office,
1400 Wilson Boulevard,Arlington, Virginia 22209๐บ๐ธ - Prepared by: Information Sciences Institute, University of Southern California,
4676 Admiralty Way,Marina del Rey, California 90291๐ - Category or status: not stated in this document ๐คทโโ๏ธ
- Replaces:
IENs 124, 112, 81, 55, 44, 40, 27, 21, 5๐
The original doesn't say it obsoletes or updates any RFC, so I'm not going to invent one. ๐ โโ๏ธ
TABLE OF CONTENTS
PREFACE ........................................................ iii
1. INTRODUCTION ..................................................... 1
1.1 Motivation .................................................... 1
1.2 Scope ......................................................... 2
1.3 About This Document ........................................... 2
1.4 Interfaces .................................................... 3
1.5 Operation ..................................................... 3
2. PHILOSOPHY ....................................................... 7
2.1 Elements of the Internetwork System ........................... 7
2.2 Model of Operation ............................................ 7
2.3 The Host Environment .......................................... 8
2.4 Interfaces .................................................... 9
2.5 Relation to Other Protocols ................................... 9
2.6 Reliable Communication ....................................... 10
2.7 Connection Establishment and Clearing ........................ 10
2.8 Data Communication ........................................... 12
2.9 Precedence and Security ...................................... 13
2.10 Robustness Principle ......................................... 13
3. FUNCTIONAL SPECIFICATION ........................................ 15
3.1 Header Format ................................................ 15
3.2 Terminology .................................................. 19
3.3 Sequence Numbers ............................................. 24
3.4 Establishing a connection .................................... 29
3.5 Closing a Connection ......................................... 35
3.6 Precedence and Security ...................................... 38
3.7 Data Communication ........................................... 38
3.8 Interfaces ................................................... 42
3.9 Event Processing ............................................. 52
GLOSSARY ............................................................ 75
REFERENCES .......................................................... 83
PREFACE ๐
This document describes the DoD Standard Transmission Control Protocol (TCP). There have been eight earlier editions of the ARPA TCP specification on which this standard is based, and the present text draws heavily from them. There have been many contributors to this work both in terms of concepts and in terms of text. This edition incorporates the addition of security, compartmentation, and precedence concepts into the TCP specification.
Jon Postel
Editor
1. INTRODUCTION ๐ฆ
Okay so, the Transmission Control Protocol (TCP) is basically meant to be a super reliable host-to-host protocol. It's for hosts talking to each other over packet-switched computer networks, and especially when a bunch of those networks are hooked up together. ๐โจ
This document spells out what the Transmission Control Protocol has to do, the program that actually implements it, and the interface that programs or users use to call on its services. ๐
1.1. Motivation
Computer communication systems are becoming a huge deal in military, government, and civilian settings. This document mostly focuses on military computer communication needs, especially being robust when communication is unreliable and staying available when there's congestion. Still, lots of these problems show up in civilian and government work too. ๐ซถ
As strategic and tactical computer networks get built and deployed, it's essential to connect them together and to have standard interprocess communication protocols that can support a wide range of applications. ๐ To get ahead of that need, the Deputy Undersecretary of Defense for Research and Engineering declared the Transmission Control Protocol (TCP) described here to be a basis for DoD-wide interprocess communication protocol standardization. ๐
TCP is a connection-oriented, end-to-end reliable protocol. It's designed to sit in a layered stack of protocols that support applications spanning multiple networks. TCP gives reliable interprocess communication between pairs of processes on hosts attached to different but interconnected computer networks. ๐ It doesn't assume much about how reliable the protocols below it are. TCP just assumes it can get a simple, potentially unreliable datagram service from the lower-level protocols. In principle, TCP should be able to run over a wide range of communication systems, from hard-wired connections to packet-switched or circuit-switched networks. ๐
TCP is based on concepts first described by Cerf and Kahn in [1]. It sits right above a basic Internet Protocol [2], which lets TCP send and receive variable-length segments of information wrapped in internet datagram "envelopes." The internet datagram is how source and destination TCPs get addressed even when they're in different networks. ๐ฎ The internet protocol also handles any fragmentation or reassembly of TCP segments needed to get them through multiple networks and interconnecting gateways. ๐งฉ On top of that, it carries information about the precedence, security classification, and compartmentation of the TCP segments, so that info can travel end-to-end across multiple networks. ๐
Here's the layering picture: ๐
Protocol Layering
+---------------------+
| higher-level |
+---------------------+
| TCP |
+---------------------+
| internet protocol |
+---------------------+
|communication network|
+---------------------+
Figure 1
Most of this document is written with TCP implementations in mind that live on the same host as the higher-level protocols. Realistically though, lots of computer systems will hook up to networks through front-end computers that house the TCP and internet protocol layers, along with network-specific software. ๐ฅ๏ธ The TCP specification describes an interface to the higher-level protocols that still seems implementable for the front-end case, as long as there's a suitable host-to-front-end protocol in place. ๐ง
1.2. Scope
TCP is meant to give a reliable process-to-process communication service in a multinetwork environment. ๐ธ It's also intended to be a host-to-host protocol that's commonly used across multiple networks. ๐ฆ
1.3. About this Document
This document is a specification of the behavior required of any TCP implementation, both when it talks to higher-level protocols and when it talks to other TCPs. ๐ The rest of this section gives a quick overview of the protocol interfaces and how things operate. Section 2 covers the philosophy behind the TCP design. Section 3 goes deep: it describes the actions TCP has to take when different events happen (new segments arriving, user calls, errors, and so on), and it lays out the exact formats of TCP segments. ๐
1.4. Interfaces
TCP has two sides. On one side it talks to user or application processes, and on the other side it talks to a lower-level protocol like Internet Protocol. ๐
The interface between an application process and TCP is described in reasonable detail. It's made up of a set of calls that feel a lot like the calls an operating system gives an application for handling files. For example, there are calls to open and close connections, and calls to send and receive data on established connections. ๐ TCP is also expected to be able to talk to application programs asynchronously. Implementors get a lot of freedom to design interfaces that suit their particular operating system, but there's a minimum level of functionality that's required at the TCP/user interface for any valid implementation. ๐
The interface between TCP and the lower-level protocol is mostly left unspecified. The one thing assumed is that some mechanism exists that lets the two layers pass information to each other asynchronously. Usually the lower-level protocol is the one that defines that interface. TCP is designed to work in a very general environment of interconnected networks, and the lower-level protocol assumed throughout this document is the Internet Protocol [2]. ๐โจ
1.5. Operation โจ
okay so, the main job of TCP is to give processes a reliable, securable logical circuit or connection between pairs of processes ๐๐ and it has to do that on top of an internet communication system that is less reliable. so it needs help in these areas:
- Basic Data Transfer
- Reliability
- Flow Control
- Multiplexing
- Connections
- Precedence and Security
here's how TCP handles each one, bestie ๐ซถ
Basic Data Transfer:
TCP can move a continuous stream of octets in each direction between its users ๐. it does this by packing some number of octets into segments for transmission through the internet system. in this stream mode, the TCPs decide when to block and forward data at their own convenience ๐ฆ.
if a user wants a record-oriented service, TCP lets them submit records, called letters ๐. when the sending user marks a record boundary (end-of-letter), the TCPs promptly forward and deliver the data up to that point to the receiver. no waiting around, it's giving efficiency ๐โโ๏ธ๐จ.
Reliability:
TCP must recover from data that is damaged, lost, duplicated, or delivered out of order by the internet communication system ๐ญ. the way it does this is by giving every octet transmitted a sequence number and requiring a positive acknowledgment (ACK) from the receiving TCP โ . if the ACK doesn't show up within a timeout interval, the data gets retransmitted ๐. on the receiving end, the sequence numbers help put segments that arrive out of order back in the right order and get rid of duplicates ๐งฉ. damage is handled by adding a checksum to each segment, checking it at the receiver, and discarding any damaged segments ๐๏ธ.
as long as the TCPs keep functioning properly and the internet system doesn't get completely partitioned, no transmission errors will affect the users ๐ . TCP recovers from internet communication system errors, and that is so iconic ๐.
Flow Control:
TCP gives the receiver a way to control how much data the sender can send ๐ฆ. this happens by returning a "window" with every ACK. the window indicates a range of acceptable sequence numbers beyond the last segment successfully received ๐ช. in stream mode, the window is the allowed number of octets the sender may transmit before getting further permission. in record mode, the window is the allowed amount of buffer space the sender may use. this can be more than the number of data octets actually transmitted if the letter size and buffer size don't match ๐คทโโ๏ธ.
Multiplexing:
so many processes inside a single Host need to use TCP at the same time, right? ๐ so TCP gives each host a set of addresses called ports. when you put a port together with the network and host addresses from the internet communication layer, you get a socket ๐. a pair of sockets uniquely identifies each connection ๐. and a single socket can be used in multiple connections at once. main character energy ๐.
each Host handles binding ports to processes on its own ๐ . still, it's useful to attach frequently used processes (e.g., a "logger" or timesharing service) to fixed sockets that are made known to the public ๐ข. then people can reach these services through the known addresses ๐ธ. figuring out and learning the port addresses of other processes can involve more dynamic mechanisms โจ.
Connections:
the reliability and flow control mechanisms need TCPs to set up and keep track of certain status information for each data stream ๐. all of that information together (sockets, sequence numbers, and window sizes) is called a connection ๐งถ. every connection is uniquely specified by a pair of sockets, one for each of its two sides ๐ฏโโ๏ธ.
when two processes want to talk, their TCP's must first establish a connection, which means setting up the status information on each side ๐ค. once the communication is done, the connection gets terminated or closed, freeing up the resources for other things ๐งน.
because connections have to be set up between unreliable hosts and over an unreliable internet communication system, TCP uses a handshake mechanism with clock-based sequence numbers ๐ฐ๏ธ. this helps avoid connections getting initialized in the wrong way ๐ โโ๏ธ.
Precedence and Security:
TCP users can indicate the security and precedence of their communication ๐. if those features aren't needed, default values are provided ๐ซง.
2. PHILOSOPHY ๐
2.1. Elements of the Internetwork System ๐
the internetwork environment is made up of hosts connected to networks, and those networks are connected to each other through gateways ๐ธ๏ธ. it's assumed here that the networks could be local networks (e.g., the ETHERNET) or large networks (e.g., the ARPANET), but either way they're based on packet switching technology ๐ฆ. the active agents that produce and consume messages are processes ๐ง. different levels of protocols in the networks, the gateways, and the hosts support an interprocess communication system. that system gives two-way data flow on logical connections between process ports ๐.
we specifically assume that data is sent from host to host through a set of networks ๐ฃ๏ธ. when we say network, we mean a packet switched network (PSN) ๐ฎ. this assumption probably isn't strictly necessary, since a circuit switched network or a hybrid of the two could also work. but to keep things concrete, we explicitly assume that the hosts are connected to one or more packet switches of a PSN ๐ฏ.
the term packet is used generically here to mean the data of one transaction between a host and a packet switch ๐ฌ. the format of data blocks exchanged between packet switches in a network generally won't be our concern ๐.
hosts are computers attached to a network. from the communication network's point of view, they're the sources and destinations of packets ๐ฅ๏ธ. processes are the active elements in host computers (following the fairly common definition of a process as a program in execution) ๐โโ๏ธ. even terminals and files or other I/O devices are viewed as communicating with each other through processes. so basically all communication is inter-process communication ๐ฌ.
since a process might need to tell apart several communication streams between itself and another process (or processes), we imagine that each process may have a number of ports. those ports are how it communicates with the ports of other processes ๐ชโจ.
2.2. Model of Operation ๐งฉ
processes send data by calling on TCP and passing buffers of data as arguments ๐ค. TCP packages the data from these buffers into segments and calls on the internet module to transmit each segment to the destination TCP ๐ฆโก๏ธ. the receiving TCP puts the data from a segment into the receiving user's buffer and notifies that user ๐. the TCPs include control information in the segments, which they use to make sure data gets transmitted reliably and in order ๐ซถ.
the model of internet communication has an internet protocol module associated with each TCP. this module provides an interface to the local network ๐. the internet module packages TCP segments inside internet datagrams and routes those datagrams to a destination internet module or an intermediate gateway ๐บ๏ธ. to send the datagram through the local network, it gets embedded in a local network packet ๐.
the packet switches may do further packaging, fragmentation, or other operations to get the local packet delivered to the destination internet module ๐ง.
at a gateway between networks, the internet datagram gets "unwrapped" from its local packet and examined to figure out which network it should go through next ๐. then it's "wrapped" in a local packet that suits the next network and routed to the next gateway, or to the final destination ๐.
a gateway is permitted to break an internet datagram up into smaller internet datagram fragments if that's necessary for transmission through the next network โ๏ธ. to do this, the gateway produces a set of internet datagrams, each carrying a fragment ๐งท. fragments may be broken into smaller ones at intermediate gateways too ๐ช. the internet datagram fragment format is designed so the destination internet module can reassemble the fragments into internet datagrams ๐งฉโจ.
a destination internet module unwraps the segment from the datagram (after reassembling the datagram, if needed) and passes it to the destination TCP ๐ฏ.
this simple model glosses over a lot of details, which is totally fine for now ๐. one important feature is the type of service. it gives information to the gateway (or internet module) to help it pick the service parameters to use when crossing the next network ๐งญ. the type of service information includes the precedence of the datagram ๐. datagrams may also carry security information, so that hosts and gateways operating in multilevel secure environments can properly separate datagrams for security reasons ๐.
2.3. The Host Environment ๐ก
TCP is assumed to be a module in a time sharing operating system ๐ฅ๏ธ. users access TCP pretty much the way they'd access the file system ๐. TCP may call on other operating system functions, for example to manage data structures ๐ ๏ธ. the actual interface to the network is assumed to be controlled by a device driver module ๐ง. TCP doesn't call the network device driver directly. instead, it calls the internet datagram protocol module, which may in turn call the device driver ๐.
even though processes are assumed to be supported by the host operating system, TCP's mechanisms don't rule out implementing TCP in a front-end processor ๐๏ธ. but in that kind of implementation, a host-to-front-end protocol has to provide the functionality needed to support the type of TCP-user interface described above ๐.
2.4. Interfaces ๐
the TCP/user interface handles calls the user makes on TCP to OPEN or CLOSE a connection, to SEND or RECEIVE data, or to get STATUS about a connection ๐. these calls work like other calls from user programs on the operating system, like calls to open, read from, and close a file ๐โจ.
the TCP/internet interface provides calls to send and receive datagrams addressed to TCP modules in hosts anywhere in the internet system ๐. these calls take parameters for passing the address, type of service, precedence, security, and other control information ๐.
2.5. Relation to Other Protocols ๐งฉ
okay so, here's where TCP sits in the protocol hierarchy ๐ง it's the middle layer, bestie, and Figure 2 shows the whole stack:
+------+ +-----+ +-----+ +-----+
|Telnet| | FTP | |Voice| ... | | Application Level
+------+ +-----+ +-----+ +-----+
| | | |
+-----+ +-----+ +-----+
| TCP | | RTP | ... | | Host Level
+-----+ +-----+ +-----+
| | |
+-------------------------------+
| Internet Protocol | Gateway Level
+-------------------------------+
|
+---------------------------+
| Local Network Protocol | Network Level
+---------------------------+
|
Protocol Relationships
Figure 2.
TCP is expected to support higher level protocols efficiently ๐ and it should be easy to plug things like the ARPANET Telnet [3] or AUTODIN II THP into TCP โจ that's giving main character energy ๐
2.6. Reliable Communication ๐
a stream of data sent on a TCP connection gets delivered reliably and in order at the destination ๐ซถ the secret sauce is sequence numbers and acknowledgments ๐ฅ
conceptually, every single octet of data gets its own sequence number ๐ข the sequence number of the first octet in a segment is the one sent with that segment, and it's called the segment sequence number. segments also carry an acknowledgment number, which is the sequence number of the next data octet the sender is expecting from the other direction ๐ฌ
here's the vibe: when TCP sends a segment, it keeps a copy on a retransmission queue and starts a timer โฑ๏ธ when the ack for that data shows up, the segment gets deleted from the queue. if the ack doesn't arrive before the timer runs out, the segment gets sent again ๐
ngl, an ack from TCP does not mean the data reached the end user ๐ it only means the receiving TCP has taken on the responsibility to deliver it ๐ซก
to control how much data flows into a TCP, there's a flow control mechanism ๐ฐ the data receiving TCP reports a window to the sending TCP. that window says how many octets, starting from the acknowledgment number, the receiver is currently ready to take ๐ธ
2.7. Connection Establishment and Clearing ๐ฆ
so TCP needs a way to tell apart all the data streams it handles, and that's the port identifier ๐ but ports get picked independently by each operating system, TCP, or user, so they might not be unique ๐ to fix that, TCP glues an internet address (identifying the TCP) onto a port identifier to make a socket, and that socket is unique across all the networks connected together ๐
a connection is fully specified by the pair of sockets at its two ends ๐ one local socket can join many connections to different foreign sockets, and a connection can carry data in both directions, which is "full duplex" ๐ฅ
TCPs are free to link ports to processes however they like ๐ still, a few basic concepts seem necessary in any implementation:
There must be well-known sockets that TCP only associates with the "appropriate" processes, by some means. we picture processes "owning" ports, and processes can only start connections on the ports they own. (How ownership actually gets implemented is a local issue, but we're imagining a Request Port user command, or a way to uniquely hand a group of ports to one process, e.g., by using the high order bits of a port name to point at a given process ๐ง)
a connection is set up in the OPEN call using the local port and foreign socket arguments. in return, TCP gives back a (short) local connection name that the user uses in later calls ๐๏ธ there's a bunch of stuff a connection needs to remember, so imagine a data structure called a Transmission Control Block (TCB) ๐๏ธ one way to build it would be to make the local connection name a pointer to that TCB. the OPEN call also says whether to actively pursue the connection or passively wait for one ๐ซถ
a passive OPEN means the process wants to accept incoming connection requests instead of starting one itself ๐ฅน often it'll accept a request from anyone, and then a foreign socket of all zeros is used to mean "unspecified socket." unspecified foreign sockets are allowed only on passive OPENs ๐ โโ๏ธ
a service process that wants to serve unknown processes could issue a passive OPEN with an unspecified foreign socket. then it can connect with any process that asks for a connection to that local socket. it'd help a lot if everyone knew that this local socket belongs to that service ๐ฃ
well-known sockets are a super handy way to link a socket address to a standard service ahead of time ๐ for example, the "Telnet-Server" process might be permanently assigned to one socket, while other sockets get reserved for File Transfer, Remote Job Entry, Text Generator, Echoer, and Sink processes (the last three are just for test purposes ๐งช). a socket address might even be reserved for a "Look-Up" service that returns the specific socket where a newly created service is running ๐ the concept of well-known sockets is part of the TCP spec, but which socket goes with which service is outside this spec ๐คทโโ๏ธ
processes can issue passive OPENs, wait for matching calls from other processes, and get told by TCP when connections are established โณ two processes that call each other at the exact same time still connect correctly ๐คฏ this flexibility is critical for distributed computing, where components act asynchronously with respect to each other ๐
there are two ways to match the sockets in a local request against an incoming segment ๐ in the first, the local request fully specified the foreign socket, so the match must be exact. in the second, the local request left the foreign socket unspecified, so any foreign socket is fine as long as the local sockets match โ
if there are several pending passive OPENs (recorded in TCBs) with the same local socket, an incoming segment should be matched to a request with the specific foreign socket from that segment, if one exists, before anything gets matched to a request with an unspecified foreign socket ๐
the procedures for setting up and clearing connections use the synchronize (SYN) and finis (FIN) control flags, and they involve swapping three messages. this is called a three-way hand shake [4] ๐ค
a connection starts when an arriving segment with a SYN meets a waiting TCB entry that a user OPEN command created ๐ matching the local and foreign sockets is what decides when a connection has started. it becomes "established" once sequence numbers are synchronized in both directions ๐
clearing a connection also means exchanging segments, and in this case they carry the FIN control flag ๐
2.8. Data Communication ๐ฆ
the data flowing on a connection can be thought of as a stream of octets, or as a sequence of records. in TCP, the records are called letters, and they're variable length ๐ in each SEND call, the sending user says whether that data finishes a letter by setting the end-of-letter parameter โ๏ธ
a letter might be too big to send in one go, so it has to be broken into segments first ๐งฉ we assume the segments get put back together into a letter before the receiving process sees it ๐งท a segment can hold all or part of a letter, but it never holds parts of more than one letter ๐ โโ๏ธ the end of a letter is marked by an EOL control flag showing up in a segment ๐
a sending TCP is allowed to gather data from the sending user and send it in segments whenever it's convenient, but once the end of letter is signaled, it must send all unsent data ๐ and when a receiving TCP has a complete letter, it must not wait for more data from the sending TCP before passing the letter up to the receiving process ๐
there's a connection between letters as sent and the buffers of data that cross the TCP/user interface ๐งบ every time an end-of-letter (EOL) flag is attached to data placed into the receiving user's buffer, that buffer goes back to the user for processing, even if it isn't full ๐ซ if a letter is longer than the user's buffer, it gets passed along in buffer-size units, and the last unit might only be partly full ๐ the receiving TCP's buffer size can be shared with the sending TCP when the connection is being set up ๐ค
TCP keeps the flow of segments under control so it doesn't get saturated or overloaded with traffic ๐ฆ it does this with window flow control: the data receiving TCP reports a window to the data sending TCP, and that window is the range of sequence numbers of data octets the receiver is currently ready to accept ๐ช
TCP also has a way to tell the receiver that, further along in the data stream than the receiver is currently reading, there's urgent data ๐จ TCP doesn't spell out what the user should do after getting that news, but the general idea is that the receiving process should act to read through to the end of the urgent data quickly ๐โโ๏ธ๐จ
2.9. Precedence and Security ๐
TCP uses the internet protocol type of service field and the security option to give TCP users precedence and security on a per connection basis ๐ก๏ธ not every TCP module will work in a multilevel secure environment. some might be limited to unclassified use only, and others might only operate at one security level and compartment ๐ so some TCP implementations and services for users might be limited to a subset of the multilevel secure case ๐ซค
TCP modules that operate in a multilevel secure environment should properly mark outgoing segments with the security, compartment, and precedence ๐ท๏ธ those modules should also give their users, or higher level protocols like Telnet or THP, an interface to specify the security level, compartment, and precedence they want for connections ๐๏ธ
2.10. Robustness Principle ๐ก๏ธ
TCP implementations should follow a general principle of robustness: be conservative in what you do, be liberal in what you accept from others ๐ซถ๐
3. FUNCTIONAL SPECIFICATION โจ
3.1. Header Format โจ
Okay bestie, so TCP segments get sent as internet datagrams ๐ฆ. The Internet Protocol header carries a bunch of info fields, including the source and destination host addresses [2]. Then a TCP header comes right after the internet header and supplies all the TCP-specific stuff ๐ . This split is iconic because it leaves room for host-level protocols other than TCP ๐.
0 1 2 3
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Source Port | Destination Port |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Sequence Number |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Acknowledgment Number |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Data | |U|A|E|R|S|F| |
| Offset| Reserved |R|C|O|S|Y|I| Window |
| | |G|K|L|T|N|N| |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Checksum | Urgent Pointer |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Options | Padding |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| data |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
TCP Header Format ๐ง
Heads up, one tick mark represents one bit position ๐
Figure 3. ๐
Source Port: 16 bits ๐ธ
The source port number.
Destination Port: 16 bits ๐ธ
The destination port number.
Sequence Number: 32 bits ๐ฆ
The sequence number of the first data octet in this segment (except when SYN is present).
Acknowledgment Number: 32 bits ๐ฆ
If the ACK control bit is set, this field contains the value of the next sequence number the sender of the segment is expecting to receive. Once a connection is established this is always sent. ๐ซถ
Data Offset: 4 bits
The number of 32 bit words in the TCP Header. This indicates where the data begins. The TCP header including options is an integral number of 32 bits long.
Reserved: 6 bits
Reserved for future use. Must be zero. ๐
Control Bits: 8 bits (from left to right): ๐ฅ
URG: Urgent Pointer field significantACK: Acknowledgment field significantEOL: End of LetterRST: Reset the connectionSYN: Synchronize sequence numbersFIN: No more data from sender
Window: 16 bits ๐ช
The number of data octets beginning with the one indicated in the acknowledgment field which the sender of this segment is willing to accept. โจ
Checksum: 16 bits ๐งฎ
The checksum field is the 16 bit one's complement of the one's complement sum of all 16 bit words in the header and text. If a segment contains an odd number of header and text octets to be checksummed, the last octet is padded on the right with zeros to form a 16 bit word for checksum purposes. The pad is not transmitted as part of the segment. While computing the checksum, the checksum field itself is replaced with zeros. ๐
The checksum also covers a 96 bit pseudo header conceptually prefixed to the TCP header. This pseudo header contains the Source Address, the Destination Address, the Protocol, and TCP length. This gives the TCP protection against misrouted segments. This information is carried in the Internet Protocol and is transferred across the TCP/Network interface in the arguments or results of calls by the TCP on the IP. ๐ญ
+--------------------------+
| Source Address |
+--------------------------+
| Destination Address |
+--------------------------+
| zero | PTCL | TCP Length |
+--------------------------+
The TCP Length is the TCP header plus the data length in octets (this is not an explicitly transmitted quantity, but is computed from the total length, and the header length). ๐ง
Urgent Pointer: 16 bits ๐จ
This field communicates the current value of the urgent pointer as a positive offset from the sequence number in this segment. The urgent pointer points to the sequence number of the octet following the urgent data. This field should only be interpreted in segments with the URG control bit set. ๐
Options: variable ๐
Options may occupy space at the end of the TCP header and are a multiple of 8 bits in length. All options are included in the checksum. An option may begin on any octet boundary. There are two cases for the format of an option:
- Case 1: A single octet of option-kind.
- Case 2: An octet of option-kind, an octet of option-length, and the actual option-data octets.
The option-length counts the two octets of option-kind and option-length as well as the option-data octets.
Note that the list of options may be shorter than the data offset field might imply. The content of the header beyond the End-of-Option option should be header padding (i.e., zero). ๐
A TCP must implement all options. ๐
Currently defined options include (kind indicated in octal): ๐
Kind Length Meaning
---- ------ -------
0 - End of option list.
1 - No-Operation.
100 - Reserved.
105 4 Buffer Size.
Specific Option Definitions ๐ฆ
End of Option List ๐
+--------+
|00000000|
+--------+
Kind=0
This option code indicates the end of the option list. This might not coincide with the end of the TCP header according to the Data Offset field. This is used at the end of all options, not the end of each option, and need only be used if the end of the options would not otherwise coincide with the end of the TCP header. ๐ซ
No-Operation ๐ท
+--------+
|00000001|
+--------+
Kind=1
This option code may be used between options, for example, to align the beginning of a subsequent option on a word boundary. There is no guarantee that senders will use this option, so receivers must be prepared to process options even if they do not begin on a word boundary. ๐ง
Buffer Size ๐ช
+--------+--------+---------+--------+
|01000101|00000100| buffer size |
+--------+--------+---------+--------+
Kind=105 Length=4
Buffer Size Option Data: 16 bits
If this option is present, then it communicates the receive buffer size at the TCP which sends this segment. This field should only be sent in the initial connection request (i.e., in segments with the SYN control bit set). If this option is not used, the default buffer size of one octet is assumed. ๐
Padding: variable ๐ซง
The TCP header padding is used to ensure that the TCP header ends and data begins on a 32 bit boundary. The padding is composed of zeros. ๐
3.2. Terminology โจ
okay bestie, before we can even talk about how TCP works, we need some vocab ๐ค๐. keeping a TCP connection alive means remembering a bunch of variables, and TCP keeps them all in one connection record called a Transmission Control Block (TCB). ๐ The TCB holds the local and remote socket numbers, the connection's security and precedence, pointers to the user's send and receive buffers, pointers to the retransmit queue and to the current segment, and a whole pile of send and receive sequence number variables. it's giving organized chaos but make it efficient ๐
Send Sequence Variables
SND.UNA - send unacknowledged
SND.NXT - send sequence
SND.WND - send window
SND.BS - send buffer size
SND.UP - send urgent pointer
SND.WL - send sequence number used for last window update
SND.LBB - send last buffer beginning
ISS - initial send sequence number
Receive Sequence Variables
RCV.NXT - receive sequence
RCV.WND - receive window
RCV.BS - receive buffer size
RCV.UP - receive urgent pointer
RCV.LBB - receive last buffer beginning
IRS - initial receive sequence number
these diagrams are gonna help you picture how those variables sit on the sequence space ๐ฆ (it's honestly so pretty when it clicks)
Send Sequence Space
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
Send Sequence Space
Figure 4.
Receive Sequence Space
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
Receive Sequence Space
Figure 5.
Current Segment Variables
there's also a set of variables that get their values straight from the fields of whatever segment is currently being handled. they show up a LOT in the discussion, so get cozy with them ๐ง
SEG.SEQ - segment sequence number
SEG.ACK - segment acknowledgment number
SEG.LEN - segment length
SEG.WND - segment window
SEG.UP - segment urgent pointer
SEG.PRC - segment precedence value
Connection States
a connection moves through a series of states over its whole lifetime ๐. the states are: LISTEN, SYN-SENT, SYN-RECEIVED, ESTABLISHED, FIN-WAIT-1, FIN-WAIT-2, TIME-WAIT, CLOSE-WAIT, CLOSING, and the fictional state CLOSED. CLOSED is fictional because it's basically the vibe where there's no TCB at all, which means no connection at all ๐. here's a quick rundown of what each one means:
LISTEN- waiting for a connection request from any remote TCP and port.SYN-SENT- waiting for a matching connection request after you've already sent one.SYN-RECEIVED- waiting for the confirming acknowledgment of a connection request, after having both received and sent one.ESTABLISHED- an open connection, ready to send and receive data segments. the main character moment โจ๐FIN-WAIT-1- waiting for a connection termination request from the remote TCP, or for an acknowledgment of the termination request you already sent.FIN-WAIT-2- waiting for a connection termination request from the remote TCP.TIME-WAIT- waiting long enough to be sure the remote TCP got the acknowledgment of its termination request.CLOSE-WAIT- waiting for a connection termination request from the local user.CLOSING- waiting for the remote TCP to acknowledge a termination request.CLOSED- no connection state at all ๐ซถ
Events
a connection changes state in response to events ๐ฆ. the events are: the user calls OPEN, SEND, RECEIVE, CLOSE, ABORT, and STATUS; incoming segments, especially the ones carrying the SYN and FIN flags; and timeouts. the Glossary has a much more complete list of terms and definitions if you ever need it ๐
the state diagram in figure 6 is a bit of a minimalist ๐ . it only shows state changes, plus the events that cause them and the actions that result. it doesn't cover error conditions or actions that don't change state. a later section goes into way more detail on how TCP reacts to events, so don't panic if something's missing here ๐
+---------+ ---------\ active OPEN
| CLOSED | \ -----------
+---------+<---------\ \ create TCB
| ^ \ \ snd SYN
passive OPEN | | CLOSE \ \
------------ | | ---------- \ \
create TCB | | delete TCB \ \
V | \ \
+---------+ CLOSE | \
| LISTEN | ---------- | |
+---------+ delete TCB | |
rcv SYN | | SEND | |
----------- | | ------- | V
+---------+ snd SYN,ACK / \ snd SYN +---------+
| |<----------------- ------------------>| |
| SYN | rcv SYN | SYN |
| RCVD |<-----------------------------------------------| SENT |
| | snd ACK | |
| |------------------ -------------------| |
+---------+ rcv ACK of SYN \ / rcv SYN,ACK +---------+
| -------------- | | -----------
| x | | snd ACK
| V V
| CLOSE +---------+
| ------- | ESTAB |
| snd FIN +---------+
| CLOSE | | rcv FIN
V ------- | | -------
+---------+ snd FIN / \ snd ACK +---------+
| FIN |<----------------- ------------------>| CLOSE |
| WAIT-1 |------------------ -------------------| WAIT |
+---------+ rcv FIN \ / CLOSE +---------+
| rcv ACK of FIN ------- | | -------
| -------------- snd ACK | | snd FIN
V x V V
+---------+ +---------+
|FINWAIT-2| | CLOSING |
+---------+ +---------+
| rcv FIN | rcv ACK of FIN
| ------- Timeout=2MSL | --------------
V snd ACK ------------ V delete TCB
+---------+ delete TCB +---------+
|TIME WAIT|----------------->| CLOSED |
+---------+ +---------+
TCP Connection State Diagram
Figure 6.
3.3. Sequence Numbers ๐ฆ
okay bestie, this is the core idea of TCP ๐ every single octet of data sent over a TCP connection gets its own sequence number. Since every octet is sequenced, each one can be acknowledged. The acknowledgment is cumulative, so an ack of sequence number X means that all octets up to but not including X were received โจ That makes duplicate detection straightforward even when retransmission happens ๐ Numbering works inside a segment too: the first data octet right after the header is the lowest numbered, and the octets that follow are numbered consecutively.
It is essential to remember that the sequence number space is finite, though very large ๐ It runs from 0 to 2**32 - 1. Because it's finite, all arithmetic on sequence numbers has to be done modulo 2**32. This unsigned arithmetic keeps the relationships between sequence numbers intact as they wrap from 2**32 - 1 back to 0. Computer modulo math has some tricky subtleties, so be extra careful when you program these comparisons ๐ญ The typical sequence number comparisons TCP needs to make are:
- (a) Determining that an acknowledgment refers to some sequence number sent but not yet acknowledged.
- (b) Determining that all sequence numbers occupied by a segment have been acknowledged (e.g., to remove the segment from a retransmission queue).
- (c) Determining that an incoming segment contains sequence numbers which are expected (i.e., that the segment "overlaps" the receive window).
On send connections, these comparisons are needed:
older sequence numbers newer sequence numbers
SND.UNA SEG.ACK SND.NXT
| | |
----|----XXXXXXX------XXXXXXXXXX---------XXXXXX----|----
| | | | | |
| | |
Segment 1 Segment 2 Segment 3
<----- sequence space ----->
Sending Sequence Space Information
Figure 7.
SND.UNA= oldest unacknowledged sequence numberSND.NXT= next sequence number to be sentSEG.ACK= acknowledgment (next sequence number expected by the acknowledging TCP)SEG.SEQ= first sequence number of a segmentSEG.SEQ+SEG.LEN-1= last sequence number of a segment
A new acknowledgment (called an "acceptable ack") is one for which this inequality holds ๐
SND.UNA < SEG.ACK =< SND.NXT
All arithmetic is modulo 2**32, and comparisons are unsigned. =< means "less than or equal" โจ
A segment on the retransmission queue is fully acknowledged if the sum of its sequence number and length is less than the acknowledgment value in the incoming segment ๐
SEG.LEN is the number of octets occupied by the data in the segment. It's really important that SEG.LEN be non-zero ๐ซถ Segments that don't occupy any sequence space (like empty acknowledgment segments) are never placed on the retransmission queue, so they wouldn't go through this particular test.
On receive connections, these comparisons are needed:
older sequence numbers newer sequence numbers
RCV.NXT RCV.NXT+RCV.WND
| |
---------XXX|XXX------XXXXXXXXXX---------XXX|XX---------
| | | | |
| | |
Segment 1 Segment 2 Segment 3
<----- sequence space ----->
Receiving Sequence Space Information
Figure 8.
RCV.NXT= next sequence number expected on incoming segmentsRCV.NXT+RCV.WND= last sequence number expected on incoming segments, plus oneSEG.SEQ= first sequence number occupied by the incoming segmentSEG.SEQ+SEG.LEN-1= last sequence number occupied by the incoming segment
A segment is judged to occupy a portion of valid receive sequence space if:
0 =< (SEG.SEQ+SEG.LEN-1 - RCV.NXT) < (RCV.NXT+RCV.WND - RCV.NXT)
SEG.SEQ+SEG.LEN-1 is the last sequence number the segment occupies. RCV.NXT is the next sequence number expected on an incoming segment, and RCV.NXT+RCV.WND is the right edge of the receive window ๐ฆ
Okay, it's a little more complicated than that ๐ because of zero windows and zero-length segments, there are four cases for whether an incoming segment is acceptable:
Segment Receive Test
Length Window
------- ------- -------------------------------------------
0 0 SEG.SEQ = RCV.NXT
0 >0 RCV.NXT =< SEG.SEQ < RCV.NXT+RCV.WND
>0 0 not acceptable
>0 >0 RCV.NXT < SEG.SEQ+SEG.LEN =< RCV.NXT+RCV.WND
Note that the acceptance test requires the end of a segment to lie inside the window, which is a bit stricter than it absolutely has to be. If at least the first sequence number of the segment lies in the receive window, or if some part of the segment does, the segment might be judged acceptable. So in Figure 8, at least segments 1 and 2 are acceptable by the strict rule, and segment 3 may or may not be, depending on how strictly you read the rule ๐
Note that when the receive window is zero, no segments should be acceptable except ACK segments. That means a TCP should be able to keep a zero receive window while still transmitting data and receiving ACKs โจ
We've also used the numbering scheme to protect certain control information. Some control flags are implicitly included in the sequence space, so they can be retransmitted and acknowledged without confusion. That way one and only one copy of the control gets acted upon ๐ฅ Control information isn't physically carried in the segment data space, so we need rules for implicitly assigning sequence numbers to control. Only the SYN and FIN need this protection, and they're only used when a connection opens and closes. For sequence number purposes, the SYN is considered to occur before the first actual data octet of the segment it's in, and the FIN is considered to occur after the last actual data octet in the segment it's in. The segment length includes both data and the sequence space taken up by controls. When a SYN is present, SEG.SEQ is the sequence number of the SYN.
Initial Sequence Number Selection
The protocol doesn't restrict a particular connection from being used over and over again ๐ธ A connection is defined by a pair of sockets, and each new instance of a connection is called an incarnation of the connection. The problem this creates is: "how does the TCP identify duplicate segments from previous incarnations of the connection?" This gets really obvious if the connection is opened and closed in quick succession, or if the connection breaks with loss of memory and then gets re-established ๐ญ
To avoid confusion, we have to stop segments from one incarnation of a connection from being used while the same sequence numbers might still be floating around the network from an earlier incarnation. We want this to hold even if a TCP crashes and loses all knowledge of the sequence numbers it's been using ๐ง When new connections are created, an initial sequence number (ISN) generator picks a new 32 bit ISN. The generator is tied to a (possibly fictitious) 32 bit clock whose low order bit increments roughly every 4 microseconds. So the ISN cycles about every 4.55 hours. Since we assume segments stay in the network for no more than tens of seconds or minutes, at worst, we can reasonably assume ISN's will be unique ๐
Each connection has a send sequence number and a receive sequence number. The initial send sequence number (ISS) is chosen by the data sending TCP, and the initial receive sequence number (IRS) is learned during the connection establishing procedure ๐
For a connection to be established or initialized, the two TCPs have to synchronize on each other's initial sequence numbers. This happens in an exchange of connection establishing messages that carry a control bit called "SYN" (for synchronize) along with the initial sequence numbers. As a shorthand, messages carrying the SYN bit are also called "SYNs". So the solution needs a suitable mechanism for picking an initial sequence number, plus a slightly involved handshake to exchange the ISN's. A "three way handshake" is necessary because sequence numbers aren't tied to a global clock in the network, and TCPs may use different mechanisms for picking ISN's. The receiver of the first SYN has no way of knowing whether the segment was an old delayed one, unless it remembers the last sequence number used on the connection (which isn't always possible). So it has to ask the sender to verify this SYN ๐ซถ
The "three way handshake" and the advantages of a "clock-driven" scheme are discussed in [4]. ๐
Knowing When to Keep Quiet
To be sure a TCP doesn't create a segment with a sequence number that an old segment still in the network might duplicate, the TCP must keep quiet for a maximum segment lifetime (MSL) before assigning any sequence numbers. This applies when starting up or recovering from a crash in which memory of sequence numbers in use was lost โณ For this specification, the MSL is taken to be 2 minutes. That's an engineering choice and may be changed if experience shows it's desirable ๐ Note that if a TCP is reinitialized in some sense but keeps its memory of sequence numbers in use, it doesn't need to wait at all. It just has to be sure to use sequence numbers larger than those it used recently โจ
It should be noted that this strategy does not protect against spoofing or other replay type duplicate message problems. ๐
3.4. Establishing a connection ๐
The "three-way handshake" is the procedure used to establish a connection ๐ It's normally started by one TCP and answered by another TCP. The procedure also works if two TCPs start it at the same time. In a simultaneous attempt, a TCP receives a "SYN" segment that carries no acknowledgment after it has sent a "SYN" itself. Of course, an old duplicate "SYN" segment arriving can make it look to the recipient like a simultaneous connection initiation is happening. Proper use of "reset" segments can sort out those cases ๐ Several examples of connection initiation follow. These examples don't show connection synchronization using data-carrying segments, but that's perfectly legit, as long as the receiving TCP doesn't deliver the data to the user until it's clear the data is valid. In other words, the data must be buffered at the receiver until the connection reaches the ESTABLISHED state ๐ซถ The three-way handshake reduces the chance of false connections. It's a trade-off between memory and messages, used to provide information for that checking ๐
The simplest three-way handshake is shown in figure 9 below. ๐ Here's how to read the figures: each line is numbered so we can point at it. Right arrows (-->) mean a TCP segment is leaving TCP A for TCP B, or arriving at B from A. Left arrows (<--) are the reverse. An ellipsis (...) means a segment is still floating around in the network (delayed) ๐ซ An "XXX" means a segment got lost or rejected ๐ Comments go in parentheses. The TCP states show where things stand AFTER the segment departs or arrives, and the segment contents sit in the middle of each line. Those contents are abbreviated to the sequence number, control flags, and ACK field. Window, addresses, lengths, and text are left out so it stays clean ๐
TCP A TCP B
1. CLOSED LISTEN
2. SYN-SENT --> <SEQ=100><CTL=SYN> --> SYN-RECEIVED
3. ESTABLISHED <-- <SEQ=300><ACK=101><CTL=SYN,ACK> <-- SYN-RECEIVED
4. ESTABLISHED --> <SEQ=101><ACK=301><CTL=ACK> --> ESTABLISHED
5. ESTABLISHED --> <SEQ=101><ACK=301><CTL=ACK><DATA> --> ESTABLISHED
Basic 3-Way Handshake for Connection Synchronization
Figure 9.
In line 2 of figure 9, TCP A starts things off by sending a SYN segment that says it'll use sequence numbers beginning with 100. โจ In line 3, TCP B sends its own SYN and acknowledges the SYN it got from TCP A. Notice that the acknowledgment field means TCP B is now expecting to hear sequence 101, which acknowledges the SYN that occupied sequence 100. Iconic. ๐
At line 4, TCP A replies with an empty segment carrying an ACK for TCP B's SYN. Then in line 5, TCP A sends some data. The segment in line 5 has the same sequence number as the one in line 4, and that's because the ACK doesn't take up any sequence number space. (If it did, we'd end up ACKing ACKs, and nobody wants that ๐ญ)
Simultaneous initiation is only slightly more complicated, as figure 10 shows. Each TCP cycles from CLOSED to SYN-SENT to SYN-RECEIVED to ESTABLISHED. ๐
The main reason for the three-way handshake is to stop old duplicate connection initiations from causing confusion. ๐ฆ To handle this, there's a special control message called reset, which was devised for exactly this job. If the receiving TCP is in a non-synchronized state (that's SYN-SENT or SYN-RECEIVED), it goes back to LISTEN when it receives an acceptable reset. If the TCP is in one of the synchronized states (ESTABLISHED, FIN-WAIT-1, FIN-WAIT-2, TIME-WAIT, CLOSE-WAIT, CLOSING), it aborts the connection and tells its user. We'll talk about that second case under "half-open" connections below. ๐
TCP A TCP B
1. CLOSED CLOSED
2. SYN-SENT --> <SEQ=100><CTL=SYN> ...
3. SYN-RECEIVED <-- <SEQ=300><CTL=SYN> <-- SYN-SENT
4. ... <SEQ=100><CTL=SYN> --> SYN-RECEIVED
5. SYN-RECEIVED --> <SEQ=101><ACK=301><CTL=ACK> ...
6. ESTABLISHED <-- <SEQ=301><ACK=101><CTL=ACK> <-- SYN-RECEIVED
7. ... <SEQ=101><ACK=301><CTL=ACK> --> ESTABLISHED
Simultaneous Connection Synchronization
Figure 10.
TCP A TCP B
1. CLOSED LISTEN
2. SYN-SENT --> <SEQ=100><CTL=SYN> ...
3. (duplicate) ... <SEQ=1000><CTL=SYN> --> SYN-RECEIVED
4. SYN-SENT <-- <SEQ=300><ACK=1001><CTL=SYN,ACK> <-- SYN-RECEIVED
5. SYN-SENT --> <SEQ=1001><CTL=RST> --> LISTEN
6. ... <SEQ=100><CTL=SYN> --> SYN-RECEIVED
7. SYN-SENT <-- <SEQ=400><ACK=101><CTL=SYN,ACK> <-- SYN-RECEIVED
8. ESTABLISHED --> <SEQ=101><ACK=401><CTL=ACK> --> ESTABLISHED
Recovery from Old Duplicate SYN
Figure 11.
Let's look at figure 11 as an example of how recovery from old duplicates works. ๐ง At line 3, an old duplicate SYN shows up at TCP B. TCP B can't tell it's an old duplicate, so it responds normally (line 4). TCP A notices the ACK field is wrong and sends back a RST (reset), with its SEQ field picked so the segment is believable. ๐ซถ When TCP B gets that RST, it goes back to LISTEN. Then the original SYN (pun intended ๐) finally arrives at line 6, and the synchronization carries on normally. If the SYN at line 6 had shown up before the RST, a more complicated exchange might have happened, with RSTs sent in both directions.
Half-Open Connections and Other Anomalies
An established connection is "half-open" if one of the TCPs has closed or aborted the connection on its end without the other one knowing. It's also half-open if the two ends have become desynchronized because a crash wiped out memory. ๐ Connections like this will automatically reset if someone tries to send data in either direction. The thing is, half-open connections are supposed to be unusual, and the recovery procedure is a little involved. ๐
If the connection no longer exists at site A, then when the user at site B tries to send any data on it, the site B TCP gets a reset control message. That message should tell the site B TCP that something is wrong, and it's expected to abort the connection. ๐
Now picture two user processes, A and B, talking to each other when a crash makes TCP A lose its memory. Depending on the operating system running A's TCP, there's a good chance some error recovery mechanism exists. Once TCP is back up, A will probably start over from the beginning or from a recovery point. So A will likely try to OPEN the connection again, or try to SEND on the connection it still thinks is open. In that second case, it gets the error message "connection not open" from its own local TCP. To establish the connection, A's TCP will send a segment containing a SYN. This leads to the scenario in figure 12. After TCP A crashes, the user tries to re-open the connection, while TCP B, meanwhile, still thinks the connection is open. ๐ธ
TCP A TCP B
1. (CRASH) (send 300,receive 100)
2. CLOSED ESTABLISHED
3. SYN-SENT --> <SEQ=400><CTL=SYN> --> (??)
4. (!!) <-- <SEQ=300><ACK=100><CTL=ACK> <-- ESTABLISHED
5. SYN-SENT --> <SEQ=100><CTL=RST> --> (Abort!!)
6. CLOSED
7. SYN-SENT --> <SEQ=400><CTL=SYN> -->
Half-Open Connection Discovery
Figure 12.
When the SYN arrives at line 3, TCP B, which is in a synchronized state, responds with an acknowledgment saying what sequence number it expects next (ACK 100). TCP A sees that this segment doesn't acknowledge anything it sent. Since TCP A is unsynchronized, it sends a reset (RST) because it has detected a half-open connection. TCP B aborts at line 5. TCP A keeps trying to establish the connection, and the problem is now just the basic 3-way handshake from figure 9. ๐
Another interesting case happens when TCP A crashes and TCP B tries to send data on what it thinks is a synchronized connection. Figure 13 shows this. Here, the data that reaches TCP A from TCP B (line 2) is unacceptable, because no such connection exists. So TCP A sends a RST. TCP B finds that RST acceptable, processes it, and aborts the connection. ๐
TCP A TCP B
1. (CRASH) (send 300,receive 100)
2. (??) <-- <SEQ=300><ACK=100><DATA=10><CTL=ACK> <-- ESTABLISHED
3. --> <SEQ=100><CTL=RST> --> (ABORT!!)
Active Side Causes Half-Open Connection Discovery
Figure 13.
In figure 14, TCPs A and B both have passive connections waiting for a SYN. An old duplicate arriving at TCP B (line 2) stirs B into action. B returns a SYN-ACK (line 3), which causes TCP A to generate a RST, because the ACK in line 3 isn't acceptable. TCP B accepts the reset and goes back to its passive LISTEN state. ๐
TCP A TCP B
1. LISTEN LISTEN
2. ... <SEQ=Z><CTL=SYN> --> SYN-RECEIVED
3. (??) <-- <SEQ=X><ACK=Z+1><CTL=SYN,ACK> <-- SYN-RECEIVED
4. --> <SEQ=Z+1><CTL=RST> --> (return to LISTEN!)
5. LISTEN LISTEN
Old Duplicate SYN Initiates a Reset on two Passive Sockets
Figure 14.
There are a bunch of other cases too, and they're all covered by the following rules for RST generation and processing. โจ
Reset Generation
As a general rule, a reset (RST) should be sent whenever a segment arrives that apparently isn't meant for the current incarnation of the connection or a future one. A reset should not be sent if it isn't clear that this is the case. So if any segment arrives for a nonexistent connection, a reset should be sent. If a segment ACKs something that has never been sent on the current connection, then one of the following two cases applies. ๐ฆ
- If the connection is in any non-synchronized state (LISTEN, SYN-SENT, SYN-RECEIVED), or if the connection doesn't exist, a reset (RST) should be formed and sent for any segment that acknowledges something not yet sent. The RST should take its SEQ field from the ACK field of the offending segment (if the ACK control bit was set), and its ACK bit should be reset (zero), except to refuse a initial SYN. A reset is also sent if an incoming segment has a security level or compartment that doesn't exactly match the level and compartment requested for the connection. And if the precedence of the incoming segment is less than the precedence level requested, a reset is sent. ๐ฅ
- If the connection is in a synchronized state (ESTABLISHED, FIN-WAIT-1, FIN-WAIT-2, TIME-WAIT, CLOSE-WAIT, CLOSING), any unacceptable segment should only get an empty acknowledgment segment back. That segment contains the current send-sequence number and an acknowledgment saying which sequence number is expected next. ๐
Reset Processing
Every reset (RST) segment gets validated by checking its SEQ fields. A reset is valid if its sequence number is in the window. For a RST received in response to an initial SYN, any sequence number is acceptable as long as the ACK field acknowledges the SYN. ๐ง
The receiver of a RST validates it first, and only then changes state. If the receiver was in the LISTEN state, it ignores the reset. If the receiver was in the SYN-RECEIVED state and had previously been in the LISTEN state, it goes back to LISTEN. Otherwise, the receiver aborts the connection and goes to the CLOSED state. And if the receiver was in any other state, it aborts the connection, advises the user, and goes to the CLOSED state. ๐
3.5. Closing a Connection โจ
okay so CLOSE basically means "I'm done sending, bestie" ๐ Closing a full-duplex connection is kinda messy, ngl, because it's not obvious what happens to the receiving side. So TCP treats CLOSE in a simplex way ๐ฆ The user who CLOSEs can keep RECEIVEing until they're told the other side has CLOSED too. So a program can do a bunch of SENDs, then a CLOSE, then keep listening until a RECEIVE fails because the other side closed. It's giving clean exit energy ๐
We assume TCP will tell the user that the other side closed, even if no RECEIVEs are pending, so the user can wrap up gracefully ๐ซถ TCP also reliably delivers every buffer that was SENT before the connection was CLOSED. So if you don't expect any data back, you just wait until the connection is CLOSED successfully, and then you know all your data reached the destination TCP. No cap, that's iconic โจ
There are basically three cases ๐
- The user tells the TCP to CLOSE the connection.
- The remote TCP starts the close by sending a FIN control signal.
- Both users CLOSE at the same time.
Case 1: Local user initiates the close ๐ธ
Here, a FIN segment gets built and put on the outgoing segment queue. TCP won't accept any more SENDs from the user, and it moves into the FIN-WAIT-1 state. RECEIVEs are still allowed in this state ๐ Every segment up to and including the FIN gets retransmitted until it's acknowledged. Once the other TCP has both ACKed the FIN and sent a FIN of its own, the first TCP can ACK that FIN. Also, a TCP that receives a FIN will ACK it but won't send its own FIN until its user has CLOSED the connection too. Very polite, very structured ๐
Case 2: TCP receives a FIN from the network ๐ง
If an unsolicited FIN shows up from the network, the receiving TCP can ACK it and tell its user the connection is closing. The user should respond with a CLOSE, and then the TCP can send a FIN to the other TCP. After that, it waits until its own FIN is acknowledged, and then it deletes the connection. If the ACK never comes, the connection is aborted after a timeout and the user is told ๐
Case 3: Both users close simultaneously ๐
When both users CLOSE at the same time, FIN segments get exchanged. Once all the segments before the FINs have been processed and acknowledged, each TCP can ACK the FIN it received. When both get those ACKs, both delete the connection. Two besties hanging up at the exact same moment, lol ๐ญ
TCP A TCP B
1. ESTABLISHED ESTABLISHED
2. (Close)
FIN-WAIT-1 --> <SEQ=100><CTL=FIN> --> CLOSE-WAIT
3. FIN-WAIT-2 <-- <SEQ=300><ACK=101><CTL=ACK> <-- CLOSE-WAIT
4. (Close)
TIME-WAIT <-- <SEQ=301><CTL=FIN> <-- CLOSING
5. TIME-WAIT --> <SEQ=100><ACK=301><CTL=ACK> --> CLOSED
6. (2 MSL)
CLOSED
Normal Close Sequence
Figure 15.
TCP A TCP B
1. ESTABLISHED ESTABLISHED
2. (Close) (Close)
FIN-WAIT-1 --> <SEQ=100><CTL=FIN> ... FIN-WAIT-1
<-- <SEQ=300><CTL=FIN> <--
... <SEQ=100><CTL=FIN> -->
3. CLOSING --> <SEQ=100><ACK=301><CTL=ACK> ... CLOSING
<-- <SEQ=300><ACK=101><CTL=ACK> <--
... <SEQ=100><ACK=301><CTL=ACK> -->
4. CLOSED CLOSED
Simultaneous Close Sequence
Figure 16.
3.6. Precedence and Security ๐ฅ
The idea is that a connection is only allowed between ports that have exactly the same security and compartment values, and at the higher of the two precedence levels that the two parts asked for ๐ซถ
The precedence levels are ๐
flash override - 111
flash - 110
immediate - 10X
priority - 01X
routine - 00X
The security levels are ๐
top secret - 11
secret - 10
confidential - 01
unclassified - 00
The compartments get assigned by the Defense Communications Agency. The defaults are precedence: routine, security: unclassified, compartment: zero ๐ A host that doesn't implement the precedence or security features should clear these fields to zero for the segments it sends.
A connection attempt with mismatched security/compartment values, or a lower precedence value, should be rejected by sending a reset. Not it, not the vibe ๐ โโ๏ธ
Also, TCP modules that only run at the default precedence value still have to check the precedence of incoming segments, and they might need to raise the precedence level they use on the connection. So even the chill ones gotta stay alert ๐
3.7. Data Communication ๐ฌโจ
okay so once the connection is established, data gets communicated by swapping segments ๐ but segments can get lost (checksum test fails, or the network is congested ๐ญ), so TCP uses retransmission (after a timeout) to make sure every single segment gets delivered ๐ซถ. duplicate segments can also show up, thanks to the network or TCP's own retransmissions ๐. as we covered in the sequence numbers section, TCP runs certain tests on the sequence and acknowledgment numbers in each segment to verify they're acceptable ๐ .
the sender keeps track of the next sequence number to use in SND.NXT ๐ฎ. the receiver keeps track of the next sequence number it expects in RCV.NXT ๐. the sender also keeps track of the oldest unacknowledged sequence number in SND.UNA ๐ธ. if the data flow is momentarily idle and everything sent has been acknowledged, then all three variables will be equal โจ.
when the sender creates a segment and transmits it, the sender advances SND.NXT ๐. when the receiver accepts a segment, it advances RCV.NXT and sends an acknowledgment ๐. when the data sender gets an acknowledgment, it advances SND.UNA ๐ฆ. the gap between these values is a measure of the delay in the communication, so it's basically a vibe check on how laggy things are ๐ข.
normally, the amount each variable advances is just the length of the data in the segment. however, when letters are used there are special provisions for coordinating the sequence numbers, the letter boundaries, and the receive buffer boundaries ๐๐.
End of Letter Sequence Number Adjustments
okay this part is lowkey the most intricate bit, so buckle up ๐ข. TCP has a provision where the receiver of data can optionally tell the sender its buffer size at the time of connection synchronization ๐ง. if that happens, the receiver must use this fixed buffer size for the entire lifetime of the connection ๐. and if a buffer size is communicated, then there is a coordination between receive buffers, letters, and sequence numbers ๐ซง.
each time a buffer is completed, either because it got filled or because of an end of letter (EOL), the sequence number gets incremented through the end of that buffer ๐.
so whenever an EOL is transmitted, the sender advances its send sequence number, SND.NXT, by enough to consume all the unused space in the receiver's buffer ๐ซ. that consumed space gets subtracted from the send window, just like the space used by actual data does ๐.
and whenever an EOL is received, the receiver advances its receive sequence number, RCV.NXT, by enough to consume all the unused space in the receiver's buffer ๐. that consumed space gets subtracted from the receive window too, just like real data ๐ฉท.
older sequence numbers newer sequence numbers
| Buffer 1 | Buffer 2
| |
----+-------------------------------+-----------------
XXXXXXXXXXXXXXXXXXXXX+++++++++++
| | |
|<-----SEG.LEN------>| |
| | |
| | |
SEG.SEQ A B
XXX - data octets from segment
+++ - phantom data
<----- sequence space ----->
End of Letter Adjustment
Figure 17.
look at this diagram, it's giving ๐จ. in the case shown, if the segment doesn't carry an EOL flag, the next value of SND.NXT or RCV.NXT will be A ๐ฏ. if it does carry an EOL flag, the next value will be B ๐.
the exchange of buffer size and sequencing info is done in units of octets ๐ข. if no buffer size is stated, the buffer size is assumed to be 1 octet ๐ค. the receiver tells the sender the size of the buffer in a SYN segment, using the 16 bit buffer size data in an option field in the TCP header ๐.
each EOL advances the sequence number (SN) to the next buffer boundary, and the logic goes like this ๐งฎ:
While LBB < SEG.SEQ+SEG.LEN
Do LBB <- LBB + BS End
SN <- LBB
where LBB is the Last Buffer Beginning, and BS is the buffer size ๐ช.
the CLOSE user call implies an end of letter, and so does the FIN control flag in an incoming segment ๐๐ .
The Communication of Urgent Information
the goal of the TCP urgent mechanism is to let the sending user stimulate the receiving user into accepting some urgent data ๐จ. it also lets the receiving TCP tell the receiving user when all the currently known urgent data has been received by the user ๐.
this mechanism lets a point in the data stream be marked as the end of "urgent" information ๐. whenever this point is ahead of the receive sequence number (RCV.NXT) at the receiving TCP, that TCP should tell the user to go into "urgent mode" ๐ฆ. when the receive sequence number catches up to the urgent pointer, the TCP should tell the user to go into "normal mode" ๐ค๏ธ. and if the urgent pointer gets updated while the user is in "read fast" mode, the update will be invisible to the user ๐ฅท.
the method uses an urgent field, which is carried in all segments transmitted ๐ฆ. the URG control flag says the urgent field is meaningful, and it should be added to the segment sequence number to get the urgent pointer ๐งฉ. if this flag isn't set, that means the urgent pointer hasn't changed ๐.
to send an urgent indication, the user must also send at least one data octet ๐ซธ. if the sending user also indicates an end of letter, the timely delivery of the urgent info to the destination process gets even better ๐โจ.
Managing the Window
the window sent in each segment shows the range of sequence numbers the sender of the window (the data receiver) is currently prepared to accept ๐ช. this is assumed to be related to the data buffer space currently available for this connection ๐๏ธ. the window info is a guideline to aim at, not a hard rule ๐ฏ.
a large window encourages transmissions, but if more data arrives than can be accepted, it gets discarded ๐ฌ. that leads to excessive retransmissions, which adds unnecessary load to the network and the TCPs ๐. a small window, on the other hand, might restrict data transmission so much that there's a round trip delay between each new segment ๐.
TCP does give you the tools to advertise a large window and then later advertise a much smaller one, without having accepted that much data ๐ซ . this is called "shrinking the window," and it's strongly discouraged ๐ซ. the robustness principle says TCPs will not shrink the window themselves, but they should be ready for other TCPs to do it ๐ก๏ธ๐ซถ.
the sending TCP must be prepared to accept and send at least one octet of new data even if the send window is zero ๐ง. it should also regularly retransmit to the receiving TCP, even when the window is zero. two minutes is recommended for that retransmission interval when the window is zero โฐ. this retransmission is essential, because it's what guarantees that when either TCP has a zero window, the window re-opening gets reliably reported to the other one ๐๐.
the sending TCP packages the data it wants to transmit into segments that fit the current window, and it may repackage segments sitting on the retransmission queue ๐ฆ๐. this repackaging is not required, but it may be helpful ๐.
users must keep reading connections they close for sending until the TCP says there's no more data ๐.
in a connection with one-way data flow, the window info is carried in acknowledgment segments that all have the same sequence number. that means there's no way to reorder them if they arrive out of order ๐. it's not a serious problem, but it does mean the window info can occasionally be temporarily based on old reports from the data receiver ๐ฐ๏ธ.
3.8. Interfaces ๐งฉ
there are of course two interfaces we care about: the user/TCP interface and the TCP/IP interface ๐. we have a pretty detailed model of the user/TCP interface, but only a sketch of the interface to the lower level protocol module ๐๏ธ.
User/TCP Interface
ngl, the functional description of user commands to the TCP is kinda fictional, since every operating system has different facilities ๐ซฃ. so we have to warn readers that different TCP implementations may have different user interfaces ๐. however, all TCPs must provide a certain minimum set of services, so that every TCP implementation can support the same protocol hierarchy ๐. this section specifies the functional interfaces required of all TCP implementations ๐.
TCP User Commands
the following sections functionally describe a USER/TCP interface ๐ป. the notation is similar to most procedure or function calls in high level languages, but this doesn't rule out trap type service calls (e.g., SVCs, UUOs, EMTs) ๐ชค.
the user commands below specify the basic functions the TCP must perform to support interprocess communication ๐ซฑ๐ซฒ. individual implementations can define their own exact format, and they may provide combinations or subsets of the basic functions in single calls โ๏ธ. in particular, some implementations may want to automatically OPEN a connection on the first SEND or RECEIVE the user issues for a given connection ๐ช.
when providing interprocess communication, the TCP must not only accept commands, but must also return information to the processes it serves ๐ฌ. that information consists of:
- (a) general information about a connection (e.g., interrupts, remote close, binding of unspecified foreign socket) ๐.
- (b) replies to specific user commands, indicating success or various types of failure ๐๐ต.
Open ๐ช
Format:
OPEN (local port, foreign socket, active/passive
[, buffer size] [, timeout] [, precedence]
[, security/compartment]) -> local connection name
we assume the local TCP knows the identity of the processes it serves, and it will check the authority of the process to use the connection specified ๐ต๏ธโโ๏ธ. depending on the implementation, the local network and TCP identifiers for the source address will either be supplied by the TCP or by the processes it serves (e.g., the program that interfaces with the TCP network) ๐งพ. all of this is because of security concerns: no TCP should be able to masquerade as another one, and so on ๐ญ. likewise, no process can masquerade as another without the collusion of the TCP ๐ โโ๏ธ๐.
if the active/passive flag is set to passive, then this is a call to LISTEN for an incoming connection ๐. a passive open may have either a fully specified foreign socket to wait for a particular connection, or an unspecified foreign socket to wait for any call ๐. a fully specified passive call can be made active by a later SEND being executed ๐ฃ.
a full-duplex transmission control block (TCB) is created and partially filled in with data from the OPEN command parameters ๐งฑ๐.
on an active OPEN command, the TCP will begin the procedure to synchronize (i.e., establish) the connection right away โก.
the buffer size, if present, tells the TCP that the caller will always receive data from the connection in buffers of that size ๐ฆ. this buffer size measures the buffer between the user and the local TCP ๐งบ. the buffer size between the two TCPs may be different ๐ซถโจ.
The timeout, if you pass one, lets the caller set a timeout for all the buffers sent on the connection โฐ๐ If a buffer doesn't get delivered to the destination before the timeout runs out, the TCP will abort the connection ๐ The present global default is 30 seconds. The buffer retransmission rate can vary, but most likely it'll be tied to how long the remote TCP takes to respond ๐ธ
The TCP (or some part of the operating system) will check that the user is actually allowed to open a connection with the requested precedence or security/compartment ๐ If you leave precedence or security/compartment out of the OPEN call, the default values should be used ๐ง
TCP will only accept an incoming request as a match if the security/compartment info is exactly the same, and only if the precedence is equal to or higher than the one requested in the OPEN call ๐ฅ
The precedence for the connection is the higher of the value you requested in the OPEN call and the value from the incoming request, and it stays locked at that value for the whole life of the connection ๐
Depending on the TCP implementation, either the TCP gives the user back a local connection name, or the user picks their own (in which case another parameter is needed in the call) ๐ฆ Once you've got that local connection name, it's a super handy shorthand for the connection defined by the <local socket, foreign socket> pair โจ
Send
Format:
SEND(local connection name, buffer address, byte count,
EOL flag, URGENT flag [, timeout])
Okay, this call causes the data in the buffer you point to be sent on the indicated connection ๐ฎ If the connection hasn't been opened, the SEND counts as an error ๐ Some implementations let you SEND first, and then an automatic OPEN happens behind the scenes โจ If the calling process isn't authorized to use this connection, an error gets returned ๐ญ
If the EOL flag is set, the data is the End Of a Letter, and the EOL bit gets set in the last TCP segment made from the buffer ๐ If the EOL flag isn't set, later SENDs will look like they're part of the same letter ๐
If the URGENT flag is set, the segments from this call get the urgent pointer set to show that some of the data is urgent ๐จ This is how you can simulate "break" signals from terminals, or error or completion codes from I/O devices, for example ๐ฅ๏ธ What the urgent signal means to the receiving process is unspecified ๐คทโโ๏ธ The receiving TCP will signal the urgent condition to the receiving process as long as the urgent pointer says the data before it hasn't been consumed yet ๐ซถ The whole point of urgent is to nudge the receiver into accepting some urgent data, and to tell them when all the urgent data they currently know about has arrived ๐
The number of times the sending user's TCP signals urgent won't necessarily match the number of times the receiving user gets told about urgent data ๐
If no foreign socket was specified in the OPEN, but the connection is established anyway (say, because a LISTENing connection got specific after a foreign segment arrived for the local socket), then the buffer you designated gets sent to the implied foreign socket ๐ฆ Generally, if you OPEN with an unspecified foreign socket, you can SEND without ever explicitly knowing the foreign socket address ๐ง
BUT, if a SEND is attempted before the foreign socket is specified, an error will be returned ๐ You can use the STATUS call to check the status of the connection ๐ In some implementations, the TCP may notify the user when an unspecified socket gets bound ๐
If a timeout is specified, the current timeout for this connection changes to the new one โฐ
In the simplest implementation, SEND wouldn't give control back to the sending process until either the transmission was complete or the timeout was exceeded ๐ด But honestly, this approach is prone to deadlocks (for example, both sides might try to do SENDs before doing any RECEIVEs) and gives poor performance, so it is not recommended ๐ โโ๏ธ A more sophisticated implementation returns immediately so the process can keep running alongside network I/O, and so that multiple SENDs can be in progress at once ๐
Multiple SENDs get served first come, first served, so the TCP will queue up the ones it can't service right away ๐๏ธ
We've been implicitly assuming an asynchronous user interface, where a SEND later gets some kind of SIGNAL or pseudo-interrupt from the serving TCP ๐ฃ The other option is to return a response right away ๐จ For instance, SENDs might return an immediate local acknowledgment, even if the distant TCP hasn't acknowledged the segment yet ๐ค You could optimistically assume eventual success, and if you're wrong, the connection will close anyway due to the timeout ๐ In implementations like this (synchronous), there will still be some asynchronous signals, but those deal with the connection itself, not with specific segments or letters ๐ง
NOTA BENE: In order for the process to tell apart the error or success indications for different SENDs, it might be a good idea for the buffer address to come back along with the coded response to the SEND request ๐ TCP-to-user signals are discussed below, and they cover what information should be returned to the calling process ๐
Receive
Format: RECEIVE (local connection name, buffer address, byte count)
This command allocates a receiving buffer for the specified connection ๐๏ธ If no OPEN came before this command, or the calling process isn't authorized to use this connection, an error is returned ๐ซ
In the simplest implementation, control wouldn't return to the calling program until either the buffer was filled or some error happened, but this approach is super prone to deadlocks ๐ฌ A more sophisticated implementation lets several RECEIVEs be outstanding at once ๐ Those get filled as segments arrive ๐ฆ This gets you more throughput, at the cost of a fancier (possibly asynchronous) way to tell the calling program that a letter has been received or a buffer has been filled ๐
If there isn't enough buffer space to reassemble a complete letter, the EOL flag won't be set in the response to the RECEIVE ๐ โโ๏ธ The buffer gets filled with as much data as it can hold ๐งบ The last buffer needed to hold the letter comes back with EOL signaled ๐
The remaining parts of a partly delivered letter get placed into buffers as they become available through successive RECEIVEs ๐งฉ If several RECEIVEs are outstanding, they might be filled with parts of one single long letter, or with at most one letter each ๐ The return codes for each RECEIVE tell you what's in the buffer ๐ท๏ธ
If a buffer size was given in the OPEN call, then every buffer presented in RECEIVE calls must be of exactly that size, or an error indication will be returned ๐
The URGENT flag only gets set if the receiving user was previously told, through a TCP-to-user signal, that urgent data is waiting ๐จ So the receiving user should be in "read-fast" mode ๐๏ธ If the URGENT flag is on, more urgent data is still hanging around ๐ If the URGENT flag is off, this RECEIVE call has returned all the urgent data, and the user can now leave "read-fast" mode ๐ฅณ
To tell apart several outstanding RECEIVEs, and to handle the case where a letter is smaller than the buffer supplied, the return code comes with both a buffer pointer and a byte count showing the actual length of the letter received ๐
Other implementations of RECEIVE might have the TCP allocate the buffer storage, or the TCP might share a ring buffer with the user ๐ Variations like these will cause obvious differences in the user interface to the TCP ๐จ
Close
Format: CLOSE(local connection name)
This command closes the specified connection ๐ช If the connection isn't open, or the calling process isn't authorized to use this connection, an error is returned ๐ โโ๏ธ CLOSE is meant to be a graceful operation, meaning outstanding SENDs get transmitted (and retransmitted) as flow control allows, until they've all been serviced ๐๏ธ So it should be fine to make several SEND calls, then a CLOSE, and expect all the data to reach the destination ๐ฆโจ Also, users should keep RECEIVEing on CLOSING connections, since the other side might still be sending the last of its data ๐ Basically, CLOSE means "I have no more to send," but it does NOT mean "I will not receive any more" ๐ โโ๏ธ๐ If the user-level protocol isn't well thought out, the closing side might be unable to get rid of all its data before timing out ๐ฉ When that happens, CLOSE turns into ABORT, and the closing TCP gives up ๐
The user can CLOSE the connection at any time on their own initiative, or in response to various prompts from the TCP (like a remote close executed, a transmission timeout exceeded, or the destination being inaccessible) ๐ซ
Because closing a connection requires talking to the foreign TCP, connections may stay in the closing state for a short time โณ If you try to reopen the connection before the TCP replies to the CLOSE command, you'll get error responses ๐
Close also implies end of letter ๐
Status
Format: STATUS(local connection name)
This is an implementation dependent user command, and it could be excluded without adverse effect ๐คทโโ๏ธ The information returned would typically come from the TCB associated with the connection ๐๏ธ
This command returns a data block containing the following information:
local socket,
foreign socket,
local connection name,
receive window,
send window,
connection state,
number of buffers awaiting acknowledgment,
number of buffers pending receipt (including partial ones),
receive buffer size,
urgent state,
precedence,
security/compartment,
and default transmission timeout.
Depending on the connection's state, or on the implementation itself, some of this info might not be available or meaningful ๐ซฃ If the calling process isn't authorized to use this connection, an error is returned ๐ This keeps unauthorized processes from snooping around and gaining info about a connection ๐ต๏ธโโ๏ธ๐ซ
Abort โจ
Format: ABORT (local connection name)
okay so ABORT is the big red button ๐ด๐ . It makes every pending SEND and RECEIVE get aborted, deletes the TCB (the connection's state record), and sends a special RESET message to the TCP on the other side. Depending on the implementation, users might get an abort indication for each outstanding SEND or RECEIVE, or they might just get an ABORT-acknowledgment. Either way, it's giving dramatic exit ๐โจ
TCP-to-User Messages
so the operating system is assumed to give the TCP a way to asynchronously poke the user program ๐ When the TCP does poke a user program, it passes along some info. A lot of the time that info is an error message. Other times it's about how a SEND or RECEIVE (or some other user call) finished up ๐ธ
Here's what gets passed along:
Local Connection Name Always
Response String Always
Buffer Address Send & Receive
Byte count (counts bytes received) Receive
End-of-Letter flag Receive
End-of-Urgent flag Receive
TCP/Network Interface
the TCP leans on a lower level protocol module to actually send and receive stuff over a network ๐ One example is the ARPA internetwork system, where that lower module is the Internet Protocol [2]. In most cases the simple interface below is perfectly adequate ๐ฆ
The following two calls cover what the TCP needs when it talks to the internet protocol module ๐
SEND (dest, TOS, TTL, BufPTR, len, Id, DF, options => result)
where:
dest = destination address
TOS = type of service
TTL = time to live
BufPTR = buffer pointer
len = length of buffer
Id = Identifier
DF = Don't Fragment
options = internet option data
result = response
OK = datagram sent ok
Error = error in arguments or local network error
Note that the precedence is included in the TOS and the
security/compartment is passed as an option.
RECV (BufPTR => result, source, dest, prot, TOS, len)
where:
BufPTR = buffer pointer
result = response
OK = datagram received ok
Error = error in arguments
source = source address
dest = destination address
prot = protocol
TOS = type of service
options = internet option data
len = length of buffer
Note that the precedence is in the TOS, and the
security/compartment is an option.
so when the TCP sends a segment, it runs the SEND call and supplies all the arguments ๐ฆ The internet protocol module checks the arguments when it gets the call, then prepares and sends the message. If the arguments are good and the local network accepts the segment, the call returns successfully โ If the arguments are bad, or the local network doesn't accept the segment, the call returns unsuccessfully โ On unsuccessful returns, a reasonable report should be made about what caused the problem, but the details of those reports are up to each implementation ๐คทโโ๏ธ
when a segment shows up at the internet protocol module from the local network, there's either a RECV call already pending from the TCP, or there isn't ๐ซฃ If there is, that pending call gets satisfied by handing the segment's info over to the TCP. If there isn't, the TCP just gets notified that a segment is waiting ๐
The notification to the TCP can come through a pseudo interrupt or something similar, whatever fits the operating system environment of the implementation โก
A TCP's RECV call can either be satisfied right away by a pending segment, or it can just hang out until a segment arrives ๐ฐ๏ธ
Now, the Internet Protocol gives us arguments for type of service and time to live. TCP uses these settings for those parameters ๐
Type of Service = Precedence: none, Package: stream,
Reliability: higher, Preference: speed, Speed: higher; or
00011111.
Time to Live = one minute, or 00111100.
Note that the assumed maximum segment lifetime is two minutes. TCP is explicitly asking that a segment be destroyed if it can't be delivered by the internet system within one minute. That's a lot of intention in one line ๐ญ
3.9. Event Processing
okay this is the heart of the whole TCP state machine ๐ง โจ The TCP basically responds to events. There are three categories of events: user calls, arriving segments, and timeouts. This section explains what the TCP does for each event. A lot of the time, the processing depends on what state the connection is in ๐
Events that occur:
- User Calls
- OPEN
- SEND
- RECEIVE
- CLOSE
- ABORT
- STATUS
- Arriving Segments
- SEGMENT ARRIVES
- Timeouts
- USER TIMEOUT
- RETRANSMISSION TIMEOUT
The model for the TCP/user interface is that user commands get an immediate return, and possibly a delayed response through an event or pseudo interrupt ๐ซ In the descriptions below, the word "signal" means cause a delayed response ๐ฃ
Error responses come back as character strings. For example, user commands that reference connections that don't exist get "error: connection not open" ๐
Please note that everything below uses arithmetic on sequence numbers, acknowledgment numbers, windows, et cetera, all modulo 2**32, the size of the sequence number space ๐ข Also, "=<" means less than or equal to ๐
A natural way to think about processing incoming segments is to imagine they get tested first for proper sequence number (so, their contents lie in the range of the expected "receive window" in the sequence number space). After that, they're generally queued and processed in sequence number order ๐ฆ
When a segment overlaps other segments that were already received, we reconstruct the segment so it contains just the new data, and we adjust the header fields so everything stays consistent ๐งฉ
OPEN Call
CLOSED STATE (i.e., TCB does not exist)
Create a new transmission control block (TCB) to hold connection state information. Fill in the local socket identifier, foreign socket, precedence, security/compartment, and user timeout information. Verify that the security and precedence requested are allowed for this user. If they aren't, return "error: precedence not allowed" or "error: security/compartment not allowed." If it's active and the foreign socket is unspecified, return "error: foreign socket unspecified". If it's active and the foreign socket is specified, issue a SYN segment. An initial send sequence number (ISS) is selected, and the TCP receive buffer size is selected (if applicable). A SYN segment of the form <SEQ=ISS><CTL=SYN> is sent (this may include the buffer size option if applicable). Set SND.UNA to ISS, SND.NXT to ISS+1, SND.LBB to ISS+1, enter SYN-SENT state, and return ๐
If the caller doesn't have access to the local socket specified, return "error: connection illegal for this process". If there's no room to create a new connection, return "error: insufficient resources". ๐ฌ
LISTEN STATE SYN-SENT STATE SYN-RECEIVED STATE ESTABLISHED STATE FIN-WAIT-1 STATE FIN-WAIT-2 STATE TIME-WAIT STATE CLOSE-WAIT STATE CLOSING STATE
Return "error: connection already exists". Already in the club, bestie ๐
SEND Call
CLOSED STATE (i.e., TCB does not exist)
If the user should no have access to such a connection, then return "error: connection illegal for this process".
Otherwise, return "error: connection does not exist". ๐
LISTEN STATE
If the foreign socket is specified, change the connection from passive to active, select an ISS, and select the receive buffer size. Send a SYN segment, set SND.UNA to ISS, SND.NXT to ISS+1, and SND.LBB to ISS+1. Enter SYN-SENT state. Data associated with the SEND may be sent with the SYN segment, or queued for transmission after entering ESTABLISHED state. The urgent bit, if requested in the command, should be sent with the first data segment sent as a result of this command. If there's no room to queue the request, respond with "error: insufficient resources". If the foreign socket was not specified, return "error: foreign socket unspecified". ๐ท
SYN-SENT STATE
Queue it for processing after the connection is ESTABLISHED. Typically nothing can be sent yet anyway, because the send window hasn't been set by the other side yet ๐ซ If there's no space, return "error: insufficient resources".
SYN-RECEIVED STATE
Queue it for later processing after entering ESTABLISHED state. If there's no space to queue, respond with "error: insufficient resources". ๐๏ธ
ESTABLISHED STATE
Segmentize the buffer, then send it or queue it for output, with a piggybacked acknowledgment (acknowledgment value = RCV.NXT) riding along with the data ๐ If there's insufficient space to remember this buffer, simply return "error: insufficient resources".
If the remote buffer size is not one octet, and this is the end of a letter, do the following end-of-letter/buffer-size adjustment processing โจ
if EOL = 0 then
SND.NXT <- SEG.SEQ + SEG.LEN
if EOL = 1 then
While SND.LBB < SEG.SEQ + SEG.LEN
Do SND.LBB <- SND.LBB + SND.BS End
SND.NXT <- SND.LBB
If the urgent flag is set, then SND.UP <- SND.NXT-1, and set the urgent pointer in the outgoing segment ๐จ
FIN-WAIT-1 STATE FIN-WAIT-2 STATE TIME-WAIT STATE
Return "error: connection closing" and don't service the request. ๐ซ
CLOSE-WAIT STATE
Segmentize any text to be sent and queue it for output. If there's insufficient space to remember the SEND, return "error: insufficient resources" ๐ซ
CLOSING STATE
Respond with "error: connection closing" ๐ฅบ
RECEIVE Call
CLOSED STATE (i.e., TCB does not exist)
If the user should no have access to such a connection, return "error: connection illegal for this process".
Otherwise return "error: connection does not exist". ๐
LISTEN STATE SYN-SENT STATE SYN-RECEIVED STATE
Queue it for processing after entering ESTABLISHED state. If there's no room to queue this request, respond with "error: insufficient resources". ๐
ESTABLISHED STATE
If insufficient incoming segments are queued to satisfy the request, queue the request. If there's no queue space to remember the RECEIVE, respond with "error: insufficient resources". ๐ชฃ
Reassemble the queued incoming segments into the receive buffer and return to the user. Mark "end of letter" (EOL) if this is the case ๐ฌ
If RCV.UP is in advance of the data currently being passed to the user, notify the user of the presence of urgent data ๐ฉ
When the TCP takes responsibility for delivering data to the user, that fact must be communicated to the sender via an acknowledgment. The formation of such an acknowledgment is described below, in the discussion of processing an incoming segment ๐ค
FIN-WAIT-1 STATE FIN-WAIT-2 STATE
Reassemble and return a letter, or as much as will fit, in the user buffer. Queue the request if it can't be serviced immediately. ๐งบ
TIME-WAIT STATE CLOSE-WAIT STATE
Okay bestie, the other side already sent its FIN ๐, so any RECEIVE has to be served from text that's been put back together but hasn't reached the user yet. If there's no reassembled text waiting, the RECEIVE gets "error: connection closing" ๐. If there is some, use it to satisfy the RECEIVE. Slay ๐
CLOSING STATE
Return "error: connection closing" ๐
CLOSE Call
CLOSED STATE (i.e., TCB does not exist)
If the user isn't allowed to have access to this connection, return "error: connection illegal for this process". ๐ซ
Otherwise, return "error: connection does not exist". ๐ธ
LISTEN STATE
Any outstanding RECEIVEs should get "error: closing" responses. Then delete the TCB and return "ok" โจ
SYN-SENT STATE
Delete the TCB, and send "error: closing" responses to any queued SENDs or RECEIVEs. Gone, no cap ๐ฆ
SYN-RECEIVED STATE
Either queue this for processing after entering the ESTABLISHED state, or segmentize and send a FIN segment. If you go with the latter, enter FIN-WAIT-1 state. Main character decisions only ๐
ESTABLISHED STATE
Queue this until all the preceding SENDs have been segmentized. Then form a FIN segment and send it. Either way, enter FIN-WAIT-1 state. ๐ง
FIN-WAIT-1 STATE FIN-WAIT-2 STATE
Ngl, strictly speaking this is an error, and it should get a "error: connection closing" response. An "ok" response would also be acceptable, as long as a second FIN isn't emitted. (The first FIN is allowed to be retransmitted though ๐)
TIME-WAIT STATE
Strictly speaking this is also an error, and it should get "error: connection closing". An "ok" response would be acceptable too. However, the FIN has already been sent and acknowledged, so nothing should be sent or retransmitted. Quiet vibes only ๐คซ
CLOSE-WAIT STATE
Queue this request until all the preceding SENDs have been segmentized. Then send a FIN segment and enter CLOSING state. ๐
CLOSING STATE
Respond with "error: connection closing" ๐
ABORT Call
CLOSED STATE (i.e., TCB does not exist)
If the user isn't allowed to have access to this connection, return "error: connection illegal for this process".
Otherwise, return "error: connection does not exist".
LISTEN STATE
Any outstanding RECEIVEs should get "error: connection reset" responses. Then delete the TCB and return "ok". Bye bye ๐
SYN-SENT STATE
Delete the TCB, and return "reset" responses to any queued SENDs or RECEIVEs. ๐
SYN-RECEIVED STATE
Send a RST of this form:
<SEQ=SND.NXT><ACK=RCV.NXT><CTL=RST,ACK>
Then return any unprocessed SENDs or RECEIVEs with the "reset" code, and delete the TCB. ๐ซ
ESTABLISHED STATE
Send a reset segment:
<SEQ=SND.NXT><ACK=RCV.NXT><CTL=RST,ACK>
All queued SENDs and RECEIVEs should get "reset" responses. Every segment queued for transmission (except the RST formed above) or retransmission should be flushed. Then delete the TCB. Full chaos mode ๐ฅ
FIN-WAIT-1 STATE FIN-WAIT-2 STATE
A reset segment (RST) should be formed and sent:
<SEQ=SND.NXT><ACK=RCV.NXT><CTL=RST,ACK>
Outstanding SENDs, RECEIVEs, CLOSEs, and any segments queued for retransmission or segmentizing should be flushed, with a "connection reset" notification to the user. Then delete the TCB. ๐
TIME-WAIT STATE
Respond with "ok" and delete the TCB. Done and dusted โจ
CLOSE-WAIT STATE
Flush any pending SENDs and RECEIVEs, returning "connection reset" responses for them. Form and send a RST segment:
<SEQ=SND.NXT><ACK=RCV.NXT><CTL=RST,ACK>
Then flush all the segment queues and delete the TCB. ๐งน
CLOSING STATE
Respond with "ok" and delete the TCB. Flush any remaining segment queues too. If a CLOSE command is still pending, respond "error: connection reset". ๐
STATUS Call
CLOSED STATE (i.e., TCB does not exist)
If the user isn't allowed to have access to this connection, return "error: connection illegal for this process".
Otherwise, return "error: connection does not exist".
LISTEN STATE
Return "state = LISTEN", and the TCB pointer. ๐
SYN-SENT STATE
Return "state = SYN-SENT", and the TCB pointer.
SYN-RECEIVED STATE
Return "state = SYN-RECEIVED", and the TCB pointer.
ESTABLISHED STATE
Return "state = ESTABLISHED", and the TCB pointer. Literally the healthiest state ๐ซถ
FIN-WAIT-1 STATE
Return "state = FIN-WAIT-1", and the TCB pointer.
FIN-WAIT-2 STATE
Return "state = FIN-WAIT-2", and the TCB pointer.
TIME-WAIT STATE
Return "state = TIME-WAIT and the TCB pointer.
CLOSE-WAIT STATE
Return "state = CLOSE-WAIT", and the TCB pointer.
CLOSING STATE
Return "state = CLOSING", and the TCB pointer.
SEGMENT ARRIVES
If the state is CLOSED (i.e., TCB does not exist), then
All data in the incoming segment is discarded. An incoming segment containing a RST is discarded. An incoming segment that doesn't contain a RST causes a RST to be sent in response. The acknowledgment and sequence field values are picked so the reset sequence will be acceptable to the TCP that sent the offending segment. ๐ต๏ธ
If the ACK bit is off, sequence number zero is used:
<SEQ=0><ACK=SEG.SEQ+SEG.LEN><CTL=RST,ACK>
If the ACK bit is on:
<SEQ=SEG.ACK><CTL=RST>
Return. ๐ช
If the state is LISTEN, then
First, check for an ACK.
Any acknowledgment is bad if it arrives on a connection still in the LISTEN state. An acceptable reset segment should be formed for any arriving ACK-bearing segment, except another RST. The RST should be formatted like this:
<SEQ=SEG.ACK><CTL=RST>
Return.
An incoming RST should be ignored. Return. ๐
If there was no ACK, then check for a SYN.
If the SYN bit is set, check the security. If the security/compartment on the incoming segment doesn't exactly match the security/compartment in the TCB, send a reset and return. If SEG.PRC is less than TCB.PRC, send a reset and return. If SEG.PRC is greater than TCB.PRC, then set TCB.PRC<-SEG.PRC. Now RCV.NXT and RCV.LBB are set to SEG.SEQ+1, IRS is set to SEG.SEQ, and any other control or text should be queued for processing later. ISS should be selected and a SYN segment sent of this form:
<SEQ=ISS><ACK=RCV.NXT><CTL=SYN,ACK>
SND.NXT and SND.LBB are set to ISS+1, and SND.UNA is set to ISS. The connection state should change to SYN-RECEIVED. Note that any other incoming control or data (combined with SYN) will be processed in the SYN-RECEIVED state, but processing of SYN and ACK should not be repeated. If the listen wasn't fully specified (i.e., the foreign socket wasn't fully specified), then the unspecified fields should be filled in now. ๐
If there was no SYN but there was other text or control:
Any other control or text-bearing segment (one not containing SYN) must have an ACK, so it would be discarded by the ACK processing. An incoming RST segment couldn't be valid, since it couldn't have been sent in response to anything sent by this incarnation of the connection. So you're unlikely to get here, but if you do, drop the segment and return. ๐ฌ
If the state is SYN-SENT, then
First, check for an ACK.
If SEG.ACK =< ISS, or SEG.ACK > SND.NXT, or the security/compartment in the segment doesn't exactly match the security/compartment in the TCB, or the precedence in the segment is less than the precedence in the TCB, send a reset:
<SEQ=SEG.ACK><CTL=RST>
Then discard the segment and return. ๐ซ
If SND.UNA =< SEG.ACK =< SND.NXT, and the security/compartment and precedence are acceptable, then the ACK is acceptable. SND.UNA should be advanced to equal SEG.ACK, and any segments on the retransmission queue that are thereby acknowledged should be removed. โ
If the ACK is ok (or there is no ACK), check the RST bit.
If the RST bit is set, signal the user "error: connection reset", enter CLOSED state, drop the segment, delete the TCB, and return. ๐ฅ
If the ACK is ok (or there is no ACK) and it wasn't a RST, check the SYN bit.
If the SYN bit is on and the security/compartment and precedence are acceptable, then RCV.NXT and RCV.LBB are set to SEG.SEQ+1, and IRS is set to SEG.SEQ. If SND.UNA > ISS (our SYN has been ACKed), change the connection state to ESTABLISHED. Otherwise, enter SYN-RECEIVED. In any case, form an ACK segment:
<SEQ=SND.NXT><ACK=RCV.NXT><CTL=ACK>
and send it. Data or controls that were queued for transmission may be included. ๐ฌ
If SEG.PRC is greater than TCB.PRC, set TCB.PRC<-SEG.PRC.
If there are other controls or text in the segment, continue processing at the fifth step below, where the URG bit is checked. Otherwise, return. ๐งต
Otherwise,
First, check the sequence number.
SYN-RECEIVED STATE ESTABLISHED STATE FIN-WAIT-1 STATE FIN-WAIT-2 STATE TIME-WAIT STATE CLOSE-WAIT STATE CLOSING STATE
Segments are processed in sequence. Initial tests on arrival are used to discard old duplicates, but further processing is done in SEG.SEQ order. If a segment's contents straddle the boundary between old and new, only the new parts should be processed. ๐ชก
There are four cases for the acceptability test for an incoming segment:
Segment Receive Test
Length Window
------- ------- -------------------------------------------
0 0 SEG.SEQ = RCV.NXT
0 >0 RCV.NXT =< SEG.SEQ < RCV.NXT+RCV.WND
>0 0 not acceptable
>0 >0 RCV.NXT < SEG.SEQ+SEG.LEN =< RCV.NXT+RCV.WND
Note that the test above guarantees that the last sequence number used by the segment lies in the receive window. If RCV.WND is zero, no segments will be acceptable, but special allowance should be made to accept valid ACKs, URGs, and RSTs. ๐ท
If an incoming segment isn't acceptable, an acknowledgment should be sent in reply:
<SEQ=SND.NXT><ACK=RCV.NXT><CTL=ACK>
If the incoming segment is unacceptable, drop it and return. ๐ โโ๏ธ
Second, check security and precedence.
If the security/compartment and precedence in the segment don't exactly match the security/compartment and precedence in the TCB, form a reset and return.
Note this check is placed after the sequence check, to stop a segment from an old connection between these parts (with a different security or precedence) from aborting the current connection. Smart, right? ๐ง
Third, check the ACK field.
SYN-RECEIVED STATE
If the RST bit is off and SND.UNA < SEG.ACK =< SND.NXT, then set SND.UNA <- SEG.ACK, remove any acknowledged segments from the retransmission queue, and enter ESTABLISHED state. ๐
If the segment acknowledgment isn't acceptable, form a reset segment:
<SEQ=SEG.ACK><CTL=RST>
and send it, unless the incoming segment is an RST (or there's no ACK). In that case, discard it and return. ๐ซง
ESTABLISHED STATE
FIN-WAIT-1 STATE and FIN-WAIT-2 STATE: in addition to the processing for the ESTABLISHED state, if the retransmission queue is empty, the user's CLOSE can be acknowledged ("ok") but do not delete the TCB. ๐
TIME-WAIT STATE: the only thing that can arrive in this state is a retransmission of the remote FIN. Acknowledge it, and restart the 2 MSL timeout. โณ
CLOSE-WAIT STATE: do the same processing as for the ESTABLISHED state. ๐ฆ
CLOSING STATE: if the ACK acknowledges our FIN then delete the TCB (enter the CLOSED state), otherwise ignore the segment. ๐
fourth, check the RST bit,
SYN-RECEIVED STATE: if the RST bit is set then, if the segment has passed sequence and acknowledgment tests, it is valid. If this connection was initiated with a passive OPEN (i.e., came from the LISTEN state), then return this connection to LISTEN state. The user need not be informed. If this connection was initiated with an active OPEN (i.e., came from SYN-SENT state) then the connection was refused, signal the user "connection refused". In either case, all segments on the retransmission queue should be removed. ๐
ESTABLISHED, FIN-WAIT-1, FIN-WAIT-2, CLOSE-WAIT, CLOSING STATE: if the RST bit is set then, any outstanding RECEIVEs and SEND should receive "reset" responses. All segment queues should be flushed. Users should also receive an unsolicited general "connection reset" signal. Enter the CLOSED state, delete the TCB, and return. ๐
TIME-WAIT: enter the CLOSED state, delete the TCB, and return. ๐ธ
fifth, check the SYN bit,
SYN-RECEIVED, ESTABLISHED STATE: if the SYN bit is set, check the segment sequence number against the receive window. The segment sequence number must be in the receive window; if not, ignore the segment. If the SYN is on and SEG.SEQ = IRS then everything is ok and no action is needed; but if they are not equal, there is an error and a reset must be sent.
If a reset must be sent it is formed as follows:
<SEQ=SEG.ACK><CTL=RST>
The connection must be aborted as if a RST had been received. ๐จ
FIN-WAIT STATE-1, FIN-WAIT STATE-2, TIME-WAIT STATE, CLOSE-WAIT STATE, CLOSING STATE: this case should not occur, since a duplicate of the SYN which started the current connection incarnation will have been filtered in the SEG.SEQ processing. Other SYN's will have been rejected by this test as well (see SYN processing for ESTABLISHED state). ๐ง
sixth, check the URG bit,
ESTABLISHED STATE, FIN-WAIT-1 STATE, FIN-WAIT-2 STATE: if the URG bit is set, RCV.UP <- max(RCV.UP,SEG.UP), and signal the user that the remote side has urgent data if the urgent pointer (RCV.UP) is in advance of the data consumed. If the user has already been signaled (or is still in the "urgent mode") for this continuous sequence of urgent data, do not signal the user again. ๐ฃ
TIME-WAIT STATE, CLOSE-WAIT STATE, CLOSING: this should not occur, since a FIN has been received from the remote side. Ignore the URG. ๐
seventh, process the segment text,
ESTABLISHED STATE: once in the ESTABLISHED state, it is possible to deliver segment text to user RECEIVE buffers. Text from segments can be moved into buffers until either the buffer is full or the segment is empty. If the segment empties and carries an EOL flag, then the user is informed, when the buffer is returned, that an EOL has been received. โจ
If buffer size is not one octet, then do the following end-of-letter/buffer-size adjustment processing:
if EOL = 0 then
RCV.NXT <- SEG.SEQ + SEG.LEN
if EOL = 1 then
While RCV.LBB < SEG.SEQ+SEG.LEN
Do RCV.LBB <- RCV.LBB + RCV.BS End
RCV.NXT <- RCV.LBB
When the TCP takes responsibility for delivering the data to the user it must also acknowledge the receipt of the data. Send an acknowledgment of the form:
<SEQ=SND.NXT><ACK=RCV.NXT><CTL=ACK>
This acknowledgment should be piggybacked on a segment being transmitted if possible without incurring undue delay. ๐ซถ
FIN-WAIT-1 STATE, FIN-WAIT-2 STATE: if there are outstanding RECEIVEs, they should be satisfied, if possible, with the text of this segment; remaining text should be queued for further processing. If a RECEIVE is satisfied, the user should be notified, with "end-of-letter" (EOL) signal, if appropriate. ๐
TIME-WAIT STATE, CLOSE-WAIT STATE: this should not occur, since a FIN has been received from the remote side. Ignore the segment text. ๐
eighth, check the FIN bit,
Send an acknowledgment for the FIN. Signal the user "connection closing", and return any pending RECEIVEs with same message. Note that FIN implies EOL for any segment text not yet delivered to the user. If the current state is ESTABLISHED, enter the CLOSE-WAIT state. If the current state is FIN-WAIT-1, enter the CLOSING state. If the current state is FIN-WAIT-2, enter the TIME-WAIT state. ๐
and return.
USER TIMEOUT
For any state if the user timeout expires, flush all queues, signal the user "error: connection aborted due to user timeout" in general and for any outstanding calls, delete the TCB, and return. โฐ
RETRANSMISSION TIMEOUT
For any state if the retransmission timeout expires on a segment in the retransmission queue, send the segment at the front of the retransmission queue again, reinitialize the retransmission timer, and return. ๐
GLOSSARY ๐
1822 BBN Report 1822, "The Specification of the Interconnection of a Host and an IMP". The specification of interface between a host and the ARPANET.
ACK A control bit (acknowledge) occupying no sequence space, which indicates that the acknowledgment field of this segment specifies the next sequence number the sender of this segment is expecting to receive, hence acknowledging receipt of all previous sequence numbers. ๐
ARPANET message The unit of transmission between a host and an IMP in the ARPANET. The maximum size is about 1012 octets (8096 bits).
ARPANET packet A unit of transmission used internally in the ARPANET between IMPs. The maximum size is about 126 octets (1008 bits).
buffer size An option (buffer size) used to state the receive data buffer size of the sender of this option. May only be sent in a segment that also carries a SYN.
connection A logical communication path identified by a pair of sockets.
datagram A message sent in a packet switched computer communications network.
Destination Address The destination address, usually the network and host identifiers.
EOL A control bit (End of Letter) occupying no sequence space, indicating that this segment ends a logical letter with the last data octet in the segment. If this end of letter causes a less than full buffer to be released to the user and the connection buffer size is not one octet then the end-of-letter/buffer-size adjustment to the receive sequence number must be made. ๐
FIN A control bit (finis) occupying one sequence number, which indicates that the sender will send no more data or control occupying sequence space.
fragment A portion of a logical unit of data, in particular an internet fragment is a portion of an internet datagram.
FTP A file transfer protocol.
header Control information at the beginning of a message, segment, fragment, packet or block of data.
host A computer. In particular a source or destination of messages from the point of view of the communication network.
Identification An Internet Protocol field. This identifying value assigned by the sender aids in assembling the fragments of a datagram.
IMP The Interface Message Processor, the packet switch of the ARPANET.
internet address A source or destination address specific to the host level.
internet datagram The unit of data exchanged between an internet module and the higher level protocol together with the internet header.
internet fragment A portion of the data of an internet datagram with an internet header.
IP Internet Protocol.
IRS The Initial Receive Sequence number. The first sequence number used by the sender on a connection.
ISN The Initial Sequence Number. The first sequence number used on a connection, (either ISS or IRS). Selected on a clock based procedure.
ISS The Initial Send Sequence number. The first sequence number used by the sender on a connection.
leader Control information at the beginning of a message or block of data. In particular, in the ARPANET, the control information on an ARPANET message at the host-IMP interface.
left sequence This is the next sequence number to be acknowledged by the data receiving TCP (or the lowest currently unacknowledged sequence number) and is sometimes referred to as the left edge of the send window.
letter A logical unit of data, in particular the logical unit of data transmitted between processes via TCP.
local packet The unit of transmission within a local network.
module An implementation, usually in software, of a protocol or other procedure.
MSL Maximum Segment Lifetime, the time a TCP segment can exist in the internetwork system. Arbitrarily defined to be 2 minutes. โฑ๏ธ
octet An eight bit byte.
Options An Option field may contain several options, and each option may be several octets in length. The options are used primarily in testing situations; for example, to carry timestamps. Both the Internet Protocol and TCP provide for options fields. ๐
packet ๐ฆ okay so a packet is a package of data with a header, and that header may or may not be logically complete โจ It's more of a physical packaging than a logical packaging of data, bestie ๐
port ๐ช the portion of a socket that says which logical input or output channel of a process the data is tied to ๐
process ๐ง a program in execution! From the point of view of TCP or any other host-to-host protocol, it's the source or destination of data ๐
PSN ๐ฐ๏ธ a Packet Switched Network, like the ARPANET ๐
RCV.BS ๐ชฃ receive buffer size, which is the remote buffer size ๐
RCV.LBB ๐งบ receive last buffer beginning
RCV.NXT โญ๏ธ receive next sequence number
RCV.UP ๐จ receive urgent pointer
RCV.WND ๐ช receive window
receive last buffer beginning ๐งบ this is the sequence number of the first octet of the most recent buffer. The value is use in calculating the next sequence number when a segment contains an end of letter indication ๐
receive next sequence number โญ๏ธ this is the next sequence number the local TCP is expecting to receive. Literally waiting on it ๐ซถ
receive window ๐ช this represents the sequence numbers the local (receiving) TCP is willing to receive. So the local TCP considers segments overlapping the range RCV.NXT to RCV.NXT + RCV.WND - 1 to carry acceptable data or control โจ Segments with sequence numbers entirely outside this range are considered duplicates and get discarded ๐๏ธ not me discarding them, but the rules say so ๐
RST ๐ a control bit (reset), occupying no sequence space, that tells the receiver to delete the connection without any further interaction ๐ญ The receiver can figure out, based on the sequence number and acknowledgment fields of the incoming segment, whether it should honor the reset command or ignore it. In no case does receipt of a segment containing RST give rise to a RST in response. Periodt ๐
RTP ๐ต Real Time Protocol: a host-to-host protocol for communication of time critical information โฐ
Rubber EOL ๐งฝ an end of letter (EOL) that needs a sequence number adjustment so the beginning of the next letter lines up on a buffer boundary. Stretchy, iykyk ๐ธ
SEG.ACK โ
segment acknowledgment
SEG.LEN ๐ segment length
SEG.PRC ๐ segment precedence value
SEG.SEQ ๐ข segment sequence
SEG.UP ๐จ segment urgent pointer field
SEG.WND ๐ช segment window field
segment ๐ฐ a logical unit of data. A TCP segment is the unit of data transfered between a pair of TCP modules, so it's basically the main character of the transfer ๐
segment acknowledgment โ the sequence number in the acknowledgment field of the arriving segment
segment length ๐ the amount of sequence number space occupied by a segment, including any controls which occupy sequence space
segment sequence ๐ข the number in the sequence field of the arriving segment
send last buffer beginning ๐งบ this is the sequence number of the first octet of the most recent buffer. This value is used in calculating the next sequence number when a segment contains an end of letter indication ๐
send sequence ๐ค this is the next sequence number the local (sending) TCP will use on the connection. It's initially selected from an initial sequence number curve (ISN) and gets incremented for each octet of data or sequenced control transmitted ๐ฆ
send window ๐ช this represents the sequence numbers which the remote (receiving) TCP is willing to receive. It's the value of the window field specified in segments from the remote (data receiving) TCP. The range of sequence numbers that a TCP may emit lies between SND.NXT and SND.UNA + SND.WND - 1 ๐
SND.BS ๐ชฃ send buffer size, the local buffer size
SND.LBB ๐งบ send last buffer beginning
SND.NXT โญ๏ธ send sequence
SND.UNA ๐ซง left sequence
SND.UP ๐จ send urgent pointer
SND.WL ๐ฐ๏ธ send sequence number at last window update
SND.WND ๐ช send window
socket ๐ an address that specifically includes a port identifier, meaning the concatenation of an Internet Address with a TCP port ๐
Source Address ๐ the source address, usually the network and host identifiers
SYN ๐ฌ a control bit in the incoming segment, occupying one sequence number, used at the initiation of a connection to indicate where the sequence numbering will start. Every story has a beginning ๐ฅน
TCB ๐๏ธ Transmission control block, the data structure that records the state of a connection ๐
TCB.PRC ๐ the precedence of the connection
TCP ๐ Transmission Control Protocol: a host-to-host protocol for reliable communication in internetwork environments. The most reliable friend in the group chat ๐ซถ
TOS ๐ Type of Service, an Internet Protocol field
Type of Service ๐ an Internet Protocol field which indicates the type of service for this internet fragment
URG ๐ฃ a control bit (urgent), occupying no sequence space, used to indicate that the receiving user should be notified to do urgent processing as long as there is data to be consumed with sequence numbers less than the value indicated in the urgent pointer ๐จ bestie, this one is a whole vibe
urgent pointer ๐ a control field meaningful only when the URG bit is on. It communicates the value of the urgent pointer, which indicates the data octet associated with the sending user's urgent call ๐
References ๐
[1] Cerf, V., and R. Kahn, "A Protocol for Packet Network Intercommunication," IEEE Transactions on Communications, Vol. COM-22, No. 5, pp 637-648, May 1974. ๐ง
[2] Postel, J. (ed.), "DOD Standard Internet Protocol," Defense Advanced Research Projects Agency, Information Processing Techniques Office, RFC 760, IEN 128, January 1980. ๐
[3] Feinler, E. and J. Postel, ARPANET Protocol Handbook, Network Information Center, SRI International, Menlo Park, CA, January 1978. ๐
[4] Dalal, Y. and C. Sunshine, "Connection Management in Transport Protocols," Computer Networks, Vol. 2, No. 6, pp. 454-473, December 1978. ๐ซ
๐ฆ where this page comes from
- ietf: rfc761 1980-01
- ๐ girlified by claude-haiku-5-5 on : a language model's rewrite of the original, under its terms