diff --git a/squinnondation/messages.py b/squinnondation/messages.py index 7a228ef..56694fd 100644 --- a/squinnondation/messages.py +++ b/squinnondation/messages.py @@ -173,12 +173,9 @@ class HelloTLV(TLV): user.send_packet(sender, Packet.construct(WarningTLV.construct( f"You were known as the ID {sender.id}, but you declared that you have the ID {self.source_id}."))) user.add_system_message(f"A client known as the id {sender.id} declared that it uses " - f"the id {self.source_id}.") + f"the id {self.source_id}.") sender.id = self.source_id - if self.source_id == user.id: - sender.marked_as_banned = True - if not sender.active: sender.id = self.source_id # The sender we are given misses an id time_hl = time.time() diff --git a/squinnondation/peers.py b/squinnondation/peers.py index 90c2a54..a63d7ba 100644 --- a/squinnondation/peers.py +++ b/squinnondation/peers.py @@ -27,7 +27,6 @@ class Peer: self.symmetric = False self.active = False self.errors = 0 - self.marked_as_banned = False try: # Resolve DNS as an IPv6 @@ -44,7 +43,7 @@ class Peer: @property def potential(self) -> bool: - return not self.active and not self.banned + return not self.active and not self.banned and not isinstance(self, User) @potential.setter def potential(self, value: bool) -> None: @@ -55,7 +54,7 @@ class Peer: """ If a client send more than 5 invalid packets, we don't trust it anymore. """ - return self.errors >= 5 or self.marked_as_banned + return self.errors >= 5 or isinstance(self, User) def __repr__(self): return self.nickname or str(self.id) or str(self.main_address) @@ -73,12 +72,11 @@ class Peer: self.last_long_hello_time = max(self.last_hello_time, other.last_long_hello_time) self.addresses.update(self.addresses) self.addresses.update(other.addresses) - if self.main_address[1] == 1212: #always prefer the non-multicast address + if self.main_address[1] == 1212: # always prefer the non-multicast address self.main_address = other.main_address elif other.main_address[1] == 1212: other.main_address = self.main_address self.id = self.id if self.id > 0 else other.id - self.marked_as_banned = other.marked_as_banned return self @@ -105,9 +103,12 @@ class User(Peer): self.multicast_socket = socket.socket(socket.AF_INET6, socket.SOCK_DGRAM, socket.IPPROTO_UDP) # Allows address to be reused self.multicast_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) - self.multicast_socket.bind(('', 1212)) #listen on all interfaces? - # To join the group, we need to give setsockopt a binary packed representation of the multicast group's address and on what interfaces we will listen (here all) - mreq = struct.pack("16s15s", socket.inet_pton(socket.AF_INET6, "ff02::4242:4242"), bytes(socket.INADDR_ANY)) #The string "16s15s" corresponds to the packing options: here it packs the arguments into a 16-byte string and a 15-byte string. + self.multicast_socket.bind(('', 1212)) # listen on all interfaces? + # To join the group, we need to give setsockopt a binary packed representation of the multicast + # group's address and on what interfaces we will listen (here all) + mreq = struct.pack("16s15s", socket.inet_pton(socket.AF_INET6, "ff02::4242:4242"), bytes(socket.INADDR_ANY)) + # The string "16s15s" corresponds to the packing options: here it packs the arguments into a 16-byte + # string and a 15-byte string. self.multicast_socket.setsockopt(socket.IPPROTO_IPV6, socket.IPV6_JOIN_GROUP, mreq) self.input_buffer = "" @@ -133,7 +134,7 @@ class User(Peer): curses.init_pair(i + 1, i, curses.COLOR_BLACK) # dictionnaries of neighbours - self.neighbours = dict() + self.neighbours = {self.main_address: self} self.nbNS = 0 self.minNS = 3 # minimal number of symmetric neighbours a user needs to have. @@ -166,14 +167,14 @@ class User(Peer): Translate an address into a peer. If this peer does not exist, creates a new peer. """ - self.data_lock.acquire() - if (address, port) in self.neighbours: return self.neighbours[(address, port)] + + self.data_lock.acquire() peer = Peer(address=address, port=port) self.neighbours[(address, port)] = peer - self.data_lock.release() + return peer def find_peer_by_id(self, peer_id: int) -> Peer: @@ -931,21 +932,25 @@ class User(Peer): If there is a collision with the address / the ID, then we merge clients into a unique one. """ self.data_lock.acquire() - + for addr in peer.addresses: if addr in self.neighbours: # Merge with the previous peer old_peer = self.neighbours[addr] + if isinstance(old_peer, User): + peer, old_peer = old_peer, peer peer.merge(old_peer) self.neighbours[addr] = peer for other_peer in list(self.neighbours.values()): if other_peer.id == peer.id > 0 and other_peer != peer: # The peer with the same id is known as a different address. We merge everything + if isinstance(other_peer, User): + peer, old_peer = other_peer, peer peer.merge(other_peer) for other_addr in peer.addresses: self.neighbours[other_addr] = peer - + self.data_lock.release() def send_neighbours(self) -> None: