CS 144 Checkpoint 5 - Network Interface
“In this week’s checkpoint, you’ll go down the stack and implement a network interface: the bridge between Internet datagrams that travel the world, and link-layer Ethernet frames that travel one hop.”
There isn’t much to say about this checkpoint. We can use three hash tables to store all the information we need to handle the network interface. The cache_
table stores the mapping between IP addresses and Ethernet addresses. The requests_
table is used to deduplicate ARP requests. The queue_
table is used to store datagrams that are waiting for an ARP response.
using IPV4Address = uint32_t;
using Timestamp = size_t;
std::unordered_map<IPV4Address, Expirable<EthernetAddress>> cache_ {};
std::unordered_map<IPV4Address, Expirable<std::monostate>> requests_ {};
std::unordered_map<IPV4Address, std::queue<InternetDatagram>> queue_ {};
Since we need to handle TTL for both the ARP requests and the cache entries, we can create a wrapper to separate the concerns.
template<typename T>
struct Expirable
{
T data;
size_t expiry_time_ms;
[[nodiscard]] bool expired( size_t current_time_ms ) const noexcept
{
return current_time_ms >= expiry_time_ms;
}
};
For the requests_
map, we don’t need to store any data, but just the expiry time. C++ 17 introduces monostate
the Unit
type in C++, which is the perfect fit for this use case.
My implementation does not attempt to delete any expired entries. I simply check whether an entry has expired when I need to access it. This approach passes all test cases without issues. But one can easily perform cleanup inside the tick
function, or impose a soft and hard limit on the number of entries in the cache if the memory usage is a concern.
This concludes Checkpoint 5.
If you find this post helpful, please consider sponsoring.
Sponsor