Restructurate active hazels

This commit is contained in:
Yohann D'ANELLO 2021-01-05 17:05:03 +01:00
parent 32ff4cbb97
commit 5c9b63d9db
Signed by: ynerant
GPG Key ID: 3A75C55819C8CF85
3 changed files with 31 additions and 29 deletions

View File

@ -21,6 +21,9 @@ class Hazelnut:
def __init__(self, nickname: str = None, address: str = "localhost", port: int = 2500):
self.nickname = nickname
self.id = -1
self.last_hello_time = 0
self.last_long_hello_time = 0
self.symmetric = False
try:
# Resolve DNS as an IPv6
@ -75,11 +78,14 @@ 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, is symmetric]
self.activehazelnuts = dict()
self.nbNS = 0
self.minNS = 3 # minimal number of symmetric neighbours a squirrel needs to have.
self.worm = Worm(self)
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"I am {self.id}")
@ -105,7 +111,7 @@ class Squirrel(Hazelnut):
creates a new hazelnut.
"""
if (address, port) in self.activehazelnuts:
return self.activehazelnuts[(address, port)][0]
return self.activehazelnuts[(address, port)]
hazelnut = Hazelnut(address=address, port=port)
return hazelnut
@ -148,10 +154,6 @@ class Squirrel(Hazelnut):
"""
Start asynchronous threads.
"""
self.worm = Worm(self)
self.hazel_manager = HazelManager(self)
self.inondator = Inondator(self)
# Kill subthreads when exitting the program
self.worm.setDaemon(True)
self.hazel_manager.setDaemon(True)
@ -260,7 +262,7 @@ class Squirrel(Hazelnut):
pkt = Packet.construct(DataTLV.construct(msg, self))
for hazelnut in list(self.activehazelnuts.values()):
self.send_packet(hazelnut[0], pkt)
self.send_packet(hazelnut, pkt)
def handle_mouse_click(self, y: int, x: int, attr: int) -> None:
"""
@ -346,9 +348,9 @@ class Squirrel(Hazelnut):
res = dict()
hazels = list(self.activehazelnuts.items())
for key, hazel in hazels:
if hazel[3]: # Only if the neighbour is symmetric
if hazel.symmetric:
next_send = uniform(1, 2)
res[key] = [hazel[0], time.time() + next_send, 0]
res[key] = [hazel, time.time() + next_send, 0]
return res
def remove_from_inundation(self, hazel: Hazelnut, sender_id: int, nonce: int) -> None:
@ -626,9 +628,9 @@ class Squirrel(Hazelnut):
self.refresh_lock.acquire()
for hazelnut in self.activehazelnuts.values():
htlv = HelloTLV().construct(16, self, hazelnut[0])
htlv = HelloTLV().construct(16, self, hazelnut)
pkt = Packet().construct(htlv)
self.send_packet(hazelnut[0], pkt)
self.send_packet(hazelnut, pkt)
self.refresh_lock.release()
@ -642,12 +644,12 @@ 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] > 2 * 60:
if time.time() - hazelnut.last_hello_time > 2 * 60:
gatlv = GoAwayTLV().construct(GoAwayType.TIMEOUT, "you did not talk to me")
pkt = Packet().construct(gatlv)
self.send_packet(hazelnut[0], pkt)
self.activehazelnuts.pop((hazelnut[0].address, hazelnut[0].port))
self.potentialhazelnuts[(hazelnut[0].address, hazelnut[0].port)] = hazelnut[0]
self.send_packet(hazelnut, pkt)
self.activehazelnuts.pop((hazelnut.address, hazelnut.port))
self.potentialhazelnuts[(hazelnut.address, hazelnut.port)] = hazelnut
self.refresh_lock.release()
@ -662,16 +664,16 @@ class Squirrel(Hazelnut):
# 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] <= 2 * 60:
if time.time() - hazelnut.last_long_hello_time <= 2 * 60:
nb_ns += 1
self.activehazelnuts[key][3] = True
ntlv = NeighbourTLV().construct(hazelnut[0].address, hazelnut[0].port)
self.activehazelnuts[key].symmetric = True
ntlv = NeighbourTLV().construct(hazelnut.address, hazelnut.port)
pkt = Packet().construct(ntlv)
for destination in self.activehazelnuts.values():
if destination[0].id != hazelnut[0].id:
self.send_packet(destination[0], pkt)
if destination.id != hazelnut.id:
self.send_packet(destination, pkt)
else:
self.activehazelnuts[key][3] = False
self.activehazelnuts[key].symmetric = False
self.nbNS = nb_ns
self.refresh_lock.release()
@ -690,7 +692,7 @@ class Squirrel(Hazelnut):
gatlv = GoAwayTLV().construct(GoAwayType.EXIT, "I am leaving! Good bye!")
pkt = Packet.construct(gatlv)
for hazelnut in self.activehazelnuts.values():
self.send_packet(hazelnut[0], pkt)
self.send_packet(hazelnut, pkt)
exit(0)

View File

@ -163,7 +163,7 @@ class HelloTLV(TLV):
sender.id = self.source_id # The sender we are given misses an id
time_hl = time.time()
else:
time_hl = squirrel.activehazelnuts[(sender.address, sender.port)][2]
time_hl = sender.last_long_hello_time
if self.is_long and self.dest_id == squirrel.id:
time_hl = time.time()
@ -171,7 +171,10 @@ class HelloTLV(TLV):
squirrel.remove_from_potential(sender.address, sender.port)
# Add entry to/actualize the active hazelnuts dictionnary
squirrel.activehazelnuts[(sender.address, sender.port)] = [sender, time_h, time_hl, True]
sender.last_hello_time = time_h
sender.last_long_hello_time = time_hl
sender.symmetric = True
squirrel.activehazelnuts[(sender.address, sender.port)] = sender
squirrel.nbNS += 1
# squirrel.add_system_message(f"Aaaawwww, {self.source_id} spoke to me and said Hello "
# + ("long" if self.is_long else "short"))

View File

@ -78,13 +78,10 @@ class Squinnondation:
if instance.args.client_address and instance.args.client_port:
hazelnut = Hazelnut(address=instance.args.client_address, port=instance.args.client_port)
squirrel.potentialhazelnuts[instance.args.client_address, instance.args.client_port] = hazelnut
htlv = HelloTLV().construct(8, squirrel)
pkt = Packet().construct(htlv)
squirrel.send_packet(hazelnut, pkt)
# if squirrel.port != 8082:
# hazelnut = Hazelnut(address='::1', port=8082)
# squirrel.potentialhazelnuts['::1', 8082] = hazelnut
squirrel.start_threads()
squirrel.wait_for_key()