exempt_peer_networks: allow exceeding target_peer_count. (#3234)

* exempt_peer_networks: allow exceeding target_peer_count.

* Flake8.

* Cleanup incorrect types.

* More typing.

* Added configuration examples for exempt_peer_networks.

* Be generous in the IP network definitions we allow as input.

* Correctly define 192.168.1.0/24 without host bits.

* Trivial change to re-trigger tests.

Co-authored-by: wjblanke <wjb98672@gmail.com>
This commit is contained in:
Peter Tripp 2021-05-12 20:44:26 -04:00 committed by GitHub
parent eb7b6dd243
commit 178f63a3a3
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 23 additions and 6 deletions

View File

@ -3,10 +3,10 @@ import logging
import ssl
import time
import traceback
from ipaddress import IPv6Address, ip_address
from ipaddress import IPv6Address, ip_address, ip_network, IPv4Network, IPv6Network
from pathlib import Path
from secrets import token_bytes
from typing import Any, Callable, Dict, List, Optional, Set, Tuple
from typing import Any, Callable, Dict, List, Optional, Union, Set, Tuple
from aiohttp import ClientSession, ClientTimeout, ServerDisconnectedError, WSCloseCode, client_exceptions, web
from aiohttp.web_app import Application
@ -25,7 +25,7 @@ from chia.types.blockchain_format.sized_bytes import bytes32
from chia.types.peer_info import PeerInfo
from chia.util.errors import Err, ProtocolError
from chia.util.ints import uint16
from chia.util.network import is_localhost
from chia.util.network import is_localhost, is_in_network
def ssl_context_for_server(
@ -145,6 +145,9 @@ class ChiaServer:
self.banned_peers: Dict[str, float] = {}
self.invalid_protocol_ban_seconds = 10
self.api_exception_ban_seconds = 10
self.exempt_peer_networks: List[Union[IPv4Network, IPv6Network]] = [
ip_network(net, strict=False) for net in config.get("exempt_peer_networks", [])
]
def my_id(self) -> bytes32:
"""If node has public cert use that one for id, if not use private."""
@ -253,7 +256,9 @@ class ChiaServer:
assert handshake is True
# Limit inbound connections to config's specifications.
if not self.accept_inbound_connections(connection.connection_type):
if not self.accept_inbound_connections(connection.connection_type) and not is_in_network(
connection.peer_host, self.exempt_peer_networks
):
self.log.info(f"Not accepting inbound connection: {connection.get_peer_info()}.Inbound limit reached.")
await connection.close()
close_event.set()
@ -662,7 +667,7 @@ class ChiaServer:
return None
return peer
def accept_inbound_connections(self, node_type: NodeType):
def accept_inbound_connections(self, node_type: NodeType) -> bool:
if not self._local_type == NodeType.FULL_NODE:
return True
inbound_count = len([conn for _, conn in self.connection_by_type[node_type].items() if not conn.is_outbound])

View File

@ -269,6 +269,9 @@ full_node:
target_peer_count: 80
# Initiate outbound connections until this number is hit.
target_outbound_peer_count: 8
# IPv4/IPv6 network addresses and CIDR blocks allowed to connect even when target_peer_count has been hit.
# exempt_peer_networks: ["192.168.0.3", "192.168.1.0/24", "fe80::/10", "2606:4700:4700::64/128"]
exempt_peer_networks: []
# Accept at most # of inbound connections for different node types.
max_inbound_wallet: 20
max_inbound_farmer: 10

View File

@ -1,7 +1,16 @@
from typing import Any
from ipaddress import ip_address, IPv4Network, IPv6Network
from typing import Iterable, Union, Any
from chia.server.outbound_message import NodeType
def is_in_network(peer_host: str, networks: Iterable[Union[IPv4Network, IPv6Network]]) -> bool:
try:
peer_host_ip = ip_address(peer_host)
return any(peer_host_ip in network for network in networks)
except ValueError:
return False
def is_localhost(peer_host: str) -> bool:
return peer_host == "127.0.0.1" or peer_host == "localhost" or peer_host == "::1" or peer_host == "0:0:0:0:0:0:0:1"