Overview
- Sliding Window for Flow Control
- Bandwidth-Delay product
- TCP streams and push
- TCP header
- tcpdump
TCP data transfer example
- A to B: seq 1, ack 1000000, window 100, 200 bytes of data
- A to B: seq 501, ack 1000000, window 100, 800 bytes of data
- B to A: seq 1000000, ack 201, window 1000, 0 bytes of data
- A to B: seq 1001, ack 1000000, window 100, 200 bytes of data
Zero windows
- suppose the window size is reduced to zero: receiver acks, and
says it has a window size of zero, since all buffers are full
- later the receiver reopens the window by sending a new ack with
a new window
- that ack is lost!
- deadlock: sender is waiting for window update, receiver is waiting
for new data
- a sender with data to send, and a zero send window, must periodically
send one byte past the window, to elicit an ack in response
Silly Window Syndrome
- receiver will move right edge of window by a small amount when
it receives a small amount of data
- if sender is window-limited, it will then send a small segment
- solution:
- receiver must move right edge of window in increments of at
least 1 MSS or 1/2 the actual window, whichever is less
- sender increment its send window in increments of at
least 1 MSS or 1/2 the estimated receiver's window, whichever is less
- sender needs a timer to send in case the estimate for the receiver's
window is wrong (the receiver's window got smaller)
Nagle Algorithm and sender SWS
- usable window is the number of bytes I could send given the
ack, window, and the next sequence number to send:
U = ack + wnd - nxt
- D is the amount of data I am ready to send
- send if I can send an MSS or 1/2 the receive buffer:
min(D, U) >= MSS or min(D, U) >= rcvbuff / 2
- send if I can send everything, and no acks are pending:
nxt = ack and D <= U
- or send if the override timeout occurs
- why not send if I could send everything but acks are pending?
(i.e. if D < MSS and nxt != ack?)
TCP delayed acks
- a receiver does not know when the sender is going to send the
next segment
- for fastest performance, a receiver should ack every segment
- in a two-way stream an ack is piggybacked on every data segment
going in the other direction
- typically, in a one-way stream TCPs should send one ack packet for
every two full-size segments
- a timer on the receiver should send an ACK for the latest data
if it has not been acked within about 20ms.
Bandwidth-Delay Product
- How big do I make the window?
- Suppose I have a small buffer of size s = 512,
I could set the window to s
- if I can send 100,000 bytes/second, and the round-trip delay is
10 ms, I can only send 512 bytes 100 times per second, or at
most 51,200 bytes/second
- if I set my window to the bandwidth-delay product, s = 1,000, I
can send at full speed
- this affects high-bandwidth applications (gigabit ethernet, microwave)
and high-latency applications (especially satellites)
TCP Streams and push
- TCP actually has a segmentation bit: PSH, or push
- when the application "pushes" the data, that information could be
conveyed all the way to the application at the other end
- if TCP can coalesce several user segments (each with PSH) into one
TCP segment, that TCP segment can only carry one PSH bit
- so passing PSH to the application is optional, and TCP has
no record boundaries
- so push is an advisory bit only: it encourages TCP (and the
application) to assume that the data must be sent (and presumably
replied to) before more data will be sent
TCP header
\tiny
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|P|R|S|F| |
| Offset| Reserved |R|C|S|S|Y|I| Window |
| | |G|K|H|T|N|N| |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Checksum | Urgent Pointer |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Options | Padding |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| data |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
TCP Header Format
TCP Header fields
- Source and Destination port: demultiplexing
- Sequence and acknowledgement: reliable delivery
- Data Offset: header size, options
- Window: flow control
- Checksum: correctness
- Urgent Pointer: "special place" in the data stream
TCP Header bits
- SYN: I want to establish a connection
- FIN: I will never again send data on this connection
- RST: kill this connection
- PSH: immediate delivery of this data is probably a good idea
- URG: the urgent pointer is valid
- ACK: the acknowledgement field is valid (set in all but the
first SYN packet)
tcpdump
- tcpdump is a utility to look at all the packets on the network
and print out the headers
- usually run as root
16:41:58.905998 maru.ics.hawaii.edu.14407 >
volcano.telnet: S 2671654129:2671654129(0)
win 512 [tos 0x10]
16:41:59.115893 volcano.telnet >
maru.ics.hawaii.edu.14407: R 0:0(0)
ack 2671654130 win 0
tcpdump example
16:47:02.285753 maru.1022 > volcano.ssh:
S 185741093:185741093(0) win 512
16:47:02.495648 volcano.ssh > maru.1022:
S 3829593384:3829593384(0)
ack 185741094 win 16352
16:47:02.495648 maru.1022 > volcano.ssh:
. ack 1 win 32120 (DF)
16:47:07.183328 volcano.ssh > maru.1022:
P 1:16(15) ack 1 win 16352 (DF)
16:47:07.183328 maru.1022 > volcano.ssh:
P 1:16(15) ack 16 win 32120 (DF) [tos 0x10]
16:47:07.433203 volcano.ssh > maru.1022:
P 16:292(276) ack 16 win 16352 (DF)
16:47:08.502673 volcano.ssh > maru.1022:
P 16:292(276) ack 16 win 16352 (DF)
16:47:08.522663 maru.1022 > volcano.ssh:
. ack 292 win 32120 (DF) [tos 0x10]