§3.5.1–3.5.2The TCP Connection · TCP Segment Structure

Transport layer Kurose & Ross pp. 227–234 · ~19 min read

  • transmission control protocol
  • three-way handshake
  • send buffer
  • receive buffer
  • maximum segment size
  • maximum transmission unit
  • acknowledgement number
  • piggybacking
  • out-of-order segment

Where you are

  • Application layer
  • Transport layer you are here
  • Network layer
  • Link layer
  • Physical layer

A TCP connection is two buffers and a handful of variables at each end. Its sequence numbers count bytes rather than packets, and that single fact is what makes the rest of TCP readable.

Words you will meet

  • Full-duplex — data flows both ways at once on one connection.
  • MTU — the largest frame a link will carry, typically 1,500 bytes.
  • MSS — the largest amount of application data in one segment, typically 1,460 bytes.
  • Sequence number — the byte-stream number of the first byte in this segment.
  • Acknowledgement number — the number of the next byte this host expects.
  • Piggybacking — carrying an acknowledgement inside a segment that already had data to send.

Why this matters

Section 3.4 built a toolkit and asked what you would build. This section starts on what was actually built.

TCP (Transmission Control Protocol) is defined in RFC (Request For Comments) 793 and refined by RFC 1122, RFC 2018, RFC 5681 and RFC 7323. It uses almost everything section 3.4 developed — error detection, retransmission, cumulative acknowledgements, timers, and header fields for sequence and acknowledgement numbers.

Get the numbering right here and the next four sections follow easily. Get it wrong and none of them will make sense.

What a connection is, and is not

TCP is connection-oriented: before one process can send data to another, the two must handshake — exchange preliminary segments that establish the parameters of the transfer. Both sides initialise a good many state variables in the process.

It is not a circuit

The “connection” is logical. Its common state resides only in the two end systems.

Recall from section 3.1 that TCP runs only in end systems, never in routers or link-layer switches. So the intermediate elements do not maintain TCP connection state at all — in the book’s phrase, they see datagrams, not connections.

That is the difference from the circuit switching of section 1.3.2, where the network itself reserved capacity and remembered who it belonged to. Nothing is reserved for a TCP connection. Its segments queue at routers exactly like everyone else’s.

Three more properties follow. A TCP connection provides full-duplex service. If there is a connection between process A and process B, data can flow from A to B at the same time as data flows from B to A. It is always point-to-point, between a single sender and a single receiver — multicasting is not possible. As the book puts it, with TCP two hosts are company and three are a crowd.

From socket to segment

Once the connection is established, the client process passes a stream of bytes through the socket. From that moment the data is in TCP’s hands.

Figure 3.28 — what a connection actually is
1 — The application writes into a socketstep 1 of 6
a TCP connection, drawn honestlysending hostreceiving hostsocket

The client process passes a stream of bytes through the socket — the door of section 2.1.2. Once through, the data belongs to TCP.

Two buffers and some variables at each end, and nothing anywhere else. Step through what happens to one file.

Read all steps as text
  1. 1 — The application writes into a socketThe client process passes a stream of bytes through the socket — the door of section 2.1.2. Once through, the data belongs to TCP.
  2. 2 — TCP puts it in the send bufferThe send buffer is one of the buffers set aside during the three-way handshake. It exists before any data is sent.
  3. 3 — TCP decides when to send, and how muchFrom time to time TCP grabs a chunk from the buffer and hands it down. RFC 793 is famously relaxed about the timing: TCP should "send that data in segments at its own convenience". The chunk is at most one MSS.
  4. 4 — And again, and againA large file becomes a run of full-MSS segments, with only the last one short. Lin’s 372 kB page is 255 segments of 1,460 bytes.
  5. 5 — The receive buffer holds it until the application readsArriving data is placed in the receive buffer. The application reads from there — not necessarily at the moment the data arrives, which is exactly the gap flow control exists to manage.
  6. 6 — Each side has bothTCP is full-duplex, so every connection has a send buffer and a receive buffer at each end, plus variables. That set of buffers and variables IS the connection — no router holds any part of it.

The MSS, and the terminology the book apologises for

The maximum segment size is the largest chunk TCP will take from the send buffer for one segment.

TCP takes those chunks from the send buffer , and the data arriving at the far end lands in a receive buffer until the application reads it.

