CNATDA 第三章学习笔记

Computer Networking: A Top-Down Approach (8th Edition)第三章 Transport Layer 的学习笔记

Introduction and Transport-Layer Services

transport layer 将 application-layer message 封装于 transport-layer segment然后交给 network layer 进行传输将 network layer 提供的 host-to-host logical communication 扩展为了 process-to-process (application-to-application) logical communication

Internet 的 network-layer protocol 是 Internet Protocol (IP)IP 提供的是 best-effort delivery service就是说它会尽力但并不保证 datagram 能成功传输也不保证传输到的顺序以及数据的完整性正确性

UDP 仅提供 process-to-process delivery 和 error checking同样是一个 unreliable serviceTCP 在 UDP 的基础上还提供 reliable data transfer 和 congestion control

Multiplexing and Demultiplexing

multiplexing 指的是将多个信道的信息合并到一个信道进行传输demultiplexing 指的是将这个合并后的信息再拆分到多个信道去

一般来说一个 host 会有很多 application 从而有很多 socket但只有一个 transport layer 以及一个 network layer

  • 在发送方transport layer 从多个 socket 收集 message 并发送给 network layer 的过程被称作 multiplexing
  • 在接收方transport layer 从 network layer 接收到 message 后传递给正确的 socket 的过程被称作 demultiplexing

multiplexing 以及 demultiplexing 需要每个 socket 有 unique identifier

  • 在 UDP 中只以 port 作为 socket identifier
  • 在 TCP 中以 destination port 和 source IP 作为 socket identifier

Connectionless Transport: UDP

UDP 仅提供 multiplexing and demultiplexing 以及 error checking但在一些 application 中它比 TCP 更加适合主要因为下列原因

  • 更好地控制何时发送数据发送什么数据TCP 有 congestion control可能会延迟发送的时间在传输失败时会重新发送可能耗时很久才传输成功
  • 无需建立连接建立 TCP connection 会产生 delay
  • 无连接状态保存 TCP connection state 需要占用系统资源
  • small header overheadTCP segment header 有 20 byte 的 overheadUDP 只有 8 byte

一些使用 UDP 的例子

  • DNS 使用 UDP 来避免建立 TCP 连接的 delay
  • 在 HTTP/3 中使用基于 UDP 的 application-layer protocol QUIC 来提供 reliable data transfer 并避免建立 TCP 连接的 delay
  • 在 network management (SNMP) 中使用 UDP 以在网络非常拥堵时发送消息
  • 在 multimedia application 尤其是即时通话中经常会使用 UDP因为对延时敏感而 loss-tolerant

但是尤其是传输 multimedia 时在没有 congestion control 的情况下传输大量数据可能导致网络拥堵进而导致 UDP 大量丢包而 TCP 传输缓慢

UDP datagram 的结构为

  • source port (16 bits)
  • destination port (16 bits)
  • length (16 bits): 整个 datagram包含 header 和 data的 byte 数
  • checksum (16 bits)将 UDP datagram 以及 IP header 的一些 field 以 16 bits 为单位视作 ones complement integer 加在一起即在进位时加 1最后取反即按位取反校验时只需检查 sum 是否全 1
  • application data (message)

UDP 的 checksum 只能用来进行 error detecting不能用来进行 error correcting错误时可以直接扔掉或者通知 application

虽然在很多 link-layer protocol 中也有 error checking但并不能保证一路上所有 link 都有 error checking并且error 可能不是在 link-to-link 的传输过程中产生的例如可能是存储在 router 中时产生的所以UDP 要提供 checksum这也是体现了 end-to-end principle 的一个例子

Principles of Reliable Data Transfer

Stop-And-Wait

