diff --git a/squinnondation/hazel.py b/squinnondation/hazel.py index 4d1806e..58bc52a 100644 --- a/squinnondation/hazel.py +++ b/squinnondation/hazel.py @@ -73,13 +73,13 @@ class Squirrel(Hazelnut): #dictionnaries of neighbours self.potentialhazelnuts = dict() self.activehazelnuts = dict() #of the form [hazelnut, time of last - #hello, time of last long hello] + #hello, time of last long hello, is symmetric] self.nbNS = 0 self.minNS = 3 #minimal number of symetric neighbours a squirrel needs #to have. self.add_system_message(f"Listening on {self.address}:{self.port}") - self.add_system_message(f"I am {self.id}}") + self.add_system_message(f"I am {self.id}") def new_hazel(self, address: str, port: int) -> Hazelnut: """ @@ -561,14 +561,17 @@ class Squirrel(Hazelnut): nbNS = 0 #could send the same to all neighbour, but it means that neighbour A could receive a message with itself in it -> if the others do not pay attention, trouble - for hazelnut in self.activehazelnuts.values() : - if time.time()-hazelnut[2]<=2*60: + for key, hazelnut in self.activehazelnuts.items() : + if time.time()-hazelnut[2]<=10 : #2*60 nbNS+=1 + self.activehazelnuts[key][3] = True ntlv = NeighbourTLV().construct(hazelnut[0].address,hazelnut[0].port) pkt = Packet().construct(ntlv) for destination in self.activehazelnuts.values() : if destination[0].id != hazelnut[0].id : self.send_packet(destination[0], pkt) + else: + self.activehazelnuts[key][3] = False self.nbNS = nbNS self.refresh_lock.release() @@ -634,6 +637,18 @@ class HazelManager(Thread): if time.time()-self.last_neighbour > 10: #60 : self.squirrel.send_neighbours() self.last_neighbour = time.time() + +class Inondator(Thread): + """ + A process to manage the inondation + """ + def __init__(self, squirrel: Squirrel, *args, **kwargs): + super().__init__(*args, **kwargs) + self.squirrel = squirrel + self.last_check = 0 + + def run(self) -> None: + while True: class Message: diff --git a/squinnondation/messages.py b/squinnondation/messages.py index cdc7ff7..7207532 100644 --- a/squinnondation/messages.py +++ b/squinnondation/messages.py @@ -2,7 +2,7 @@ # SPDX-License-Identifier: GPL-3.0-or-later import re from typing import Any, List, Optional -#from ipaddress import IPv6Address +from ipaddress import IPv6Address from enum import Enum import socket import sys @@ -168,7 +168,7 @@ class HelloTLV(TLV): squirrel.remove_from_potential(sender.address, sender.port) squirrel.activehazelnuts[(sender.address, sender.port)] = [sender, timeH,\ - timeHL] + timeHL, True] squirrel.nbNS += 1 squirrel.add_system_message(f"Aaaawwww, {self.source_id} spoke to me and said me Hello " + ("long" if self.is_long else "short")) @@ -195,13 +195,13 @@ class HelloTLV(TLV): class NeighbourTLV(TLV): type: int = 3 length: int - ip_address: str + ip_address: IPv6Address port: int def unmarshal(self, raw_data: bytes) -> None: self.type = raw_data[0] self.length = raw_data[1] - self.ip_address = raw_data[2:18]#IPv6Address() + self.ip_address = IPv6Address(raw_data[2:18]) self.port = int.from_bytes(raw_data[18:20], sys.byteorder) def marshal(self) -> bytes: @@ -211,8 +211,8 @@ class NeighbourTLV(TLV): self.port.to_bytes(2, sys.byteorder) def handle(self, squirrel: Any, sender: Any) -> None: - if not (self.ip_address,self.port) in squirrel.activehazelnuts and not (self.ip_address,self.port) in squirrel.potentialhazelnuts: - squirrel.potentialhazelnuts[(self.ip_address, self.port)] = squirrel.new_hazel(self.ip_address, self.port) + if not (str(self.ip_address),self.port) in squirrel.activehazelnuts and not (str(self.ip_address),self.port) in squirrel.potentialhazelnuts: + squirrel.potentialhazelnuts[(str(self.ip_address), self.port)] = squirrel.new_hazel(str(self.ip_address), self.port) squirrel.add_system_message(f"New potential friend {self.ip_address}:{self.port}!") @staticmethod @@ -220,7 +220,7 @@ class NeighbourTLV(TLV): tlv = NeighbourTLV() tlv.type = 3 tlv.length = 18 #A priori... - tlv.ip_address = address + tlv.ip_address = IPv6Address(address) tlv.port = port return tlv @@ -256,12 +256,13 @@ class DataTLV(TLV): TODO: Check that the tuple (sender_id, nonce) is unique to avoid duplicates. """ msg = self.data.decode('UTF-8') - if not squirrel.receive_message_from(msg, self.sender_id, self.nonce): - # The message was already received - return - + # Acknowledge the packet squirrel.send_packet(sender, Packet.construct(AckTLV.construct(self.sender_id, self.nonce))) + + if not squirrel.receive_message_from(msg, self.sender_id, self.nonce): + # The message was already received, do not print it + return nickname_match = re.match("(.*): (.*)", msg) if nickname_match is None: @@ -339,7 +340,7 @@ class GoAwayTLV(TLV): def unmarshal(self, raw_data: bytes) -> None: self.type = raw_data[0] self.length = raw_data[1] - self.code = GoAwayTLV.GoAwayType(raw_data[2]) + self.code = GoAwayType(raw_data[2]) self.message = raw_data[3:self.length - 1].decode("UTF-8") def marshal(self) -> bytes: @@ -350,7 +351,7 @@ class GoAwayTLV(TLV): def handle(self, squirrel: Any, sender: Any) -> None: if squirrel.is_active(sender) : - squirrel.activehazelnuts.pop((sender.addess, sender.port)) + squirrel.activehazelnuts.pop((sender.address, sender.port)) squirrel.potentialhazelnuts[(sender.address, sender.port)] = sender squirrel.add_system_message("Some told me that he went away : "+self.message)