Warn users when they send poop messages and ban them if they are too many

This commit is contained in:
Yohann D'ANELLO 2021-01-05 20:54:14 +01:00
parent 0a4ebd0c92
commit 5bb4748056
Signed by: ynerant
GPG Key ID: 3A75C55819C8CF85
1 changed files with 29 additions and 2 deletions

View File

@ -11,7 +11,7 @@ import re
import socket import socket
import time import time
from .messages import Packet, DataTLV, HelloTLV, GoAwayTLV, GoAwayType, NeighbourTLV from .messages import Packet, DataTLV, HelloTLV, GoAwayTLV, GoAwayType, NeighbourTLV, WarningTLV
class Hazelnut: class Hazelnut:
@ -25,6 +25,7 @@ class Hazelnut:
self.last_long_hello_time = 0 self.last_long_hello_time = 0
self.symmetric = False self.symmetric = False
self.active = False self.active = False
self.errors = 0
try: try:
# Resolve DNS as an IPv6 # Resolve DNS as an IPv6
@ -48,8 +49,19 @@ class Hazelnut:
@property @property
def main_address(self) -> Tuple[str, int]: def main_address(self) -> Tuple[str, int]:
"""
A client can have multiple addresses.
We contact it only on one of them.
"""
return self.addresses[0] return self.addresses[0]
@property
def banned(self) -> bool:
"""
If a client send more than 5 invalid packets, we don't trust it anymore.
"""
return self.errors >= 5
def __repr__(self): def __repr__(self):
return self.nickname or str(self.id) or str(self.main_address) return self.nickname or str(self.id) or str(self.main_address)
@ -165,7 +177,22 @@ class Squirrel(Hazelnut):
Warning: the process is blocking, it should be ran inside a dedicated thread. Warning: the process is blocking, it should be ran inside a dedicated thread.
""" """
data, addr = self.receive_raw_data() data, addr = self.receive_raw_data()
return Packet.unmarshal(data), self.find_hazelnut(addr[0], addr[1]) hazelnut = self.find_hazelnut(addr[0], addr[1])
if hazelnut.banned:
# The client already sent errored packets
self.send_packet(hazelnut, Packet.construct(WarningTLV.construct(
"You got banned since you sent too much errored packets.")))
raise ValueError("Client is banned.")
try:
pkt = Packet.unmarshal(data)
except ValueError as error:
# The packet contains an error. We memorize it and warn the other user.
hazelnut.errors += 1
self.send_packet(hazelnut, Packet.construct(WarningTLV.construct(
f"An error occured while reading your packet: {error}")))
raise error
else:
return pkt, hazelnut
def receive_raw_data(self) -> Tuple[bytes, Any]: def receive_raw_data(self) -> Tuple[bytes, Any]:
""" """