示例#1
0
    def process_update(self, message):
        if "db" not in message:
            self.send_error(message["txid"], "Missing field in packet of type 'update'. Expected 'db'.", message["address"])
            return False
        if type(message["db"]) is not dict:
            self.send_error(message["txid"], "Invalid contents of field 'db'.", message["address"])
            return False

        node_list = []
        for na in message["db"]:
            address = self.check_node_address(na)
            if address is False:
                self.send_error(message["txid"], "Invalid index of DB_RECORD.", message["address"])
                return False
            node_list.append(address)
            
        node_key = "{ip},{po}".format(ip = message["address"][0], po = message["address"][1])
        if node_key in message["db"] and not self.check_node_db(message["db"][node_key]):
            self.send_error(message["txid"], "Invalid contents of DB_RECORD.", message["address"])
            return False
        if not self.node_db.update_node(message["address"][0], message["address"][1], message["db"][node_key]):
            self.packet_queue.queue_message(tools.create_packet("update", db = self.node_db.get_database()), message["address"])

        self.node_db.remove_known_nodes(node_list)
        for na in node_list:
            self.packet_queue.queue_message(tools.create_packet("update", db = self.node_db.get_database()), na)
示例#2
0
 def process_getlist(self, message):
     peerlist = self.node_db.getlist_peer(message["address"])
     if peerlist == None:
         self.send_error(message["txid"], "Can't answer to unregistered peers.", message["address"])
         return False
         
     ack = tools.create_packet("ack")
     ack["txid"] = message["txid"]
     self.packet_queue.queue_message(ack, message["address"])
     response = tools.create_packet("list", peers = peerlist)
     response["txid"] = message["txid"]
     self.packet_queue.queue_message(response, message["address"], 2, 2)
示例#3
0
    def run(self):
        while not (self.stop and self.packet_queue.empty()):
            message = self.recieve()
            if message == "stop":
                self.stop = True
                continue
            if message is False:
                continue

            if message["type"] == "hello":
                self.process_hello(message)
            elif message["type"] == "getlist":
                self.process_getlist(message)
            elif message["type"] == "update":
                self.process_update(message)
            elif message["type"] == "disconnect":
                self.node_db.disconnect_node(message["address"][0], message["address"][1])
                ack = tools.create_packet("ack")
                ack["txid"] = message["txid"]
                self.packet_queue.queue_message(ack, message["address"])
            elif message["type"] == "ack":
                self.packet_queue.pop_ack(message["txid"])
                self.node_db.pop_block(message["txid"])
            else:
                self.send_error(message["txid"], "Error: Unexpected packet of type '{}'".format(message["type"]), message["address"])
示例#4
0
 def disconnect_from_nodes(self):
     nodes = self.node_db.get_nodes()
     txids = []
     for n in nodes:
         p = tools.create_packet("disconnect")
         txids.append(p["txid"])
         self.packet_queue.queue_message(p, (n["ipv4"], n["port"]), 2, 2, 3)
     self.node_db.disconnect_all(txids)
     return True
示例#5
0
 def send_message(self, sender, recipient, message):
     if sender != self.info.username:
         tools.err_print(
             "Warning: --from argument value does not match the username set to peer. Using the --from value anyway."
         )
     MessageThread(
         tools.create_packet("message",
                             fro=sender,
                             to=recipient,
                             message=message), self.packet_queue,
         self.peerlist,
         (str(self.info.reg_ipv4), self.info.reg_port)).start()
     return True
示例#6
0
    def run(self):
        while not self.stop_event.is_set():
            next_hello = self.node_db.get_oldest_hello() + 30
            next_echo = self.node_db.get_oldest_echo() + 12
            next_unblock = self.node_db.get_oldest_block() + 2
            nodes_to_update = []
            next_update = self.node_db.get_oldest_update(nodes_to_update) + 4

            if len(nodes_to_update) > 0:
                update_db = self.node_db.get_database()
                for address in nodes_to_update:
                    self.packet_queue.queue_message(tools.create_packet("update", db = update_db), address)

            self.stop_event.wait(min(next_hello, next_echo, next_unblock, next_update) - time.time())
