Пример #1
0
    def handle_routing_packet(self, packet, dynamic):
        """
        Updates the cost and routing tables using the given routing packet

        :param packet: Routing packet to update tables for
        :type packet: RoutingPacket
        :param dynamic: Whether we're handling a dynamic or static packet
        :type dynamic: bool
        :return: Nothing
        :rtype: None
        """
        # No routing table yet. Begin creation, then handle this packet
        if not self._get_intermediate_routing_table(dynamic):
            self.create_routing_table(dynamic)
        did_update = False
        cost_table = packet.costTable
        src_id = packet.src.id

        # Get the appropriate routing table
        routing_table = self._get_intermediate_routing_table(dynamic)
        # Update costs by adding the cost to travel to the source node
        src_cost = routing_table[src_id].cost
        for identifier in cost_table.keys():
            cost_table[identifier] = cost_table[identifier] + src_cost

        src_link = routing_table[src_id].link
        # Update our routing table based on the received table
        for identifier, cost in cost_table.items():
            # New entry to tables or smaller cost
            if identifier not in routing_table or \
                    cost < routing_table[identifier].cost:
                did_update = True
                routing_table[identifier] = LinkCostTuple(src_link, cost)

        # Store and broadcast the updated table if an update occurred
        if did_update:
            self.sameDataCounter = 0
            self.store_routing_table(dynamic, routing_table)
            new_cost_table = self.cost_table_from_routing_table(dynamic)
            self.broadcast_table(new_cost_table, dynamic)
        else:
            self.sameDataCounter += 1
            # Log the same data receipt
            Logger.debug(Network.get_time(),
                         "%s received no new routing table "
                         "data." % self)
            # Log finalized routing table
            Logger.trace(
                Network.get_time(), "%s final %s routing table:" %
                (self, "dynamic" if dynamic else "static"))
            if dynamic:
                self.handle_same_dynamic_routing_table()
Пример #2
0
    def handle_routing_packet(self, packet, dynamic):
        """
        Updates the cost and routing tables using the given routing packet

        :param packet: Routing packet to update tables for
        :type packet: RoutingPacket
        :param dynamic: Whether we're handling a dynamic or static packet
        :type dynamic: bool
        :return: Nothing
        :rtype: None
        """
        # No routing table yet. Begin creation, then handle this packet
        if not self._get_intermediate_routing_table(dynamic):
            self.create_routing_table(dynamic)
        did_update = False
        cost_table = packet.costTable
        src_id = packet.src.id

        # Get the appropriate routing table
        routing_table = self._get_intermediate_routing_table(dynamic)
        # Update costs by adding the cost to travel to the source node
        src_cost = routing_table[src_id].cost
        for identifier in cost_table.keys():
            cost_table[identifier] = cost_table[identifier] + src_cost

        src_link = routing_table[src_id].link
        # Update our routing table based on the received table
        for identifier, cost in cost_table.items():
            # New entry to tables or smaller cost
            if identifier not in routing_table or \
                    cost < routing_table[identifier].cost:
                did_update = True
                routing_table[identifier] = LinkCostTuple(src_link, cost)

        # Store and broadcast the updated table if an update occurred
        if did_update:
            self.sameDataCounter = 0
            self.store_routing_table(dynamic, routing_table)
            new_cost_table = self.cost_table_from_routing_table(dynamic)
            self.broadcast_table(new_cost_table, dynamic)
        else:
            self.sameDataCounter += 1
            # Log the same data receipt
            Logger.debug(Network.get_time(), "%s received no new routing table "
                                             "data." % self)
            # Log finalized routing table
            Logger.trace(Network.get_time(), "%s final %s routing table:"
                         % (self, "dynamic" if dynamic else "static"))
            if dynamic:
                self.handle_same_dynamic_routing_table()
Пример #3
0
    def update_dynamic_routing_table(self, routing_table):
        """
        Replace the old dynamicRoutingTable with the given new one

        :param routing_table: Routing table to update the old one with
        :type routing_table: dict[str, LinkCostTuple]
        :return: Nothing
        :rtype: None
        """
        Logger.trace(Network.get_time(), "%s:" % self)
        Logger.trace(Network.get_time(), "Replacing old dynamic routing table:")
        self.print_routing_table(self.dynamicRoutingTable)
        Logger.trace(Network.get_time(), "With new dynamic routing table:")
        self.print_routing_table(self.newDynamicRoutingTable)
        self.dynamicRoutingTable = routing_table
Пример #4
0
    def create_routing_table(self, dynamic=None):
        """
        Begins creation of a routing table by broadcasting adjacent link costs

        :param dynamic: Whether to create a dynamic or static routing table
        :type dynamic: bool
        :return: Nothing
        :rtype: None
        """
        if not dynamic:
            dynamic = self.dynamicEnabled
        # Only add the dynamic routing table update timer once
        if dynamic and not self.dynamicRoutingTableTimerAdded:
            self.add_timer(UpdateDynamicRoutingTableEvent(None, self),
                           Network.get_time(), DYNAMIC_UPDATE_INTERVAL)
            self.dynamicRoutingTableTimerAdded = True
        # Reset the dynamic routing table same data counter
        self.sameDataCounter = 0
        # Initialize cost of reaching oneself as 0
        routing_table = {self.id: LinkCostTuple(None, 0)}
        # Create cost table to broadcast with costs of this router's neighbors
        # { node_id : cost }
        cost_table = {}
        for link in self.links:
            # Get the dynamic or static cost of the link
            cost = link.dynamic_cost() if dynamic else link.static_cost()
            other_node_id = link.other_node(self).id
            cost_table[other_node_id] = cost
            routing_table[other_node_id] = LinkCostTuple(link, cost)
        self.store_routing_table(dynamic, routing_table)
        self.broadcast_table(cost_table, dynamic)
