Skip to content

Commit 429787a

Browse files
committed
feat(connect): add forward CONNECT mode + local dev helpers
1 parent 49a36ae commit 429787a

File tree

15 files changed

+1115
-49
lines changed

15 files changed

+1115
-49
lines changed

Cargo.lock

Lines changed: 54 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ iroh-base = { version = "0.95" }
2424
iroh-tickets = "0.2"
2525
iroh-metrics = "0.38"
2626
iroh-n0des = { version = "0.8", features = ["tickets"] }
27+
iroh-relay = { version = "0.95" }
2728
log = "0.4"
2829
open = "5"
2930
openidconnect = "4.0.1"

README.md

Lines changed: 131 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,137 @@ cd cli
1717
cargo run -- --help
1818
```
1919

20+
### Local forward-proxy demo (no GUI)
21+
This exercises the CONNECT-based gateway flow that Envoy will use in staging/prod.
22+
23+
#### 1) Start a local DNS dev server (out-of-band)
24+
Use a non-`.local` origin (e.g. `datumconnect.test`):
25+
26+
```
27+
cargo run -p datum-connect -- dns-dev serve \
28+
--origin datumconnect.test \
29+
--bind 127.0.0.1:53535 \
30+
--data ./dns-dev.yml
31+
```
32+
33+
#### 2) Start the listen node (connector side)
34+
This prints the endpoint id and the iroh UDP bound sockets you must publish:
35+
36+
```
37+
cargo run -p datum-connect -- serve
38+
```
39+
40+
Copy the printed `dns-dev upsert` example, but run it via `cargo run -p datum-connect -- ...`
41+
and make sure the origin matches `datumconnect.test`. Quote IPv6 addresses like `"[::]:1234"`.
42+
43+
#### 3) Verify TXT resolution
44+
The `serve` command prints the z-base-32 ID and the full DNS name. Query it with:
45+
46+
```
47+
dig +norecurse @127.0.0.1 -p 53535 TXT _iroh.<z32>.datumconnect.test
48+
```
49+
50+
#### 4) Start the gateway in forward mode
51+
52+
```
53+
cargo run -p datum-connect -- gateway \
54+
--port 8080 \
55+
--mode forward \
56+
--discovery dns \
57+
--dns-origin datumconnect.test \
58+
--dns-resolver 127.0.0.1:53535
59+
60+
Discovery modes:
61+
- `default`: iroh defaults (n0 preset).
62+
- `dns`: only the provided DNS origin/resolver.
63+
- `hybrid`: default + custom DNS.
64+
```
65+
66+
#### 5) Send a CONNECT request
67+
If your target TCP service is on `127.0.0.1:5173`:
68+
69+
```
70+
curl --proxytunnel -x 127.0.0.1:8080 \
71+
--proxy-header "x-iroh-endpoint-id: REPLACE_WITH_ENDPOINT_ID" \
72+
"http://127.0.0.1:5173"
73+
```
74+
75+
### GUI demo (browser tunnel)
76+
This mirrors the same flow, but uses the GUI to create the proxy entry.
77+
78+
If you want a one-shot experience, run:
79+
80+
```
81+
./scripts/try-ui-demo.sh
82+
```
83+
84+
It starts dns-dev, an HTTPS origin, the gateway, and the GUI, and waits for you to
85+
create a TCP proxy in the UI before visiting `https://localhost:5173` in the browser.
86+
87+
#### 1) Start `dns-dev`
88+
```
89+
cargo run -p datum-connect -- dns-dev serve \
90+
--origin datumconnect.test \
91+
--bind 127.0.0.1:53535 \
92+
--data ./dns-dev.yml
93+
```
94+
95+
#### 2) Start a local HTTPS origin (so the browser uses CONNECT)
96+
```
97+
openssl req -x509 -nodes -newkey rsa:2048 -days 1 \
98+
-keyout /tmp/iroh-dev.key -out /tmp/iroh-dev.crt \
99+
-subj "/CN=localhost"
100+
openssl s_server -accept 5173 -cert /tmp/iroh-dev.crt -key /tmp/iroh-dev.key -www
101+
```
102+
103+
#### 3) Run the GUI (share the repo with CLI)
104+
```
105+
export DATUM_CONNECT_REPO=$(pwd)/.datum-connect-dev
106+
cd ui
107+
dx serve --platform desktop
108+
```
109+
110+
#### 4) Create a proxy in the GUI
111+
Add a TCP proxy for `127.0.0.1:5173`.
112+
113+
#### 5) Start the listen node (uses the same repo)
114+
```
115+
cd ..
116+
export DATUM_CONNECT_REPO=$(pwd)/.datum-connect-dev
117+
cargo run -p datum-connect -- serve
118+
```
119+
Copy the printed `dns-dev upsert` example, but change the origin to `datumconnect.test`
120+
and run it via `cargo run -p datum-connect -- ...` (quote IPv6 addresses).
121+
122+
#### 6) Start the gateway in forward mode
123+
```
124+
export DATUM_CONNECT_REPO=$(pwd)/.datum-connect-dev
125+
cargo run -p datum-connect -- gateway \
126+
--port 8080 \
127+
--mode forward \
128+
--discovery dns \
129+
--dns-origin datumconnect.test \
130+
--dns-resolver 127.0.0.1:53535
131+
```
132+
133+
#### 7) Start a local entrypoint that always tunnels through the gateway
134+
This avoids any browser proxy configuration. It listens on `127.0.0.1:8888` and
135+
uses CONNECT under the hood to reach the target:
136+
```
137+
cargo run -p datum-connect -- tunnel-dev \
138+
--gateway 127.0.0.1:8080 \
139+
--node-id REPLACE_WITH_ENDPOINT_ID \
140+
--target-host 127.0.0.1 \
141+
--target-port 5173
142+
```
143+
Now visit:
144+
```
145+
https://localhost:8888
146+
```
147+
You should see the `openssl s_server` status page (cipher list + handshake info).
148+
That output is expected and means the CONNECT request tunneled through the gateway
149+
to the local origin.
150+
20151
### Running the UI:
21152

22153
to run the UI, make sure you have rust, cargo, and dioxus installed:

cli/Cargo.toml

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,3 +12,11 @@ tracing-subscriber.workspace = true
1212
clap = { version = "4.5.50", features = ["derive", "env"] }
1313
tracing.workspace = true
1414
tokio-util.workspace = true
15+
serde.workspace = true
16+
serde_yml.workspace = true
17+
async-trait = "0.1.89"
18+
humantime = "2.1.0"
19+
hickory-server = "0.25.2"
20+
hickory-proto = "0.25.2"
21+
iroh-base.workspace = true
22+
z32 = "1.0.3"

0 commit comments

Comments
 (0)