コード例 #1
0
    def forward_to_main_router(self, parsed_message):
        new_source_mac = self.router_data["server_side"]["mac_address"]
        destination_ip = parsed_message["destination_ip"]

        # find the router to which this one is connected
        for ip_address in self.network_connections:
            self.main_router_ip_address = ip_address
            break


        new_destination_mac = self.arp_table_mac[self.main_router_ip_address]
        destination_socket = self.socket_server_side

        parsed_message.update(
            source_mac=new_source_mac,
            destination_mac=new_destination_mac
        )
        
        utils.show_status(
            self.router_id,
            "notifying main router of incoming message"
        )
        self.notify_incoming_message()

        self.send_message(parsed_message, destination_socket, destination_ip)
コード例 #2
0
    def run(self):

        utils.show_status(self.getName(), "starting")
        connected = self.go_online()
        if(self.connected_to_server is False):
            if(connected is True):
                utils.show_status(self.router_id, "listening for packets")
            
                while not self.stop_event.isSet():
                    self.listen_server_side_aux_router()

                utils.show_status(self.router_id, "closing connections")
                # self.socket_server_side.shutdown(0)
                self.socket_server_side.close()
                # self.socket_client_side.shutdown(0)
                self.socket_client_side.close()

            # exit procedure
            self.stop_event.clear()
            utils.show_status(self.router_id, "going offline")
            del self.routers_threads[self.router_id]
        elif(connected is True):
            utils.show_status(self.router_id, "listening for packets")
        else:
            self.join()
コード例 #3
0
    def notify_incoming_connection(self):
        msg = " ".join(["notifying",self.router_id, \
         "of an incoming connection"])
        utils.show_status(self.client_id, msg)

        listen_task = threading.Thread(
            target=self.router_thread.listen_connections_client_side,
            daemon=True)
        listen_task.start()
コード例 #4
0
 def notify_incoming_message(self):
     msg = " ".join(["notifying", self.router_id, "of an incoming message"])
     utils.show_status(self.client_id, msg)
     my_ip_address = self.client_data["ip_address"]
     listen_task = threading.Thread(
         target=self.router_thread.listen_client_side,
         args=[my_ip_address],
         daemon=True)
     listen_task.start()
コード例 #5
0
    def accept_connections(self):
        connections = len(self.routers_gateway_ip) + 1

        while connections > 0:
            connected = self.listen_connections_server_side()
            if(connected is True): 
                connections -= 1

        utils.show_status(self.router_id, "all connections established")
コード例 #6
0
 def go_online(self):
     if(self.server_ip in self.network_connections): 
         self.connected_to_server = True
         self.accept_connections() 
         connected = True
     else:   # connect with routers in network_connections
         connected = self.connect_with_routers()
         
     utils.show_status(self.router_id, "connected to the network")
     return connected
コード例 #7
0
    def listen_client_side(self, ip_address):      
        utils.show_status(
            self.router_id,
            "releasing lock, client can send the message"
        )
        # releasing lock, client can send the message
        self.sync_event_message.set()

        sender_socket = self.arp_table_socket[ip_address]
        self.listen_on_demand(sender_socket, self.handle_message_client_side)
コード例 #8
0
 def join(self, timeout=None):
     if(self.connected_to_server is True):
         utils.show_status(self.router_id, "going offline")
         self.socket_server_side.close()
         self.socket_client_side.close()
         self.stop_event.clear()
         del self.routers_threads[self.router_id]
     else:
         self.stop_event.set()
         threading.Thread.join(self, timeout)
コード例 #9
0
    def send_message(self, parsed_message):
        destination_ip = self.server_data["gateway_ip"]
        packet = utils.rewrite_packet(parsed_message)

        msg = " ".join(["Sending message to:", destination_ip])
        utils.show_status(self.server_id, msg)

        self.notify_incoming_connection()  # alert main router

        check.socket_send(self.server_connection, packet,
                          "Could not send the message")
コード例 #10
0
    def handle_message_server_side(self, parsed_message):

        utils.show_status(
            self.router_id,
            "deciding where the message should go..."
        )

        if(self.connected_to_server is True):
            self.handle_message_main_router(parsed_message)
        else:
            self.handle_message_aux_router(parsed_message)
