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)
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)
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"])
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
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
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())
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"]))
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()
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.")
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.")
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)
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
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
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