Esempio n. 1
0
    def add_static_route(self, host, port):
        """
        Adds a static route to a host directly connected to this router.

        Called automatically by the framework whenever a host is connected
        to this router.

        :param host: the host.
        :param port: the port that the host is attached to.
        :returns: nothing.
        """
        # `port` should have been added to `peer_tables` by `handle_link_up`
        # when the link came up.
        assert port in self.peer_tables, "Link is not up?"

        table = self.peer_tables[port]

        table[host] = PeerTableEntry(dst=host,
                                     latency=0,
                                     expire_time=PeerTableEntry.FOREVER)

        # TODO: fill this in!

        self.update_forwarding_table()
        self.send_routes(force=False)
Esempio n. 2
0
    def handle_route_advertisement(self, dst, port, route_latency):
        """
        Called when the router receives a route advertisement from a neighbor.

        :param dst: the destination of the advertised route.
        :param port: the port that the advertisement came from.
        :param route_latency: latency from the neighbor to the destination.
        :return: nothing.
        """
        # TODO: fill this in!
        self.peer_tables[port][dst]=PeerTableEntry(dst,route_latency,api.current_time()+ROUTE_TTL)
        self.update_forwarding_table()
        self.send_routes(force=False)
Esempio n. 3
0
 def expire_routes(self):
     """
     Clears out expired routes from peer tables; updates forwarding table
     accordingly.
     """
     # TODO: fill this in!
     for table in self.peer_tables.values():
         for key, element in table.items():
             if (api.current_time() > element.expire_time):
                 if self.POISON_MODE:
                     table[key]=PeerTableEntry(key,INFINITY,api.current_time()+ROUTE_TTL)
                 else:
                     table.pop(key)
     self.update_forwarding_table()
Esempio n. 4
0
    def handle_link_down(self, port):
        """
        Called by the framework when a link attached to this router does down.

        :param port: the port number used by the link.
        :returns: nothing.
        """
        # TODO: fill this in!s
        self.link_latency[port] = INFINITY

        for dst, entry in self.peer_tables[port].items():
            self.peer_tables[port][dst] = PeerTableEntry(
                dst, INFINITY, entry.expire_time)
        self.update_forwarding_table()
        self.send_routes()
Esempio n. 5
0
    def add_static_route(self, host, port):
        """
        Adds a static route to a host directly connected to this router.

        Called automatically by the framework whenever a host is connected
        to this router.

        :param host: the host.
        :param port: the port that the host is attached to.
        :returns: nothing.
        """
        # `port` should have been added to `peer_tables` by `handle_link_up`
        # when the link came up.
        assert port in self.peer_tables, "Link is not up?"
        pte = PeerTableEntry(host, 0, PeerTableEntry.FOREVER)
        self.peer_tables[port][host] = pte
        self.update_forwarding_table()
Esempio n. 6
0
    def expire_routes(self):
        """
        Clears out expired routes from peer tables; updates forwarding table
        accordingly.
        """
        # TODO: fill this in!
        for port, peer_table_entry in self.peer_tables.items():
            for host, entry in peer_table_entry.items():
                if entry.expire_time <= api.current_time():
                    if self.POISON_MODE:
                        peer_table_entry[host] = PeerTableEntry(
                            host, INFINITY,
                            api.current_time() + ROUTE_TTL)
                    else:
                        del peer_table_entry[host]

        self.update_forwarding_table()
Esempio n. 7
0
    def handle_route_advertisement(self, dst, port, route_latency):
        """
        Called when the router receives a route advertisement from a neighbor.

        :param dst: the destination of the advertised route.
        :param port: the port that the advertisement came from.
        :param route_latency: latency from the neighbor to the destination.
        :return: nothing.
        """
        neighborPeerTable = self.peer_tables.get(port)
        ptEntry = PeerTableEntry(dst, route_latency,
                                 api.current_time() + ROUTE_TTL)
        neighborPeerTable.update({dst: ptEntry})
        self.peer_tables.update({port: neighborPeerTable})

        self.update_forwarding_table()
        self.send_routes(force=False)
Esempio n. 8
0
    def handle_link_down(self, port):
        """
        Called by the framework when a link attached to this router does down.

        :param port: the port number used by the link.
        :returns: nothing.
        """
        # TODO: fill this in!
        if self.POISON_MODE:
            for host, entry in self.peer_tables[port].items():
                self.peer_tables[port][host]=PeerTableEntry(host,INFINITY,api.current_time()+ROUTE_TTL)
        else:
            for key in self.peer_tables.keys():
                if key == port:
                    self.peer_tables.pop(key)
        self.port_table.remove(port)
        self.update_forwarding_table()
        self.send_routes()