コード例 #11
0
    def notify_incoming_connection(self):
        msg = " ".join(["notifying",self.router_id, \
         "of an incoming connection"])
        utils.show_status(self.server_id, msg)

        my_ip_address = self.server_data["ip_address"]
        listen_task = threading.Thread(
            target=self.router_thread.listen_server_side_main_router,
            args=[my_ip_address],
            daemon=True)
        listen_task.start()
コード例 #12
0
    def forward_message(self, parsed_message):
        msg = " ".join(["client", parsed_message["destination_ip"], \
            "is online: forwading message"])
        utils.show_status(self.server_id, msg)

        parsed_message.update(
            source_mac=self.server_data.get("mac_address"),
            destination_mac=self.arp_table_mac[self.server_data["gateway_ip"]])

        utils.report(self.server_id, parsed_message,
                     "reading packet received from a router")

        self.send_message(parsed_message)
コード例 #13
0
    def handle_message(self, parsed_message):
        time.sleep(2)
        utils.show_status(self.server_id,
                          "deciding how to handle the message...")

        if (parsed_message["message"] == "{going offline}"):
            self.mark_client_offline(parsed_message)
        elif (parsed_message["message"] == "{going online}"):
            self.mark_client_online(parsed_message)
        elif (self.is_client_unreachable(parsed_message)):
            self.resend_back_message(parsed_message)
        else:
            self.forward_message(parsed_message)
コード例 #14
0
    def resend_back_message(self, parsed_message):
        msg = " ".join(["client", parsed_message["destination_ip"], \
            "is not online: resending message back"])
        utils.show_status(self.server_id, msg)

        sender_ip_address = parsed_message["source_ip"]
        parsed_message.update(
            source_ip=self.server_data.get("ip_address"),
            source_mac=self.server_data.get("mac_address"),
            destination_ip=sender_ip_address,
            destination_mac=self.arp_table_mac[self.server_data["gateway_ip"]],
            message="Client not currently available")

        self.send_message(parsed_message)
コード例 #15
0
    def go_online(self):
        utils.show_status(self.server_id, "connecting to the network")

        router_port = self.server_data["gateway_port"]
        router_address = ("localhost", router_port)
        gateway_ip = self.server_data["gateway_ip"]

        connected = check.socket_connect(self.server_connection,
                                         router_address, self.server_id)

        if (connected is True):
            msg = " ".join(["connected to", gateway_ip])
            utils.show_status(self.server_id, msg)

        return connected
コード例 #16
0
    def handle_message_client_side(self, parsed_message):
        client_ip = parsed_message.get("source_ip")
        client_mac = parsed_message["source_mac"]

        if(self.waiting_arp_request is True):
            self.arp_table_mac[client_ip] = client_mac
            self.waiting_arp_request = False
            message_to_send = self.packets_queue.pop()
            self.handle_message_server_side(message_to_send)
        elif(self.connected_to_server is True):
            self.forward_to_server(parsed_message)
        else:
            utils.show_status(self.router_id, "forwading to main router")
            self.forward_to_main_router(parsed_message)
        
        time.sleep(2)
コード例 #17
0
    def connect_with_routers(self):
        connected_to_all = True
        for ip_address, port in self.network_connections.items():
                connected = check.socket_connect(
                    self.socket_server_side,
                    ("localhost", port),
                    self.router_id
                )
                if(connected is True):
                    msg = " ".join(["connected with router:", ip_address])
                    utils.show_status(self.router_id, msg)
                else:
                    connected_to_all = False

        utils.show_status(self.router_id, "all connections established")
        return connected_to_all
コード例 #18
0
    def go_offline(self):

        utils.show_status(self.client_id, "going offline")
        gateway_ip = self.client_data["gateway_ip"]
        server_ip = self.client_data["server_ip"]

        leave_packet = utils.write_packet(self.client_data.get("ip_address"),
                                          server_ip,
                                          self.client_data.get("mac_address"),
                                          self.arp_table_mac[gateway_ip],
                                          "{going offline}")

        self.notify_incoming_message()
        self.sync_event_message.wait()  # wait for router approval
        self.sync_event_message.clear()

        check.socket_send(self.client_connection, leave_packet, self.client_id,
                          "Leave packet could not be sent")

        self.join()
