relay preparing for public internet

This commit is contained in:
Dobromir Popov
2026-07-09 08:01:22 +02:00
parent 9ec4ca9ce1
commit 6ba8546c55
8 changed files with 344 additions and 26 deletions

View File

@@ -103,6 +103,28 @@ def main() -> None:
default=None,
help="Public ws(s):// relay URL advertised to nodes, for example wss://ai.neuron.d-popov.com/ws",
)
common.add_argument(
"--embedded-relay",
action="store_true",
help="Run the relay WebSocket server in this tracker process (still uses meshnet_relay.RelayServer)",
)
common.add_argument(
"--relay-host",
default="127.0.0.1",
help="Bind address for --embedded-relay (default: 127.0.0.1; use 0.0.0.0 only when exposing the relay port directly)",
)
common.add_argument(
"--relay-port",
type=int,
default=8765,
help="Bind port for --embedded-relay (default: 8765)",
)
common.add_argument(
"--relay-max-peers",
type=int,
default=500,
help="Maximum WebSocket peers accepted by --embedded-relay",
)
common.add_argument(
"--billing-db",
default=DEFAULT_BILLING_DB_PATH,
@@ -378,6 +400,10 @@ def main() -> None:
cluster_self_url=args.self_url,
stats_db=getattr(args, "stats_db", None),
relay_url=relay_url,
embedded_relay=args.embedded_relay,
embedded_relay_host=args.relay_host,
embedded_relay_port=args.relay_port,
embedded_relay_max_peers=args.relay_max_peers,
enable_billing=not args.no_billing,
billing_db=None if args.no_billing else args.billing_db,
max_charge_per_request=args.max_charge_per_request,

View File

@@ -101,6 +101,12 @@ def derive_relay_url_from_public_tracker_url(url: str | None) -> str | None:
return f"wss://{parsed.netloc}/ws"
def _local_relay_url(host: str, port: int) -> str:
"""Return a node-consumable ws:// URL for an embedded relay bind address."""
advertise_host = "127.0.0.1" if host in {"", "0.0.0.0", "::"} else host
return f"ws://{advertise_host}:{port}/ws"
def _load_model_presets_from_data() -> dict[str, dict]:
"""Load recommended model presets from package JSON data."""
try:
@@ -2459,6 +2465,7 @@ class _TrackerHTTPServer(socketserver.ThreadingMixIn, http.server.HTTPServer):
hf_pricing_log: "HfPricingLog | None" = None,
models_dir: Path | None = None,
route_stats: "RouteStatsStore | None" = None,
relay_status: dict | None = None,
) -> None:
super().__init__(addr, handler)
self.registry = registry
@@ -2496,6 +2503,9 @@ class _TrackerHTTPServer(socketserver.ThreadingMixIn, http.server.HTTPServer):
self.active_proxies_lock = threading.Lock()
self.route_stats: RouteStatsStore = route_stats or RouteStatsStore()
self.route_rng = random.Random()
self.relay_status = dict(
relay_status or {"mode": "external" if self.relay_url else "off"}
)
class _TrackerHandler(http.server.BaseHTTPRequestHandler):
@@ -2930,6 +2940,7 @@ class _TrackerHandler(http.server.BaseHTTPRequestHandler):
self._send_json(200, {
"relay_url": server.relay_url,
"relay": dict(server.relay_status),
"pool": _pool_summary(nodes),
"memory_pool": memory_pool,
"recommended_models": [
@@ -5779,6 +5790,10 @@ class TrackerServer:
cluster_self_url: str | None = None,
stats_db: str | None = None,
relay_url: str | None = None,
embedded_relay: bool = False,
embedded_relay_host: str = "127.0.0.1",
embedded_relay_port: int = 8765,
embedded_relay_max_peers: int = 500,
billing: BillingLedger | None = None,
enable_billing: bool = False,
billing_db: str | None = None,
@@ -5821,6 +5836,12 @@ class TrackerServer:
self._cluster_peers: list[str] = list(cluster_peers) if cluster_peers else []
self._cluster_self_url: str | None = cluster_self_url
self._relay_url = relay_url
self._embedded_relay_enabled = bool(embedded_relay)
self._embedded_relay_host = embedded_relay_host
self._embedded_relay_port = int(embedded_relay_port)
self._embedded_relay_max_peers = int(embedded_relay_max_peers)
self._embedded_relay: Any | None = None
self._embedded_relay_actual_port: int | None = None
self._registry: dict[str, _NodeEntry] = {}
self._lock = threading.Lock()
self._server: _TrackerHTTPServer | None = None
@@ -5924,13 +5945,59 @@ class TrackerServer:
self._route_stats = RouteStatsStore(routing_config)
self.port: int | None = None
def _start_embedded_relay(self) -> dict:
"""Start the shared RelayServer class in-process for tracker+relay deployments."""
if not self._embedded_relay_enabled:
return {"mode": "external" if self._relay_url else "off"}
if self._embedded_relay is not None:
return self._embedded_relay_status()
try:
from meshnet_relay.server import RelayServer # type: ignore[import-not-found]
except Exception as exc: # pragma: no cover - only hit in broken installs
raise RuntimeError(
"embedded relay requires the meshnet-relay package to be installed"
) from exc
relay = RelayServer(
host=self._embedded_relay_host,
port=self._embedded_relay_port,
max_peers=self._embedded_relay_max_peers,
)
actual_port = relay.start()
self._embedded_relay = relay
self._embedded_relay_actual_port = actual_port
return self._embedded_relay_status()
def _embedded_relay_status(self) -> dict:
advertised_url = (
self._relay_url
or derive_relay_url_from_public_tracker_url(self._cluster_self_url)
or _local_relay_url(self._embedded_relay_host, self._embedded_relay_actual_port or self._embedded_relay_port)
)
return {
"mode": "embedded",
"url": advertised_url,
"bind_host": self._embedded_relay_host,
"bind_port": self._embedded_relay_actual_port or self._embedded_relay_port,
"max_peers": self._embedded_relay_max_peers,
}
def start(self) -> int:
if self._server is not None:
raise RuntimeError("TrackerServer is already running")
relay_status = self._start_embedded_relay()
effective_relay_url = (
self._relay_url
or derive_relay_url_from_public_tracker_url(self._cluster_self_url)
or (relay_status.get("url") if relay_status.get("mode") == "embedded" else None)
)
http_relay_status = (
{**relay_status, "url": effective_relay_url}
if relay_status.get("mode") == "embedded"
else {"mode": "external", "url": effective_relay_url}
if effective_relay_url
else {"mode": "off"}
)
# Start HTTP server first so we know our port
@@ -5960,6 +6027,7 @@ class TrackerServer:
hf_pricing_log=self._hf_pricing_log,
models_dir=self._models_dir,
route_stats=self._route_stats,
relay_status=http_relay_status,
)
self.port = self._server.server_address[1]
@@ -6275,6 +6343,11 @@ class TrackerServer:
self._raft.stop()
if self._gossip is not None:
self._gossip.stop()
embedded_relay = self._embedded_relay
self._embedded_relay = None
self._embedded_relay_actual_port = None
if embedded_relay is not None:
embedded_relay.stop()
if self._server is None:
return
self._rebalance_stop.set()