Exemple #1
0
    def ___reply_with_cached_path(self, path: List[int],
                                  dest_address: ILNPAddress,
                                  original_destination_id: int):
        """Replies to request with cached path"""
        reply = LocatorRouteReply(original_destination_id,
                                  LocatorHopList(path))
        header = ControlHeader(reply.TYPE, reply.size_bytes())
        message = ControlMessage(header, reply)
        reply_packet = ILNPPacket(self.my_address,
                                  dest_address,
                                  payload_length=message.size_bytes(),
                                  payload=message)
        # Next hop is either in my locator, neighbour locator , or hop before my locator
        if dest_address.loc == self.my_address.loc:
            logger.info("Next hop is in my locator")
            self.net_interface.send(
                bytes(reply_packet),
                self.forwarding_table.find_next_hop_for_local_node(
                    dest_address.id))
        else:
            logger.info("Next hop is in other locator")
            next_hop_locator = path[len(path) -
                                    2] if len(path) > 1 else dest_address.loc
            logger.info("Next hop locator is {}".format(next_hop_locator))
            self.net_interface.send(
                bytes(reply_packet),
                self.forwarding_table.find_next_hop_for_locator(
                    next_hop_locator))

        self.monitor.record_sent_packet(True, False)
Exemple #2
0
    def __handle_expired_link_list_message(self, packet: ILNPPacket):
        if packet.src.loc != self.my_address.loc:
            logger.info("Link failure in other network. None of my concern")
            return

        central_node_id: int = packet.src.id
        expired_message: ExpiredLinkList = packet.payload.body
        learned_something = False
        for expired_node_id in expired_message.lost_link_ids:
            learned_something |= self.network_graph.remove_link(
                central_node_id, expired_node_id)

        if learned_something:
            packet.decrement_hop_limit()
            if packet.hop_limit > 0:
                self.net_interface.broadcast(bytes(packet))
                self.monitor.record_sent_packet(True, True)
                self.update_available = True
Exemple #3
0
def extend_route_request(packet: ILNPPacket):
    """Appends empty locator to hop list and updates size of control and ILNP header payload lengths"""
    header: ControlHeader = packet.payload.header
    body: LocatorRouteRequest = packet.payload.body
    # Add empty locator to be overwritten
    body.locator_hop_list.append(0)
    # Refresh control header payload length
    header.payload_length = body.size_bytes()
    # Refresh ILNPPacket payload length
    packet.payload_length = packet.payload.size_bytes()
Exemple #4
0
    def __forward_locator_route_request(self, packet: ILNPPacket):
        """Forwards the route request to all neighbours it hasn't already visited"""

        packet.decrement_hop_limit()
        if len(self.forwarding_table.next_hop_to_locator) == 0:
            logger.info(
                "No neighbour locators to send destination request to.")
            logger.info("Discarding.")
            return
        elif packet.hop_limit == 0:
            logger.info("No more hops. Discarding.")
            return

        request_list: LocatorHopList = packet.payload.body.locator_hop_list
        path: List[int] = request_list.locator_hops
        if path[len(path) - 1] is not self.my_address.loc:
            self.net_interface.send(
                bytes(packet),
                self.forwarding_table.find_next_hop_for_locator(
                    path[len(path) - 1]))
            self.monitor.record_sent_packet(True, True)
        else:
            # Get all neighbour locators not already in path and not the original source
            unvisited_neighbours = [
                locator for locator in
                self.forwarding_table.next_hop_to_locator.keys()
                if locator not in path and locator != packet.src.loc
            ]
            # Forward packet to each neighbour locator
            if len(unvisited_neighbours) > 0:
                extend_route_request(packet)
                for locator in unvisited_neighbours:
                    logger.info("Forwarding to {}".format(locator))
                    # Change last hop locator on each iteration
                    request_list.locator_hops[len(request_list.locator_hops) -
                                              1] = locator
                    self.net_interface.send(
                        bytes(packet),
                        self.forwarding_table.find_next_hop_for_locator(
                            locator))
                    self.monitor.record_sent_packet(True, True)
Exemple #5
0
 def __build_rreq(self, request_id: int, dest_id: int,
                  first_hop_locator: int) -> ILNPPacket:
     logger.info("Building route request for {} via locator {}".format(
         dest_id, first_hop_locator))
     initial_list = LocatorHopList([first_hop_locator])
     rreq = LocatorRouteRequest(request_id, True, initial_list)
     header = ControlHeader(rreq.TYPE, rreq.size_bytes())
     control = ControlMessage(header, rreq)
     return ILNPPacket(self.my_address,
                       ILNPAddress(0, dest_id),
                       payload=control,
                       payload_length=control.size_bytes())