コード例 #19
0
    def forward_to_client(self, parsed_message):
        destination_ip = parsed_message["destination_ip"]
        new_source_mac = self.router_data["client_side"]["mac_address"]

        if(destination_ip not in self.arp_table_mac 
                and self.waiting_arp_request is False):
            utils.show_status(self.router_id, "sending ARP request")
            self.send_arp_request(parsed_message, new_source_mac, destination_ip)
        else:
            utils.show_status(
                self.router_id,
                "forwading packet to recipient client"
            )                    
            new_destination_mac = self.arp_table_mac[destination_ip]
            self.forward_message(
                parsed_message, 
                new_source_mac, 
                destination_ip, 
                new_destination_mac
            )
コード例 #20
0
def load_network(path):
    network_data = {}
    try:
        with open(path, "r") as file:
            cfg = yaml.safe_load(file)
            servers_data = cfg["servers"]
            routers_data = cfg["routers"]
            clients_data = cfg["clients"]
    except yaml.YAMLError as err_msg:
        msg = " ".join(["error loading network configuration file", \
            str(err_msg)])
        utils.show_status("main", msg)
        sys.exit()

    # pack dictionaries
    network_data["servers_data"] = servers_data
    network_data["routers_data"] = routers_data
    network_data["clients_data"] = clients_data

    return network_data
コード例 #21
0
    def send_message(self, parsed_message, destination_socket, destination_ip):
        packet = utils.rewrite_packet(
            parsed_message    
        )

        utils.report(
            self.router_id,
            parsed_message,
            "preparing to forward the following packet:"
        )
        
        check.socket_send(
            destination_socket,
            packet,
            self.router_id,
            "packet to the client could not be sent"
        )

        msg = " ".join(["message sent to", destination_ip])
        utils.show_status(self.router_id, msg)
コード例 #22
0
    def listen_server_side_aux_router(self):

        received_message = check.socket_recv(
            self.socket_server_side,
            self.router_id
        )

        if(received_message is not None and len(received_message) > 0):

            parsed_message = utils.read_packet(received_message)

            msg = " ".join(["message received from:", self.server_ip])
            utils.show_status(self.router_id, msg)
            utils.report(
                self.router_id,
                parsed_message,
                "reading packet received"
            )

            self.handle_message_server_side(parsed_message)
コード例 #23
0
    def listen_packets(self):
        received_message = check.socket_recv(self.client_connection,
                                             self.client_id)

        if (received_message is not None and len(received_message) > 0):
            parsed_message = utils.read_packet(received_message)
            time.sleep(2)  # give time to router to show its status
            msg = " ".join(
                ["message received from:", parsed_message["source_ip"]])
            utils.show_status(self.client_id, msg)
            utils.report(self.client_id, parsed_message,
                         "reading received packet")

            if (parsed_message["destination_mac"] == BROADCAST_MAC):
                msg = " ".join([
                    "received an ARP request from", parsed_message["source_ip"]
                ])
                utils.show_status(self.client_id, msg)

                self.send_message(parsed_message.get("source_ip"),
                                  "{ARP reply}")
コード例 #24
0
    def listen_connections_server_side(self):

        network_connection, address = check.socket_accept(
            self.socket_server_side,
            "Connection could not be established"
        )
    
        if(network_connection != None and
            network_connection not in self.arp_table_socket):

            if(address[1] in self.routers_gateway_ip):
                ip_address = self.routers_gateway_ip[address[1]]
                msg = " ".join(["connected with router:", ip_address])
                utils.show_status(self.router_id, msg)
            else:
                msg = " ".join(["connected with server:", self.server_ip])
                utils.show_status(self.router_id, msg)
                ip_address = self.server_ip
            self.arp_table_socket[ip_address] = network_connection
            return True
        return False
コード例 #25
0
    def run(self):
        utils.show_status(self.getName(), "starting")
        connected = self.go_online()

        if (connected is True):
            utils.show_status(self.server_id, "listening for incoming packets")
            while not self.stop_event.isSet():
                self.listen_packets()

        # exit procedure
        utils.show_status(self.server_id, "closing connection")
        self.server_connection.close()
        utils.show_status(self.server_id, "going offline")
        del self.servers_threads[self.server_id]
