mirror of
https://github.com/jmcorgan/fips.git
synced 2026-07-22 07:48:26 +00:00
docs: reviewer feedback pass on Nostr-discovery surface
Walk through reviewer feedback on the Nostr-discovery docs and land 18 items. Bulk patterns: - `external_addr` / `public: true` semantics consistently misdescribed. The advert path is gated on `cfg.is_public()`; inside that branch the daemon picks an address by precedence (`external_addr`, non-wildcard `bind_addr`, STUN). The docs treated `public: true` and `external_addr` as alternatives when they are stacked: `public: true` is the master switch and `external_addr` populates the address inside it. Reconciled across `enable-nostr-discovery.md` and `advertise-your-node.md`: add `public: true` to the `external_addr` examples; replace "STUN as a logging cross-check" with "STUN is skipped entirely"; fix "neither flag is needed" for direct public bind (both flags still required); make the publish-tutorial Step 3 conditional on the chosen Step 2 path (STUN runs only on the `public: true` path); rewrite the troubleshooting "wrong public IP advertised" bullet with two coherent fixes. - `udp:nat` overpromised as a symmetric-NAT solution. Symmetric NAT on either side typically defeats the punch. Reframe `udp:nat` as best-effort hole-punching for nodes without a directly reachable UDP endpoint in the how-to, the publish tutorial (intro, callout, section heading rewrite from "If you're behind symmetric NAT" to "If your direct UDP advert isn't reachable"), the consume tutorial's "What's next" pointer, and `tutorials/README.md`. Promote reachability over named NAT classes: STUN can confirm the public IP but not that the listener-port mapping is open. - YAML "silently ignores unknown keys" is wrong. Config parser rejects unknown fields via `serde(deny_unknown_fields)` on the per-section structs; misspelled fields refuse the daemon's start with a parse-error line in the journal. Fixed in the publish tutorial's troubleshooting and the open-discovery tutorial's `policy` typo bullet. Mechanical fixes: - Repoint stale anchors. `getting-started.md` and `configuration.md` linked to `#installation` / `#inspect` on the README; the README has no such headings. Repoint to `#quick-start` and `cli-fipsctl.md`. Two stale anchors in the publish tutorial pointing at non-existent sub-scenarios in the how-to (`#sub-scenario-2c-...`, `#sub-scenario-2b-tor-onion-node`) repointed to the correct anchors. - Drop the `fipsctl show status` claim from the open-discovery troubleshooting bullet (`show_status` doesn't include `discovery.nostr.policy`). Replace with daemon startup logs. - Fix the `advertise: false` parenthetical in the consume-only tutorial (`default_advertise()` returns `true`; we set `false` explicitly for the consume-only path). - Drop the "supplies a relay list" overstatement in two activation paragraphs (the how-to and the design doc). Default relay / STUN-server lists ship in the config; both are optional overrides. - Add the missing `transports.udp.public` entry to the open-discovery tutorial's prerequisites checklist. Tutorial users coming out of advertise-your-node could be on either the direct-UDP (`public: true`) or `udp:nat` (`public: false`) path; list both. Files: docs/getting-started.md, docs/reference/configuration.md, docs/how-to/enable-nostr-discovery.md, docs/tutorials/README.md, docs/tutorials/advertise-your-node.md, docs/tutorials/resolve-peers-via-nostr.md, docs/tutorials/open-discovery.md, docs/design/fips-nostr-discovery.md.
This commit is contained in:
@@ -15,8 +15,9 @@ every supported platform and ships in every stock packaging artifact
|
||||
`.zip`). It is runtime-opt-in: the YAML configuration defaults to
|
||||
disabled (`node.discovery.nostr.enabled: false`), so the discovery
|
||||
runtime stays dormant — and opens no relay connections — until an
|
||||
operator flips the flag and supplies a relay list. When disabled, nodes
|
||||
behave exactly as before: only the static `peers[]` addresses are used.
|
||||
operator flips the flag. Default relay and STUN-server lists ship in
|
||||
the config; both are optional overrides. When disabled, nodes behave
|
||||
exactly as before: only the static `peers[]` addresses are used.
|
||||
|
||||
## Role
|
||||
|
||||
|
||||
@@ -29,9 +29,10 @@ running nodes can mesh.
|
||||
|
||||
- A Linux, macOS, or Windows host. Linux is the most exercised
|
||||
platform; macOS and Windows installers are available.
|
||||
- The pre-built installer for your platform (see the
|
||||
[Releases page](../README.md#installation)), **or** a source
|
||||
checkout if you want to build the installer yourself.
|
||||
- The pre-built installer for your platform (see the project
|
||||
README's [Quick start](../README.md#quick-start) section for
|
||||
download links), **or** a source checkout if you want to build
|
||||
the installer yourself.
|
||||
- For the source-build path only: a working Rust toolchain (the
|
||||
version pinned in `rust-toolchain.toml` is auto-installed by
|
||||
rustup), and the platform-specific build dependencies listed in
|
||||
@@ -63,7 +64,7 @@ per-platform installer:
|
||||
- Windows — `.zip` with service-install scripts
|
||||
- Generic systemd Linux — `.tar.gz` with an `install.sh` script
|
||||
|
||||
See the [project README's Installation section](../README.md#installation)
|
||||
See the [project README's Quick start section](../README.md#quick-start)
|
||||
for download links and per-platform invocations.
|
||||
|
||||
### From source
|
||||
|
||||
@@ -4,7 +4,8 @@ Nostr-mediated discovery lets FIPS nodes find each other (and punch
|
||||
through UDP NAT) using public Nostr relays as the signaling channel.
|
||||
The feature ships in every stock packaging artifact but is **off by
|
||||
default** — it activates when an operator sets
|
||||
`node.discovery.nostr.enabled: true` and provides a relay list. See
|
||||
`node.discovery.nostr.enabled: true`. Default relay and STUN-server
|
||||
lists ship in the config; both are optional overrides. See
|
||||
[../design/fips-nostr-discovery.md](../design/fips-nostr-discovery.md)
|
||||
for the design and rationale; see
|
||||
[../reference/configuration.md](../reference/configuration.md) for the
|
||||
@@ -126,15 +127,20 @@ transports:
|
||||
udp:
|
||||
bind_addr: "0.0.0.0:2121"
|
||||
advertise_on_nostr: true
|
||||
external_addr: "203.0.113.45:2121" # ← explicit
|
||||
public: true # ← required, master switch
|
||||
external_addr: "203.0.113.45:2121" # ← explicit address
|
||||
```
|
||||
|
||||
`external_addr` accepts a bare IP (combined with the bind port) or a
|
||||
full `host:port`. Setting both `public: true` and `external_addr`
|
||||
together is allowed — the explicit override wins, with STUN as a
|
||||
logging cross-check. If UDP is bound directly to a public IP rather
|
||||
than to a wildcard, neither flag is needed; the daemon advertises
|
||||
the bound endpoint.
|
||||
full `host:port`. `public: true` is the master switch that gates UDP
|
||||
advertisement; inside that branch, the daemon picks the advertised
|
||||
address in precedence order: explicit `external_addr` (no STUN
|
||||
observation), a non-wildcard `bind_addr`, or STUN auto-discovery.
|
||||
Setting `external_addr` alongside `public: true` skips STUN entirely
|
||||
— there is no logging cross-check. If UDP is bound directly to a
|
||||
public IP rather than to a wildcard, neither `external_addr` nor STUN
|
||||
is needed — but `advertise_on_nostr: true` and `public: true` are
|
||||
still both required for the daemon to publish the endpoint.
|
||||
|
||||
What this achieves: the node publishes a single
|
||||
`udp:<public-ip>:2121` endpoint to the three default advert relays
|
||||
@@ -202,9 +208,17 @@ proceeds normally.
|
||||
> a `udp:nat` advert without signaling relays or STUN servers is
|
||||
> unreachable by construction.
|
||||
|
||||
Works best with full-cone NAT on at least one side. Symmetric NAT on
|
||||
both sides is not reliably traversable with this protocol and will
|
||||
time out after `punch_duration_ms`.
|
||||
Hole-punching is best-effort. It works reliably when both sides are
|
||||
full-cone or port-restricted NATs. Symmetric NAT on either side
|
||||
typically defeats the punch — the public port a peer sees varies per
|
||||
remote endpoint, so the address learned via STUN does not match the
|
||||
mapping the peer actually needs. The punch attempt times out after
|
||||
`punch_duration_ms`. `udp:nat` is the only NAT-traversal mechanism
|
||||
in FIPS; when it can't succeed, there's no in-protocol substitute.
|
||||
Being reachable then becomes a deployment-prerequisite question
|
||||
rather than a transport question — a publicly reachable port (UDP
|
||||
or TCP — both require the same kind of network resource) published
|
||||
as a direct advert per Sub-scenario 2a or 2b.
|
||||
|
||||
### Sub-scenario 2b: TCP
|
||||
|
||||
|
||||
@@ -59,7 +59,7 @@ peers: # Static peer list
|
||||
The control socket provides access to node state and runtime management
|
||||
via the `fipsctl` command-line tool. In addition to read-only status
|
||||
queries, `fipsctl connect` and `fipsctl disconnect` enable runtime peer
|
||||
management. See the project [README](../../README.md#inspect) for the
|
||||
management. See the [`fipsctl` reference](cli-fipsctl.md) for the
|
||||
command list.
|
||||
|
||||
On Linux, the control socket is a Unix domain socket with filesystem
|
||||
|
||||
@@ -25,7 +25,7 @@ cover every option.
|
||||
| 1 | [join-the-test-mesh.md](join-the-test-mesh.md) | Add one public test peer to your config, watch the link come up, ping that peer and a second mesh node it routes you to. The starting point for everything else. |
|
||||
| 2 | [persistent-identity.md](persistent-identity.md) | Pin your daemon to a stable Nostr keypair so your address stops changing on every restart. Other operators can now add you to their `peers:` lists; the services you host get a fixed name. |
|
||||
| 3 | [resolve-peers-via-nostr.md](resolve-peers-via-nostr.md) | Stop hard-coding peer addresses. Drop the address line from your peer entry and let the daemon look up the current endpoint from public Nostr relays at dial time. |
|
||||
| 4 | [advertise-your-node.md](advertise-your-node.md) | Publish your own UDP endpoint to Nostr so any operator who knows your npub can reach you, with a short final section on `udp:nat` traversal for symmetric-NAT networks. |
|
||||
| 4 | [advertise-your-node.md](advertise-your-node.md) | Publish your own UDP endpoint to Nostr so any operator who knows your npub can reach you, with a short final section on `udp:nat` best-effort hole-punching for nodes without a directly reachable UDP endpoint. |
|
||||
| 5 | [open-discovery.md](open-discovery.md) | Switch to `policy: open` and let your peer list populate itself from the ambient `fips-overlay-v1` namespace. Hands-off mesh participation. |
|
||||
| 6 | [reach-mesh-services.md](reach-mesh-services.md) | Drive ordinary IPv6 tools — `ping6`, `nc`, `traceroute6`, `curl`, `ssh` — at mesh nodes by `<npub>.fips`. Get a feel for the daemon's IPv6 adapter, which makes unmodified IPv6 software work over the mesh. |
|
||||
| 7 | [host-a-service.md](host-a-service.md) | Bring up an HTTP server bound to `fips0` so mesh nodes can reach it, with a deliberate exposure decision (mesh-only vs every interface), and the mesh firewall as a default-deny baseline. The peer ACL (a separate, transport-layer control over which npubs may peer with your node) is briefly mentioned alongside. |
|
||||
|
||||
@@ -8,8 +8,9 @@ your own endpoint(s), so any other operator who knows your
|
||||
npub can dial you the same way you dialed `test-us01`.
|
||||
|
||||
The whole exercise should take about ten minutes if you have
|
||||
a public IP or full-cone home NAT. A short final section
|
||||
covers the alternative path for symmetric-NAT networks.
|
||||
a public IP or a UDP listener that's reachable from outside.
|
||||
A short final section covers `udp:nat` best-effort hole-punching
|
||||
for the cases where direct UDP advertising isn't an option.
|
||||
|
||||
## What you'll build
|
||||
|
||||
@@ -74,9 +75,13 @@ port to put in the advert:
|
||||
> - `public: true` — daemon does a one-shot STUN observation
|
||||
> against the configured STUN servers and uses the reflexive
|
||||
> IPv4 it learns. Right when your public IP is dynamic or
|
||||
> you'd rather not pin it in config. Works for nodes with a
|
||||
> directly-bound public IP and for nodes behind full-cone
|
||||
> NAT (most home routers).
|
||||
> you'd rather not pin it in config. Note: STUN observes the
|
||||
> reflexive IP from an ephemeral socket, then pairs it with
|
||||
> the listener's bind port for the advert — the advert is
|
||||
> only useful if your listener really is reachable at that
|
||||
> public IP/port, which the daemon can't tell from STUN
|
||||
> alone. A manual probe from a second host is the only sure
|
||||
> check.
|
||||
> - `external_addr: "<ip>[:<port>]"` — explicit override.
|
||||
> Right when you already know your public IP — a static
|
||||
> residential IP, an Elastic IP behind 1:1 NAT, a cloud
|
||||
@@ -86,8 +91,9 @@ port to put in the advert:
|
||||
> to the public IP returns `EADDRNOTAVAIL`.
|
||||
>
|
||||
> If you bind UDP to a specific public IP rather than
|
||||
> `0.0.0.0`, neither flag is needed — the daemon advertises
|
||||
> whatever it's bound to.
|
||||
> `0.0.0.0`, neither STUN nor `external_addr` is needed — but
|
||||
> `advertise_on_nostr: true` and `public: true` are still both
|
||||
> required for the daemon to publish the endpoint.
|
||||
|
||||
Adverts don't sit on the relays forever:
|
||||
|
||||
@@ -167,14 +173,17 @@ transports:
|
||||
udp:
|
||||
bind_addr: "0.0.0.0:2121"
|
||||
advertise_on_nostr: true
|
||||
public: true
|
||||
external_addr: "203.0.113.45:2121"
|
||||
```
|
||||
|
||||
Replace `203.0.113.45:2121` with your actual public IP and
|
||||
port. The bare-IP form `external_addr: "203.0.113.45"` is also
|
||||
accepted; the daemon combines it with the bind port. You may
|
||||
set both `public: true` and `external_addr` together — the
|
||||
explicit override wins, with STUN as a logging cross-check.
|
||||
accepted; the daemon combines it with the bind port. `public:
|
||||
true` is still required as the master switch that gates UDP
|
||||
advertisement; setting `external_addr` alongside it wins, and
|
||||
STUN auto-discovery is skipped entirely (no logging
|
||||
cross-check).
|
||||
|
||||
`advertise_on_nostr: true` is the bit that says "include this
|
||||
transport in my published advert" — common to both paths.
|
||||
@@ -191,8 +200,11 @@ sudo systemctl status fips
|
||||
Status should show `active (running)`. Within a few seconds the
|
||||
daemon will:
|
||||
|
||||
1. Run a one-shot STUN observation against the default STUN
|
||||
servers to learn its public IP.
|
||||
1. Determine the address to advertise. If you set `external_addr`,
|
||||
the daemon uses it directly and skips STUN. If you set only
|
||||
`public: true`, the daemon runs a one-shot STUN observation
|
||||
against the default STUN servers and uses the reflexive IPv4 it
|
||||
learns.
|
||||
2. Build a Kind 37195 advert listing
|
||||
`udp:<public-ip>:2121` (and any other transports you have
|
||||
`advertise_on_nostr: true` on).
|
||||
@@ -200,12 +212,13 @@ daemon will:
|
||||
4. Publish it to the three default advert relays.
|
||||
5. Schedule a refresh every 30 minutes.
|
||||
|
||||
If STUN fails (for example, if the network blocks outbound
|
||||
UDP/3478), the daemon emits a WARN line in the journal and
|
||||
suppresses the UDP entry from the advert rather than publishing
|
||||
a wrong address. The link to `test-us01` from the previous
|
||||
tutorial keeps working regardless — only the publish side is
|
||||
gated on STUN.
|
||||
If you took the `public: true` path and STUN fails (for example,
|
||||
the network blocks outbound UDP/3478), the daemon emits a WARN
|
||||
line in the journal and suppresses the UDP entry from the advert
|
||||
rather than publishing a wrong address. The link to `test-us01`
|
||||
from the previous tutorial keeps working regardless — only the
|
||||
publish side is gated on STUN, and only on the STUN path. The
|
||||
`external_addr` path doesn't depend on STUN reachability at all.
|
||||
|
||||
Quick sanity check on the journal:
|
||||
|
||||
@@ -295,22 +308,24 @@ verifiable in Step 4.
|
||||
to them specifically or not. The test mesh's open-discovery
|
||||
nodes will pick you up automatically.
|
||||
|
||||
## If you're behind symmetric NAT
|
||||
## If your direct UDP advert isn't reachable
|
||||
|
||||
`public: true` + STUN works on most home and office NATs (the
|
||||
full-cone variety) and on nodes with a directly-bound public
|
||||
IP. It does *not* work on symmetric NAT, where the NAT mapping
|
||||
is keyed on (source-port, destination-host) so the IP/port
|
||||
your STUN server saw isn't the IP/port a different peer would
|
||||
see.
|
||||
`public: true` advertises the IP STUN observes paired with your
|
||||
listener's bind port. That advert is only useful if your listener
|
||||
really is reachable at that public IP/port — STUN can confirm the
|
||||
public IP but not that an unsolicited inbound packet to the bind
|
||||
port will make it through. The most common cause of the listener
|
||||
being unreachable is symmetric NAT (where the public port a peer
|
||||
sees varies per remote endpoint), but other configurations can
|
||||
have the same effect.
|
||||
|
||||
For symmetric-NAT networks the alternative is `udp:nat` mode,
|
||||
which advertises a placeholder `udp:nat` endpoint along with
|
||||
the daemon's signaling-relay and STUN-server lists, and
|
||||
performs UDP hole-punching at dial time. Both sides need to be
|
||||
running matching configs and at least one side needs a
|
||||
non-symmetric NAT for the punch to succeed; symmetric on both
|
||||
sides is not reliably traversable and will time out.
|
||||
When direct UDP advertising can't be relied on, the alternative
|
||||
is `udp:nat` mode, which advertises a placeholder `udp:nat`
|
||||
endpoint along with the daemon's signaling-relay and STUN-server
|
||||
lists, and performs UDP hole-punching at dial time. Hole-punching
|
||||
is best-effort — it works reliably when both sides are full-cone
|
||||
or port-restricted, and symmetric NAT on either side typically
|
||||
defeats it. Both sides need matching configs.
|
||||
|
||||
The minimal config switch:
|
||||
|
||||
@@ -339,7 +354,7 @@ discovery:
|
||||
|
||||
For the full setup including peer-side config and the punch-
|
||||
duration knob, see
|
||||
[../how-to/enable-nostr-discovery.md § Capability 2c](../how-to/enable-nostr-discovery.md#sub-scenario-2c-udp-hole-punching-for-nodes-behind-nat).
|
||||
[../how-to/enable-nostr-discovery.md § When the node is behind NAT](../how-to/enable-nostr-discovery.md#when-the-node-is-behind-nat).
|
||||
|
||||
Separately from NAT considerations, FIPS supports running a
|
||||
node behind a Tor onion service as a deployment shape in its
|
||||
@@ -347,7 +362,7 @@ own right — chosen for the privacy, anonymity, and
|
||||
censorship-resistance properties it brings, not as a fallback
|
||||
when UDP or TCP fail. If those properties are an independent
|
||||
goal for your node, see
|
||||
[../how-to/enable-nostr-discovery.md § Sub-scenario 2b](../how-to/enable-nostr-discovery.md#sub-scenario-2b-tor-onion-node)
|
||||
[../how-to/enable-nostr-discovery.md § Tor onion node](../how-to/enable-nostr-discovery.md#tor-onion-node)
|
||||
and
|
||||
[../how-to/deploy-tor-onion.md](../how-to/deploy-tor-onion.md).
|
||||
|
||||
@@ -364,10 +379,12 @@ If your advert doesn't appear on the relays:
|
||||
with a non-public address (e.g., `10.x.x.x` or
|
||||
`192.168.x.x`), STUN didn't see your real public IP — likely
|
||||
you're behind a CGNAT that NATs your STUN traffic too, or a
|
||||
corporate firewall that proxies it. Switch to the
|
||||
`external_addr` form from Step 2 with your actual public
|
||||
IP, or replace `public: true` with the bound interface IP
|
||||
directly under `bind_addr`.
|
||||
corporate firewall that proxies it. Two correct fixes:
|
||||
(a) keep `public: true` and add `external_addr: <your-IP>`
|
||||
(the explicit override wins and skips STUN); or (b) bind
|
||||
directly to your public interface
|
||||
(`bind_addr: <pub-ip>:2121`) and keep `advertise_on_nostr:
|
||||
true` and `public: true`. Don't drop those flags.
|
||||
|
||||
- **Relay reachability.** `nak req` against a relay you can
|
||||
reach but no events return — possibly the publish failed
|
||||
@@ -379,9 +396,14 @@ If your advert doesn't appear on the relays:
|
||||
nak req ... wss://offchain.pub
|
||||
```
|
||||
|
||||
- **`advertise_on_nostr` typo.** YAML is case-sensitive and
|
||||
silently ignores unknown keys. If `nak` returns no advert at
|
||||
all, double-check the spelling on the UDP block and that
|
||||
- **`advertise_on_nostr` typo.** YAML is case-sensitive. The
|
||||
config parser rejects unknown keys via
|
||||
`serde(deny_unknown_fields)` on the per-section structs, so a
|
||||
misspelled field will refuse the daemon's start with a
|
||||
parse-error line in the journal naming the unknown field.
|
||||
If the daemon is running but `nak` returns no advert, the
|
||||
field was accepted but something else is wrong; double-check
|
||||
the spelling on the UDP block and that
|
||||
`discovery.nostr.advertise: true` is also set.
|
||||
|
||||
## What's next
|
||||
|
||||
@@ -110,8 +110,12 @@ You should be coming out of
|
||||
[advertise-your-node](advertise-your-node.md) with:
|
||||
|
||||
- Persistent identity, advertising enabled
|
||||
(`discovery.nostr.advertise: true`), UDP advertising on
|
||||
Nostr (`transports.udp.advertise_on_nostr: true`).
|
||||
(`discovery.nostr.advertise: true`), and either the
|
||||
direct-UDP path
|
||||
(`transports.udp.advertise_on_nostr: true`,
|
||||
`transports.udp.public: true`) or the `udp:nat` path
|
||||
(`transports.udp.advertise_on_nostr: true`,
|
||||
`transports.udp.public: false`) from the previous tutorial.
|
||||
- A static `test-us01` peer entry that the daemon dials
|
||||
outbound; possibly an inbound `test-us03` peer (the
|
||||
open-discovery test mesh node that dialed in after seeing
|
||||
@@ -288,11 +292,12 @@ the previous tutorial:
|
||||
WebSocket connection to the relays is failing repeatedly,
|
||||
no adverts arrive. Look for relay-connection errors in
|
||||
`sudo journalctl -u fips -n 200`.
|
||||
- **`policy: open` typo.** YAML accepts and ignores unknown
|
||||
values silently. If `fipsctl show status` (or the daemon's
|
||||
startup log) shows `policy: configured_only`, the YAML
|
||||
didn't parse the new value — re-check spelling and
|
||||
indentation.
|
||||
- **`policy: open` typo.** YAML is case-sensitive, and the
|
||||
`policy` field is a serde enum that rejects unknown values —
|
||||
a misspelled value produces a config-parse error at startup
|
||||
rather than a silent fall-back. If the daemon refuses to
|
||||
start, check `sudo journalctl -u fips -n 200` for the
|
||||
parse-error line naming the field and value.
|
||||
|
||||
If too many peers are appearing and you want to dial down:
|
||||
|
||||
|
||||
@@ -125,9 +125,10 @@ Two knobs, one job each:
|
||||
`wss://offchain.pub`) and is now able to query and consume
|
||||
adverts.
|
||||
- `advertise: false` keeps the publish side off. Your daemon
|
||||
will not publish an advert of its own at this stage. (This
|
||||
is the default, but it is good practice to make the choice
|
||||
explicit while you're learning.)
|
||||
will not publish an advert of its own at this stage. The
|
||||
default is `true`, so we are setting it explicitly to
|
||||
disable advertising for this consume-only tutorial. The next
|
||||
tutorial flips it back on.
|
||||
|
||||
## Step 3: Switch the peer entry to `via_nostr`
|
||||
|
||||
@@ -270,8 +271,9 @@ If the link does not come up:
|
||||
[advertise-your-node](advertise-your-node.md) publishes your
|
||||
daemon's UDP endpoint on Nostr so other operators can add
|
||||
you to their `peers:` list with `via_nostr: true` and reach
|
||||
you the way you just reached `test-us01`. Includes a section
|
||||
on `udp:nat` NAT traversal for symmetric-NAT networks.
|
||||
you the way you just reached `test-us01`. Includes a short
|
||||
final section on `udp:nat`, the best-effort hole-punching
|
||||
path for nodes without a directly reachable UDP endpoint.
|
||||
|
||||
- **Discover peers with no prior configuration.**
|
||||
[open-discovery](open-discovery.md) switches your daemon to
|
||||
|
||||
Reference in New Issue
Block a user