Esempio n. 9
0
    def expire_routes(self):
        """
        Clears out expired routes from peer tables; updates forwarding table
        accordingly.
        """
        # TODO: fill this in!

        if self.POISON_MODE:
            for p, peer_table in self.peer_tables.items():
                for pte in peer_table:
                    if ((peer_table[pte].expire_time < api.current_time()) and (peer_table[pte].expire_time != PeerTableEntry.FOREVER)):
                        peer_table[pte] = PeerTableEntry(peer_table[pte].dst, INFINITY, api.current_time() + ROUTE_TTL)

        else:
            for port, peer_table in self.peer_tables.items():
                for pte in peer_table.keys():
                    if ((peer_table[pte].expire_time < api.current_time()) and (peer_table[pte].expire_time != PeerTableEntry.FOREVER)):
                        del peer_table[pte]

        self.update_forwarding_table()
Esempio n. 10
0
    def handle_link_down(self, port):
        """
        Called by the framework when a link attached to this router does down.

        :param port: the port number used by the link.
        :returns: nothing.
        """
        # TODO: fill this in!


        if self.POISON_MODE:
            for p, peer_table in self.peer_tables.items():
                if p == port:
                    for pte in peer_table:
                        self.poisoned_routes.add(p)
                        peer_table[pte] = PeerTableEntry(peer_table[pte].dst, INFINITY, api.current_time() + ROUTE_TTL)
        else:
            del self.peer_tables[port]
            del self.link_latency[port]

        self.update_forwarding_table()
        self.send_routes(force=False)
Esempio n. 11
0
    def send_routes(self, force=False):
        """
        Send route advertisements for all routes in the forwarding table.

        :param force: if True, advertises ALL routes in the forwarding table;
                      otherwise, advertises only those routes that have
                      changed since the last advertisement.
        :return: nothing.
        """

        # print(self.history)
        # print(self.forwarding_table)

        if (self.POISON_MODE):
            # print(self.history)
            # print(self.forwarding_table)
            for port in self.history:
                pTable = self.history[port]

                for host in pTable:

                    if ((host not in self.forwarding_table)
                            and (port in self.peer_tables)):
                        packet = basics.RoutePacket(destination=host,
                                                    latency=INFINITY)
                        # self.send(packet, port=port)

                        # pTable[host] = packet
                        # self.history[port] = pTable
                        temp = self.peer_tables[port]
                        temp[host] = PeerTableEntry(
                            dst=host,
                            latency=INFINITY,
                            expire_time=api.current_time() + ROUTE_TTL)

                self.update_forwarding_table()

        for port, table in self.peer_tables.items():

            for host, entry in self.forwarding_table.items():

                tempLatency = None

                if (self.POISON_MODE):

                    if (entry.port == port):
                        tempLatency = INFINITY
                    else:
                        if (entry.latency > INFINITY):
                            tempLatency = INFINITY
                        else:
                            tempLatency = entry.latency

# pTable = self.peer_tables[port]
# pTable[host] = PeerTableEntry(dst=host, latency=INFINITY, expire_time=api.current_time()+ROUTE_TTL)
# self.update_forwarding_table()

                elif (entry.port != port):

                    if (entry.latency > INFINITY):
                        tempLatency = INFINITY
                    else:
                        tempLatency = entry.latency

                if (tempLatency):
                    packet = basics.RoutePacket(destination=entry.dst,
                                                latency=tempLatency)

                    if (force):
                        self.send(packet, port=port)

                        pTable = {}

                        # if port already in history, get the table
                        if (port in self.history):
                            pTable = self.history[port]

# port not in history, create new dictionary entry
                        else:
                            self.history[port] = {}
                            pTable = self.history[port]

                        pTable[host] = packet
                        self.history[port] = pTable

                    # -------------------- Stage 8 --------------------
                    else:
                        send = False
                        pTable = {}

                        # if port already in history, get the table
                        if (port in self.history):
                            pTable = self.history[port]

                        # port not in history, create new dictionary entry
                        else:
                            self.history[port] = {}
                            pTable = self.history[port]

                    # Host in history
                        if (host in pTable):
                            prevEntry = pTable[host]

                            # Packet is not the same, update history and send
                            if ((prevEntry.latency != tempLatency)
                                    or (host != entry.dst)):
                                pTable[host] = packet
                                send = True

                    # Host not in history, add to history and send
                        else:
                            pTable[host] = packet
                            send = True
                            self.history[port] = pTable

                        if (send):
                            self.send(packet, port=port)