示例#1
0
    def test_json_encoding(self):
        packet = BBBPacket('2.2.2.2', '3.3.3.3', BBBPacketType.FLOOD, 'memes',
                           0)
        packet_bytes = packet.to_bytes()
        packet_redux = BBBPacket.from_bytes(packet_bytes)

        assert packet.__dict__ == packet_redux.__dict__

        h = SHA256.new(packet_bytes)
        h_redux = SHA256.new(packet_redux.to_bytes())
        assert h.hexdigest() == h_redux.hexdigest()

        router1 = BasicRouter('1.1.1.1', test=True)
        router1.sign(packet)

        packet_bytes = packet.to_bytes()
        packet_redux = BBBPacket.from_bytes(packet_bytes)

        assert packet.__dict__ == packet_redux.__dict__
        router1.keys['2.2.2.2'] = router1.packet_key.publickey()
        assert router1.verify(packet_redux)
        router1.sqn_numbers['2.2.2.2'] = -1
        assert router1.verify(packet)
示例#2
0
    def update_neighbors(self):
        """Periodically sends out routing information to neighbors.
        Implements Split Horizon to avoid Count-to-Infinity problems.
        """
        while True:
            # Calculate a dictionary where each key is the ip of a neighbor
            # and the value is a list of all the destinations we should display
            # format: {neighbor_ip: [dst_ip]}
            route_updates = {
                n: [d for d in self.routes if self.routes[d] != n]
                for n in self.neighbors
            }

            # Iterate through calculated updates
            for neighbor, routes in route_updates.items():
                if routes:
                    # Get old socket for the neighbors_ip if it exists
                    try:
                        neighbor_socket = self.sockets[neighbor]
                    except KeyError:
                        # If it does not exist, make a new one, store it in
                        # the list of open sockets and dispatch a client thread
                        neighbor_endpoint = (neighbor, ROUTER_PORT)
                        neighbor_socket = socket.socket()
                        neighbor_socket.connect(neighbor_endpoint)
                        self.sockets[neighbor] = neighbor_socket
                        threading.Thread(target=self.handle_client,
                                         args=(neighbor_socket,
                                               neighbor_endpoint)).start()

                    # Create and send appropriate route packet for neighbor
                    self.sqn_lock.acquire()
                    route_packet = BBBPacket(
                        src=self.ip_address,
                        dst=neighbor,
                        type=BBBPacketType.ROUTEUPDATE,
                        payload=json.dumps(routes),
                        seq=self.sqn_counter,
                    )
                    self.sqn_counter += 1
                    self.sqn_lock.release()
                    self.sign(route_packet)
                    self.socket_lock.acquire()
                    neighbor_socket.sendall(route_packet.to_bytes())
                    self.socket_lock.release()
            time.sleep(30)
示例#3
0
    def test_handle_flood_flood(self):
        router1 = BasicRouter('1.1.1.1', test=True)
        router2 = BasicRouter('2.2.2.2', test=True)
        router1.neighbors.add('2.2.2.2')
        router1.neighbors.add('3.3.3.3')
        router1.sockets['2.2.2.2'] = Mock()
        router1.sockets['3.3.3.3'] = Mock()

        message = 'hello world'
        packet = BBBPacket('2.2.2.2', '3.3.3.3', BBBPacketType.FLOOD, message,
                           0)

        router2.sign(packet)
        router1.keys['2.2.2.2'] = router2.packet_key.publickey()
        router1.handle_flood(packet, ('2.2.2.2', 9999))
        # Packet should be sent to 3.3.3.3, but not 2.2.2.2
        router1.sockets['2.2.2.2'].sendall.assert_not_called()
        router1.sockets['3.3.3.3'].sendall.assert_called_with(
            packet.to_bytes())
示例#4
0
 def send_hello_flood(self, dst, count):
     """Function to simply send a packet with hello string as its payload.
     Invoked via CLI.
     """
     for i in range(int(count)):
         for address in self.neighbors:
             self.sqn_lock.acquire()
             packet = BBBPacket(
                 src=self.ip_address,
                 dst=dst,
                 type=BBBPacketType.FLOOD,
                 payload="hello-{0}".format(i),
                 seq=self.sqn_counter,
             )
             self.sqn_counter += 1
             self.sqn_lock.release()
             self.sign(packet)
             self.socket_lock.acquire()
             self.sockets[address].sendall(packet.to_bytes())
             self.socket_lock.release()
         time.sleep(10)
示例#5
0
    def __init__(self, topo_path="simple.json"):
        """Constructor
        @topo_path      name of the topology file to parse
        """
        self.sockets = {}
        seq_num = 0

        # Load the network topology from the json file
        self.topology = {}
        with open(path_join(TOPO_DIRECTORY, topo_path), 'r') as topo_file:
            self.topology = json.loads(topo_file.read())

        while True:
            for host, config in self.topology.items():
                # get corresponding socket for host
                print("attempting to connect to: {0}".format(host))
                endpoint = (host, ROUTER_PORT)
                try:
                    host_socket = self.sockets[endpoint]
                except KeyError:
                    # create and store a new socket if necessary
                    host_socket = socket.socket()
                    self.sockets[endpoint] = host_socket
                    host_socket.connect(endpoint)

                # create configuration packet and send it to the host
                config_packet = BBBPacket(
                    src=host_socket.getsockname()[0],
                    dst=host,
                    type=BBBPacketType.MASTERCONFIG,
                    payload=json.dumps(config),
                    seq=seq_num,
                )
                host_socket.sendall(config_packet.to_bytes())
                seq_num += 1
            sleep(TOPO_UPDATE_PERIOD)