The MSS is derived from the link below. First find the maximum transmission unit — the largest link-layer frame the sending host can emit. Then set the MSS so that the segment plus its TCP and IP (Internet Protocol) headers, typically 40 bytes, still fits in one frame. Ethernet and PPP (Point-to-Point Protocol) both use a 1,500-byte MTU, so a typical MSS is 1,460 bytes.

Now the warning. The MSS is the maximum amount of application-layer data in the segment, not the maximum size of the segment including headers. The book calls this terminology confusing, notes that we have to live with it because it is well entrenched, and moves on. So will we — but read the name as maximum segment payload in your head.

The segment size therefore comes from the link, not from TCP:

MSS=MTU(TCP header+IP header)MSS = MTU - (\text{TCP header} + \text{IP header})

The maximum segment size

What each symbol means

  • MTUthe largest frame this link will carry (bytes)
  • MSSthe largest amount of application data in one segment (bytes)

Read aloud: Take the biggest frame the link allows, and leave room for the two headers. What is left is how much of the application’s data can travel in one segment.

Maximum segment size1,460 bytes of application data

the largest frame this link will carry is the MTU = 1,500 bytes
a segment must leave room for its TCP and IP headers = 40 bytes
MSS = 1,500 − 40 = 1,460 bytes
so 97.3 % of each frame is the application's data
note: the MSS bounds the DATA, not the whole segment — the segment is 1,500 bytes

Change any number above and the arithmetic re-runs, carrying the units through.

The defaults are Ethernet and PPP, which both use a 1,500-byte MTU. Read the last line of the working — it is the piece of terminology the book warns you about.

There are also methods for discovering the path MTU, the largest frame that can cross every link from source to destination. The MSS can then be set from that instead [RFC 1191].

The segment

Figure 3.29 — the TCP segment
08162432bitSource port #16 bitsDest port #16 bitsSequence number32 bitsAcknowledgment number32 bitsHeader length4 bitsUnused4 bitsCWRECEURGACKPSHRSTSYNFINReceive window16 bitsInternet checksum16 bitsUrgent data pointer16 bitsOptionsvariable number of resource recordsusually emptyDatavariable number of resource recordsat most one MSS

Click any box to read what that part of the message is for.

Every field, as text
  • Source port # — 16 bits — part of the four-tuple (example: 49153)
  • Dest port # — 16 bits — part of the four-tuple (example: 80)
  • Sequence number — 32 bits — the byte-stream number of the first byte of data here (example: 3841271296)
  • Acknowledgment number — 32 bits — the next byte this host expects to receive (example: 2264810497)
  • Header length — 4 bits — header size in 32-bit words (example: 5)
  • Unused — 4 bits — reserved
  • CWR — 1 bits — Congestion Window Reduced
  • ECE — 1 bits — ECN Echo
  • URG — 1 bits — urgent data present
  • ACK — 1 bits — the acknowledgment number is valid
  • PSH — 1 bits — pass this up immediately
  • RST — 1 bits — reset the connection
  • SYN — 1 bits — connection setup
  • FIN — 1 bits — no more data from me
  • Receive window — 16 bits — how many bytes the receiver can still accept (example: 65535)
  • Internet checksum — 16 bits — did any bit change?
  • Urgent data pointer — 16 bits — where the urgent data ends

Twenty bytes when the options are empty, which is usual. Click any field. The eight flag bits are drawn vertically, exactly as the book draws them.

Two of the flag names are used constantly from here on. SYN (synchronize) is set on the segments that open a connection; FIN (finish) is set on the segments that close it. Both belong to section 3.5.6.

The book says six flag bits. The figure has eight.

The text of this section states that “the flag field contains 6 bits”, and then describes eight flags: CWR, ECE, URG, ACK, PSH, RST, SYN and FIN. Figure 3.29 draws all eight, and the arithmetic only works with eight — 4 bits of header length, 4 unused, 8 flags and a 16-bit receive window make exactly 32.

Six is the original count from RFC 793: URG, ACK, PSH, RST, SYN, FIN. CWR and ECE were added later, by RFC 3168, for the explicit congestion notification of section 3.7.2, taking two of the six reserved bits and leaving four. The sentence is a leftover; the figure is current. Follow the figure.

In plain words

