From d1461afdda0d46bb6f74a779ba992624d7a77ec2 Mon Sep 17 00:00:00 2001 From: ridethepig Date: Sat, 18 Feb 2023 14:51:28 +0000 Subject: [PATCH] check lab6 ok --- .gitignore | 2 ++ libsponge/router.cc | 33 ++++++++++++++++++++++++++++----- libsponge/router.hh | 6 ++++++ 3 files changed, 36 insertions(+), 5 deletions(-) diff --git a/.gitignore b/.gitignore index 08ee2d0..674405c 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,4 @@ /build /.ccls-cache +/.vscode +/.cache \ No newline at end of file diff --git a/libsponge/router.cc b/libsponge/router.cc index 010c622..1964374 100644 --- a/libsponge/router.cc +++ b/libsponge/router.cc @@ -1,6 +1,7 @@ #include "router.hh" #include +#include using namespace std; @@ -28,15 +29,37 @@ void Router::add_route(const uint32_t route_prefix, const size_t interface_num) { cerr << "DEBUG: adding route " << Address::from_ipv4_numeric(route_prefix).ip() << "/" << int(prefix_length) << " => " << (next_hop.has_value() ? next_hop->ip() : "(direct)") << " on interface " << interface_num << "\n"; - - DUMMY_CODE(route_prefix, prefix_length, next_hop, interface_num); - // Your code here. + uint32_t mask = 0; + if (prefix_length > 0) mask = (1 << 31) >> (prefix_length - 1); + _route_table.push_back(std::make_tuple(route_prefix, prefix_length, next_hop, interface_num, mask)); } //! \param[in] dgram The datagram to be routed void Router::route_one_datagram(InternetDatagram &dgram) { - DUMMY_CODE(dgram); - // Your code here. + auto dst_ip = dgram.header().dst; + auto best_match = _route_table.end(); + int longest_prefix = 0; + for (auto rule = _route_table.begin(); rule != _route_table.end(); ++ rule) { + auto route_prefix = std::get<0>(*rule); + auto prefix_length = std::get<1>(*rule); + auto mask = std::get<4>(*rule); + if ((mask & route_prefix) == (mask & dst_ip)) { + if (longest_prefix <= prefix_length) { + longest_prefix = prefix_length; + best_match = rule; + } + } + } + if (best_match != _route_table.end()) { + if (dgram.header().ttl <= 1) { + return; + } + else { + dgram.header().ttl --; + } + auto next_hop = std::get<2>(*best_match).value_or(Address::from_ipv4_numeric(dgram.header().dst)); + _interfaces[std::get<3>(*best_match)].send_datagram(dgram, next_hop); + } } void Router::route() { diff --git a/libsponge/router.hh b/libsponge/router.hh index 33348db..0899889 100644 --- a/libsponge/router.hh +++ b/libsponge/router.hh @@ -1,10 +1,13 @@ #ifndef SPONGE_LIBSPONGE_ROUTER_HH #define SPONGE_LIBSPONGE_ROUTER_HH +#include "address.hh" #include "network_interface.hh" +#include #include #include +#include //! \brief A wrapper for NetworkInterface that makes the host-side //! interface asynchronous: instead of returning received datagrams @@ -44,6 +47,9 @@ class Router { //! The router's collection of network interfaces std::vector _interfaces{}; + //! Internal routing table. Tuple(prefix, prefix_length, next_hop, interface, mask) + std::vector, size_t, uint32_t>> _route_table {}; + //! Send a single datagram from the appropriate outbound interface to the next hop, //! as specified by the route with the longest prefix_length that matches the //! datagram's destination address.