3.1 KiB
Lab 5 Writeup
My name: Catfood
My SUNet ID: 998244353
I collaborated with: An orange cat
This lab took me about 3 hours to do.
Program Structure and Design of the NetworkInterface:
这次的讲义给的很清楚,该做啥每一步都写了,也没啥隐藏的要调试的地方。
主要的工作是:根据 next_hop 的 IP 地址来查询 Ethernet 地址,然后组装 eth 帧;以及管理 ARP。
维护两个内部结构,ARP 缓存 _arp_cache、未发送的数据包链表 _suspended_datagrams。
- ARP 缓存做了一点设计,把 IP 地址映射到一个以太网地址,同时还要附加上过期时间和正在查询标志。这里用一个 pair 和 optional 来包装,pair 里面另一个元素表示超时。如果 optional 有值,那么就是一个正常的表项;如果没有值,那么说明刚刚为这个 IP 发送了 ARP,五秒之后才可能清空。
- 加入等待队列的时候,记得把
next_hop一起塞进去,毕竟是发给next_hop而不是数据包的目标地址。
实现三个方法
send_datagram:上来先查 cache,如果查到了,那就直接发。如果查不到,那么看看是不是已经发过 ARP 了,如果是,那么就直接塞进等待队列;如果不是,需要构造一个新的 ARP Request 然后广播。recv_frame:首先判断地址,接收广播和本机IP,否则丢掉。如果是 IPv4,那么解析并返回;如果是 ARP,先解析。如果是 ARP Request 并且目标 IP 是自己,需要发回 ARP Reply,这里不需要广播、直接用发送者的以太网地址,并且需要将 SRC-DST 交换。
无论是不是 REQUEST,都需要学习。直接把发送端 IP 到物理地址的映射塞进 cache,如果已经存在也无所谓,反正要刷新过期时间。
最后记得遍历等待队列,看看有没有能发的包(也就是等于本次接收到的 ARP SRC-IP),如果能发,从等待队列删除并调用send_datagramtick:遍历缓存,更新过期时间,如果过期需要删掉。
Implementation Challenges:
难度不是很大。之所以花了我3个小时,其中有一个小时都是在解决 C++ 的问题。最离谱的是 remove_if,死活编译不过去,然后我只好不用他。GCC 的报错信息就跟那啥似的,一大坨,根本看不懂。最后看下来好像是,隐式禁用了拷贝构造,然后就用不了了。最后看了看,发现 reference 的 notes 里面有一句 These algorithms cannot be used with associative containers such as std::set and std::map because their iterator types do not dereference to MoveAssignable types (the keys in these containers are not modifiable)。 艹!
Remaining Bugs:
实验不要求,我也没有实现发回 ICMP 的功能,要是一直 ARP 查不到,那有的数据包就会一直挂在等待队列里面
-
Optional: I had unexpected difficulty with: [describe]
-
Optional: I think you could make this lab better by: [describe]
-
Optional: I was surprised by: [describe]
-
Optional: I'm not sure about: [感觉好多都没测啊,鬼知道超时啥的有没有正常工作]