|
54 | 54 | - 测试 2:每隔一段时间生成一系列的序列号,这些序列号应该不重复 |
55 | 55 | - 代码量:~10 行 |
56 | 56 | - 教学目的:了解序列号的大小关系,如何在整数溢出的情况下,实现保证相对顺序的比较 |
| 57 | +- 验收要求:通过自动化测试 |
57 | 58 |
|
58 | 59 | ### Step 2. TCP 三次握手连接的建立(3-way handshake) |
59 | 60 |
|
|
65 | 66 | - 测试 3b:测试服务端逻辑,启动 lwip-client 和 lab-server,在输出日志中检查 TCP 状态机的转移 |
66 | 67 | - 代码量:~50 行 |
67 | 68 | - 教学目的:学习 TCP 建立连接的三次握手过程,初步接触框架中发送 TCP 分组的方法和 TCP 状态机的实现,强化 SYN 占用序列号的记忆 |
| 69 | +- 验收要求:通过自动化测试 |
68 | 70 |
|
69 | 71 | ### Step 3. 简易的发送和接收逻辑(send & receive) |
70 | 72 |
|
|
77 | 79 | - 测试 4b:测试服务端逻辑,启动 lwip-client 和 lab-server,在输出日志中检查是否正确完成了 HTTP 请求 |
78 | 80 | - 代码量:~50 行 |
79 | 81 | - 教学目的:理解 TCP 栈与用户程序交互的方式,TCP 栈内发送缓存和接收缓存的意义,如何维护发送和接收的序列号空间(即 `SND.UNA`,`SND.NXT`,`SND.WND`,`RCV.NXT` 和 `RCV.WND`) |
| 82 | +- 验收要求:通过自动化测试 |
80 | 83 |
|
81 | 84 | ### Step 4. TCP 连接的终止(connection termination) |
82 | 85 |
|
|
87 | 90 | - 测试 5a:测试客户端逻辑,启动 lab-client 和 lwip-server,在输出日志中检查是否出现了正确的状态机转移 |
88 | 91 | - 测试 5b:测试服务端逻辑,启动 lwip-client 和 lab-server,在输出日志中检查是否出现了正确的状态机转移 |
89 | 92 | - 教学目的:理解 TCP 连接终止的四次挥手过程,强化 FIN 占用序列号的记忆 |
| 93 | +- 验收要求:通过自动化测试 |
90 | 94 |
|
91 | 95 | ### Step 5. 访问百度主页(visit baidu homepage) |
92 | 96 |
|
|
97 | 101 | - 注意:部分发行版可能没有自带 socat命令, 需要额外安装 socat 软件包 |
98 | 102 | - 注意:在关闭连接的过程中,当百度的服务器处于`FIN_WAIT_2`状态时,它只能接受`ACK=1, FIN=1`的包,而不会接受`ACK=0, FIN=1`的包,收到`ACK=0, FIN=1`的包时,服务器既不会返回`ACK`,也不会进入`TIME_WAIT`状态。如果你的实现里只能发送`ACK=0, FIN=1`的包,那么你的客户端可能会卡在`LAST_ACK`状态,无法进入`CLOSE`状态。(此条感谢尤梓锐同学提醒) |
99 | 103 | - 教学目的:了解一个最小的 TCP 实现所需要的功能,并获得阶段性的成就 |
| 104 | +- 验收要求:通过自动化测试,并展示下载的百度网页 |
100 | 105 |
|
101 | 106 | ### Step 6. 重传和乱序重排(retransmission and out of order handling) |
102 | 107 |
|
|
107 | 112 | - 测试 7b:启动 lab-client 和 lab-server,lab-server模拟 HTTP response 的延迟、乱序发送,在输出日志中检查是否出现了正确的状态机转移 |
108 | 113 | - 测例的具体实现机理可以参见源代码。欢迎对这两个测例进行改进,通过其他方式来展现重传和乱序重排的效果 |
109 | 114 | - 教学目的:理解在网络中出现丢包或者乱序的时候,如何在协议上保持不重不漏、顺序正确地实现数据传输 |
| 115 | +- 验收要求:通过抓包、日志等方式展示重传和重排,展示场景可以参考自动化测试脚本 |
110 | 116 |
|
111 | 117 | ### Step 7. 实现 Nagle 算法(Nagle's algorithm) |
112 | 118 |
|
|
118 | 124 | - 请比较开启 Nagle 算法与关闭 Nagle 算法时,TCP 连接的传输效率 |
119 | 125 | - 注意:编译时,我们用 `ENABLE_NAGLE` 这个宏来区分 Nagle 算法是否启用。如果存在 `ENABLE_NAGLE` 这个宏,你的 TCP 实现就应该启用 Nagle 算法 |
120 | 126 | - 教学目的:学习并实现一个经典的 TCP 上的优化 |
| 127 | +- 验收要求:展示开启 Nagle 算法时 TCP 连接的传输效率相比关闭 Nagle 算法时有所提高,展示场景可以参考自动化测试脚本 |
121 | 128 |
|
122 | 129 | ### Step 8. 实现慢启动,冲突避免,快速重传和快速恢复(slow start, congestion avoidance and fast retransmit/recovery) |
123 | 130 |
|
|
132 | 139 | - 在测试中在模拟的网络层中实现一个类似漏桶算法的限速方法,当客户端平均接收带宽超过 10KiB/s 时,通过丢包(在客户端接收时丢弃)模拟网络拥塞 |
133 | 140 | - 测试 9a 模拟极端的网络拥塞情况,带宽超过上限时,丢弃所有到达的包;测试 9b 模拟偶然的网络拥塞情况,带宽超过上限时,以一定概率丢弃到达的包 |
134 | 141 | - 请比较测试 9a 和 9b 下,TCP 连接的传输效率 |
| 142 | +- 注:为了便于显示拥塞控制算法的效果,你可以修改 MTU 以便观察 |
135 | 143 | - 教学目的:学习并实现经典的拥塞控制协议,并理解 TCP 协议栈是如何通过丢包和重复的 ACK 来判断链路上是否拥挤的,拥挤时要如何让出带宽来缓解网络的拥挤程度 |
| 144 | +- 验收要求:通过抓包、日志等方式展示慢启动和冲突避免阶段 cwnd 的变化模式,以及在丢包发生后算法的行为,展示场景可以参考自动化测试脚本 |
136 | 145 |
|
137 | 146 | ## 限选功能(总分 40 分) |
138 | 147 |
|
139 | 148 | ### Feature 1. 实现 TCP BBR 拥塞控制算法 |
140 | 149 |
|
141 | 150 | - 分数:40 |
142 | 151 | - 参考文档:[RFC BBR draft](https://datatracker.ietf.org/doc/html/draft-cardwell-iccrg-bbr-congestion-control-00) |
| 152 | +- 由于 lwIP 的一些实现细节,不建议在本部分实验中使用 lwIP 库,客户端和服务器都使用本实验实现的程序即可 |
143 | 153 | - 教学目的:学习并实现一个较为复杂和现代的拥塞控制算法 |
| 154 | +- 验收要求:能介绍 TCP BBR 拥塞控制算法的核心思想 |
144 | 155 |
|
145 | 156 | #### Step 1. 实现 pacing 功能 |
146 | 157 |
|
147 | 158 | - 分数:5 |
148 | 159 | - BBR 算法中使用了 pacing 功能,通过控制发送时间间隔的方式控制发送速率。 |
149 | 160 | - 在这一步中,你很可能需要使用定时器。你可以在“实验框架”一节中获得一些提示。 |
150 | 161 | - 完成这一步后,你应能使发送端按照给定速率发送。 |
| 162 | +- 验收要求:能通过控制 pacing 速率,使相同流以不同时间完成传输。 |
151 | 163 |
|
152 | 164 | #### Step 2. 构建 rate sample |
153 | 165 |
|
154 | 166 | - 分数:10 |
| 167 | +- 参考文档:[RFC Delivery Rate Estimation draft](https://datatracker.ietf.org/doc/html/draft-cheng-iccrg-delivery-rate-estimation) |
155 | 168 | - BBR 算法中需要根据收到的 ACK 还原网络情况。因此,需要针对每一个 ACK 都构建一个 rate sample,并将其作为参数传入拥塞控制算法对于 ACK 的响应函数中。 |
156 | 169 | - rate sample 中应当至少包含如下信息:RTT、delivery rate。 |
157 | 170 | - 为了构建 rate sample,可能需要维护一些额外的数据结构。 |
158 | 171 | - 完成这一步后,你应能在收到每一个 ACK 后输出一组统计信息。 |
| 172 | +- 验收要求:能展示收到每个 ACK 后的统计信息;展示的 RTT 与配置的链路延迟相匹配;展示的 delivery rate 与 pacing rate 设置的速率相匹配 |
159 | 173 |
|
160 | 174 | #### Step 3. 实现 BBR 算法 |
161 | 175 |
|
162 | 176 | - 分数:25 |
163 | 177 | - 你已经完成了必要的准备工作。现在,将 BBR 算法实现出来吧! |
| 178 | +- 提示:BBR 算法同时使用 cwnd 和 pacing rate 来控制发送,你只需理解在算法的几个状态以及核心状态的探测循环中 cwnd 和 pacing rate 应当如何设置,并正确计算和设置即可。 |
| 179 | +- 验收要求:能展示 BBR 算法的工作循环;能展示 BBR 算法在遇到丢包时的行为。如果能展示出比必选功能 Step 8 更高的带宽和更低的延迟就更好了。 |
| 180 | +- 验收提示:可以参考必选功能 Step 8 的自动化测试脚本模拟网络环境;推荐使用统计量随时间变化的图表来展示 BBR 的行为。 |
164 | 181 |
|
165 | 182 | ### Feature 2. 实现 SACK |
166 | 183 |
|
167 | 184 | - 由于 lwIP 不支持 SACK,此处需要用 TUN 模式进行测试。 |
168 | 185 | - 分数:20 |
169 | 186 | - 参考文档:[RFC 2018](https://datatracker.ietf.org/doc/html/rfc2018) [RFC 2018 勘误](https://www.rfc-editor.org/errata_search.php?rfc=2018&rec_status=0) |
170 | 187 | - 教学目的:学习并实现一个比较复杂一些的 TCP Option,理解如何通过添加简单的数据结构和扩展的方式来解决原有协议的不足 |
| 188 | +- 验收要求:能展示一个发出 SACK 的场景,并展示发出的 SACK 包;展示 SACK 接收方利用 SACK 实现的功能,通过对比不使用 SACK 的行为展示 SACK 的作用 |
171 | 189 |
|
172 | 190 | !!! tip "BBRv2" |
173 | 191 |
|
|
0 commit comments