diff --git a/squinnondation/hazel.py b/squinnondation/hazel.py index 2a4a5ab..4a1da53 100644 --- a/squinnondation/hazel.py +++ b/squinnondation/hazel.py @@ -36,8 +36,8 @@ class Hazelnut: # See https://fr.wikipedia.org/wiki/Adresse_IPv6_mappant_IPv4 address = "::ffff:" + socket.getaddrinfo(address, None, socket.AF_INET)[0][4][0] - self.addresses = list() - self.addresses.append((address, port)) + self.addresses = set() + self.addresses.add((address, port)) @property def potential(self) -> bool: @@ -53,7 +53,7 @@ class Hazelnut: A client can have multiple addresses. We contact it only on one of them. """ - return self.addresses[0] + return list(self.addresses)[0] @property def banned(self) -> bool: @@ -68,6 +68,19 @@ class Hazelnut: def __str__(self): return repr(self) + def merge(self, other: "Hazelnut") -> "Hazelnut": + """ + Merge the hazelnut data with one other. + The symmetric and active properties are kept from the original client. + """ + self.errors = max(self.errors, other.errors) + self.last_hello_time = max(self.last_hello_time, other.last_hello_time) + 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) + self.id = self.id if self.id > 0 else other.id + return self + class Squirrel(Hazelnut): """ @@ -686,19 +699,13 @@ class Squirrel(Hazelnut): if addr in self.hazelnuts: # Merge with the previous hazel old_hazel = self.hazelnuts[addr] - for other_addr in old_hazel.addresses: - if other_addr not in hazelnut.addresses: - hazelnut.addresses.append(other_addr) - self.hazelnuts[other_addr] = hazelnut + hazelnut.merge(old_hazel) self.hazelnuts[addr] = hazelnut for other_hazel in list(self.hazelnuts.values()): if other_hazel.id == hazelnut.id > 0 and other_hazel != hazelnut: # The hazelnut with the same id is known as a different address. We merge everything - for addr in other_hazel.addresses: - self.hazelnuts[addr] = hazelnut - if addr not in hazelnut.addresses: - hazelnut.addresses.append(addr) + hazelnut.merge(other_hazel) def send_neighbours(self) -> None: """