Twenty bytes of header, of which the two sequence-number fields take eight.

For a large file that overhead is trivial — 20 bytes on 1,460 is under 1.4 %. For an interactive application it is not. A Telnet or ssh segment often carries one byte of data, making the whole segment 21 bytes: 95 % header.

Sequence numbers count bytes

This is the fact to hold on to.

TCP views data as an unstructured but ordered stream of bytes, and its sequence numbers are over that stream — not over the series of transmitted segments. So:

The sequence number for a segment is the byte-stream number of the first byte in the segment.

Take a 500,000-byte file with an MSS of 1,000 bytes, numbering the first byte 0. TCP constructs 500 segments. The first is given sequence number 0, the second 1,000, the third 2,000, and so on. The sequence number is not a count of segments; it is a position in the file.

Acknowledgement numbers are trickier

TCP is full-duplex, so host A may be receiving from B while sending to B. Each segment arriving from B has a sequence number for the B-to-A stream.

The acknowledgement number that A puts in its segment is the sequence number of the next byte A is expecting from B.

Two examples, both the book’s.

Simple. A has received bytes 0 through 535 from B. It is waiting for byte 536, so it puts 536 in the acknowledgement field.

Not simple. A has received bytes 0–535 and bytes 900–1000, but not 536–899. A is still waiting for byte 536, so its next segment to B again carries 536. The 101 bytes it is already holding go entirely unmentioned — there is no field in which to mention them.

Because TCP only acknowledges bytes up to the first missing byte, TCP is said to provide cumulative acknowledgements.

What happens to those out-of-order bytes?

In that second example A received the third segment before the second. So what does a host do with an out-of-order segment ?

The TCP RFCs do not say. The decision is left to whoever implements TCP, and there are two choices:

  1. Discard it immediately — which, as section 3.4.3 showed, simplifies the receiver considerably.
  2. Keep the out-of-order bytes and wait for the missing ones to fill the gap.

The second is more efficient in terms of network capacity, and is the approach taken in practice. Remember that when section 3.5.4 asks whether TCP is Go-Back-N or selective repeat — its acknowledgements say one thing and its buffering says another.

Where the numbering starts

The examples above assumed the first byte is numbered 0. In truth, both sides of a connection randomly choose an initial sequence number.

The reason is a hazard section 3.4.4 already met. A segment from an earlier, already-terminated connection between the same two hosts — using the same port numbers — may still be wandering in the network. Random starting numbers make it very unlikely that such a segment looks valid in the new connection [Sunshine 1978].

And the sequence-number space is finite, so at a high enough rate it wraps:

Twrap=232×8RT_{wrap} = \frac{2^{32} \times 8}{R}

How long until the sequence numbers repeat?

What each symbol means

  • 2³²distinct byte numbers a 32-bit field can hold (bytes)
  • Rthe rate the connection actually achieves (bits/s)

Read aloud: How long can this connection run before it starts reusing byte numbers it has used before?

Time to wrap344 s

a 32-bit field counts 4,294,967,296 distinct byte numbers
that is 3.436e+10 bits of data before the numbering repeats
at 100 Mbps the space wraps in 344 s
a packet is assumed to survive at most 180 s in the network
344 s > 180 s — an old copy is dead before its number comes round again

Change any number above and the arithmetic re-runs, carrying the units through.

Section 3.4.4 needed old copies to be dead before a number is reused, and assumed a three-minute packet lifetime. Try 1 Gbps, then 10 Gbps.

Random starting points do not fix a long connection

Randomising the start protects a new connection from an old one. It does nothing for a single connection that runs long enough to reuse its own numbers.

Try the calculator at 1 Gbps: 32 bits of byte numbering wraps in about 34 seconds — well inside the three-minute packet lifetime section 3.4.4 assumed. At 10 Gbps it is 3.4 seconds. Only at 100 Mbps and below is there real headroom, at 344 seconds.

This is what the timestamp option in RFC 7323 is for. It lets a receiver tell a wrapped sequence number from a stale one, using a field the header did not originally have.

Telnet, as a case study in numbering

Telnet, defined in RFC 854, is an interactive remote-login protocol over TCP. It is worth a look because it makes the numbering visible. (In practice ssh has replaced it, because Telnet sends everything — passwords included — unencrypted; section 8.7 covers the consequences.)

Every character the user types is sent to the remote host, which echoes a copy back so it can be displayed. Each character therefore crosses the network twice between the keystroke and the letter appearing on screen.

Figure 3.31 — one character, three segments
message 3 of 3
Host Athe client — starts at 42TimeHost Bthe server — starts at 79Timeuser types Cecho back, so the user can see itSeq=42, ACK=79, data = ‘C’Seq=79, ACK=43, data = ‘C’Seq=43, ACK=80, no data

Click any arrow to see what that message says and why it is sent.

The user types C. Follow the numbers: every acknowledgement is one past the last byte received. Click each arrow.

Read this diagram as text
  1. Host A sends Seq=42, ACK=79, data = ‘C’ to Host B. The client’s first segment carries sequence number 42 — the byte-stream number of the single byte it contains. It has received nothing yet, so its acknowledgement number is 79: the first byte it expects from the server.
  2. Host B sends Seq=79, ACK=43, data = ‘C’ to Host A. This segment does two jobs at once. It acknowledges the client’s byte 42 by putting 43 in the acknowledgement field — the next byte it expects. And it echoes the character back, which is what Telnet does so the user can see what they typed. The acknowledgement rides along on a data segment: it is piggybacked.
  3. Host A sends Seq=43, ACK=80, no data to Host B. Purely an acknowledgement of the echoed character: 80 means "I have byte 79, send me 80 next". Its data field is empty, and there was no data of its own to piggyback on. It still carries a sequence number, 43, simply because the field exists and must hold something.

Lifelines, left to right: Host A (host), Host B (server).

In plain words

Three segments for one letter, and the numbers tell the whole story:

  • 42 → 43. The client’s byte is number 42, so the server asks for 43 next.
  • 79 → 80. The server’s echoed byte is number 79, so the client asks for 80.
  • The middle segment does two jobs at once — echoing the character and acknowledging the original. That is piggybacking , and it is free, because every segment has an acknowledgement field whether it uses it or not.

The third segment has nothing to piggyback on, so it travels almost empty: 20 bytes of header to carry the number 80.

Case history — Cerf, Kahn and TCP/IP (Transmission Control Protocol / Internet Protocol)

In the early 1970s packet-switched networks were proliferating, the ARPAnet among many, and each had its own protocol. Vinton Cerf and Robert Kahn saw the importance of interconnecting them, and invented a cross-network protocol called TCP/IP. They published it in May 1974 in IEEE (Institute of Electrical and Electronics Engineers) Transactions on Communications Technology [Cerf 1974].

They began by seeing it as a single entity. It was later split into its two parts, TCP and IP, operating separately — which is the division this whole book is organised around.

The design predates personal computers, smartphones, Ethernet, DSL (Digital Subscriber Line) , WiFi (IEEE 802.11 wireless LAN) , the Web and streaming video. Cerf and Kahn wanted a protocol that would support applications not yet imagined and let arbitrary hosts and link technologies interoperate. In 2004 they received the ACM’s Turing Award for it.

Check yourself

Check yourself

0 of 6 answered
  1. 1.A TCP connection is established between Bangkok and Frankfurt, crossing eleven routers. Where does the connection actually exist?

  2. 2.predictSet the MSS calculator to an MTU of 1,500 bytes and 40 bytes of header. What does 1,460 describe?

    Read the last line of the working.

  3. 3.Host A has received bytes 0 through 535 from B, and also bytes 900 through 1000. Bytes 536 to 899 are missing. What acknowledgement number does A send?

  4. 4.predictIn the Telnet exchange the user types one character. Why does the third segment have a sequence number when it carries no data?

  5. 5.predictSet the wrap calculator to 32 bits and 1 Gbps. Is the sequence space large enough?

    Compare it with the three-minute maximum packet lifetime from section 3.4.4.

  6. 6.What does a TCP receiver do with a segment that arrives out of order?

What to remember

  • A TCP connection is buffers and variables in the two end systems. Routers hold nothing about it — it is logical, not a circuit.
  • The MSS is derived from the link’s MTU: 1,500 − 40 = 1,460 bytes. It bounds the data, not the segment.
  • Sequence numbers count bytes, not packets. The acknowledgement number is the next byte expected, one past the last byte received in order, and that is what makes acknowledgements cumulative.