diff --git a/squinnondation/hazel.py b/squinnondation/hazel.py index 06f4ad8..dd74177 100644 --- a/squinnondation/hazel.py +++ b/squinnondation/hazel.py @@ -35,8 +35,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.address = address # IPv6Address(address) - self.port = port + self.addresses = list() + self.addresses.append((address, port)) @property def potential(self) -> bool: @@ -46,6 +46,10 @@ class Hazelnut: def potential(self, value: bool) -> None: self.active = not value + @property + def main_address(self) -> Tuple[str, int]: + return self.addresses[0] + class Squirrel(Hazelnut): """ @@ -61,7 +65,7 @@ class Squirrel(Hazelnut): # Create UDP socket self.socket = socket.socket(socket.AF_INET6, socket.SOCK_DGRAM) # Bind the socket - self.socket.bind((self.address, self.port)) + self.socket.bind(self.main_address) self.squinnondation = instance @@ -94,7 +98,7 @@ class Squirrel(Hazelnut): self.hazel_manager = HazelManager(self) self.inondator = Inondator(self) - self.add_system_message(f"Listening on {self.address}:{self.port}") + self.add_system_message(f"Listening on {self.main_address[0]}:{self.main_address[1]}") self.add_system_message(f"I am {self.id}") def new_hazel(self, address: str, port: int) -> Hazelnut: @@ -139,7 +143,7 @@ class Squirrel(Hazelnut): Send a raw packet to a client. """ self.refresh_lock.acquire() - res = self.socket.sendto(data, (client.address, client.port)) + res = self.socket.sendto(data, client.main_address) self.refresh_lock.release() return res @@ -367,7 +371,8 @@ class Squirrel(Hazelnut): self.refresh_lock.acquire() if (sender_id, nonce) in self.recent_messages: # If a peer is late in its acknowledgement, the absence of the previous if causes an error. - self.recent_messages[(sender_id, nonce)][2].pop((hazel.address, hazel.port), None) + for addr in hazel.addresses: + self.recent_messages[(sender_id, nonce)][2].pop(addr, None) if not self.recent_messages[(sender_id, nonce)][2]: # If dictionnary is empty, remove the message self.recent_messages.pop((sender_id, nonce), None) @@ -660,7 +665,13 @@ class Squirrel(Hazelnut): self.refresh_lock.release() def update_hazelnut_table(self, hazelnut: Hazelnut) -> None: - self.hazelnuts[(hazelnut.address, hazelnut.port)] = hazelnut + for addr in hazelnut.addresses: + if addr in self.hazelnuts: + 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[addr] = hazelnut def send_neighbours(self) -> None: """ @@ -676,7 +687,7 @@ class Squirrel(Hazelnut): if time.time() - hazelnut.last_long_hello_time <= 2 * 60: nb_ns += 1 self.hazelnuts[key].symmetric = True - ntlv = NeighbourTLV().construct(hazelnut.address, hazelnut.port) + ntlv = NeighbourTLV().construct(*hazelnut.main_address) pkt = Packet().construct(ntlv) for destination in self.activehazelnuts.values(): if destination.id != hazelnut.id: diff --git a/squinnondation/messages.py b/squinnondation/messages.py index 2b94af8..e718e34 100644 --- a/squinnondation/messages.py +++ b/squinnondation/messages.py @@ -222,7 +222,7 @@ class NeighbourTLV(TLV): self.port.to_bytes(2, sys.byteorder) def handle(self, squirrel: Any, sender: Any) -> None: - if squirrel.address == str(self.ip_address) and squirrel.port == self.port: + if (self.ip_address, self.port) in squirrel.addresses: # This case should never happen (and in our protocol it is not possible), # but we include this test as a security measure. return