From 7abaa7bcd483ce6f0241dd87a92c1c3524a075b1 Mon Sep 17 00:00:00 2001 From: eichhornchen Date: Tue, 29 Dec 2020 15:06:27 +0100 Subject: [PATCH] Repaired a few bugs in inundation (and the bug notes in the last commit) --- squinnondation/hazel.py | 44 ++++++++++++++++++-------------- squinnondation/messages.py | 9 ++++--- squinnondation/squinnondation.py | 3 ++- 3 files changed, 32 insertions(+), 24 deletions(-) diff --git a/squinnondation/hazel.py b/squinnondation/hazel.py index 1071a14..d5fe396 100644 --- a/squinnondation/hazel.py +++ b/squinnondation/hazel.py @@ -301,7 +301,7 @@ class Squirrel(Hazelnut): This add the message in the history if not already done. Returns True iff the message was not already received previously. """ - if (sender_id, nonce) not in self.recent_messages: + if (sender_id, nonce) not in self.received_messages: #If it is a new message, add it to recent_messages d = self.make_inundation_dict() pkt = Packet().construct(tlv) @@ -333,12 +333,14 @@ class Squirrel(Hazelnut): """ Remove the sender from the list of neighbours to be inundated """ + 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) if not self.recent_messages[(sender_id, nonce)][2] : #If dictionnary is empty, remove the message self.recent_messages.pop((sender_id, nonce), None) + self.refresh_lock.release() def clean_inundation(self): """ @@ -359,15 +361,22 @@ class Squirrel(Hazelnut): self.refresh_lock.acquire() for key in self.recent_messages: - for key2 in self.recent_messages[key][2]: - if time.time()-self.recent_messages[key][2][key2][1] >= 0: + k = list(self.recent_messages[key][2].keys()) + for key2 in k: + if time.time()>= self.recent_messages[key][2][key2][1] : + self.add_system_message(f"inundating {self.recent_messages[key][2][key2][0].id} with message {key}") + #send the packet if it is overdue self.send_packet(self.recent_messages[key][2][key2][0], self.recent_messages[key][0]) + + #change the time until the next send + a = self.recent_messages[key][2][key2][2] + self.recent_messages[key][2][key2][2] = a+1 + next_send = uniform(2**(a-1), 2**a) + self.recent_messages[key][2][key2][1] = time.time()+next_send - a = self.recent_messages[key][2][key2][2] - - if a==5: #the neighbour is not reactive enough - gatlv = GoAwayTLV().construct(GoAwayType.TIMEOUT, "No acknowledge") + if self.recent_messages[key][2][key2][2]>=5: #the neighbour is not reactive enough + gatlv = GoAwayTLV().construct(GoAwayType.TIMEOUT, f"{self.id} No acknowledge") pkt = Packet().construct(gatlv) self.send_packet( self.recent_messages[key][2][key2][0], pkt) @@ -375,12 +384,6 @@ class Squirrel(Hazelnut): self.potentialhazelnuts[key2] = self.recent_messages[key][2][key2][0] self.recent_messages[key][2].pop(key2) - #change the time until the next send - self.recent_messages[key][2][key2][2] = a+1 - next_send = uniform(2**(a-1), 2**a) - self.recent_messages[key][2][key2][1] = time.time()+next_send - - self.refresh_lock.release() def add_system_message(self, msg: str) -> None: @@ -618,7 +621,7 @@ class Squirrel(Hazelnut): val = list(self.activehazelnuts.values()) #create a copy because the dict size will change for hazelnut in val : - if time.time()-hazelnut[1]>10: #2*60: + if time.time()-hazelnut[1]>2*60: gatlv = GoAwayTLV().construct(GoAwayType.TIMEOUT, "you did not talk to me") pkt = Packet().construct(gatlv) self.send_packet(hazelnut[0], pkt) @@ -638,7 +641,7 @@ 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 key, hazelnut in self.activehazelnuts.items() : - if time.time()-hazelnut[2]<=10 : #2*60 + if time.time()-hazelnut[2]<=2*60: nbNS+=1 self.activehazelnuts[key][3] = True ntlv = NeighbourTLV().construct(hazelnut[0].address,hazelnut[0].port) @@ -694,7 +697,7 @@ class HazelManager(Thread): while True: #First part of neighbour management: ensure the squirrel has enough #symmetric neighbours. - if time.time()-self.last_potential > 5: + if time.time()-self.last_potential > 30: to_contact = self.squirrel.potential_to_contact() for hazel in to_contact : @@ -702,7 +705,8 @@ class HazelManager(Thread): self.last_potential = time.time() #Second part: send long HelloTLVs to neighbours every 30 seconds - if time.time()-self.last_check > 5: #30 : + if time.time()-self.last_check > 30 : + self.squirrel.add_system_message(f"I have {len(list(self.squirrel.activehazelnuts.values()))} friends") self.squirrel.send_hello() self.last_check = time.time() @@ -710,7 +714,7 @@ class HazelManager(Thread): self.squirrel.verify_activity() #Fourth part: verify symmetric neighbours and send NeighbourTLV every minute - if time.time()-self.last_neighbour > 10: #60 : + if time.time()-self.last_neighbour > 60 : self.squirrel.send_neighbours() self.last_neighbour = time.time() @@ -726,7 +730,9 @@ class Inondator(Thread): def run(self) -> None: while True: #clean the dictionnary - self.squirrel.clean_inundation() + if time.time()-self.last_check > 30 : + self.squirrel.clean_inundation() + self.last_check = time.time() #inundate self.squirrel.main_inundation() diff --git a/squinnondation/messages.py b/squinnondation/messages.py index c9fd962..5730c9f 100644 --- a/squinnondation/messages.py +++ b/squinnondation/messages.py @@ -162,7 +162,7 @@ class HelloTLV(TLV): sender.id = self.source_id #The sender we are given misses an id timeHL = time.time() else : - timeHL = squirrel.activehazelnuts[(sender.address, sender.port)] + timeHL = squirrel.activehazelnuts[(sender.address, sender.port)][2] if self.is_long and self.dest_id == squirrel.id : timeHL = time.time() @@ -173,8 +173,8 @@ class HelloTLV(TLV): squirrel.activehazelnuts[(sender.address, sender.port)] = [sender, timeH,\ 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")) + #squirrel.add_system_message(f"Aaaawwww, {self.source_id} spoke to me and said me Hello " + # + ("long" if self.is_long else "short")) @property def is_long(self) -> bool: @@ -216,7 +216,7 @@ class NeighbourTLV(TLV): def handle(self, squirrel: Any, sender: Any) -> None: 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}!") + #squirrel.add_system_message(f"New potential friend {self.ip_address}:{self.port}!") @staticmethod def construct(address: str, port: int) -> "NeighbourTLV": @@ -265,6 +265,7 @@ class DataTLV(TLV): if not squirrel.receive_message_from(self, msg, self.sender_id, self.nonce, sender): # The message was already received, do not print it + squirrel.add_system_message(f"I was inundated a message which I already knew {self.sender_id, self.nonce}") return nickname_match = re.match("(.*): (.*)", msg) diff --git a/squinnondation/squinnondation.py b/squinnondation/squinnondation.py index 2a94668..6da4af4 100644 --- a/squinnondation/squinnondation.py +++ b/squinnondation/squinnondation.py @@ -6,7 +6,7 @@ import time from argparse import ArgumentParser from typing import Any -from .hazel import Hazelnut, Squirrel, Worm, HazelManager +from .hazel import Hazelnut, Squirrel, Worm, HazelManager, Inondator from .messages import Packet, HelloTLV from .term_manager import TermManager @@ -86,4 +86,5 @@ class Squinnondation: Worm(squirrel).start() HazelManager(squirrel).start() + Inondator(squirrel).start() squirrel.wait_for_key()