Пример #5
0
    def update_dynamic_routing_table(self, routing_table):
        """
        Replace the old dynamicRoutingTable with the given new one

        :param routing_table: Routing table to update the old one with
        :type routing_table: dict[str, LinkCostTuple]
        :return: Nothing
        :rtype: None
        """
        Logger.trace(Network.get_time(), "%s:" % self)
        Logger.trace(Network.get_time(),
                     "Replacing old dynamic routing table:")
        self.print_routing_table(self.dynamicRoutingTable)
        Logger.trace(Network.get_time(), "With new dynamic routing table:")
        self.print_routing_table(self.newDynamicRoutingTable)
        self.dynamicRoutingTable = routing_table
Пример #6
0
    def create_routing_table(self, dynamic=None):
        """
        Begins creation of a routing table by broadcasting adjacent link costs

        :param dynamic: Whether to create a dynamic or static routing table
        :type dynamic: bool
        :return: Nothing
        :rtype: None
        """
        if not dynamic:
            dynamic = self.dynamicEnabled
        # Only add the dynamic routing table update timer once
        if dynamic and not self.dynamicRoutingTableTimerAdded:
            self.add_timer(UpdateDynamicRoutingTableEvent(None, self),
                           Network.get_time(), DYNAMIC_UPDATE_INTERVAL)
            self.dynamicRoutingTableTimerAdded = True
        # Reset the dynamic routing table same data counter
        self.sameDataCounter = 0
        # Initialize cost of reaching oneself as 0
        routing_table = {self.id: LinkCostTuple(None, 0)}
        # Create cost table to broadcast with costs of this router's neighbors
        # { node_id : cost }
        cost_table = {}
        for link in self.links:
            # Get the dynamic or static cost of the link
            cost = link.dynamic_cost() if dynamic else link.static_cost()
            other_node_id = link.other_node(self).id
            cost_table[other_node_id] = cost
            routing_table[other_node_id] = LinkCostTuple(link, cost)
        self.store_routing_table(dynamic, routing_table)
        self.broadcast_table(cost_table, dynamic)
Пример #7
0
 def handle_same_dynamic_routing_table(self):
     """
     Handle the receipt of a routing table that provided no updates. If we
     have seen the same data SAME_DATA_THRESHOLD times, dispatch an event
     to update the dynamic routing table in the future, and replace the old
     dynamic routing table with the new one. Otherwise re-broadcast the
     routing table.
     """
     if self.sameDataCounter >= self.SAME_DATA_THRESHOLD:
         self.update_dynamic_routing_table(self.newDynamicRoutingTable)
         # Reset the dynamic cost for the links, we're done updating
         map(lambda l: l.reset_dynamic_cost(Network.get_time()), self.links)
     else:
         new_cost_table = self.cost_table_from_routing_table(dynamic=True)
         self.broadcast_table(new_cost_table, dynamic=True)
Пример #8
0
    def broadcast_table(self, cost_table, dynamic):
        """
        Broadcasts given table to all nodes this router is connected to.

        :param cost_table: Cost table to broadcast
        :type cost_table: dict[str, float]
        :param dynamic: Whether we're broadcasting dynamic/static routing table
        :type dynamic: bool
        :return: Nothing
        :rtype: None
        """
        packet_type = DynamicRoutingPacket if dynamic else StaticRoutingPacket
        for link in self.links:
            packet = packet_type(deepcopy(cost_table), self, link.other_node(self))
            self.send(packet, link, Network.get_time())
Пример #9
0
 def handle_same_dynamic_routing_table(self):
     """
     Handle the receipt of a routing table that provided no updates. If we
     have seen the same data SAME_DATA_THRESHOLD times, dispatch an event
     to update the dynamic routing table in the future, and replace the old
     dynamic routing table with the new one. Otherwise re-broadcast the
     routing table.
     """
     if self.sameDataCounter >= self.SAME_DATA_THRESHOLD:
         self.update_dynamic_routing_table(self.newDynamicRoutingTable)
         # Reset the dynamic cost for the links, we're done updating
         map(lambda l: l.reset_dynamic_cost(Network.get_time()), self.links)
     else:
         new_cost_table = self.cost_table_from_routing_table(dynamic=True)
         self.broadcast_table(new_cost_table, dynamic=True)
Пример #10
0
    def broadcast_table(self, cost_table, dynamic):
        """
        Broadcasts given table to all nodes this router is connected to.

        :param cost_table: Cost table to broadcast
        :type cost_table: dict[str, float]
        :param dynamic: Whether we're broadcasting dynamic/static routing table
        :type dynamic: bool
        :return: Nothing
        :rtype: None
        """
        packet_type = DynamicRoutingPacket if dynamic else StaticRoutingPacket
        for link in self.links:
            packet = packet_type(deepcopy(cost_table), self,
                                 link.other_node(self))
            self.send(packet, link, Network.get_time())
Пример #11
0
 def print_routing_table(routing_table):
     if not routing_table:
         Logger.trace(Network.get_time(), "None")
         return
     for i, j in routing_table.items():
         Logger.trace(Network.get_time(), "\t%s: %s" % (i, j))
Пример #12
0
 def print_routing_table(routing_table):
     if not routing_table:
         Logger.trace(Network.get_time(), "None")
         return
     for i, j in routing_table.items():
         Logger.trace(Network.get_time(), "\t%s: %s" % (i, j))