diff options
| author | Christophe Besson <cbesson@gmail.com> | 2026-08-30 22:17:30 +0200 |
|---|---|---|
| committer | Christophe Besson <cbesson@gmail.com> | 2026-08-30 22:17:30 +0200 |
| commit | 07e6e4271ea3a45e9cd364eb6ec05801a653d9e8 (patch) | |
| tree | 5d2dea4251ee2ecea32aeef80d09167d08085dd0 /packages/meshbay-node/src/meshbay_node/config.py | |
| parent | bf56b60b95c5413d592f0199320d637978792756 (diff) | |
| download | meshbay-07e6e4271ea3a45e9cd364eb6ec05801a653d9e8.tar.gz | |
feat: configurable STUN server fallbacks for WebRTC ICE
The WebRTC transport relied on a single Google STUN server — if it was
unreachable, ICE gathering waited the full 4s timeout. Now four public
servers are used by default (Google ×2, Cloudflare, Mozilla), configurable
via node.toml, the Node page UI, and the CLI (meshbay-node stun list|add|
remove|reset). Changes are hot-swapped on the live transport.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Diffstat (limited to 'packages/meshbay-node/src/meshbay_node/config.py')
| -rw-r--r-- | packages/meshbay-node/src/meshbay_node/config.py | 15 |
1 files changed, 15 insertions, 0 deletions
diff --git a/packages/meshbay-node/src/meshbay_node/config.py b/packages/meshbay-node/src/meshbay_node/config.py index 5d9282d..b94d03a 100644 --- a/packages/meshbay-node/src/meshbay_node/config.py +++ b/packages/meshbay-node/src/meshbay_node/config.py @@ -18,6 +18,13 @@ except ImportError: log = logging.getLogger(__name__) +DEFAULT_STUN_SERVERS: list[str] = [ + "stun:stun.l.google.com:19302", + "stun:stun1.l.google.com:19302", + "stun:stun.cloudflare.com:3478", + "stun:stun.services.mozilla.com:3478", +] + DEFAULT_CONFIG_PATH = Path.home() / ".config" / "meshbay" / "node.toml" EXAMPLE_CONFIG = """\ @@ -57,6 +64,10 @@ transcode_incompatible_video = true # gathering to specific interfaces (by OS adapter name). # ice_interfaces = ["wlp0s20f3", "eth0"] +# STUN servers for WebRTC ICE candidate gathering (NAT traversal). By default +# four public servers are used; set this to override. +# stun_servers = ["stun:stun.l.google.com:19302", "stun:stun.cloudflare.com:3478"] + # Browser and native clients reach this node over WebRTC DataChannel via hub # signaling — no inbound port to open. QUIC is the optional direct path. @@ -145,6 +156,7 @@ class NodeConfig: # the gather for the full 5-second timeout — measured at 6 s total on a # machine with a Tailscale wt0 interface. ice_interfaces: list[str] = field(default_factory=list) # include-list overrides auto + stun_servers: list[str] = field(default_factory=list) # empty = DEFAULT_STUN_SERVERS @dataclass @@ -305,6 +317,9 @@ def load_config(path: Path = DEFAULT_CONFIG_PATH) -> Config: ice_if = nd.get("ice_interfaces") if isinstance(ice_if, list): cfg.node.ice_interfaces = [str(s) for s in ice_if] + stun = nd.get("stun_servers") + if isinstance(stun, list): + cfg.node.stun_servers = [str(s) for s in stun] # Multi-group: [[groups]] array if "groups" in raw: |