SYMBOL INDEX (659 symbols across 57 files) FILE: src/asyncio_socks_server/addons/auth.py class FileAuth (line 9) | class FileAuth(Addon): method __init__ (line 16) | def __init__(self, path: str | Path): method _load (line 20) | def _load(self) -> dict[str, str]: method on_auth (line 27) | async def on_auth(self, username: str, password: str) -> bool | None: FILE: src/asyncio_socks_server/addons/base.py class Addon (line 11) | class Addon: method on_start (line 19) | async def on_start(self) -> None: method on_stop (line 22) | async def on_stop(self) -> None: method on_auth (line 25) | async def on_auth(self, username: str, password: str) -> bool | None: method on_connect (line 28) | async def on_connect(self, flow: Flow) -> Connection | None: method on_udp_associate (line 31) | async def on_udp_associate(self, flow: Flow) -> UdpRelayBase | None: method on_data (line 34) | async def on_data( method on_flow_close (line 39) | async def on_flow_close(self, flow: Flow) -> None: method on_error (line 42) | async def on_error(self, error: Exception) -> None: FILE: src/asyncio_socks_server/addons/chain.py class ChainRouter (line 9) | class ChainRouter(Addon): method __init__ (line 16) | def __init__( method on_connect (line 27) | async def on_connect(self, flow: Flow) -> Connection | None: FILE: src/asyncio_socks_server/addons/ip_filter.py class IPFilter (line 9) | class IPFilter(Addon): method __init__ (line 17) | def __init__( method _is_allowed (line 25) | def _is_allowed(self, host: str) -> bool: method on_connect (line 37) | async def on_connect(self, flow: Flow) -> None: FILE: src/asyncio_socks_server/addons/logger.py class Logger (line 10) | class Logger(Addon): method __init__ (line 13) | def __init__(self): method on_connect (line 16) | async def on_connect(self, flow: Flow) -> None: method on_data (line 19) | async def on_data( method on_error (line 25) | async def on_error(self, error: Exception) -> None: FILE: src/asyncio_socks_server/addons/manager.py function _is_overridden (line 13) | def _is_overridden(addon: Addon, method_name: str) -> bool: class AddonManager (line 18) | class AddonManager: method __init__ (line 19) | def __init__(self, addons: list[Addon] | None = None): method dispatch_start (line 24) | async def dispatch_start(self) -> None: method dispatch_stop (line 29) | async def dispatch_stop(self) -> None: method dispatch_auth (line 36) | async def dispatch_auth(self, username: str, password: str) -> bool | ... method dispatch_connect (line 44) | async def dispatch_connect(self, flow: Flow) -> Connection | None: method dispatch_udp_associate (line 52) | async def dispatch_udp_associate(self, flow: Flow) -> UdpRelayBase | N... method dispatch_data (line 62) | async def dispatch_data( method dispatch_flow_close (line 75) | async def dispatch_flow_close(self, flow: Flow) -> None: method dispatch_error (line 83) | async def dispatch_error(self, error: Exception) -> None: FILE: src/asyncio_socks_server/addons/stats.py class FlowStats (line 16) | class FlowStats(Addon): method __init__ (line 25) | def __init__( method on_connect (line 53) | async def on_connect(self, flow: Flow) -> None: method on_udp_associate (line 56) | async def on_udp_associate(self, flow: Flow) -> None: method on_flow_close (line 59) | async def on_flow_close(self, flow: Flow) -> None: method on_error (line 70) | async def on_error(self, error: Exception) -> None: method snapshot (line 82) | def snapshot(self) -> dict[str, Any]: method active_flows (line 109) | def active_flows(self) -> list[dict[str, Any]]: method _active_flow_snapshots (line 114) | def _active_flow_snapshots(self) -> list[dict[str, Any]]: method recent_closed_flows (line 119) | def recent_closed_flows(self) -> list[dict[str, Any]]: method flows (line 123) | def flows(self) -> dict[str, Any]: method errors (line 130) | def errors(self) -> dict[str, Any]: method _track_flow (line 138) | def _track_flow(self, flow: Flow) -> None: method _flow_snapshot (line 156) | def _flow_snapshot(self, flow: Flow, state: str) -> dict[str, Any]: method _sample_rates (line 172) | def _sample_rates(self) -> None: method _sample_flow_rate (line 191) | def _sample_flow_rate(self, flow: Flow) -> None: method _format_wall_time (line 212) | def _format_wall_time(timestamp: float) -> str: method _duration (line 216) | def _duration(started_at: float) -> float: class FlowAudit (line 220) | class FlowAudit(Addon): method __init__ (line 223) | def __init__(self, max_recent_records: int = 100) -> None: method on_flow_close (line 235) | async def on_flow_close(self, flow: Flow) -> None: method snapshot (line 238) | def snapshot( method reset (line 266) | def reset(self) -> None: method _record (line 278) | def _record(self, flow: Flow) -> None: method _add_total (line 313) | def _add_total( method _sorted_totals (line 334) | def _sorted_totals( method _format_optional_time (line 345) | def _format_optional_time(cls, timestamp: float | None) -> str: method _format_wall_time (line 351) | def _format_wall_time(timestamp: float) -> str: class StatsAPI (line 355) | class StatsAPI(Addon): method __init__ (line 365) | def __init__( method on_start (line 381) | async def on_start(self) -> None: method on_stop (line 391) | async def on_stop(self) -> None: method on_connect (line 398) | async def on_connect(self, flow: Flow) -> None: method on_udp_associate (line 402) | async def on_udp_associate(self, flow: Flow) -> None: method on_flow_close (line 406) | async def on_flow_close(self, flow: Flow) -> None: method on_error (line 410) | async def on_error(self, error: Exception) -> None: method snapshot (line 414) | def snapshot(self) -> dict[str, Any]: method _handle_http (line 417) | async def _handle_http( method _write_json (line 458) | async def _write_json( method _write_audit (line 480) | async def _write_audit( method _int_query (line 498) | def _int_query(query: dict[str, list[str]], name: str, default: int) -... method _str_query (line 508) | def _str_query(query: dict[str, list[str]], name: str) -> str | None: class StatsServer (line 515) | class StatsServer(StatsAPI): FILE: src/asyncio_socks_server/addons/traffic.py class TrafficCounter (line 7) | class TrafficCounter(Addon): method __init__ (line 10) | def __init__(self): method on_connect (line 15) | async def on_connect(self, flow: Flow) -> None: method on_flow_close (line 18) | async def on_flow_close(self, flow: Flow) -> None: FILE: src/asyncio_socks_server/addons/udp_over_tcp_entry.py class UdpOverTcpEntry (line 12) | class UdpOverTcpEntry(Addon): method __init__ (line 19) | def __init__( method on_udp_associate (line 30) | async def on_udp_associate(self, flow: Flow) -> UdpRelayBase | None: class _Bridge (line 34) | class _Bridge(UdpRelayBase): method __init__ (line 37) | def __init__( method start (line 54) | async def start(self) -> Address: method set_client_transport (line 69) | def set_client_transport(self, transport: asyncio.DatagramTransport) -... method stop (line 72) | async def stop(self) -> None: method handle_client_datagram (line 86) | def handle_client_datagram(self, data: bytes, client_addr: tuple[str, ... method _tcp_to_client (line 112) | async def _tcp_to_client(self) -> None: FILE: src/asyncio_socks_server/cli.py function main (line 8) | def main() -> None: FILE: src/asyncio_socks_server/client/client.py function connect (line 15) | async def connect( function _happy_eyeballs_connect (line 40) | async def _happy_eyeballs_connect( function _negotiate (line 125) | async def _negotiate( function _request_connect (line 163) | async def _request_connect( FILE: src/asyncio_socks_server/core/address.py function detect_atyp (line 11) | def detect_atyp(host: str) -> Atyp: function encode_address (line 25) | def encode_address(host: str, port: int) -> bytes: function decode_address (line 39) | async def decode_address(reader: asyncio.StreamReader) -> Address: function encode_reply (line 54) | def encode_reply( FILE: src/asyncio_socks_server/core/logging.py function setup_logging (line 10) | def setup_logging(level: str = "INFO") -> None: function get_logger (line 18) | def get_logger() -> logging.Logger: function fmt_addr (line 22) | def fmt_addr(addr: Address) -> str: function fmt_connection (line 26) | def fmt_connection(src: Address, dst: Address) -> str: function fmt_bytes (line 30) | def fmt_bytes(n: int) -> str: FILE: src/asyncio_socks_server/core/protocol.py class ProtocolError (line 10) | class ProtocolError(Exception): function parse_method_selection (line 14) | def parse_method_selection(data: bytes) -> tuple[int, set[int]]: function build_method_reply (line 25) | def build_method_reply(method: int) -> bytes: function parse_username_password (line 31) | async def parse_username_password( function build_auth_reply (line 44) | def build_auth_reply(success: bool) -> bytes: function parse_request (line 50) | async def parse_request(reader: asyncio.StreamReader) -> tuple[Cmd, Addr... function parse_udp_header (line 73) | def parse_udp_header(data: bytes) -> tuple[Address, int, bytes]: function build_udp_header (line 108) | def build_udp_header(address: Address) -> bytes: FILE: src/asyncio_socks_server/core/socket.py function _is_ipv6 (line 7) | def _is_ipv6(host: str) -> bool: function create_dualstack_tcp_socket (line 15) | def create_dualstack_tcp_socket(host: str, port: int) -> socket.socket: function create_dualstack_udp_socket (line 28) | def create_dualstack_udp_socket(host: str, port: int = 0) -> socket.socket: FILE: src/asyncio_socks_server/core/types.py class Rep (line 9) | class Rep(IntEnum): class AuthMethod (line 23) | class AuthMethod(IntEnum): class Cmd (line 31) | class Cmd(IntEnum): class Atyp (line 38) | class Atyp(IntEnum): class Direction (line 46) | class Direction(StrEnum): class Address (line 54) | class Address: method __str__ (line 58) | def __str__(self) -> str: class Flow (line 63) | class Flow: FILE: src/asyncio_socks_server/server/connection.py class Connection (line 10) | class Connection: FILE: src/asyncio_socks_server/server/server.py class Server (line 30) | class Server: method __init__ (line 31) | def __init__( method run (line 50) | def run(self) -> None: method _install_signal_handlers (line 53) | def _install_signal_handlers(self) -> None: method _run (line 64) | async def _run(self) -> None: method _wait_for_client_tasks (line 92) | async def _wait_for_client_tasks(self) -> None: method _handle_client (line 111) | async def _handle_client( method _do_handshake_and_relay (line 130) | async def _do_handshake_and_relay( method _handle_connect (line 181) | async def _handle_connect( method _handle_udp_associate (line 254) | async def _handle_udp_associate( method _error_to_rep (line 329) | def _error_to_rep(exc: Exception) -> Rep: method request_shutdown (line 336) | def request_shutdown(self) -> None: function _create_client_udp_socket (line 340) | def _create_client_udp_socket(host: str) -> socket.socket: class _ClientUdpProtocol (line 350) | class _ClientUdpProtocol(asyncio.DatagramProtocol): method __init__ (line 351) | def __init__(self, relay: UdpRelayBase) -> None: method connection_made (line 354) | def connection_made(self, transport: asyncio.DatagramTransport) -> None: method datagram_received (line 357) | def datagram_received(self, data: bytes, addr: tuple[str, int]) -> None: method error_received (line 360) | def error_received(self, exc: Exception) -> None: FILE: src/asyncio_socks_server/server/tcp_relay.py function _copy (line 10) | async def _copy( function handle_tcp_relay (line 42) | async def handle_tcp_relay( FILE: src/asyncio_socks_server/server/udp_over_tcp.py function encode_udp_frame (line 10) | async def encode_udp_frame(address: Address, data: bytes) -> bytes: function read_udp_frame (line 21) | async def read_udp_frame( FILE: src/asyncio_socks_server/server/udp_over_tcp_exit.py function _normalize_host (line 15) | def _normalize_host(host: str) -> str: function _map_addr_for_sendto (line 21) | def _map_addr_for_sendto( class UdpOverTcpExitServer (line 35) | class UdpOverTcpExitServer: method __init__ (line 42) | def __init__(self, host: str = "::", port: int = 0, ttl: float = 300.0): method run (line 48) | def run(self) -> None: method request_shutdown (line 51) | def request_shutdown(self) -> None: method _run (line 54) | async def _run(self) -> None: function _handle_tcp (line 134) | async def _handle_tcp( FILE: src/asyncio_socks_server/server/udp_relay.py function _normalize_host (line 12) | def _normalize_host(host: str) -> str: function _map_addr_for_sendto (line 19) | def _map_addr_for_sendto( class UdpRelayBase (line 37) | class UdpRelayBase: method start (line 40) | async def start(self) -> Address: method set_client_transport (line 43) | def set_client_transport(self, transport: asyncio.DatagramTransport) -... method stop (line 46) | async def stop(self) -> None: method handle_client_datagram (line 49) | def handle_client_datagram(self, data: bytes, client_addr: tuple[str, ... class UdpRelay (line 53) | class UdpRelay(UdpRelayBase): method __init__ (line 61) | def __init__(self, client_addr: Address, flow: Flow, ttl: float = 300.0): method start (line 72) | async def start(self) -> Address: method set_client_transport (line 87) | def set_client_transport(self, transport: asyncio.DatagramTransport) -... method stop (line 90) | async def stop(self) -> None: method handle_client_datagram (line 100) | def handle_client_datagram(self, data: bytes, client_addr: tuple[str, ... method _on_remote_data (line 117) | def _on_remote_data(self, data: bytes, remote_addr: tuple[str, int]) -... method _ttl_cleanup_loop (line 134) | async def _ttl_cleanup_loop(self) -> None: class _UdpProtocol (line 148) | class _UdpProtocol(asyncio.DatagramProtocol): method __init__ (line 149) | def __init__(self, on_data: Callable[[bytes, tuple[str, int]], None]) ... method connection_made (line 153) | def connection_made(self, transport: asyncio.DatagramTransport) -> None: method datagram_received (line 156) | def datagram_received(self, data: bytes, addr: tuple[str, int]) -> None: method error_received (line 159) | def error_received(self, exc: Exception) -> None: FILE: tests/conftest.py function echo_server (line 10) | async def echo_server(): function udp_echo_server (line 33) | async def udp_echo_server(): function _start_server (line 55) | async def _start_server(**kwargs): function _stop_server (line 65) | async def _stop_server(server, task): FILE: tests/e2e_helpers.py function socks5_connect (line 9) | async def socks5_connect( function read_socks_reply (line 44) | async def read_socks_reply(reader: asyncio.StreamReader) -> bytes: function open_udp_associate (line 57) | async def open_udp_associate( FILE: tests/test_addon_builtins.py function _make_flow (line 11) | def _make_flow(**kwargs): class TestFileAuth (line 23) | class TestFileAuth: method test_valid_credentials (line 24) | async def test_valid_credentials(self, tmp_path): method test_unknown_user (line 32) | async def test_unknown_user(self, tmp_path): method test_missing_file (line 39) | async def test_missing_file(self, tmp_path): class TestIPFilter (line 44) | class TestIPFilter: method test_blocked (line 45) | async def test_blocked(self): method test_allowed_list (line 54) | async def test_allowed_list(self): method test_not_in_allowed (line 60) | async def test_not_in_allowed(self): method test_no_rules (line 65) | async def test_no_rules(self): class TestLogger (line 71) | class TestLogger: method test_on_connect (line 72) | async def test_on_connect(self): method test_on_data (line 79) | async def test_on_data(self): method test_on_error (line 85) | async def test_on_error(self): FILE: tests/test_addon_builtins_extended.py function _make_flow (line 13) | def _make_flow(**kwargs): class TestFileAuthExtended (line 25) | class TestFileAuthExtended: method test_corrupted_json_file (line 26) | async def test_corrupted_json_file(self, tmp_path): method test_empty_json_file (line 33) | async def test_empty_json_file(self, tmp_path): method test_credentials_cached_after_first_load (line 40) | async def test_credentials_cached_after_first_load(self, tmp_path): method test_unicode_credentials (line 56) | async def test_unicode_credentials(self, tmp_path): method test_unknown_user (line 63) | async def test_unknown_user(self, tmp_path): class TestIPFilterExtended (line 71) | class TestIPFilterExtended: method test_ipv6_blocked (line 72) | async def test_ipv6_blocked(self): method test_ipv6_allowed (line 79) | async def test_ipv6_allowed(self): method test_domain_source_falls_back (line 87) | async def test_domain_source_falls_back(self): method test_empty_rules (line 97) | async def test_empty_rules(self): class TestLoggerExtended (line 106) | class TestLoggerExtended: method test_on_data_returns_data_passthrough (line 107) | async def test_on_data_returns_data_passthrough(self): method test_on_connect_returns_none (line 113) | async def test_on_connect_returns_none(self): method test_on_error_does_not_raise (line 120) | async def test_on_error_does_not_raise(self): FILE: tests/test_addon_chain.py function _start_server (line 11) | async def _start_server(**kwargs): function _stop_server (line 21) | async def _stop_server(server, task): function echo_server (line 27) | async def echo_server(): class TestChainRouter (line 47) | class TestChainRouter: method test_two_hop_chain (line 48) | async def test_two_hop_chain(self, echo_server): method test_chain_with_auth (line 71) | async def test_chain_with_auth(self, echo_server): FILE: tests/test_addon_edge_cases.py function _make_flow (line 8) | def _make_flow(**kwargs): class ConnectReturning (line 20) | class ConnectReturning(Addon): method __init__ (line 21) | def __init__(self, value=None): method on_connect (line 24) | async def on_connect(self, flow): class TrackingAddon (line 28) | class TrackingAddon(Addon): method __init__ (line 29) | def __init__(self, name, calls): method on_start (line 33) | async def on_start(self): method on_stop (line 36) | async def on_stop(self): class DataTransform (line 40) | class DataTransform(Addon): method __init__ (line 41) | def __init__(self, transform_fn): method on_data (line 44) | async def on_data(self, direction, data, flow): class ErrorRaiser (line 48) | class ErrorRaiser(Addon): method __init__ (line 49) | def __init__(self, raise_on_error=False): method on_error (line 53) | async def on_error(self, error): class AuthAddon (line 59) | class AuthAddon(Addon): method __init__ (line 60) | def __init__(self, result): method on_auth (line 63) | async def on_auth(self, username, password): class TestCompetitiveConnect (line 67) | class TestCompetitiveConnect: method test_first_addon_returns_connection (line 68) | async def test_first_addon_returns_connection(self): method test_second_addon_returns_connection (line 79) | async def test_second_addon_returns_connection(self): method test_no_addon_returns_connection (line 89) | async def test_no_addon_returns_connection(self): class TestPipelineEdgeCases (line 99) | class TestPipelineEdgeCases: method test_pipeline_with_intermediate_none (line 100) | async def test_pipeline_with_intermediate_none(self): method test_pipeline_empty_bytes (line 124) | async def test_pipeline_empty_bytes(self): class TestAddonExceptions (line 138) | class TestAddonExceptions: method test_auth_addon_raises_exception (line 139) | async def test_auth_addon_raises_exception(self): method test_data_addon_raises_exception (line 151) | async def test_data_addon_raises_exception(self): method test_error_addon_exception_suppressed (line 163) | async def test_error_addon_exception_suppressed(self): method test_error_addon_all_called (line 172) | async def test_error_addon_all_called(self): class TestLifecycleOrder (line 184) | class TestLifecycleOrder: method test_multiple_addons_start_stop_order (line 185) | async def test_multiple_addons_start_stop_order(self): method test_addon_with_only_data_override (line 199) | async def test_addon_with_only_data_override(self): class TestCompetitiveAuth (line 218) | class TestCompetitiveAuth: method test_first_auth_wins_true (line 219) | async def test_first_auth_wins_true(self): method test_first_auth_wins_false (line 224) | async def test_first_auth_wins_false(self): method test_all_none_passes_through (line 229) | async def test_all_none_passes_through(self): FILE: tests/test_addon_manager.py function _make_flow (line 6) | def _make_flow(**kwargs): class LifeCycleAddon (line 18) | class LifeCycleAddon(Addon): method __init__ (line 19) | def __init__(self): method on_start (line 23) | async def on_start(self): method on_stop (line 26) | async def on_stop(self): class TestLifecycle (line 30) | class TestLifecycle: method test_start_stop (line 31) | async def test_start_stop(self): method test_empty_manager (line 39) | async def test_empty_manager(self): method test_base_addon_skipped (line 44) | async def test_base_addon_skipped(self): class AuthAllow (line 49) | class AuthAllow(Addon): method on_auth (line 50) | async def on_auth(self, username, password): class AuthDeny (line 54) | class AuthDeny(Addon): method on_auth (line 55) | async def on_auth(self, username, password): class AuthPass (line 59) | class AuthPass(Addon): method on_auth (line 60) | async def on_auth(self, username, password): class TestCompetitiveAuth (line 64) | class TestCompetitiveAuth: method test_first_allow_wins (line 65) | async def test_first_allow_wins(self): method test_first_deny_wins (line 70) | async def test_first_deny_wins(self): method test_all_pass (line 75) | async def test_all_pass(self): method test_passthrough_then_allow (line 80) | async def test_passthrough_then_allow(self): class UpperAddon (line 86) | class UpperAddon(Addon): method on_data (line 87) | async def on_data(self, direction, data, flow): class AppendAddon (line 91) | class AppendAddon(Addon): method on_data (line 92) | async def on_data(self, direction, data, flow): class DropAddon (line 96) | class DropAddon(Addon): method on_data (line 97) | async def on_data(self, direction, data, flow): class TestPipelineData (line 101) | class TestPipelineData: method test_single_transform (line 102) | async def test_single_transform(self): method test_chain_transforms (line 107) | async def test_chain_transforms(self): method test_drop_stops_pipeline (line 112) | async def test_drop_stops_pipeline(self): method test_no_addons (line 117) | async def test_no_addons(self): class ErrorAddon (line 123) | class ErrorAddon(Addon): method __init__ (line 124) | def __init__(self): method on_error (line 127) | async def on_error(self, error): class ErrorRaisingAddon (line 131) | class ErrorRaisingAddon(Addon): method on_error (line 132) | async def on_error(self, error): class TestObservationalError (line 136) | class TestObservationalError: method test_all_called (line 137) | async def test_all_called(self): method test_exception_doesnt_propagate (line 146) | async def test_exception_doesnt_propagate(self): FILE: tests/test_addon_stats.py function _start_server (line 15) | async def _start_server(**kwargs): function _stop_server (line 25) | async def _stop_server(server, task): function _get_json (line 30) | async def _get_json(port: int, path: str): function _request_json (line 34) | async def _request_json(port: int, method: str, path: str): class TestStatsServer (line 47) | class TestStatsServer: method test_flow_stats_has_no_network_side_effects (line 48) | async def test_flow_stats_has_no_network_side_effects(self, echo_server): method test_health_endpoint (line 70) | async def test_health_endpoint(self): method test_stats_api_can_present_external_flow_stats_without_double_counting (line 80) | async def test_stats_api_can_present_external_flow_stats_without_doubl... method test_errors_endpoint (line 105) | async def test_errors_endpoint(self): method test_flow_audit_has_no_network_side_effects (line 118) | async def test_flow_audit_has_no_network_side_effects(self, echo_server): method test_stats_api_exposes_flow_audit (line 145) | async def test_stats_api_exposes_flow_audit(self, echo_server): method test_stats_api_reports_audit_disabled (line 175) | async def test_stats_api_reports_audit_disabled(self): method test_tracks_active_and_closed_tcp_flows (line 185) | async def test_tracks_active_and_closed_tcp_flows(self, echo_server): method test_tracks_errors (line 238) | async def test_tracks_errors(self): method test_not_found (line 248) | async def test_not_found(self): FILE: tests/test_cli.py class TestCliArgs (line 10) | class TestCliArgs: method test_default_values (line 12) | def test_default_values(self, mock_server_cls): method test_custom_host_port (line 19) | def test_custom_host_port(self, mock_server_cls): method test_auth_parsing (line 33) | def test_auth_parsing(self, mock_server_cls): method test_auth_with_colon_in_password (line 43) | def test_auth_with_colon_in_password(self, mock_server_cls): method test_invalid_log_level (line 52) | def test_invalid_log_level(self): method test_debug_log_level (line 58) | def test_debug_log_level(self, mock_server_cls): method test_no_auth_flag (line 68) | def test_no_auth_flag(self, mock_server_cls): FILE: tests/test_client.py function _start_server (line 10) | async def _start_server(**kwargs): function _stop_server (line 20) | async def _stop_server(server, task): function echo_server (line 26) | async def echo_server(): class TestClientConnect (line 46) | class TestClientConnect: method test_no_auth (line 47) | async def test_no_auth(self, echo_server): method test_with_auth (line 60) | async def test_with_auth(self, echo_server): method test_auth_failure (line 78) | async def test_auth_failure(self, echo_server): method test_connection_refused (line 93) | async def test_connection_refused(self): FILE: tests/test_client_edge_cases.py function _fake_socks_server (line 12) | async def _fake_socks_server(*responses): function _fake_socks_server_with_responses (line 40) | async def _fake_socks_server_with_responses(responses): class TestClientNegotiationFailures (line 71) | class TestClientNegotiationFailures: method test_proxy_returns_wrong_version (line 72) | async def test_proxy_returns_wrong_version(self): method test_proxy_returns_no_acceptable_method (line 83) | async def test_proxy_returns_no_acceptable_method(self): method test_connect_reply_failure (line 94) | async def test_connect_reply_failure(self): method test_connect_reply_wrong_version (line 111) | async def test_connect_reply_wrong_version(self): class TestClientConnectionFailures (line 127) | class TestClientConnectionFailures: method test_happy_eyeballs_falls_back_after_fast_first_failure (line 128) | async def test_happy_eyeballs_falls_back_after_fast_first_failure( method test_connection_refused (line 166) | async def test_connection_refused(self): method test_auth_failure (line 172) | async def test_auth_failure(self): FILE: tests/test_concurrent.py function _socks5_proxy_connect (line 10) | async def _socks5_proxy_connect(proxy: Address, target: Address): class TestConcurrentConnections (line 36) | class TestConcurrentConnections: method test_20_simultaneous_connections (line 37) | async def test_20_simultaneous_connections(self, echo_server): method test_concurrent_with_addon (line 63) | async def test_concurrent_with_addon(self, echo_server): class TestLargePayloads (line 90) | class TestLargePayloads: method test_1mb_payload (line 91) | async def test_1mb_payload(self, echo_server): method test_many_small_writes (line 114) | async def test_many_small_writes(self, echo_server): class TestRapidConnectDisconnect (line 139) | class TestRapidConnectDisconnect: method test_rapid_10_cycles (line 140) | async def test_rapid_10_cycles(self): FILE: tests/test_connection.py class TestConnection (line 9) | class TestConnection: method test_dataclass_fields (line 10) | async def test_dataclass_fields(self): method test_address_type (line 19) | async def test_address_type(self): FILE: tests/test_core_address.py class TestDetectAtyp (line 12) | class TestDetectAtyp: method test_ipv4 (line 13) | def test_ipv4(self): method test_ipv6 (line 17) | def test_ipv6(self): method test_domain (line 21) | def test_domain(self): class TestEncodeDecodeAddress (line 26) | class TestEncodeDecodeAddress: method _roundtrip (line 27) | def _roundtrip(self, host: str, port: int): method test_ipv4_roundtrip (line 39) | def test_ipv4_roundtrip(self): method test_ipv6_roundtrip (line 44) | def test_ipv6_roundtrip(self): method test_domain_roundtrip (line 49) | def test_domain_roundtrip(self): method test_encode_ipv4_binary (line 54) | def test_encode_ipv4_binary(self): method test_encode_ipv6_binary (line 60) | def test_encode_ipv6_binary(self): method test_encode_domain_binary (line 66) | def test_encode_domain_binary(self): class TestEncodeReply (line 74) | class TestEncodeReply: method test_success_reply (line 75) | def test_success_reply(self): method test_failure_reply (line 81) | def test_failure_reply(self): FILE: tests/test_core_protocol.py class TestMethodSelection (line 18) | class TestMethodSelection: method test_valid_no_auth (line 19) | def test_valid_no_auth(self): method test_valid_username_password (line 25) | def test_valid_username_password(self): method test_wrong_version (line 31) | def test_wrong_version(self): method test_too_short (line 35) | def test_too_short(self): method test_build_method_reply (line 39) | def test_build_method_reply(self): class TestUsernamePassword (line 45) | class TestUsernamePassword: method test_parse (line 46) | def test_parse(self): method test_wrong_version (line 60) | def test_wrong_version(self): method test_build_auth_reply (line 72) | def test_build_auth_reply(self): class TestParseRequest (line 77) | class TestParseRequest: method _make_request (line 78) | def _make_request(self, cmd: int, host: str, port: int) -> bytes: method test_connect_ipv4 (line 86) | def test_connect_ipv4(self): method test_connect_ipv6 (line 100) | def test_connect_ipv6(self): method test_connect_domain (line 114) | def test_connect_domain(self): method test_udp_associate (line 128) | def test_udp_associate(self): method test_wrong_version (line 140) | def test_wrong_version(self): method test_unsupported_command (line 152) | def test_unsupported_command(self): class TestUdpHeader (line 165) | class TestUdpHeader: method test_parse_ipv4 (line 166) | def test_parse_ipv4(self): method test_parse_domain (line 179) | def test_parse_domain(self): method test_build_udp_header (line 191) | def test_build_udp_header(self): method test_too_short (line 197) | def test_too_short(self): FILE: tests/test_core_socket.py function test_tcp_unspecified_ipv4_uses_ipv4_socket (line 9) | def test_tcp_unspecified_ipv4_uses_ipv4_socket(): function test_udp_unspecified_ipv4_uses_ipv4_socket (line 17) | def test_udp_unspecified_ipv4_uses_ipv4_socket(): function test_tcp_unspecified_ipv6_keeps_dualstack_socket (line 26) | def test_tcp_unspecified_ipv6_keeps_dualstack_socket(): FILE: tests/test_core_types.py function test_rep_values (line 11) | def test_rep_values(): function test_auth_method_values (line 17) | def test_auth_method_values(): function test_cmd_values (line 23) | def test_cmd_values(): function test_atyp_values (line 28) | def test_atyp_values(): function test_direction_constants (line 34) | def test_direction_constants(): function test_address_frozen (line 39) | def test_address_frozen(): function test_address_str (line 45) | def test_address_str(): FILE: tests/test_e2e.py function _socks5_proxy_connect (line 9) | async def _socks5_proxy_connect(proxy: Address, target: Address, auth=No... class TestE2ETcp (line 60) | class TestE2ETcp: method test_bidirectional_relay (line 61) | async def test_bidirectional_relay(self, echo_server): method test_multiple_connections (line 82) | async def test_multiple_connections(self, echo_server): method test_client_library (line 103) | async def test_client_library(self, echo_server): class TestE2EChain (line 119) | class TestE2EChain: method test_three_hop_chain (line 120) | async def test_three_hop_chain(self, echo_server): class UpperAddon (line 147) | class UpperAddon(Addon): method on_data (line 148) | async def on_data(self, direction, data, flow): class TestE2EAddons (line 152) | class TestE2EAddons: method test_pipeline_transform (line 153) | async def test_pipeline_transform(self, echo_server): method test_traffic_counter (line 175) | async def test_traffic_counter(self, echo_server): FILE: tests/test_e2e_auth_chain.py class TestAuthChain (line 8) | class TestAuthChain: method test_chain_with_auth_at_entry (line 9) | async def test_chain_with_auth_at_entry(self, echo_server): method test_chain_with_auth_at_exit (line 33) | async def test_chain_with_auth_at_exit(self, echo_server): method test_chain_both_hops_require_auth (line 55) | async def test_chain_both_hops_require_auth(self, echo_server): method test_chain_auth_failure_propagates (line 83) | async def test_chain_auth_failure_propagates(self, echo_server): FILE: tests/test_e2e_data_paths.py class TestBidirectionalData (line 12) | class TestBidirectionalData: method test_simultaneous_bidirectional (line 13) | async def test_simultaneous_bidirectional(self, echo_server): class TestLargeDataChain (line 36) | class TestLargeDataChain: method test_512kb_through_chain (line 37) | async def test_512kb_through_chain(self, echo_server): class TestMultiAddonComposition (line 65) | class TestMultiAddonComposition: method test_ipfilter_and_traffic_counter (line 66) | async def test_ipfilter_and_traffic_counter(self, echo_server): method test_ipfilter_blocks_then_traffic_zero (line 86) | async def test_ipfilter_blocks_then_traffic_zero(self, echo_server): method test_pipeline_and_chain_combined (line 105) | async def test_pipeline_and_chain_combined(self, echo_server): class TestAddonDataDrop (line 128) | class TestAddonDataDrop: method test_drop_addon_silences_upstream (line 129) | async def test_drop_addon_silences_upstream(self, echo_server): class TestFlowBytesAccuracy (line 155) | class TestFlowBytesAccuracy: method test_traffic_counter_through_chain (line 156) | async def test_traffic_counter_through_chain(self, echo_server): class TestMixedProtocol (line 187) | class TestMixedProtocol: method test_tcp_and_udp_concurrent (line 188) | async def test_tcp_and_udp_concurrent(self, echo_server, udp_echo_serv... class TestBinaryDataRoundtrip (line 239) | class TestBinaryDataRoundtrip: method test_null_bytes_and_binary (line 240) | async def test_null_bytes_and_binary(self, echo_server): method test_binary_through_chain (line 261) | async def test_binary_through_chain(self, echo_server): FILE: tests/test_e2e_lifecycle.py class TestClientDisconnect (line 8) | class TestClientDisconnect: method test_abrupt_client_disconnect_no_crash (line 9) | async def test_abrupt_client_disconnect_no_crash(self, echo_server): method test_target_disconnect_mid_relay (line 29) | async def test_target_disconnect_mid_relay(self): class TestGracefulShutdown (line 60) | class TestGracefulShutdown: method test_active_connections_complete_on_shutdown (line 61) | async def test_active_connections_complete_on_shutdown(self): class TestRepeatedConnections (line 94) | class TestRepeatedConnections: method test_50_sequential_connections (line 95) | async def test_50_sequential_connections(self, echo_server): method test_connection_reuse_stability (line 109) | async def test_connection_reuse_stability(self, echo_server): FILE: tests/test_e2e_policy_errors.py class TestIPFilterE2E (line 10) | class TestIPFilterE2E: method test_allowed_ip_connects (line 11) | async def test_allowed_ip_connects(self, echo_server): method test_blocked_ip_rejected (line 24) | async def test_blocked_ip_rejected(self, echo_server): class TestConnectionRefusedE2E (line 39) | class TestConnectionRefusedE2E: method test_target_refused_returns_error_reply (line 40) | async def test_target_refused_returns_error_reply(self): method test_unreachable_target_through_chain (line 54) | async def test_unreachable_target_through_chain(self): class TestDomainNameTarget (line 73) | class TestDomainNameTarget: method test_domain_target_resolved (line 74) | async def test_domain_target_resolved(self, echo_server): FILE: tests/test_flow.py function _make_flow (line 14) | def _make_flow(**kwargs): class TestFlowDataclass (line 29) | class TestFlowDataclass: method test_construction_with_defaults (line 30) | def test_construction_with_defaults(self): method test_mutable_bytes (line 43) | def test_mutable_bytes(self): method test_protocol_literal (line 50) | def test_protocol_literal(self): method test_started_at_monotonic (line 56) | def test_started_at_monotonic(self): class CloseCapture (line 72) | class CloseCapture(Addon): method __init__ (line 73) | def __init__(self): method on_flow_close (line 76) | async def on_flow_close(self, flow): class CloseCrasher (line 80) | class CloseCrasher(Addon): method on_flow_close (line 81) | async def on_flow_close(self, flow): class TestOnFlowClose (line 85) | class TestOnFlowClose: method test_called_for_all_addons (line 86) | async def test_called_for_all_addons(self): method test_exception_does_not_propagate (line 96) | async def test_exception_does_not_propagate(self): method test_receives_final_flow_snapshot (line 104) | async def test_receives_final_flow_snapshot(self): method test_base_addon_skipped (line 114) | async def test_base_addon_skipped(self): method test_no_addons (line 118) | async def test_no_addons(self): class TestTcpFlowBytes (line 126) | class TestTcpFlowBytes: method _pipe (line 127) | async def _pipe(self): method test_copy_updates_bytes_up (line 138) | async def test_copy_updates_bytes_up(self): method test_copy_updates_bytes_down (line 158) | async def test_copy_updates_bytes_down(self): method test_bidirectional_relay_bytes (line 180) | async def test_bidirectional_relay_bytes(self): class TestUdpRelayFlowInjection (line 227) | class TestUdpRelayFlowInjection: method test_constructor_stores_flow (line 228) | async def test_constructor_stores_flow(self): method test_udp_bytes_single_write (line 233) | async def test_udp_bytes_single_write(self, udp_echo_server): FILE: tests/test_ipv6.py function _start_server_ipv6 (line 16) | async def _start_server_ipv6(**kwargs): function _stop_server (line 26) | async def _stop_server(server, task): function _skip_bind_address (line 31) | async def _skip_bind_address(reader): function _socks5_connect_ipv6 (line 42) | async def _socks5_connect_ipv6(proxy_addr: Address, target: Address): class TestIPv6TCP (line 56) | class TestIPv6TCP: method ipv6_echo_server (line 58) | async def ipv6_echo_server(self): method test_tcp_connect_ipv6_loopback (line 77) | async def test_tcp_connect_ipv6_loopback(self, ipv6_echo_server): method test_tcp_ipv4_on_dualstack (line 92) | async def test_tcp_ipv4_on_dualstack(self): class TestIPv6UDP (line 135) | class TestIPv6UDP: method ipv6_udp_echo_server (line 137) | async def ipv6_udp_echo_server(self): method test_udp_associate_ipv6 (line 157) | async def test_udp_associate_ipv6(self, ipv6_udp_echo_server): FILE: tests/test_logging.py class TestSetupLogging (line 15) | class TestSetupLogging: method test_sets_level_debug (line 16) | def test_sets_level_debug(self): method test_sets_level_info (line 21) | def test_sets_level_info(self): class TestGetLogger (line 27) | class TestGetLogger: method test_returns_named_logger (line 28) | def test_returns_named_logger(self): class TestFmtAddr (line 33) | class TestFmtAddr: method test_ipv4 (line 34) | def test_ipv4(self): method test_ipv6 (line 37) | def test_ipv6(self): method test_domain (line 40) | def test_domain(self): class TestFmtConnection (line 44) | class TestFmtConnection: method test_format (line 45) | def test_format(self): class TestFmtBytes (line 52) | class TestFmtBytes: method test_zero (line 53) | def test_zero(self): method test_bytes (line 56) | def test_bytes(self): method test_boundary_1023 (line 59) | def test_boundary_1023(self): method test_boundary_1024 (line 62) | def test_boundary_1024(self): method test_kilobytes (line 65) | def test_kilobytes(self): method test_just_under_mb (line 68) | def test_just_under_mb(self): method test_exact_mb (line 71) | def test_exact_mb(self): method test_megabytes (line 74) | def test_megabytes(self): FILE: tests/test_protocol_robustness.py class TestMethodSelectionEdgeCases (line 16) | class TestMethodSelectionEdgeCases: method test_empty_data (line 17) | def test_empty_data(self): method test_single_byte (line 21) | def test_single_byte(self): method test_wrong_version (line 25) | def test_wrong_version(self): method test_nmethods_zero (line 29) | def test_nmethods_zero(self): method test_extra_bytes_beyond_methods (line 34) | def test_extra_bytes_beyond_methods(self): method test_all_methods (line 40) | def test_all_methods(self): class TestUsernamePasswordEdgeCases (line 46) | class TestUsernamePasswordEdgeCases: method test_empty_username (line 47) | async def test_empty_username(self): method test_empty_password (line 55) | async def test_empty_password(self): method test_max_length_username (line 63) | async def test_max_length_username(self): method test_wrong_auth_version (line 72) | async def test_wrong_auth_version(self): method test_truncated_password (line 79) | async def test_truncated_password(self): class TestParseRequestEdgeCases (line 88) | class TestParseRequestEdgeCases: method test_unsupported_atyp (line 89) | async def test_unsupported_atyp(self): method test_unsupported_command (line 97) | async def test_unsupported_command(self): method test_wrong_version_in_request (line 105) | async def test_wrong_version_in_request(self): method test_ipv4_truncated (line 112) | async def test_ipv4_truncated(self): method test_domain_empty_label (line 120) | async def test_domain_empty_label(self): method test_domain_max_length (line 127) | async def test_domain_max_length(self): method test_domain_truncated (line 134) | async def test_domain_truncated(self): method test_port_truncated (line 142) | async def test_port_truncated(self): class TestUdpHeaderEdgeCases (line 151) | class TestUdpHeaderEdgeCases: method test_too_short (line 152) | def test_too_short(self): method test_ipv4_truncated (line 156) | def test_ipv4_truncated(self): method test_ipv6_truncated (line 161) | def test_ipv6_truncated(self): method test_domain_truncated (line 166) | def test_domain_truncated(self): method test_unsupported_atyp (line 171) | def test_unsupported_atyp(self): method test_header_only_no_payload (line 175) | def test_header_only_no_payload(self): method test_ipv6_full_roundtrip (line 183) | def test_ipv6_full_roundtrip(self): method test_domain_roundtrip (line 195) | def test_domain_roundtrip(self): FILE: tests/test_server.py function _start_server (line 10) | async def _start_server( function _stop_server (line 25) | async def _stop_server(server: Server, task: asyncio.Task): function echo_server (line 31) | async def echo_server(): function _socks5_connect (line 51) | async def _socks5_connect( class TestServerConnect (line 102) | class TestServerConnect: method test_no_auth_connect (line 103) | async def test_no_auth_connect(self, echo_server): method test_no_auth_rejected_when_auth_required (line 118) | async def test_no_auth_rejected_when_auth_required(self, echo_server): method test_auth_success (line 131) | async def test_auth_success(self, echo_server): method test_auth_failure (line 148) | async def test_auth_failure(self, echo_server): class DataCounter (line 167) | class DataCounter(Addon): method __init__ (line 168) | def __init__(self): method on_data (line 172) | async def on_data(self, direction, data, flow): class TestServerWithAddon (line 180) | class TestServerWithAddon: method test_data_counting (line 181) | async def test_data_counting(self, echo_server): FILE: tests/test_server_errors.py function _raw_connect (line 11) | async def _raw_connect(proxy): function _read_reply (line 16) | async def _read_reply(reader): class TestHandshakeErrors (line 30) | class TestHandshakeErrors: method test_truncated_method_selection (line 31) | async def test_truncated_method_selection(self): method test_wrong_socks_version (line 45) | async def test_wrong_socks_version(self): method test_disconnect_after_method_reply (line 57) | async def test_disconnect_after_method_reply(self): method test_disconnect_during_auth (line 72) | async def test_disconnect_during_auth(self): method test_nmethods_zero (line 87) | async def test_nmethods_zero(self): class TestRequestErrors (line 101) | class TestRequestErrors: method test_connect_to_refused_port (line 102) | async def test_connect_to_refused_port(self): method test_failed_connect_closes_observed_flow (line 123) | async def test_failed_connect_closes_observed_flow(self): class TestConnectionDrop (line 152) | class TestConnectionDrop: method test_drop_during_relay (line 153) | async def test_drop_during_relay(self, echo_server): method test_multiple_rapid_connect_disconnect (line 176) | async def test_multiple_rapid_connect_disconnect(self): class TestErrorToRep (line 198) | class TestErrorToRep: method test_connection_refused (line 199) | def test_connection_refused(self): method test_network_unreachable (line 202) | def test_network_unreachable(self): method test_generic_oserror (line 206) | def test_generic_oserror(self): method test_generic_exception (line 210) | def test_generic_exception(self): FILE: tests/test_server_lifecycle.py class StopTracker (line 9) | class StopTracker(Addon): method __init__ (line 10) | def __init__(self): method on_start (line 14) | async def on_start(self): method on_stop (line 17) | async def on_stop(self): class TestServerStartup (line 21) | class TestServerStartup: method test_server_binds_to_port (line 22) | async def test_server_binds_to_port(self): method test_server_with_zero_port_gets_ephemeral (line 29) | async def test_server_with_zero_port_gets_ephemeral(self): class TestServerShutdown (line 41) | class TestServerShutdown: method test_request_shutdown_stops_server (line 42) | async def test_request_shutdown_stops_server(self): method test_shutdown_calls_addon_stop (line 48) | async def test_shutdown_calls_addon_stop(self): method test_shutdown_closes_listening_socket (line 55) | async def test_shutdown_closes_listening_socket(self): FILE: tests/test_tcp_relay.py function _make_flow (line 14) | def _make_flow(**kwargs): function _pipe (line 26) | async def _pipe(): class UpperAddon (line 42) | class UpperAddon(Addon): method on_data (line 43) | async def on_data(self, direction, data, flow): class DropAddon (line 47) | class DropAddon(Addon): method on_data (line 48) | async def on_data(self, direction, data, flow): class TestCopy (line 52) | class TestCopy: method test_copies_data (line 53) | async def test_copies_data(self): method test_stops_on_eof (line 74) | async def test_stops_on_eof(self): method test_addon_pipeline_applied (line 88) | async def test_addon_pipeline_applied(self): method test_addon_returns_none_skips_write (line 107) | async def test_addon_returns_none_skips_write(self): method test_connection_error_handled (line 127) | async def test_connection_error_handled(self): method test_writer_closed_on_finish (line 147) | async def test_writer_closed_on_finish(self): class TestHandleTcpRelay (line 160) | class TestHandleTcpRelay: method test_bidirectional_relay (line 161) | async def test_bidirectional_relay(self): method test_relay_stops_when_client_closes (line 201) | async def test_relay_stops_when_client_closes(self): FILE: tests/test_udp_associate_hook.py class _CustomRelay (line 11) | class _CustomRelay(UdpRelayBase): method __init__ (line 14) | def __init__(self): method start (line 20) | async def start(self) -> Address: method set_client_transport (line 24) | def set_client_transport(self, transport: asyncio.DatagramTransport) -... method stop (line 27) | async def stop(self) -> None: method handle_client_datagram (line 30) | def handle_client_datagram(self, data: bytes, client_addr: tuple[str, ... class _CustomAddon (line 34) | class _CustomAddon(Addon): method __init__ (line 35) | def __init__(self, relay: UdpRelayBase): method on_udp_associate (line 38) | async def on_udp_associate(self, flow) -> UdpRelayBase | None: class _PassAddon (line 42) | class _PassAddon(Addon): method on_udp_associate (line 43) | async def on_udp_associate(self, flow) -> UdpRelayBase | None: class _FailingRelay (line 47) | class _FailingRelay(UdpRelayBase): method __init__ (line 48) | def __init__(self): method start (line 51) | async def start(self) -> Address: method set_client_transport (line 54) | def set_client_transport(self, transport: asyncio.DatagramTransport) -... method stop (line 57) | async def stop(self) -> None: method handle_client_datagram (line 60) | def handle_client_datagram(self, data: bytes, client_addr: tuple[str, ... class _ErrorTracker (line 64) | class _ErrorTracker(Addon): method __init__ (line 65) | def __init__(self): method on_error (line 68) | async def on_error(self, error: Exception) -> None: function _start_server (line 72) | async def _start_server(**kwargs): function _stop_server (line 82) | async def _stop_server(server, task): class TestUdpAssociateHook (line 87) | class TestUdpAssociateHook: method test_addon_returns_custom_handler (line 88) | async def test_addon_returns_custom_handler(self): method test_addon_returns_none_uses_default (line 119) | async def test_addon_returns_none_uses_default(self): method test_competitive_first_wins (line 139) | async def test_competitive_first_wins(self): method test_relay_start_failure_returns_socks_error_and_dispatches_error (line 172) | async def test_relay_start_failure_returns_socks_error_and_dispatches_... FILE: tests/test_udp_over_tcp.py class TestUdpOverTcpFrame (line 7) | class TestUdpOverTcpFrame: method test_roundtrip_ipv4 (line 8) | async def test_roundtrip_ipv4(self): method test_roundtrip_ipv6 (line 23) | async def test_roundtrip_ipv6(self): method test_roundtrip_domain (line 38) | async def test_roundtrip_domain(self): method test_multiple_frames (line 53) | async def test_multiple_frames(self): method test_empty_payload (line 74) | async def test_empty_payload(self): FILE: tests/test_udp_over_tcp_e2e.py function _start_server (line 14) | async def _start_server(**kwargs): function _stop_server (line 24) | async def _stop_server(server, task): function _start_exit_server (line 29) | async def _start_exit_server(**kwargs): function _stop_exit_server (line 39) | async def _stop_exit_server(server, task): function _skip_bind_address (line 44) | async def _skip_bind_address(reader): class TestUdpOverTcpE2E (line 55) | class TestUdpOverTcpE2E: method test_full_chain_udp_roundtrip (line 56) | async def test_full_chain_udp_roundtrip(self): method test_chain_multiple_datagrams (line 145) | async def test_chain_multiple_datagrams(self): FILE: tests/test_udp_over_tcp_exit.py function _start_exit_server (line 10) | async def _start_exit_server(**kwargs): function _stop_exit_server (line 20) | async def _stop_exit_server(server, task): class TestUdpOverTcpExit (line 25) | class TestUdpOverTcpExit: method test_tcp_to_udp_roundtrip (line 26) | async def test_tcp_to_udp_roundtrip(self): method test_multiple_datagrams (line 71) | async def test_multiple_datagrams(self): FILE: tests/test_udp_relay.py function _udp_flow (line 13) | def _udp_flow(): function _build_udp_datagram (line 23) | def _build_udp_datagram(dst: Address, payload: bytes) -> bytes: function _socks5_udp_associate (line 28) | async def _socks5_udp_associate(proxy: Address, auth=None): class TestUdpRelayUnit (line 92) | class TestUdpRelayUnit: method test_start_returns_bind_address (line 93) | async def test_start_returns_bind_address(self): method test_stop_cancels_ttl_task (line 102) | async def test_stop_cancels_ttl_task(self): method test_handle_client_datagram_routes_outbound (line 109) | async def test_handle_client_datagram_routes_outbound(self, udp_echo_s... method test_handle_client_datagram_empty_payload_ignored (line 129) | async def test_handle_client_datagram_empty_payload_ignored(self): method test_handle_client_datagram_malformed_ignored (line 141) | async def test_handle_client_datagram_malformed_ignored(self): method test_routing_table_entries_created (line 150) | async def test_routing_table_entries_created(self): method test_routing_table_entries_refreshed (line 160) | async def test_routing_table_entries_refreshed(self): class TestUdpRelayTTL (line 176) | class TestUdpRelayTTL: method test_ttl_cleanup_removes_expired (line 177) | async def test_ttl_cleanup_removes_expired(self): method test_ttl_cleanup_keeps_active (line 204) | async def test_ttl_cleanup_keeps_active(self): class TestUdpAssociateE2E (line 225) | class TestUdpAssociateE2E: method test_udp_associate_handshake (line 226) | async def test_udp_associate_handshake(self): method test_udp_associate_with_auth (line 239) | async def test_udp_associate_with_auth(self): method test_udp_associate_send_and_receive (line 251) | async def test_udp_associate_send_and_receive(self, udp_echo_server): method test_tcp_close_ends_relay (line 292) | async def test_tcp_close_ends_relay(self):