Repaired a few bugs in inundation (and the bug notes in the last commit)

This commit is contained in:
eichhornchen 2020-12-29 15:06:27 +01:00
parent 04f6fb6002
commit 7abaa7bcd4
3 changed files with 32 additions and 24 deletions

View File

@ -301,7 +301,7 @@ class Squirrel(Hazelnut):
This add the message in the history if not already done. This add the message in the history if not already done.
Returns True iff the message was not already received previously. 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 #If it is a new message, add it to recent_messages
d = self.make_inundation_dict() d = self.make_inundation_dict()
pkt = Packet().construct(tlv) pkt = Packet().construct(tlv)
@ -333,12 +333,14 @@ class Squirrel(Hazelnut):
""" """
Remove the sender from the list of neighbours to be inundated Remove the sender from the list of neighbours to be inundated
""" """
self.refresh_lock.acquire()
if (sender_id, nonce) in self.recent_messages: 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. #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) 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 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.recent_messages.pop((sender_id, nonce), None)
self.refresh_lock.release()
def clean_inundation(self): def clean_inundation(self):
""" """
@ -359,15 +361,22 @@ class Squirrel(Hazelnut):
self.refresh_lock.acquire() self.refresh_lock.acquire()
for key in self.recent_messages: for key in self.recent_messages:
for key2 in self.recent_messages[key][2]: k = list(self.recent_messages[key][2].keys())
if time.time()-self.recent_messages[key][2][key2][1] >= 0: 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 #send the packet if it is overdue
self.send_packet(self.recent_messages[key][2][key2][0], self.recent_messages[key][0]) 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 self.recent_messages[key][2][key2][2]>=5: #the neighbour is not reactive enough
gatlv = GoAwayTLV().construct(GoAwayType.TIMEOUT, f"{self.id} No acknowledge")
if a==5: #the neighbour is not reactive enough
gatlv = GoAwayTLV().construct(GoAwayType.TIMEOUT, "No acknowledge")
pkt = Packet().construct(gatlv) pkt = Packet().construct(gatlv)
self.send_packet( self.send_packet(
self.recent_messages[key][2][key2][0], pkt) 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.potentialhazelnuts[key2] = self.recent_messages[key][2][key2][0]
self.recent_messages[key][2].pop(key2) 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() self.refresh_lock.release()
def add_system_message(self, msg: str) -> None: 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 val = list(self.activehazelnuts.values()) #create a copy because the dict size will change
for hazelnut in val : 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") gatlv = GoAwayTLV().construct(GoAwayType.TIMEOUT, "you did not talk to me")
pkt = Packet().construct(gatlv) pkt = Packet().construct(gatlv)
self.send_packet(hazelnut[0], pkt) self.send_packet(hazelnut[0], pkt)
@ -638,7 +641,7 @@ class Squirrel(Hazelnut):
nbNS = 0 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 #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() : for key, hazelnut in self.activehazelnuts.items() :
if time.time()-hazelnut[2]<=10 : #2*60 if time.time()-hazelnut[2]<=2*60:
nbNS+=1 nbNS+=1
self.activehazelnuts[key][3] = True self.activehazelnuts[key][3] = True
ntlv = NeighbourTLV().construct(hazelnut[0].address,hazelnut[0].port) ntlv = NeighbourTLV().construct(hazelnut[0].address,hazelnut[0].port)
@ -694,7 +697,7 @@ class HazelManager(Thread):
while True: while True:
#First part of neighbour management: ensure the squirrel has enough #First part of neighbour management: ensure the squirrel has enough
#symmetric neighbours. #symmetric neighbours.
if time.time()-self.last_potential > 5: if time.time()-self.last_potential > 30:
to_contact = self.squirrel.potential_to_contact() to_contact = self.squirrel.potential_to_contact()
for hazel in to_contact : for hazel in to_contact :
@ -702,7 +705,8 @@ class HazelManager(Thread):
self.last_potential = time.time() self.last_potential = time.time()
#Second part: send long HelloTLVs to neighbours every 30 seconds #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.squirrel.send_hello()
self.last_check = time.time() self.last_check = time.time()
@ -710,7 +714,7 @@ class HazelManager(Thread):
self.squirrel.verify_activity() self.squirrel.verify_activity()
#Fourth part: verify symmetric neighbours and send NeighbourTLV every minute #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.squirrel.send_neighbours()
self.last_neighbour = time.time() self.last_neighbour = time.time()
@ -726,7 +730,9 @@ class Inondator(Thread):
def run(self) -> None: def run(self) -> None:
while True: while True:
#clean the dictionnary #clean the dictionnary
self.squirrel.clean_inundation() if time.time()-self.last_check > 30 :
self.squirrel.clean_inundation()
self.last_check = time.time()
#inundate #inundate
self.squirrel.main_inundation() self.squirrel.main_inundation()

View File

@ -162,7 +162,7 @@ class HelloTLV(TLV):
sender.id = self.source_id #The sender we are given misses an id sender.id = self.source_id #The sender we are given misses an id
timeHL = time.time() timeHL = time.time()
else : 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 : if self.is_long and self.dest_id == squirrel.id :
timeHL = time.time() timeHL = time.time()
@ -173,8 +173,8 @@ class HelloTLV(TLV):
squirrel.activehazelnuts[(sender.address, sender.port)] = [sender, timeH,\ squirrel.activehazelnuts[(sender.address, sender.port)] = [sender, timeH,\
timeHL, True] timeHL, True]
squirrel.nbNS += 1 squirrel.nbNS += 1
squirrel.add_system_message(f"Aaaawwww, {self.source_id} spoke to me and said me Hello " #squirrel.add_system_message(f"Aaaawwww, {self.source_id} spoke to me and said me Hello "
+ ("long" if self.is_long else "short")) # + ("long" if self.is_long else "short"))
@property @property
def is_long(self) -> bool: def is_long(self) -> bool:
@ -216,7 +216,7 @@ class NeighbourTLV(TLV):
def handle(self, squirrel: Any, sender: Any) -> None: 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: 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.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 @staticmethod
def construct(address: str, port: int) -> "NeighbourTLV": 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): if not squirrel.receive_message_from(self, msg, self.sender_id, self.nonce, sender):
# The message was already received, do not print it # 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 return
nickname_match = re.match("(.*): (.*)", msg) nickname_match = re.match("(.*): (.*)", msg)

View File

@ -6,7 +6,7 @@ import time
from argparse import ArgumentParser from argparse import ArgumentParser
from typing import Any 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 .messages import Packet, HelloTLV
from .term_manager import TermManager from .term_manager import TermManager
@ -86,4 +86,5 @@ class Squinnondation:
Worm(squirrel).start() Worm(squirrel).start()
HazelManager(squirrel).start() HazelManager(squirrel).start()
Inondator(squirrel).start()
squirrel.wait_for_key() squirrel.wait_for_key()