"""Service name → host/port registry. Thread-safe registry mapping service names (HTTP_PROXY, SAM, etc.) to local host:port pairs. Ported from net.i2p.util.PortMapper. """ from __future__ import annotations import threading from dataclasses import dataclass @dataclass class _Entry: host: str port: int class PortMapper: """Thread-safe service name → (host, port) registry.""" def __init__(self) -> None: self._lock = threading.Lock() self._services: dict[str, _Entry] = {} def register(self, service: str, host: str, port: int) -> None: with self._lock: self._services[service] = _Entry(host=host, port=port) def unregister(self, service: str) -> None: with self._lock: self._services.pop(service, None) def get_port(self, service: str, default: int = -1) -> int: with self._lock: entry = self._services.get(service) return entry.port if entry else default def get_host(self, service: str, default: str = "127.0.0.1") -> str: with self._lock: entry = self._services.get(service) return entry.host if entry else default def get_all_services(self) -> dict[str, tuple[str, int]]: with self._lock: return {k: (v.host, v.port) for k, v in self._services.items()}