relay over ws supossedly working

This commit is contained in:
Dobromir Popov
2026-06-30 21:06:39 +02:00
parent d0307fcc84
commit 61074a8fe8
6 changed files with 429 additions and 32 deletions

View File

@@ -35,13 +35,32 @@ def _get_json(url: str, timeout: float = 10.0) -> dict:
return json.loads(r.read())
def _infer_relay_url_from_tracker(tracker_url: str) -> str | None:
"""Infer relay WebSocket URL from a public HTTPS tracker origin.
Public deployments colocate relay at /ws on the same host as the tracker API
(see QUICKSTART nginx layout). Local LAN trackers use a separate relay port
and must advertise relay_url explicitly via /v1/network/map.
"""
parsed = urllib.parse.urlparse(tracker_url)
if parsed.scheme != "https":
return None
host = parsed.hostname
if not host or host in ("127.0.0.1", "localhost"):
return None
return f"wss://{parsed.netloc}/ws"
def _discover_relay_url(tracker_url: str) -> str | None:
relay_url: str | None = None
try:
network_map = _get_json(f"{tracker_url}/v1/network/map", timeout=5.0)
raw = network_map.get("relay_url")
if isinstance(raw, str) and raw:
relay_url = raw
except Exception:
return None
relay_url = network_map.get("relay_url")
return relay_url if isinstance(relay_url, str) and relay_url else None
pass
return relay_url or _infer_relay_url_from_tracker(tracker_url)
def _start_relay_bridge_if_available(
@@ -49,8 +68,9 @@ def _start_relay_bridge_if_available(
wallet_address: str,
local_base_url: str,
advertised_endpoint: str,
relay_url: str | None = None,
) -> tuple[RelayHttpBridge | None, dict]:
relay_url = _discover_relay_url(tracker_url)
relay_url = relay_url or _discover_relay_url(tracker_url)
if not relay_url:
return None, {}
peer_id = peer_id_from_wallet(wallet_address)
@@ -222,7 +242,8 @@ def _warn_virtual_network_ip(ip: str | None) -> None:
f" This range is used by Docker, WSL2, and virtual machines and is\n"
f" NOT reachable from other physical machines on your LAN.\n"
f" Cross-host pipeline hops WILL time out.\n"
f" Fix: pass --advertise-host <your-LAN-ip> (e.g. 192.168.x.x).\n",
f" Fix: use a public tracker with relay (wss://…/ws), or pass\n"
f" --advertise-host <your-LAN-ip> (e.g. 192.168.x.x).\n",
flush=True,
)
except Exception:
@@ -260,6 +281,7 @@ def run_startup(
"""
tracker_url = tracker_url.rstrip("/")
relay_url = _discover_relay_url(tracker_url)
# 1. Hardware detection
if advertise_host is None and host == "0.0.0.0":
@@ -275,7 +297,10 @@ def run_startup(
except Exception:
advertise_host = socket.getfqdn()
_warn_virtual_network_ip(advertise_host)
if relay_url:
print(f"Relay advertised by tracker — using outbound tunnel {relay_url}", flush=True)
else:
_warn_virtual_network_ip(advertise_host)
print("Detecting hardware...", flush=True)
hw = detect_hardware()
@@ -361,6 +386,7 @@ def run_startup(
address,
local_base_url,
endpoint,
relay_url=relay_url,
)
_attach_relay_bridge(node, relay_bridge)
# Register with tracker so other nodes can auto-join this model.
@@ -451,6 +477,7 @@ def run_startup(
address,
local_base_url,
endpoint,
relay_url=relay_url,
)
_attach_relay_bridge(node, relay_bridge)
auto_reg_payload = {
@@ -548,6 +575,7 @@ def run_startup(
address,
local_base_url,
endpoint,
relay_url=relay_url,
)
_attach_relay_bridge(node, relay_bridge)

View File

@@ -4,7 +4,7 @@ import argparse
import sys
import time
from .server import TrackerServer
from .server import TrackerServer, derive_relay_url_from_public_tracker_url
def main() -> None:
@@ -52,6 +52,7 @@ def main() -> None:
if args.command in {None, "start"}:
cluster_peers = [u.strip() for u in args.cluster_peers.split(",") if u.strip()]
relay_url = args.relay_url or derive_relay_url_from_public_tracker_url(args.self_url)
server = TrackerServer(
host=args.host,
port=args.port,
@@ -59,7 +60,7 @@ def main() -> None:
cluster_peers=cluster_peers or None,
cluster_self_url=args.self_url,
stats_db=getattr(args, "stats_db", None),
relay_url=args.relay_url,
relay_url=relay_url,
)
port = server.start()
print(f"meshnet-tracker listening on http://{args.host}:{port}", flush=True)

View File

@@ -37,6 +37,19 @@ from .gossip import NodeGossip
from .raft import RaftNode
def derive_relay_url_from_public_tracker_url(url: str | None) -> str | None:
"""Return wss://host/ws when url is a public HTTPS tracker origin."""
if not url:
return None
parsed = urllib.parse.urlparse(url)
if parsed.scheme != "https":
return None
host = parsed.hostname
if not host or host in ("127.0.0.1", "localhost"):
return None
return f"wss://{parsed.netloc}/ws"
DEFAULT_MODEL_PRESETS: dict[str, dict] = {
"stub-model": {
"layers_start": 0,
@@ -1228,6 +1241,33 @@ class _TrackerHandler(http.server.BaseHTTPRequestHandler):
if auth:
req.add_header("Authorization", auth)
relay_headers = {
"Content-Type": "application/json",
"X-Meshnet-Route": downstream_urls,
**({"Authorization": auth} if auth else {}),
}
if node.relay_addr:
print(
f"[tracker] proxy via relay {request_id}: {node.relay_addr} "
f"(direct endpoint {target_url})",
flush=True,
)
relayed = _relay_http_request(
node.relay_addr,
path="/v1/chat/completions",
body=raw_body,
headers=relay_headers,
)
if relayed is not None:
self._send_relayed_response(relayed)
return
print(
f"[tracker] relay proxy failed {request_id}: {node.relay_addr}; "
f"trying direct {target_url}",
flush=True,
)
try:
upstream = urllib.request.urlopen(req, timeout=300.0)
print(f"[tracker] proxy connected {request_id}: {target_url}", flush=True)
@@ -1247,23 +1287,11 @@ class _TrackerHandler(http.server.BaseHTTPRequestHandler):
if node.relay_addr:
print(
f"[tracker] direct proxy failed {request_id}: {target_url}: {exc}; "
f"trying relay {node.relay_addr}",
f"relay already attempted for {node.relay_addr}",
flush=True,
)
relayed = _relay_http_request(
node.relay_addr,
path="/v1/chat/completions",
body=raw_body,
headers={
"Content-Type": "application/json",
"X-Meshnet-Route": downstream_urls,
**({"Authorization": auth} if auth else {}),
},
)
if relayed is not None:
self._send_relayed_response(relayed)
return
print(f"[tracker] proxy failed {request_id}: {target_url}: {exc}", flush=True)
else:
print(f"[tracker] proxy failed {request_id}: {target_url}: {exc}", flush=True)
self._send_json(503, {"error": {
"message": f"upstream node unreachable: {exc}",
"type": "service_unavailable",
@@ -2040,6 +2068,11 @@ class TrackerServer:
if self._server is not None:
raise RuntimeError("TrackerServer is already running")
effective_relay_url = (
self._relay_url
or derive_relay_url_from_public_tracker_url(self._cluster_self_url)
)
# Start HTTP server first so we know our port
self._server = _TrackerHTTPServer(
(self._host, self._requested_port),
@@ -2050,7 +2083,7 @@ class TrackerServer:
self._model_presets,
self._contracts,
self._minimum_stake,
relay_url=self._relay_url,
relay_url=effective_relay_url,
stats=self._stats,
)
self.port = self._server.server_address[1]