Exemple #6
0
    def handle_data_packet(self, packet: ILNPPacket, attempt_forward=True):
        """Attempt basic routing of packet using available resources"""
        logger.info("Handling data packet")
        if packet.dest.id == self.my_address.id:
            logger.info("Packet for me, adding to received queue <3")
            self.arrived_data_queue.put((packet.payload.body, packet.src.id))
            return

        if not attempt_forward:
            return

        # Locator discovery might be necessary for packets coming from me
        is_from_me = packet.src.id == self.my_address.id
        if packet.dest.loc is None and is_from_me:
            logger.info("Don't know locator, need to find.")
            self.control_plane.find_route(packet)
            return

        destination_is_local = packet.dest.loc == self.my_address.loc
        next_hop = self.forwarding_table.get_next_hop(packet.dest,
                                                      destination_is_local)

        if next_hop is not None:
            logger.info("Found next hop, forwarding to {}".format(next_hop))
            packet.decrement_hop_limit()
            if packet.hop_limit > 0:
                self.net_interface.send(bytes(packet), next_hop)
                self.monitor.record_sent_packet(False, not is_from_me)
            else:
                logger.info("No more hops. Discarding packet")
        elif destination_is_local:
            logger.info("No node exists with that ID in this locator.")
            logger.info("Discarding packet")
        elif is_from_me:
            logger.info(
                "Finding route for packet destined for external locator")
            self.control_plane.find_route(packet)
        else:
            logger.info("No next hop found for packet. Dropping packet.")
Exemple #7
0
    def __broadcast_lsdb(self):
        """Broadcasts my LSDB to neighbouring nodes"""
        logger.info("Broadcasting my LSDB")
        lsdb = self.network_graph.to_lsdb_message(
            next(self.lsb_sequence_generator))
        header = ControlHeader(LSDBMessage.TYPE, lsdb.size_bytes())
        control_message = ControlMessage(header, lsdb)
        packet = ILNPPacket(self.my_address,
                            ALL_LINK_LOCAL_NODES_ADDRESS,
                            payload_length=control_message.size_bytes(),
                            payload=control_message)

        self.net_interface.broadcast(bytes(packet))
        self.monitor.record_sent_packet(True, False)
Exemple #8
0
    def __send_keepalive(self):
        """Broadcasts hello message containing this nodes current lambda"""
        keepalive = Hello(self.__calc_my_lambda())
        header = ControlHeader(keepalive.TYPE, keepalive.size_bytes())
        control_message = ControlMessage(header, keepalive)

        packet = ILNPPacket(self.my_address,
                            ALL_LINK_LOCAL_NODES_ADDRESS,
                            hop_limit=0,
                            payload_length=control_message.size_bytes(),
                            payload=bytes(control_message))

        self.net_interface.broadcast(bytes(packet))
        self.monitor.record_sent_packet(True, False)
Exemple #9
0
    def __handle_expired_links(self, expired: List[int]):
        """Broadcasts information about lost links and removes them from our network graph"""
        for expired_node_id in expired:
            self.network_graph.remove_link(self.my_address.id, expired_node_id)

        expired_message = ExpiredLinkList(expired)
        header = ControlHeader(expired_message.TYPE,
                               expired_message.size_bytes())
        control_message = ControlMessage(header, expired_message)
        packet = ILNPPacket(self.my_address,
                            ALL_LINK_LOCAL_NODES_ADDRESS,
                            payload_length=control_message.size_bytes(),
                            payload=control_message)

        self.net_interface.broadcast(bytes(packet))
        self.monitor.record_sent_packet(True, False)
Exemple #10
0
 def __reply_to_locator_route_request(self, packet: ILNPPacket):
     """Replies to request with reverse of their path"""
     request: LocatorRouteRequest = packet.payload.body
     path: List[int] = request.locator_hop_list.locator_hops
     reply = LocatorRouteReply(self.my_address.id, LocatorHopList(path))
     header = ControlHeader(reply.TYPE, reply.size_bytes())
     message = ControlMessage(header, reply)
     reply_packet = ILNPPacket(self.my_address,
                               packet.src,
                               payload_length=message.size_bytes(),
                               payload=bytes(message))
     # Next hop is either neighbour, or hop before my locator
     next_hop_locator = path[len(path) -
                             2] if len(path) > 1 else packet.src.loc
     self.net_interface.send(
         bytes(reply_packet),
         self.forwarding_table.find_next_hop_for_locator(next_hop_locator))
     self.monitor.record_sent_packet(True, False)
Exemple #11
0
    def send(self, data, dest_id):
        """
         Wraps the given data in an ILNPPacket for the given destination ID,
        and adds it to the queue to be processed
        :param data: data to be sent
        :param dest_id: id of node to be sent to
        """
        if not self.monitor.running:
            raise IOError("Router is not running.")

        message = build_data_message(data)

        src_addr = self.my_address
        dest_loc = self.forwarding_table.get_locator_for_id(dest_id)
        dest_addr = ILNPAddress(dest_loc, dest_id)
        logger.info("Sending data from {} to {}".format(
            str(src_addr), str(dest_addr)))
        packet = ILNPPacket(src_addr,
                            dest_addr,
                            payload=message,
                            payload_length=message.size_bytes())

        self.packet_queue.put(packet)
Exemple #12
0
def parse_packet(data) -> ILNPPacket:
    """Parses contents of packet"""
    packet = ILNPPacket.from_bytes(data)
    packet.payload = ControlMessage.from_bytes(packet.payload)
    return packet