Linting
This commit is contained in:
parent
7abaa7bcd4
commit
ac249716f7
|
@ -1,9 +1,10 @@
|
||||||
# Copyright (C) 2020 by eichhornchen, ÿnérant
|
# Copyright (C) 2020 by eichhornchen, ÿnérant
|
||||||
# SPDX-License-Identifier: GPL-3.0-or-later
|
# SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
|
|
||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
from random import randint, uniform
|
from random import randint, uniform
|
||||||
from typing import Any, Tuple
|
from typing import Any, Tuple
|
||||||
#from ipaddress import IPv6Address
|
# from ipaddress import IPv6Address
|
||||||
from threading import Thread, RLock
|
from threading import Thread, RLock
|
||||||
import curses
|
import curses
|
||||||
import re
|
import re
|
||||||
|
@ -30,7 +31,7 @@ class Hazelnut:
|
||||||
# See https://fr.wikipedia.org/wiki/Adresse_IPv6_mappant_IPv4
|
# See https://fr.wikipedia.org/wiki/Adresse_IPv6_mappant_IPv4
|
||||||
address = "::ffff:" + socket.getaddrinfo(address, None, socket.AF_INET)[0][4][0]
|
address = "::ffff:" + socket.getaddrinfo(address, None, socket.AF_INET)[0][4][0]
|
||||||
|
|
||||||
self.address = address #IPv6Address(address)
|
self.address = address # IPv6Address(address)
|
||||||
self.port = port
|
self.port = port
|
||||||
|
|
||||||
|
|
||||||
|
@ -61,7 +62,8 @@ class Squirrel(Hazelnut):
|
||||||
|
|
||||||
self.history = []
|
self.history = []
|
||||||
self.received_messages = dict()
|
self.received_messages = dict()
|
||||||
self.recent_messages = dict() #of the form [Pkt(DataTLV), date of first reception, dict(neighbour, date of the next send, nb of times it has already been sent)]
|
self.recent_messages = dict() # of the form [Pkt(DataTLV), date of first reception,
|
||||||
|
# dict(neighbour, date of the next send, nb of times it has already been sent)]
|
||||||
self.history_pad = curses.newpad(curses.LINES - 2, curses.COLS)
|
self.history_pad = curses.newpad(curses.LINES - 2, curses.COLS)
|
||||||
self.input_pad = curses.newpad(1, curses.COLS)
|
self.input_pad = curses.newpad(1, curses.COLS)
|
||||||
self.emoji_pad = curses.newpad(18, 12)
|
self.emoji_pad = curses.newpad(18, 12)
|
||||||
|
@ -70,34 +72,33 @@ class Squirrel(Hazelnut):
|
||||||
curses.init_color(curses.COLOR_WHITE, 1000, 1000, 1000)
|
curses.init_color(curses.COLOR_WHITE, 1000, 1000, 1000)
|
||||||
for i in range(curses.COLOR_BLACK + 1, curses.COLOR_WHITE):
|
for i in range(curses.COLOR_BLACK + 1, curses.COLOR_WHITE):
|
||||||
curses.init_pair(i + 1, i, curses.COLOR_BLACK)
|
curses.init_pair(i + 1, i, curses.COLOR_BLACK)
|
||||||
|
|
||||||
#dictionnaries of neighbours
|
# dictionnaries of neighbours
|
||||||
self.potentialhazelnuts = dict()
|
self.potentialhazelnuts = dict()
|
||||||
self.activehazelnuts = dict() #of the form [hazelnut, time of last
|
self.activehazelnuts = dict() # of the form [hazelnut, time of last hello,
|
||||||
#hello, time of last long hello, is symmetric]
|
# time of last long hello, is symmetric]
|
||||||
self.nbNS = 0
|
self.nbNS = 0
|
||||||
self.minNS = 3 #minimal number of symmetric neighbours a squirrel needs
|
self.minNS = 3 # minimal number of symmetric neighbours a squirrel needs to have.
|
||||||
#to have.
|
|
||||||
|
|
||||||
self.add_system_message(f"Listening on {self.address}:{self.port}")
|
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:
|
def new_hazel(self, address: str, port: int) -> Hazelnut:
|
||||||
"""
|
"""
|
||||||
Returns a new hazelnut (with no id nor nickname)
|
Returns a new hazelnut (with no id nor nickname)
|
||||||
"""
|
"""
|
||||||
hazelnut = Hazelnut(address=address, port=port)
|
hazelnut = Hazelnut(address=address, port=port)
|
||||||
return hazelnut
|
return hazelnut
|
||||||
|
|
||||||
def is_active(self, hazel: Hazelnut) -> bool :
|
def is_active(self, hazel: Hazelnut) -> bool:
|
||||||
return (hazel.address, hazel.port) in self.activehazelnuts
|
return (hazel.address, hazel.port) in self.activehazelnuts
|
||||||
|
|
||||||
def is_potential(self, hazel: Hazelnut) -> bool :
|
def is_potential(self, hazel: Hazelnut) -> bool:
|
||||||
return (hazel.address, hazel.port) in self.potentialhazelnuts
|
return (hazel.address, hazel.port) in self.potentialhazelnuts
|
||||||
|
|
||||||
def remove_from_potential(self, address: str, port: int)-> None:
|
def remove_from_potential(self, address: str, port: int) -> None:
|
||||||
self.potentialhazelnuts.pop((address, port), None)
|
self.potentialhazelnuts.pop((address, port), None)
|
||||||
|
|
||||||
def find_hazelnut(self, address: str, port: int) -> Hazelnut:
|
def find_hazelnut(self, address: str, port: int) -> Hazelnut:
|
||||||
"""
|
"""
|
||||||
Translate an address into a hazelnut. If this hazelnut does not exist,
|
Translate an address into a hazelnut. If this hazelnut does not exist,
|
||||||
|
@ -169,7 +170,7 @@ class Squirrel(Hazelnut):
|
||||||
|
|
||||||
self.handle_key_pressed(key)
|
self.handle_key_pressed(key)
|
||||||
|
|
||||||
def handle_key_pressed(self, key: str) -> None:
|
def handle_key_pressed(self, key: str) -> None: # noqa: C901
|
||||||
"""
|
"""
|
||||||
Process the key press from the user.
|
Process the key press from the user.
|
||||||
"""
|
"""
|
||||||
|
@ -302,88 +303,87 @@ class Squirrel(Hazelnut):
|
||||||
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.received_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)
|
||||||
self.recent_messages[(sender_id, nonce)] = [pkt, time.time(), d]
|
self.recent_messages[(sender_id, nonce)] = [pkt, time.time(), d]
|
||||||
|
|
||||||
#in all cases, remove the sender from the list of neighbours to be inundated
|
# in all cases, remove the sender from the list of neighbours to be inundated
|
||||||
self.remove_from_inundation(relay, sender_id, nonce)
|
self.remove_from_inundation(relay, sender_id, nonce)
|
||||||
|
|
||||||
if (sender_id, nonce) in self.received_messages:
|
if (sender_id, nonce) in self.received_messages:
|
||||||
return False
|
return False
|
||||||
|
|
||||||
self.add_message(msg) #for display purposes
|
self.add_message(msg) # for display purposes
|
||||||
self.received_messages[(sender_id, nonce)] = Message(msg, sender_id, nonce)
|
self.received_messages[(sender_id, nonce)] = Message(msg, sender_id, nonce)
|
||||||
return True
|
return True
|
||||||
|
|
||||||
def make_inundation_dict(self) -> dict:
|
def make_inundation_dict(self) -> dict:
|
||||||
"""
|
"""
|
||||||
Takes the activehazels dictionnary and returns a list of [hazel, date+random, 0]
|
Takes the activehazels dictionnary and returns a list of [hazel, date+random, 0]
|
||||||
"""
|
"""
|
||||||
res = dict()
|
res = dict()
|
||||||
l = list(self.activehazelnuts.items())
|
hazels = list(self.activehazelnuts.items())
|
||||||
for key, hazel in l:
|
for key, hazel in hazels:
|
||||||
if hazel[3]: #Only if the neighbour is symmetric
|
if hazel[3]: # Only if the neighbour is symmetric
|
||||||
next_send = uniform(1, 2)
|
next_send = uniform(1, 2)
|
||||||
res[key] = [hazel[0], time.time()+next_send, 0]
|
res[key] = [hazel[0], time.time() + next_send, 0]
|
||||||
return res
|
return res
|
||||||
|
|
||||||
def remove_from_inundation(self, hazel: Hazelnut, sender_id: int, nonce: int) -> None:
|
def remove_from_inundation(self, hazel: Hazelnut, sender_id: int, nonce: int) -> None:
|
||||||
"""
|
"""
|
||||||
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()
|
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()
|
self.refresh_lock.release()
|
||||||
|
|
||||||
def clean_inundation(self):
|
def clean_inundation(self) -> None:
|
||||||
"""
|
"""
|
||||||
Remove messages which are overdue (older than 2 minutes) from the inundation dictionnary.
|
Remove messages which are overdue (older than 2 minutes) from the inundation dictionnary.
|
||||||
"""
|
"""
|
||||||
self.refresh_lock.acquire()
|
self.refresh_lock.acquire()
|
||||||
|
|
||||||
for key in self.recent_messages:
|
for key in self.recent_messages:
|
||||||
if time.time()-self.recent_messages[key][1] > 120:
|
if time.time() - self.recent_messages[key][1] > 120:
|
||||||
self.recent_messages.pop(key)
|
self.recent_messages.pop(key)
|
||||||
|
|
||||||
self.refresh_lock.release()
|
self.refresh_lock.release()
|
||||||
|
|
||||||
def main_inundation(self):
|
def main_inundation(self) -> None:
|
||||||
"""
|
"""
|
||||||
The main inundation function.
|
The main inundation function.
|
||||||
"""
|
"""
|
||||||
self.refresh_lock.acquire()
|
self.refresh_lock.acquire()
|
||||||
|
|
||||||
for key in self.recent_messages:
|
for key in self.recent_messages:
|
||||||
k = list(self.recent_messages[key][2].keys())
|
k = list(self.recent_messages[key][2].keys())
|
||||||
for key2 in k:
|
for key2 in k:
|
||||||
if time.time()>= self.recent_messages[key][2][key2][1] :
|
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}")
|
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
|
# change the time until the next send
|
||||||
a = self.recent_messages[key][2][key2][2]
|
a = self.recent_messages[key][2][key2][2]
|
||||||
self.recent_messages[key][2][key2][2] = a+1
|
self.recent_messages[key][2][key2][2] = a + 1
|
||||||
next_send = uniform(2**(a-1), 2**a)
|
next_send = uniform(2 ** (a - 1), 2 ** a)
|
||||||
self.recent_messages[key][2][key2][1] = time.time()+next_send
|
self.recent_messages[key][2][key2][1] = time.time() + next_send
|
||||||
|
|
||||||
if self.recent_messages[key][2][key2][2]>=5: #the neighbour is not reactive enough
|
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")
|
gatlv = GoAwayTLV().construct(GoAwayType.TIMEOUT, f"{self.id} 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)
|
|
||||||
self.activehazelnuts.pop(key2)
|
self.activehazelnuts.pop(key2)
|
||||||
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)
|
||||||
|
|
||||||
self.refresh_lock.release()
|
self.refresh_lock.release()
|
||||||
|
|
||||||
def add_system_message(self, msg: str) -> None:
|
def add_system_message(self, msg: str) -> None:
|
||||||
|
@ -579,82 +579,83 @@ class Squirrel(Hazelnut):
|
||||||
curses.LINES - 2, curses.COLS - 2)
|
curses.LINES - 2, curses.COLS - 2)
|
||||||
|
|
||||||
self.refresh_lock.release()
|
self.refresh_lock.release()
|
||||||
|
|
||||||
def potential_to_contact(self) -> list:
|
def potential_to_contact(self) -> list:
|
||||||
"""
|
"""
|
||||||
Returns a list of hazelnuts the squirrel should contact if it does
|
Returns a list of hazelnuts the squirrel should contact if it does
|
||||||
not have enough symmetric neighbours.
|
not have enough symmetric neighbours.
|
||||||
"""
|
"""
|
||||||
self.refresh_lock.acquire()
|
self.refresh_lock.acquire()
|
||||||
|
|
||||||
res = []
|
res = []
|
||||||
lp = len(self.potentialhazelnuts)
|
lp = len(self.potentialhazelnuts)
|
||||||
val = list(self.potentialhazelnuts.values())
|
val = list(self.potentialhazelnuts.values())
|
||||||
|
|
||||||
for i in range(min(lp, max(0,self.minNS-self.nbNS))) :
|
for i in range(min(lp, max(0, self.minNS - self.nbNS))):
|
||||||
a = randint(0, lp-1)
|
a = randint(0, lp - 1)
|
||||||
res.append(val[a])
|
res.append(val[a])
|
||||||
|
|
||||||
self.refresh_lock.release()
|
self.refresh_lock.release()
|
||||||
return res
|
return res
|
||||||
|
|
||||||
def send_hello(self) -> None:
|
def send_hello(self) -> None:
|
||||||
"""
|
"""
|
||||||
Sends a long HelloTLV to all active neighbours.
|
Sends a long HelloTLV to all active neighbours.
|
||||||
"""
|
"""
|
||||||
self.refresh_lock.acquire()
|
self.refresh_lock.acquire()
|
||||||
|
|
||||||
for hazelnut in self.activehazelnuts.values() :
|
for hazelnut in self.activehazelnuts.values():
|
||||||
htlv = HelloTLV().construct(16, self, hazelnut[0])
|
htlv = HelloTLV().construct(16, self, hazelnut[0])
|
||||||
pkt = Packet().construct(htlv)
|
pkt = Packet().construct(htlv)
|
||||||
self.send_packet(hazelnut[0], pkt)
|
self.send_packet(hazelnut[0], pkt)
|
||||||
|
|
||||||
self.refresh_lock.release()
|
self.refresh_lock.release()
|
||||||
|
|
||||||
def verify_activity(self) -> None:
|
def verify_activity(self) -> None:
|
||||||
"""
|
"""
|
||||||
All neighbours that have not sent a HelloTLV in the last 2
|
All neighbours that have not sent a HelloTLV in the last 2
|
||||||
minutes are considered not active.
|
minutes are considered not active.
|
||||||
"""
|
"""
|
||||||
self.refresh_lock.acquire()
|
self.refresh_lock.acquire()
|
||||||
|
|
||||||
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]>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)
|
||||||
self.activehazelnuts.pop((hazelnut[0].address, hazelnut[0].port))
|
self.activehazelnuts.pop((hazelnut[0].address, hazelnut[0].port))
|
||||||
self.potentialhazelnuts[(hazelnut[0].address, hazelnut[0].port)] = hazelnut[0]
|
self.potentialhazelnuts[(hazelnut[0].address, hazelnut[0].port)] = hazelnut[0]
|
||||||
|
|
||||||
self.refresh_lock.release()
|
self.refresh_lock.release()
|
||||||
|
|
||||||
|
|
||||||
def send_neighbours(self) -> None:
|
def send_neighbours(self) -> None:
|
||||||
"""
|
"""
|
||||||
Update the number of symmetric neighbours and
|
Update the number of symmetric neighbours and
|
||||||
send all neighbours NeighbourTLV
|
send all neighbours NeighbourTLV
|
||||||
"""
|
"""
|
||||||
self.refresh_lock.acquire()
|
self.refresh_lock.acquire()
|
||||||
|
|
||||||
nbNS = 0
|
nb_ns = 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
|
||||||
for key, hazelnut in self.activehazelnuts.items() :
|
# A could receive a message with itself in it -> if the others do not pay attention, trouble
|
||||||
if time.time()-hazelnut[2]<=2*60:
|
for key, hazelnut in self.activehazelnuts.items():
|
||||||
nbNS+=1
|
if time.time() - hazelnut[2] <= 2 * 60:
|
||||||
|
nb_ns += 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)
|
||||||
pkt = Packet().construct(ntlv)
|
pkt = Packet().construct(ntlv)
|
||||||
for destination in self.activehazelnuts.values() :
|
for destination in self.activehazelnuts.values():
|
||||||
if destination[0].id != hazelnut[0].id :
|
if destination[0].id != hazelnut[0].id:
|
||||||
self.send_packet(destination[0], pkt)
|
self.send_packet(destination[0], pkt)
|
||||||
else:
|
else:
|
||||||
self.activehazelnuts[key][3] = False
|
self.activehazelnuts[key][3] = False
|
||||||
self.nbNS = nbNS
|
self.nbNS = nb_ns
|
||||||
|
|
||||||
self.refresh_lock.release()
|
self.refresh_lock.release()
|
||||||
|
|
||||||
|
|
||||||
class Worm(Thread):
|
class Worm(Thread):
|
||||||
"""
|
"""
|
||||||
The worm is the hazel listener.
|
The worm is the hazel listener.
|
||||||
|
@ -678,6 +679,7 @@ class Worm(Thread):
|
||||||
self.squirrel.refresh_history()
|
self.squirrel.refresh_history()
|
||||||
self.squirrel.refresh_input()
|
self.squirrel.refresh_input()
|
||||||
|
|
||||||
|
|
||||||
class HazelManager(Thread):
|
class HazelManager(Thread):
|
||||||
"""
|
"""
|
||||||
A process to cleanly manage the squirrel's neighbours
|
A process to cleanly manage the squirrel's neighbours
|
||||||
|
@ -688,36 +690,37 @@ class HazelManager(Thread):
|
||||||
self.last_potential = 0
|
self.last_potential = 0
|
||||||
self.last_check = 0
|
self.last_check = 0
|
||||||
self.last_neighbour = 0
|
self.last_neighbour = 0
|
||||||
|
|
||||||
htlv = HelloTLV().construct(8, self.squirrel)
|
htlv = HelloTLV().construct(8, self.squirrel)
|
||||||
pkt = Packet().construct(htlv)
|
pkt = Packet().construct(htlv)
|
||||||
self.hellopkt = pkt
|
self.hellopkt = pkt
|
||||||
|
|
||||||
def run(self) -> None:
|
def run(self) -> None:
|
||||||
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 > 30:
|
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:
|
||||||
self.squirrel.send_packet(hazel, self.hellopkt)
|
self.squirrel.send_packet(hazel, self.hellopkt)
|
||||||
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 > 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.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()
|
||||||
|
|
||||||
#Third part: get rid of inactive neighbours
|
# Third part: get rid of inactive neighbours
|
||||||
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 > 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()
|
||||||
|
|
||||||
|
|
||||||
class Inondator(Thread):
|
class Inondator(Thread):
|
||||||
"""
|
"""
|
||||||
A process to manage the inondation
|
A process to manage the inondation
|
||||||
|
@ -726,17 +729,17 @@ class Inondator(Thread):
|
||||||
super().__init__(*args, **kwargs)
|
super().__init__(*args, **kwargs)
|
||||||
self.squirrel = squirrel
|
self.squirrel = squirrel
|
||||||
self.last_check = 0
|
self.last_check = 0
|
||||||
|
|
||||||
def run(self) -> None:
|
def run(self) -> None:
|
||||||
while True:
|
while True:
|
||||||
#clean the dictionnary
|
# clean the dictionnary
|
||||||
if time.time()-self.last_check > 30 :
|
if time.time() - self.last_check > 30:
|
||||||
self.squirrel.clean_inundation()
|
self.squirrel.clean_inundation()
|
||||||
self.last_check = time.time()
|
self.last_check = time.time()
|
||||||
|
|
||||||
#inundate
|
# inundate
|
||||||
self.squirrel.main_inundation()
|
self.squirrel.main_inundation()
|
||||||
|
|
||||||
|
|
||||||
class Message:
|
class Message:
|
||||||
"""
|
"""
|
||||||
|
|
|
@ -123,13 +123,14 @@ class PadNTLV(TLV):
|
||||||
squirrel.add_system_message(f"I received {self.length} zeros, am I so a bag guy ? :cold_sweat:")
|
squirrel.add_system_message(f"I received {self.length} zeros, am I so a bag guy ? :cold_sweat:")
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def construct(length: int) -> "Pad1TLV":
|
def construct(length: int) -> "PadNTLV":
|
||||||
tlv = PadNTLV()
|
tlv = PadNTLV()
|
||||||
tlv.type = 1
|
tlv.type = 1
|
||||||
tlv.length = length
|
tlv.length = length
|
||||||
tlv.mbz = b'0'*length
|
tlv.mbz = b'0' * length
|
||||||
return tlv
|
return tlv
|
||||||
|
|
||||||
|
|
||||||
class HelloTLV(TLV):
|
class HelloTLV(TLV):
|
||||||
type: int = 2
|
type: int = 2
|
||||||
length: int
|
length: int
|
||||||
|
@ -157,24 +158,23 @@ class HelloTLV(TLV):
|
||||||
return data
|
return data
|
||||||
|
|
||||||
def handle(self, squirrel: Any, sender: Any) -> None:
|
def handle(self, squirrel: Any, sender: Any) -> None:
|
||||||
timeH = time.time()
|
time_h = time.time()
|
||||||
if not squirrel.is_active(sender) :
|
if not squirrel.is_active(sender):
|
||||||
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()
|
time_hl = time.time()
|
||||||
else :
|
else:
|
||||||
timeHL = squirrel.activehazelnuts[(sender.address, sender.port)][2]
|
time_hl = 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()
|
time_hl = time.time()
|
||||||
|
|
||||||
#Make sure the sender is not in the potential hazelnuts
|
# Make sure the sender is not in the potential hazelnuts
|
||||||
squirrel.remove_from_potential(sender.address, sender.port)
|
squirrel.remove_from_potential(sender.address, sender.port)
|
||||||
|
|
||||||
#Add entry to/actualize the active hazelnuts dictionnary
|
# Add entry to/actualize the active hazelnuts dictionnary
|
||||||
squirrel.activehazelnuts[(sender.address, sender.port)] = [sender, timeH,\
|
squirrel.activehazelnuts[(sender.address, sender.port)] = [sender, time_h, time_hl, 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:
|
||||||
|
@ -187,11 +187,11 @@ class HelloTLV(TLV):
|
||||||
tlv.source_id = squirrel.id if squirrel else 0
|
tlv.source_id = squirrel.id if squirrel else 0
|
||||||
if (destination is None) or destination.id == -1 or length == 8:
|
if (destination is None) or destination.id == -1 or length == 8:
|
||||||
tlv.length = 8
|
tlv.length = 8
|
||||||
tlv.dest_id = None #if the destination id is not known, or
|
tlv.dest_id = None # if the destination id is not known, or
|
||||||
#if the destination was not precised, send a short hello
|
# if the destination was not precised, send a short hello
|
||||||
else :
|
else:
|
||||||
tlv.length = 16
|
tlv.length = 16
|
||||||
tlv.dest_id = destination.id
|
tlv.dest_id = destination.id
|
||||||
return tlv
|
return tlv
|
||||||
|
|
||||||
|
|
||||||
|
@ -214,19 +214,22 @@ class NeighbourTLV(TLV):
|
||||||
self.port.to_bytes(2, sys.byteorder)
|
self.port.to_bytes(2, sys.byteorder)
|
||||||
|
|
||||||
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 \
|
||||||
squirrel.potentialhazelnuts[(str(self.ip_address), self.port)] = squirrel.new_hazel(str(self.ip_address), self.port)
|
and not (str(self.ip_address), self.port) in squirrel.potentialhazelnuts:
|
||||||
#squirrel.add_system_message(f"New potential friend {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}!")
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def construct(address: str, port: int) -> "NeighbourTLV":
|
def construct(address: str, port: int) -> "NeighbourTLV":
|
||||||
tlv = NeighbourTLV()
|
tlv = NeighbourTLV()
|
||||||
tlv.type = 3
|
tlv.type = 3
|
||||||
tlv.length = 18 #A priori...
|
tlv.length = 18 # A priori...
|
||||||
tlv.ip_address = IPv6Address(address)
|
tlv.ip_address = IPv6Address(address)
|
||||||
tlv.port = port
|
tlv.port = port
|
||||||
return tlv
|
return tlv
|
||||||
|
|
||||||
|
|
||||||
class DataTLV(TLV):
|
class DataTLV(TLV):
|
||||||
type: int = 4
|
type: int = 4
|
||||||
length: int
|
length: int
|
||||||
|
@ -259,10 +262,10 @@ class DataTLV(TLV):
|
||||||
TODO: Check that the tuple (sender_id, nonce) is unique to avoid duplicates.
|
TODO: Check that the tuple (sender_id, nonce) is unique to avoid duplicates.
|
||||||
"""
|
"""
|
||||||
msg = self.data.decode('UTF-8')
|
msg = self.data.decode('UTF-8')
|
||||||
|
|
||||||
# Acknowledge the packet
|
# Acknowledge the packet
|
||||||
squirrel.send_packet(sender, Packet.construct(AckTLV.construct(self.sender_id, self.nonce)))
|
squirrel.send_packet(sender, Packet.construct(AckTLV.construct(self.sender_id, self.nonce)))
|
||||||
|
|
||||||
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}")
|
squirrel.add_system_message(f"I was inundated a message which I already knew {self.sender_id, self.nonce}")
|
||||||
|
@ -331,14 +334,15 @@ class AckTLV(TLV):
|
||||||
tlv.nonce = nonce
|
tlv.nonce = nonce
|
||||||
return tlv
|
return tlv
|
||||||
|
|
||||||
|
|
||||||
class GoAwayType(Enum):
|
class GoAwayType(Enum):
|
||||||
UNKNOWN = 0
|
UNKNOWN = 0
|
||||||
EXIT = 1
|
EXIT = 1
|
||||||
TIMEOUT = 2
|
TIMEOUT = 2
|
||||||
PROTOCOL_VIOLATION = 3
|
PROTOCOL_VIOLATION = 3
|
||||||
|
|
||||||
|
|
||||||
class GoAwayTLV(TLV):
|
class GoAwayTLV(TLV):
|
||||||
|
|
||||||
type: int = 6
|
type: int = 6
|
||||||
length: int
|
length: int
|
||||||
code: GoAwayType
|
code: GoAwayType
|
||||||
|
@ -357,20 +361,21 @@ class GoAwayTLV(TLV):
|
||||||
self.message.encode("UTF-8")[:self.length - 1]
|
self.message.encode("UTF-8")[:self.length - 1]
|
||||||
|
|
||||||
def handle(self, squirrel: Any, sender: Any) -> None:
|
def handle(self, squirrel: Any, sender: Any) -> None:
|
||||||
if squirrel.is_active(sender) :
|
if squirrel.is_active(sender):
|
||||||
squirrel.activehazelnuts.pop((sender.address, sender.port))
|
squirrel.activehazelnuts.pop((sender.address, sender.port))
|
||||||
squirrel.potentialhazelnuts[(sender.address, sender.port)] = sender
|
squirrel.potentialhazelnuts[(sender.address, sender.port)] = sender
|
||||||
squirrel.add_system_message("Some told me that he went away : "+self.message)
|
squirrel.add_system_message("Some told me that he went away : " + self.message)
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def construct(GAtype: GoAwayType, message: str) -> "GoAwayTLV":
|
def construct(ga_type: GoAwayType, message: str) -> "GoAwayTLV":
|
||||||
tlv = GoAwayTLV()
|
tlv = GoAwayTLV()
|
||||||
tlv.type = 6
|
tlv.type = 6
|
||||||
tlv.code = GAtype
|
tlv.code = ga_type
|
||||||
tlv.message = message
|
tlv.message = message
|
||||||
tlv.length = 1 + len(tlv.message)
|
tlv.length = 1 + len(tlv.message)
|
||||||
return tlv
|
return tlv
|
||||||
|
|
||||||
|
|
||||||
class WarningTLV(TLV):
|
class WarningTLV(TLV):
|
||||||
type: int = 7
|
type: int = 7
|
||||||
length: int
|
length: int
|
||||||
|
|
|
@ -2,7 +2,6 @@
|
||||||
# SPDX-License-Identifier: GPL-3.0-or-later
|
# SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
|
|
||||||
import curses
|
import curses
|
||||||
import time
|
|
||||||
from argparse import ArgumentParser
|
from argparse import ArgumentParser
|
||||||
from typing import Any
|
from typing import Any
|
||||||
|
|
||||||
|
@ -80,9 +79,9 @@ class Squinnondation:
|
||||||
pkt = Packet().construct(htlv)
|
pkt = Packet().construct(htlv)
|
||||||
squirrel.send_packet(hazelnut, pkt)
|
squirrel.send_packet(hazelnut, pkt)
|
||||||
|
|
||||||
## if squirrel.port != 8082:
|
# if squirrel.port != 8082:
|
||||||
## hazelnut = Hazelnut(address='::1', port=8082)
|
# hazelnut = Hazelnut(address='::1', port=8082)
|
||||||
## squirrel.potentialhazelnuts['::1',8082] = hazelnut
|
# squirrel.potentialhazelnuts['::1', 8082] = hazelnut
|
||||||
|
|
||||||
Worm(squirrel).start()
|
Worm(squirrel).start()
|
||||||
HazelManager(squirrel).start()
|
HazelManager(squirrel).start()
|
||||||
|
|
Loading…
Reference in New Issue