在 stop-and-wait protocol 中sender 每次确认 receiver 收到了 packet 才会发下一个 packet

  1. checksum: 传输过程中可能出错需要进行 error detection
  2. acknowledgment (ACK):
    • 需要告诉 sender 没有丢包
    • 收到 packet 时需要告诉 sender 是否出错
  3. retransmission: 未收到 ACK 或收到 negative acknowledgment (NAK) 时需要重新传输
  4. sequence number: retransmission 可能是因为 ACK 的传输出了问题这会导致 duplicate packetsequence number 的作用之一是识别 duplicate packet在 stop-and-wait protocol 中用 0/1 作为 sequence number 即可这也被称作 alternating-bit protocol
  5. timeout: 丢包需要通过超时来检测超时了就 retransmit如果等待太久性能会受影响所以 timeout 一般被设为较有可能是丢包的值而非几乎能确定是丢包的值
  6. ACK with sequence number: 通过超时检测丢包可能带来 duplicate packetACK 传输出错或用时过长需要通过在 ACK 中加入 sequence number 来标识 acknowledge 的是哪个 packet以此也可以通过上一个 packet 的 ACK 代替表示当前 packet 出错的 NAK

Pipelined Reliable Data Transfer

stop-and-wait 虽然 work但每次都要等上一个 packet 成功传输才能传下一个性能太差

同时传输多个 packet 被称作 pipelining这意味着

  • sequence number 需要更大的值域不止是 1 bit 的 0/1至少正在传输的这些 packet 需要互不相同的 sequence number
  • sender 需要 buffer 以支持多个 packet 的 retransmissionreceiver 也可能需要 buffer

有两种基础的实现方法go-back-n (GBN) 和 selective repeat (SR)

Go-Back-N

receiver: 只接受按正确顺序依次收到的 packet顺序错误的 packet 直接扔掉顺序正确但有 error 的 packet 通过发送上一个 packet 的 ACK 进行 negative acknowledgment

sender:

  • 有一个 sliding window 表示当前有效的 sequence number 范围
  • window 内前一半已发送尚未收到 ACK后一半 sequence number 尚未使用
  • 如果 window 内所有 sequence number 均已被使用将不能发送新的 packet
  • 收到的 ACK 被视作 cumulative acknowledgment即在这个 ACK 的 sequence number 之前的 packet 也被视作已 ACK
  • 收到 ACK 时将 window 滑动到这个 ACK 之后
  • 所有未 ACK 的 packet 共用一个 timer
  • retransmit 时发送 window 内所有尚未 ACK 的 packet

GBN 的好处是 receiver 不需要 buffer坏处是一个 packet 出错就要把整个 window 内的 packet 重新发送

Selective Repeat

sender:

  • sliding window 与 GBN 类似但前一半中除了开头如果有一定未 ACK后面的可能已 ACK 也可能没有
  • ACKtimerretransmission 都是每个 packet 独立的
  • 收到 window 开头的 ACK 时滑动到首个未 ACK 处如果均已 ACK 则是未使用处

receiver:

  • 也需要维护一个 sliding window但这个 window 和 sender 的不保证一致其开头是尚未收到的最小的 sequence number
  • 收到非 window 开头的 packet 时需要 buffer 下来
  • 收到 window 开头的 packet 时将已 buffer 的 packet 连续段按顺序传给 application并滑动 window
  • 收到 window 开头减去 window 大小到 window 开头减一这个范围内的 packet 时这表示之前对这个 packet 的 ACK 的传输出了问题或者耗时过长也需要 ACK
  • 无论收到的是哪个 packet如果有 error 则直接不管因为 ACK 对每个 packet 独立不能通过设置 ACK 的 sequence number 来表示 negative acknowledgment也可以选择引入 NAK若不引入则只能不管

需要注意的是由于 sender 和 receiver 的 window 可能不同window 大小不能超过 sequence number 值域的一半

最后无论是 GBN 还是 SR因为 sequence number 的值域有限循环使用如果一个 duplicate packet (duplicate ACK) 的传输耗时太久可能会占用重复的 sequence number在实践中采取的解决方法一般是在一个 packet 传输了几分钟后便认为它已经没了

Connection-Oriented Transport: TCP

The TCP Connection

TCP connection 在两个 end system 中都建立了一些 state variable但它只是 logical connection并没有在 network core 中建立 circuit与 circuit-switched network 不同

TCP connection 是 full-duplex 的即建立连接后双方都可以向对方发送信息是 point-to-point 的即不能 multicasting

TCP connection 是通过 three-way handshake 建立的通过 TCP 发送 message 时会先放入 send buffer接收到 message 时会先放入 receive buffer