示例#7
0
    def process_message(self, message):
        if not all(f in message for f in ("from", "to", "message")):
            self.send_error(
                message["txid"],
                "Missing fields in 'message' packet. Expected 'from', 'to' and 'message'.",
                message["address"])
            return False
        if not message["to"] == self.username:
            self.send_error(message["txid"], "Incorrect IP or username.",
                            message["address"])
            return False

        ack = tools.create_packet("ack")
        ack["txid"] = message["txid"]
        self.packet_queue.queue_message(ack, message["address"])
        print("{frm}: {msg}".format(frm=message["from"],
                                    msg=message["message"]))
示例#8
0
    def __init__(self, info):
        self.info = info
        self.hello_packet = tools.create_packet("hello",
                                                username=self.info.username,
                                                ipv4=str(self.info.chat_ipv4),
                                                port=self.info.chat_port)
        self.peerlist = PeerList()

        self.socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
        self.socket.bind((str(self.info.chat_ipv4), self.info.chat_port))
        self.packet_queue = tools.PacketQueue()

        self.listen_thread = ListenThread(self.socket, self.packet_queue,
                                          self.peerlist, self.info.username)
        self.send_thread = tools.SendThread(self.socket, self.packet_queue)
        self.hello_thread = HelloThread(
            self.hello_packet, (str(self.info.reg_ipv4), self.info.reg_port),
            self.packet_queue)
        self.listen_thread.start()
        self.send_thread.start()
        self.hello_thread.start()
示例#9
0
    def run(self):
        ack_wait_event = threading.Event()
        self.packet_queue.queue_message(tools.create_packet("getlist"),
                                        self.node,
                                        1,
                                        2,
                                        ack_event=ack_wait_event)
        if not ack_wait_event.wait(2):
            tools.err_print("ERROR: GETLIST not ACK'ed.")
            return

        if self.peerlist.update_event.wait(2):
            address = self.peerlist.get_address(self.message["to"])
            if not address == None:
                self.packet_queue.queue_message(self.message, address, 2, 2)
            else:
                tools.err_print(
                    "ERROR: No peer with username {} found.".format(
                        self.message["to"]))
        else:
            tools.err_print("ERROR: No LIST recieved.")
示例#10
0
    def run(self):
        ack_wait_event = threading.Event()
        self.packet_queue.queue_message(tools.create_packet("getlist"),
                                        self.node,
                                        1,
                                        2,
                                        ack_event=ack_wait_event)
        if not ack_wait_event.wait(2):
            tools.err_print("ERROR: GETLIST not ACK'ed.")
            return

        if self.peerlist.update_event.wait(5):
            print("- - - - - - - - - -")
            print("       PEERS       ")
            print("- - - - - - - - - -")
            peers = self.peerlist.get_list()
            for p in peers:
                print("{} at {}:{}".format(p["username"], p["ipv4"],
                                           p["port"]))
            print("- - - - - - - - - -")
        else:
            tools.err_print("ERROR: No LIST recieved.")
示例#11
0
    def process_list(self, message):
        if not "peers" in message:
            self.send_error(message["txid"],
                            "Missing 'peers' field in packet of type 'list'.",
                            message["address"])
            return False
        peers = message["peers"]
        if type(peers) is not dict:
            self.send_error(message["txid"],
                            "Invalid contents of 'peers' field.",
                            message["address"])
            return False
        for p in peers:
            if not self.check_peer_record(peers[p]):
                self.send_error(message["txid"],
                                "Invalid contents of 'peers' field.",
                                message["address"])
                return False

        ack = tools.create_packet("ack")
        ack["txid"] = message["txid"]
        self.packet_queue.queue_message(ack, message["address"])
        self.peerlist.update(peers)
示例#12
0
 def update_peer_list(self):
     self.packet_queue.queue_message(
         tools.create_packet("getlist"),
         (str(self.info.reg_ipv4), self.info.reg_port), 2, 2)
     return True
示例#13
0
 def synchronise_with_nodes(self):
     nodes = self.node_db.get_nodes()
     for n in nodes:
         self.packet_queue.queue_message(tools.create_packet("update", db = self.node_db.get_database()), (n["ipv4"], n["port"]))
     return True
示例#14
0
 def connect_to_node(self, ip, port):
     self.packet_queue.queue_message(tools.create_packet("update", db = self.node_db.get_database()), (ip, port))
     return True