コード例 #26
0
    def listen_connections_client_side(self):

        utils.show_status(
            self.router_id,
            "releasing lock, client can connect to this router"
        )
        self.sync_event_connection.set()

        while True:
            client_connection, address = check.socket_accept(
                self.socket_client_side,
                self.router_id
            )

            if(client_connection != None and 
            client_connection not in self.arp_table_socket):    
                    ip_address = self.clients_gateway_ip[address[1]]
                    self.arp_table_socket[ip_address] = client_connection
                    msg = " ".join(["connected with client", ip_address])
                    utils.show_status(self.router_id, msg)
                    self.sync_event_connection.set() # waiting for router approval
                    break # only the first valid connection is accepted
コード例 #27
0
    def send_message(self, recipient_ip, message):

        gateway_ip = self.client_data["gateway_ip"]

        packet = utils.write_packet(self.client_data["ip_address"],
                                    recipient_ip,
                                    self.client_data.get("mac_address"),
                                    self.arp_table_mac[gateway_ip], message)

        utils.show_status(self.client_id,
                          "waiting for router listening messages")
        self.notify_incoming_message()
        # waiting for router approving message sending
        self.sync_event_message.wait()

        sent = check.socket_send(self.client_connection, packet,
                                 self.router_id)
        if (sent is True):
            msg = " ".join(["message sent to", gateway_ip])
            utils.show_status(self.client_id, msg)

        self.sync_event_message.clear()
コード例 #28
0
def close_all_connections(entities_threads):
    utils.show_status("main", "beginning shutdown")
    # unpack dictionary and creating defensive copies to avoid changing
    # size of the dictionaries during iteration

    if ("servers_threads" in entities_threads):
        servers_threads = entities_threads["servers_threads"]
        servers_threads_list = list(servers_threads.values())
        for server_thread in servers_threads_list:
            server_thread.join()
    if ("routers_threads" in entities_threads):
        routers_threads = entities_threads["routers_threads"]
        routers_threads_list = list(routers_threads.values())
        for router_thread in routers_threads_list:
            router_thread.join()

    if ("clients_threads" in entities_threads):
        clients_threads = entities_threads["clients_threads"]
        clients_threads_list = list(clients_threads.values())
        for client_thread in clients_threads_list:
            client_thread.join()

    utils.show_status("main", "shutdown completed")
コード例 #29
0
    def notify_incoming_message(self):
        utils.show_status(
            self.router_id,
            "notifying an incoming message from this router"
        )
        
        my_ip_address = self.router_data["server_side"]["ip_address"]

        for router, router_data in self.routers_data.items():
            if(router_data["server_side"]["ip_address"] == \
            self.main_router_ip_address):
                router_id = router
                break

        router_thread = self.routers_threads[router_id]

        # tell the main router to start listening for a message 
        # from this router
        listen_task = threading.Thread(
            target=router_thread.listen_server_side_main_router,
            args=[my_ip_address],
            daemon=True
        )
        listen_task.start()
コード例 #30
0
    def go_online(self):

        utils.show_status(self.client_id, "connecting to the network")
        server_ip = self.client_data["server_ip"]
        router_port = self.client_data["gateway_port"]
        router_address = ("localhost", router_port)
        gateway_ip = self.client_data["gateway_ip"]

        self.notify_incoming_connection()
        # waiting for router approving connection
        self.sync_event_connection.wait()
        self.sync_event_connection.clear()  # ready for reuse

        connected = check.socket_connect(self.client_connection,
                                         router_address, self.client_id)

        if (connected is True):
            utils.show_status(self.client_id, "going online")
            # waiting for router completing connection procedure
            self.sync_event_connection.wait()
            self.sync_event_connection.clear()  # ready for reuse

            greeting_packet = utils.write_packet(
                self.client_data.get("ip_address"), server_ip,
                self.client_data.get("mac_address"),
                self.arp_table_mac[gateway_ip], "{going online}")

            utils.show_status(self.client_id,
                              "waiting for router accepting message")
            self.notify_incoming_message()
            # waiting for router approving message sending
            self.sync_event_message.wait()
            self.sync_event_message.clear()

            check.socket_send(self.client_connection, greeting_packet,
                              self.client_id,
                              "Greeting packet could not be sent")

        return connected