diff --git a/examples/echo/echo_quic.py b/examples/echo/echo_quic.py index a2f8ffd0..6289cc54 100644 --- a/examples/echo/echo_quic.py +++ b/examples/echo/echo_quic.py @@ -13,6 +13,7 @@ Modified from the original TCP version to use QUIC transport, providing: """ import argparse +import logging import multiaddr import trio @@ -67,6 +68,7 @@ async def run(port: int, destination: str, seed: int | None = None) -> None: idle_timeout=30.0, max_concurrent_streams=1000, connection_timeout=10.0, + enable_draft29=False, ) # CHANGED: Add QUIC transport options @@ -142,7 +144,14 @@ def main() -> None: type=int, help="provide a seed to the random number generator", ) + parser.add_argument( + "-log", + "--loglevel", + default="DEBUG", + help="Provide logging level. Example --loglevel debug, default=warning", + ) args = parser.parse_args() + logging.basicConfig(level=args.loglevel.upper()) try: trio.run(run, args.port, args.destination, args.seed) except KeyboardInterrupt: diff --git a/libp2p/transport/quic/connection.py b/libp2p/transport/quic/connection.py index abdb3d8f..e1693fa4 100644 --- a/libp2p/transport/quic/connection.py +++ b/libp2p/transport/quic/connection.py @@ -35,7 +35,7 @@ if TYPE_CHECKING: from .transport import QUICTransport logging.basicConfig( - level=logging.DEBUG, + level="DEBUG", format="%(asctime)s [%(levelname)s] %(message)s", handlers=[logging.StreamHandler()], ) diff --git a/libp2p/transport/quic/listener.py b/libp2p/transport/quic/listener.py index 4cbc8e74..fd023a3a 100644 --- a/libp2p/transport/quic/listener.py +++ b/libp2p/transport/quic/listener.py @@ -17,7 +17,6 @@ import trio from libp2p.abc import IListener from libp2p.custom_types import THandler, TProtocol from libp2p.transport.quic.security import QUICTLSConfigManager -from libp2p.transport.quic.utils import custom_quic_version_to_wire_format from .config import QUICTransportConfig from .connection import QUICConnection @@ -25,6 +24,7 @@ from .exceptions import QUICListenError from .utils import ( create_quic_multiaddr, create_server_config_from_base, + custom_quic_version_to_wire_format, is_quic_multiaddr, multiaddr_to_quic_version, quic_multiaddr_to_endpoint, @@ -356,7 +356,6 @@ class QUICListener(IListener): for protocol, config in self._quic_configs.items(): wire_versions = custom_quic_version_to_wire_format(protocol) if wire_versions == packet_info.version: - print("PROTOCOL:", protocol) quic_config = config break @@ -395,7 +394,6 @@ class QUICListener(IListener): # Process initial packet quic_conn.receive_datagram(data, addr, now=time.time()) - print("Processing quic events") await self._process_quic_events(quic_conn, addr, destination_cid) await self._transmit_for_connection(quic_conn, addr) @@ -755,8 +753,26 @@ class QUICListener(IListener): def get_addrs(self) -> tuple[Multiaddr]: return tuple(self.get_addresses()) - def get_stats(self) -> dict[str, int]: - return self._stats - def is_listening(self) -> bool: - raise NotImplementedError() + """ + Check if the listener is currently listening for connections. + + Returns: + bool: True if the listener is actively listening, False otherwise + + """ + return self._listening and not self._closed + + def get_stats(self) -> dict[str, int | bool]: + """ + Get listener statistics including the listening state. + + Returns: + dict: Statistics dictionary with current state information + + """ + stats = self._stats.copy() + stats["is_listening"] = self.is_listening() + stats["active_connections"] = len(self._connections) + stats["pending_connections"] = len(self._pending_connections) + return stats diff --git a/libp2p/transport/quic/utils.py b/libp2p/transport/quic/utils.py index 97634a91..03708778 100644 --- a/libp2p/transport/quic/utils.py +++ b/libp2p/transport/quic/utils.py @@ -25,22 +25,22 @@ UDP_PROTOCOL = "udp" IP4_PROTOCOL = "ip4" IP6_PROTOCOL = "ip6" -SERVER_CONFIG_PROTOCOL_V1 = f"{QUIC_V1_PROTOCOL}_SERVER" -SERVER_CONFIG_PROTOCOL_DRAFT_29 = f"{QUIC_V1_PROTOCOL}_SERVER" -CLIENT_CONFIG_PROTCOL_V1 = f"{QUIC_DRAFT29_PROTOCOL}_SERVER" -CLIENT_CONFIG_PROTOCOL_DRAFT_29 = f"{QUIC_DRAFT29_PROTOCOL}_SERVER" +SERVER_CONFIG_PROTOCOL_V1 = f"{QUIC_V1_PROTOCOL}_server" +SERVER_CONFIG_PROTOCOL_DRAFT_29 = f"{QUIC_V1_PROTOCOL}_server" +CLIENT_CONFIG_PROTCOL_V1 = f"{QUIC_DRAFT29_PROTOCOL}_client" +CLIENT_CONFIG_PROTOCOL_DRAFT_29 = f"{QUIC_DRAFT29_PROTOCOL}_client" CUSTOM_QUIC_VERSION_MAPPING = { SERVER_CONFIG_PROTOCOL_V1: 0x00000001, # RFC 9000 CLIENT_CONFIG_PROTCOL_V1: 0x00000001, # RFC 9000 - SERVER_CONFIG_PROTOCOL_DRAFT_29: 0xFF00001D, # draft-29 - CLIENT_CONFIG_PROTOCOL_DRAFT_29: 0xFF00001D, # draft-29 + SERVER_CONFIG_PROTOCOL_DRAFT_29: 0x00000001, # draft-29 + CLIENT_CONFIG_PROTOCOL_DRAFT_29: 0x00000001, # draft-29 } # QUIC version to wire format mappings (required for aioquic) QUIC_VERSION_MAPPINGS = { QUIC_V1_PROTOCOL: 0x00000001, # RFC 9000 - QUIC_DRAFT29_PROTOCOL: 0xFF00001D, # draft-29 + QUIC_DRAFT29_PROTOCOL: 0x00000001, # draft-29 } # ALPN protocols for libp2p over QUIC @@ -249,7 +249,7 @@ def custom_quic_version_to_wire_format(version: TProtocol) -> int: QUICUnsupportedVersionError: If version is not supported """ - wire_version = QUIC_VERSION_MAPPINGS.get(version) + wire_version = CUSTOM_QUIC_VERSION_MAPPING.get(version) if wire_version is None: raise QUICUnsupportedVersionError(f"Unsupported QUIC version: {version}") @@ -370,7 +370,7 @@ def create_server_config_from_base( transport_config, "max_datagram_size", 1200 ) # Ensure we have ALPN protocols - if server_config.alpn_protocols: + if not server_config.alpn_protocols: server_config.alpn_protocols = ["libp2p"] logger.debug("Successfully created server config without deepcopy") diff --git a/pyproject.toml b/pyproject.toml index 75191548..ac9689d0 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -22,8 +22,7 @@ dependencies = [ "exceptiongroup>=1.2.0; python_version < '3.11'", "grpcio>=1.41.0", "lru-dict>=1.1.6", - # "multiaddr>=0.0.9", - "multiaddr @ git+https://github.com/multiformats/py-multiaddr.git@db8124e2321f316d3b7d2733c7df11d6ad9c03e6", + "multiaddr (>=0.0.9,<0.0.10)", "mypy-protobuf>=3.0.0", "noiseprotocol>=0.3.0", "protobuf>=4.25.0,<5.0.0",