Skip to content

Commit 6a6e3f0

Browse files
authored
Merge pull request #20 from n0-computer/net-diagnostics
net diagnostics docs
2 parents 3dc6914 + a16eb1c commit 6a6e3f0

2 files changed

Lines changed: 135 additions & 0 deletions

File tree

docs.json

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,10 @@
104104
"iroh-services/relays/public",
105105
"iroh-services/relays/managed"
106106
]
107+
},
108+
{
109+
"group": "Net Diagnostics",
110+
"pages": ["iroh-services/net-diagnostics"]
107111
}
108112
]
109113
}

iroh-services/net-diagnostics.mdx

Lines changed: 131 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,131 @@
1+
---
2+
title: "Network Diagnostics"
3+
description: "Diagnose user connectivity issues with remote diagnostic reporting"
4+
---
5+
6+
Net Diagnostics lets you run network connectivity reports on your endpoints from iroh-services. Reports cover NAT type, UDP connectivity, relay latency, port mapping protocol availability, and direct addresses — everything you need to debug connection issues. You can initiate reports from iroh-services, which will reach out to configured remote nodes that have authorized diagnostics, gather details about the endpoint's connectivity context, and forward the report to your project on iroh services to assess how to help your user get the best connection they can.
7+
8+
Net Diagnostics is available on the **Enterprise plan**.
9+
10+
## Quick Start
11+
12+
### 1. Get your API secret
13+
14+
Go to your project's **Settings** page and copy the API secret. In your terminal, export it as an environment variable:
15+
16+
```bash
17+
export N0DES_API_SECRET=<your-api-secret>
18+
```
19+
20+
### 2. Run the diagnostics client
21+
22+
Clone the [iroh-n0des](https://github.com/n0-computer/iroh-n0des) repo and run the `net_diagnostics` example:
23+
24+
```bash
25+
git clone https://github.com/n0-computer/iroh-n0des.git
26+
cd iroh-n0des
27+
cargo run --example net_diagnostics --features net_diagnostics,client_host
28+
```
29+
30+
Leave this terminal open. The example connects to n0des, grants the diagnostics capability to your project, and waits for incoming diagnostics requests.
31+
32+
### 3. Run a diagnostic from the dashboard
33+
34+
Go to your project's **Endpoints** page. You should see the example client listed as an online endpoint. Click **Run Diagnostics** to generate a report.
35+
36+
The report appears on the **Net Diagnostics** page and includes:
37+
38+
- **NAT Type** — No NAT, Endpoint-Independent, Endpoint-Dependent, or Unknown
39+
- **UDP Connectivity** — IPv4 and IPv6 status with public addresses
40+
- **NAT Mapping** — whether mapping varies by destination (symmetric NAT detection)
41+
- **Direct Addresses** — local addresses the endpoint is listening on
42+
- **Port Mapping** — UPnP, PCP, and NAT-PMP availability
43+
- **Relay Latencies** — per-relay IPv4, IPv6, and HTTPS round-trip times
44+
- **Captive Portal** — detection of captive portal interference
45+
46+
## Understanding the Report
47+
48+
### NAT Types
49+
50+
| NAT Type | What it means | Connection quality |
51+
|---|---|---|
52+
| **No NAT** | Local address matches public address | Direct connections work with correct firewall config |
53+
| **Endpoint-Independent** | One outbound UDP packet opens a port for any sender | Holepunching works reliably |
54+
| **Endpoint-Dependent** | Only the specific destination can reply (symmetric NAT) | Connections will primarily use relays |
55+
| **Unknown** | NAT behavior could not be determined | Check UDP connectivity |
56+
57+
### Connectivity Summary
58+
59+
The report includes a color-coded connectivity summary:
60+
61+
- **Green** — UDP works and NAT is favorable. Direct connections should work.
62+
- **Orange** — Endpoint-Dependent NAT. Direct connections may be difficult; traffic will often be relayed.
63+
- **Red** — No UDP connectivity. Traffic will be relayed.
64+
65+
## Integrating Net Diagnostics Into Your App
66+
67+
To add net diagnostics support to your own iroh application, you need to:
68+
69+
1. Connect to n0des with an `iroh_n0des::Client`
70+
2. Grant the `NetDiagnosticsCap::GetAny` capability to n0des so it can request diagnostics from your endpoint
71+
3. Run a `ClientHost` so n0des can dial back into your endpoint
72+
73+
Here's a minimal integration:
74+
75+
```rust
76+
use anyhow::Result;
77+
use iroh::{Endpoint, protocol::Router};
78+
use iroh_n0des::{
79+
ApiSecret, Client, ClientHost, CLIENT_HOST_ALPN, API_SECRET_ENV_VAR_NAME,
80+
caps::NetDiagnosticsCap,
81+
};
82+
83+
async fn setup_net_diagnostics(endpoint: &Endpoint) -> Result<Router> {
84+
// Parse the API secret from the environment
85+
let secret = ApiSecret::from_env_var(API_SECRET_ENV_VAR_NAME)?;
86+
let remote_id = secret.addr().id;
87+
88+
// Build the n0des client
89+
let client = Client::builder(endpoint)
90+
.api_secret(secret)?
91+
.build()
92+
.await?;
93+
94+
// Grant the GetAny capability so n0des can request diagnostics
95+
// from this endpoint on demand
96+
let client2 = client.clone();
97+
tokio::spawn(async move {
98+
client2
99+
.grant_capability(remote_id, vec![NetDiagnosticsCap::GetAny])
100+
.await
101+
.unwrap();
102+
});
103+
104+
// Set up a ClientHost so n0des can dial back into this endpoint
105+
let host = ClientHost::new(endpoint);
106+
let router = Router::builder(endpoint.clone())
107+
.accept(CLIENT_HOST_ALPN, host)
108+
.spawn();
109+
110+
Ok(router)
111+
}
112+
```
113+
114+
Add the following to your `Cargo.toml`:
115+
116+
```toml
117+
[dependencies]
118+
iroh-n0des = { version = "...", features = ["net_diagnostics", "client_host"] }
119+
```
120+
121+
### How It Works
122+
123+
When you click **Run Diagnostics** in the dashboard, n0des dials back into your endpoint using the capability token your app granted. Your `ClientHost` receives the request, runs the diagnostics locally (probing UDP connectivity, NAT behavior, relay latency, and port mapping), and returns the report to n0des for display.
124+
125+
The capability grant (`NetDiagnosticsCap::GetAny`) authorizes n0des to request diagnostics from your endpoint. Without this grant, the **Run Diagnostics** button will be disabled in the dashboard even if the endpoint is online.
126+
127+
### Requirements
128+
129+
- The `net_diagnostics` and `client_host` cargo features must be enabled on `iroh-n0des`
130+
- The `N0DES_API_SECRET` environment variable must be set before your app starts
131+
- The `ClientHost` must be registered on the `Router` with `CLIENT_HOST_ALPN` so n0des can reach it

0 commit comments

Comments
 (0)