TCP 会根据 maximum transmission unit (MTUlink-layer frame 的最大 size) 计算出合适的 maximum segment size (MSSsegment 包含的 data (application message) 的最大 size) 使得 data 加上 TCP header 和 IP header 后不超过 MTU

TCP Segment Structure

TCP segment 的结构如下图所示1

TCP segment structure

其中 options 是可选且可变长的所以 TCP header 是可变长的但一般是 20 byte

各项的含义部分见下文

Sequence Numbers and Acknowledgment Numbers

TCP 将发送的所有 message 连在一起视作一个无结构但有序的 byte streamsegment 的 sequence number 表示的是 message 的第一个 byte 在 byte stream 中的位置双方client 和 server的 sequence number 是分别计算的

为了尽量避免 sequence number 与留存在网络中的其他 segment 发生冲突以及其他安全原因一次连接中的首个 byte 的 sequence number 一般不是 0而是随机选择

acknowledgment number 是期待收到的下个尚未收到的首个byte 的 sequence number是 cumulative acknowledgment

收到顺序错误的 segment 时TCP 没有规定如何处理但一般都会 buffer 下来

一个 segment 中可以同时包含 acknowledgment 和 data这时 acknowledgment 被称作 piggybacked on the data segment也可以只有 acknowledgment 没有 data此时 segment 仍有 sequence number设为下一个 byte 的 sequence number

Round-Trip Time Estimation and Timeout

一个 segment 的 sample RTT (ss) 指的是 segment 进入 network layer 直到 acknowledgment 被接收的用时

在多数 TCP implementation 中在计算一个 segment 的 sample RTT 时不会再去计算正在同时传输的其他 segment 的 sample RTT并且只会计算一次就传输成功的 segment 的 sample RTT不会计算 retransmission 的 sample RTT

estimated RTT (ee) 是计算出的这些 sample RTT 的 exponential weighted moving average (EWMA)用来平缓 RTT 的波动e78e+18se \gets \frac 78 e + \frac 18 s

dev RTT (dd) 用来衡量 RTT 波动的大小d34d+14sed \gets \frac 34 d + \frac 14 |s - e|

timeout interval (tt) 在 estimated RTT 的基础上根据 dev RTT 提供了一定的冗余t=e+4dt = e + 4d

timeout interval 的初始值一般是 1 秒在发生 retransmission 时timeout interval 会翻倍而在得到新的 sample RTT 后即某个 segment 一次就传输成功后又会回到正常的计算方式

Reliable Data Transfer

TCP 一般只使用一个 retransmission timer用来给 oldest segment 计时

虽然 TCP 和 GBN 有些类似但 TCP 在 retransmit 时一次只传一个 segment而 receiver 往往也会 buffer 顺序错误的 segment

retransmission 在两种情况下发生timeout 或者收到三个 duplicate ACK即相同 sequence number 的第四个 ACK这被称作 fast retransmit这意味着只收到一个或两个 duplicate ACK 的时候还是会等到 timeout 才 retransmit因为这往往意味着只是顺序错误而不是丢包2

一般还会实现 delayed ACK即只 ACK 一个 segment 时会尝试等到下一个 segment 一起 ACK但不会等超过 500ms这样可以减少通信量尤其是经过等待后 ACK 可以被 piggyback 时3但是 cumulative ACK 以及 duplicate ACK 都会立即发送不会等待

Flow Control

receiver 有一个 buffer但 application 不一定会立刻从 buffer 中读取如果 application 读得太慢就需要 sender 不要发太快来避免 buffer overflow

TCP header 中包含 receive window (rwnd\mathrm{rwnd}) 表示 buffer 的剩余空间而 sender 需要保证已发送未被 ACK 的数据总量不超过 rwnd\mathrm{rwnd}

rwnd\mathrm{rwnd} 为 0 会阻断 sender 发送更多 segment而为了让 receiver 有机会告诉 sender 更新后的 rwnd\mathrm{rwnd}防止通信被一直阻断下去sender 需要发送 probing of zero window即 1 byte 的 data可以以以指数上升的间隔发送4 5好多以

TCP Connection Management

书上只讲了最基本的情况没有讲各种 corner case说是可以去看TCP/IP Illustrated

