Warn users when they send poop messages and ban them if they are too many
This commit is contained in:
		@@ -11,7 +11,7 @@ import re
 | 
			
		||||
import socket
 | 
			
		||||
import time
 | 
			
		||||
 | 
			
		||||
from .messages import Packet, DataTLV, HelloTLV, GoAwayTLV, GoAwayType, NeighbourTLV
 | 
			
		||||
from .messages import Packet, DataTLV, HelloTLV, GoAwayTLV, GoAwayType, NeighbourTLV, WarningTLV
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class Hazelnut:
 | 
			
		||||
@@ -25,6 +25,7 @@ class Hazelnut:
 | 
			
		||||
        self.last_long_hello_time = 0
 | 
			
		||||
        self.symmetric = False
 | 
			
		||||
        self.active = False
 | 
			
		||||
        self.errors = 0
 | 
			
		||||
 | 
			
		||||
        try:
 | 
			
		||||
            # Resolve DNS as an IPv6
 | 
			
		||||
@@ -48,8 +49,19 @@ class Hazelnut:
 | 
			
		||||
 | 
			
		||||
    @property
 | 
			
		||||
    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]
 | 
			
		||||
 | 
			
		||||
    @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):
 | 
			
		||||
        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.
 | 
			
		||||
        """
 | 
			
		||||
        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]:
 | 
			
		||||
        """
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user