建立 TCP connection

  1. client 向 server 发 SYN segment: SYN flag setsequence number 是 client ISNinitial sequence number第一个 byte 的 sequence number 是 client ISN + 1
  2. server 收到 SYN segment建立 buffer 和 state向 client 发 SYNACK segment: SYN flag setACK 了 SYN segmentsequence number 是 server ISN
  3. client 收到 SYNACK segment建立 buffer 和 state向 server 发 SYNACK 的 ACK可以携带 application data

或者也可以拆开看

  • client 和 server 互发 SYNclient 先发SYN 不携带 application datasequence number 用来表示 ISN
  • 收到 SYN 要 ACKACK 可以 piggyback 到 SYN 或者 application data 上
  • 收到 SYN 时会建立 buffer 以及 state variable

在断开连接时双方会互相发送 FIN package (FIN flag set)以及相应的 ACK首先提出断开连接的一方在发送最后一个 ACK 后会等待一段时间一般是 30s再真的断开连接以给对方机会 retransmit FIN segment防止这最后一个 ACK 丢包导致对方一直等着

如果尝试连接到一个不接受 TCP 连接的端口会返回 RST flag set 的 segment

Principles of Congestion Control

congestion 会导致

  • large queue delay
  • router buffer overflow 会导致丢包以及 retransmission
  • large delay 会导致 premature timeout 以及 unneeded retransmission
  • 在传输路径上如果在一个 router 处发生了丢包在此之前的 router 的 work 都浪费了

congestion control 分为两大类

  • end-to-end: 不依赖于 network layer依靠 retransmission 或 delay 增大等现象推断出 congestion
  • network-assisted: router 提供 congestion feedback一个 bit 表示 link 是否 congested或者更复杂的信息例如 available bit rate可以是由 router 发一个新的 packet或者修改正在传输的其他 packet一方收到 feedback 后再发给另一方

TCP Congestion Control

Classic TCP Congestion Control

classic TCP congestion control 是 end-to-end 的

TCP 使用 congestion window (cwnd\mathrm{cwnd}) 来限制发送速率cwnd\mathrm{cwnd} 的效果与 receive window (rwnd\mathrm{rwnd}) 类似会将 unacknowledged 的数据总量限制在 min(cwnd,rwnd)\min(\mathrm{cwnd}, \mathrm{rwnd}) 之内从而将发送速率限制在约 cwnd/RTT\mathrm{cwnd} / \mathrm{RTT}

classic TCP congestion control 的基本原则

  • retransmission 是 congestion 的征兆需要减小 cwnd\mathrm{cwnd}
  • segment 被 acknowledge 是没有 congestion 的征兆可以增大 cwnd\mathrm{cwnd}
  • 增大 cwnd\mathrm{cwnd} 相当于是在进行试探即不断增大发送速率来试探增大到多大会发生 congestion

具体分为三种模式

  • slow start: 初始状态以及 timeout 后转移到的状态cwnd=1 MSS\mathrm{cwnd} = 1\ \mathrm{MSS} 开始每个 RTT cwnd\mathrm{cwnd} 翻倍直到 cwndssthresh\mathrm{cwnd \geqslant \mathrm{ssthresh}}转移到 congestion avoidance
  • congestion avoidance: 每个 RTT 内 cwnd\mathrm{cwnd} 增大 1 MSS1\ \mathrm{MSS}
  • fast recovery: fast retransmit 后转移到的状态cwnd=ssthresh+3 MSS\mathrm{cwnd} = \mathrm{ssthresh} + 3\ \mathrm{MSS} 开始每个 duplicate ACK 都让 cwnd\mathrm{cwnd} 增大 1 MSS1\ \mathrm{MSS}直到收到非 duplicate 的新的 ACK转移到 congestion avoidance

具体细节如下图所示6

FSM description of TCP congestion control

正常情况下会在 congestion avoidance 和 fast recovery 之间反复切换此时 cwnd\mathrm{cwnd} 的增长是线性的降低是减半称其是 additive-increase, multiplicative-decrease (AIMD) 的AIMD congestion control 会导致 cwnd\mathrm{cwnd} 呈锯齿状变化

TCP congestion control 有多个版本上文描述的是 TCP Reno如果用 slow start 来代替 fast recovery 则是更古老的 TCP Tahoe

TCP Reno 的锯齿状 cwnd\mathrm{cwnd} 变化曲线实际上没能快速恢复到导致 congestion 的临界值会产生较大的浪费一个优化后的版本是 TCP CUBIC它修改了 congestion avoidance 阶段的上升曲线使其是一个三次函数曲线如下图所示7

TCP congestion avoidance sending rates: TCP Reno and TCP CUBIC

Network-Assisted Explicit Congestion Notification

Explicit Congestion Notification (ECN) 是 network-assisted congestion control 的一种手段它对 TCP 和 IP 都进行了扩展

ECN 使用了 IP datagram header 的两个 bit一个用来告诉 router 通信双方是 ECN-capable 的另一个由 router 设置表示自己处于 congestion一般会在丢包实际发生前就设置

在一方收到 router 的 congestion 信息后会在发给另一方的 ACK segment 里设置 ECE (explicit congestion notification echo) flag另一方收到 ECE 后会将 congestion window 减半并在下一个 segment 里设置 CWR (congestion window reduced) flag

除了 TCP还有其他 transport-layer protocol 利用了 ECN例如与 UDP 类似但提供了 congestion control 的 DCCP为 data center 设计的 DCTCPDCQCN 等

Delayed-based Congestion Control

delay-based congestion control 也能在丢包发生前就检测到 congestion

TCP Vegas 会检测历史最大的 throughputcwnd/RTT\mathrm{cwnd} / \mathrm{RTT}若当前的 throughput 明显小于历史最大值则说明发生了 congestion

BBR 的思路类似并采用了一些机制使其在与非 delay-based 的 congestion control 竞争时保持 fairGoogle 在 2016 年已经在内部的 B4 网络中采用 BBR 替换了 TCP CUBIC

此外还有 TIMELYCompound TCPFAST 等 delay-based congestion control protocol

Fairness

假设有 KK 个 TCP 连接共用一个 transmission rate 为 RR 的 bottleneck link并且这个 link 上没有其他数据传输如果每个连接的 throughput 都大约是 R/KR/K则称所使用的 congestion control mechanism 是 fair 的

在各方的 RTT 相同且只有 TCP 连接时AIMD congestion control 是 fair 的如下图所示8addictive increase 是沿 45 度方向的multiplicative decrease 是朝着原点的所以会趋向 fair

但是在各方 RTT 不同时RTT 小的往往能获得更大的 throughput

Throughput realized by two TCP connections

在有 UDP 连接参与时由于 UDP 没有 congestion control可能会导致 unfair

上面讨论的 fairness 是对于 connection 而言的而对于 application / host 就不一定 fair 了因为可以建立多个 parallel TCP connection例如浏览器一般就会这样做

Evolution of Transport-Layer Functionality

虽然 Internet 只有 TCP 和 UDP 两个 transport-layer protocol但 transport-layer functionality 依然在不断演化

现在有非常多不同版本的 TCP 实现例如上文提到的 TCP CUBICBBR 等或是解决了旧版实现中的一些问题或是更适配于特定的应用场景网络环境

QUIC 是一个基于 UDP 的 application-layer protocol有下列 feature

  • 需要 handshake 建立连接且所有数据都是加密的connection-establishment handshake 和 authentication and encryption handshake 被合并在了一起从而比 TLS 更快
  • 以 stream 为单位传输 application data而多个 stream 可以放在单个 packet 中传输
  • reliable data transfer其中 in-order delivery 是对每个 stream 分别保序所以不同 stream 之间不会带来阻塞 (HOL blocking)
  • 与 TCP 类似的 congestion control

作为一个 application-level protocolQUIC 可以比 transport-layer protocol 更频繁地更新

Footnotes

  1. p231, Figure 3.29: TCP segment structure

  2. 3 Fast Retransmit - RFC2001

  3. 4.2.3.2 When to Send an ACK Segment - RFC1122

  4. Managing the Window - RFC793

  5. 4.2.2.17 Probing Zero Windows - RFC1122

  6. p268, Figure 3.51: FSM description of TCP congestion control

  7. p272, Figure 3.54: TCP congestion avoidance sending rates: TCP Reno and TCP CUBIC

  8. p278, Figure 3.57: Throughput realized by TCP connections 1 and 2