derptun 0.16.2 → 0.16.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md
CHANGED
|
@@ -1,43 +1,62 @@
|
|
|
1
1
|
# derphole
|
|
2
2
|
|
|
3
|
-
`derphole` is a
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
3
|
+
`derphole` is a small CLI for the network job that should not require a new
|
|
4
|
+
network: move bytes, expose a local TCP service, or exchange SSH access for one
|
|
5
|
+
short session when neither side has an inbound port to offer.
|
|
6
|
+
|
|
7
|
+
The obvious answer is "use a VPN." Sometimes that is correct. If you need
|
|
8
|
+
stable private IPs, ACLs, subnet routes, exit nodes, and machines that remember
|
|
9
|
+
each other, use a VPN. If you need one transfer, one tunnel, or one shared
|
|
10
|
+
terminal, a VPN is a lot of state for a short conversation.
|
|
11
|
+
|
|
12
|
+
This repo ships three tools:
|
|
13
|
+
|
|
14
|
+
- `derphole` for one-shot files, byte streams, receive-code flows, temporary
|
|
15
|
+
localhost shares, and SSH access exchange.
|
|
16
|
+
- [`derptun`](#tcp-tunnels) for longer-lived TCP tunnels with stable server and
|
|
17
|
+
client tokens.
|
|
18
|
+
- [`derpssh`](#share-a-terminal) for shared terminal sessions with host approval
|
|
19
|
+
and no open ports.
|
|
20
|
+
|
|
21
|
+
The tools use the public Tailscale [DERP](#what-is-derp) relay network for
|
|
22
|
+
rendezvous and fallback, then promote live traffic to direct encrypted UDP when
|
|
23
|
+
possible. Payload bytes stay end-to-end encrypted on relay fallback, direct UDP,
|
|
24
|
+
and authenticated QUIC stream paths. DERP sees routing metadata and packet
|
|
25
|
+
timing, not contents.
|
|
26
|
+
|
|
27
|
+
These tools are **not** affiliated with Tailscale and do **not** use
|
|
28
|
+
`tailscaled`.
|
|
29
|
+
|
|
30
|
+
They are also not a WireGuard overlay or a VPN. `derphole` handles one token,
|
|
31
|
+
one session, one transfer or shared service. `derptun` handles one tunnel with
|
|
32
|
+
reusable scoped tokens. `derpssh` handles one approved PTY session. See
|
|
33
|
+
[Transport Model](#transport-model), [Why It Is Fast](#why-it-is-fast), and
|
|
34
|
+
[Security Model](#security-model).
|
|
35
|
+
|
|
36
|
+
No Tailscale account, tailnet, daemon, or self-hosted control plane is required.
|
|
37
|
+
Session tokens carry authorization. Treat them like passwords with a shorter
|
|
38
|
+
half-life. Public sessions fetch the DERP map at runtime so both sides can find
|
|
39
|
+
relay and bootstrap nodes.
|
|
28
40
|
|
|
29
41
|
## Pick the Workflow
|
|
30
42
|
|
|
31
|
-
- Use `listen` and `pipe`
|
|
32
|
-
- Use `send` and `receive`
|
|
33
|
-
-
|
|
34
|
-
- Use `
|
|
35
|
-
- Use
|
|
36
|
-
- Use [`
|
|
43
|
+
- Use `listen` and `pipe` when you want raw bytes and shell pipelines.
|
|
44
|
+
- Use `send` and `receive` when you want text, files, directories, progress, and
|
|
45
|
+
receive-code UX.
|
|
46
|
+
- Use `share` and `open` when you want temporary access to a local TCP service.
|
|
47
|
+
- Use `ssh invite` and `ssh accept` when you want to exchange SSH access.
|
|
48
|
+
- Use [`derpssh`](#share-a-terminal) when two people need one approved terminal.
|
|
49
|
+
- Use [`derptun`](#tcp-tunnels) when the TCP tunnel needs reusable tokens and
|
|
50
|
+
reconnects.
|
|
37
51
|
|
|
38
52
|
## Quick Start
|
|
39
53
|
|
|
40
|
-
`listen` receives bytes and prints a token. `pipe` sends stdin into that token.
|
|
54
|
+
`listen` receives bytes and prints a token. `pipe` sends stdin into that token.
|
|
55
|
+
`share` and `open` do the same shape of thing for local TCP services. The trick
|
|
56
|
+
is small on purpose: one token, one capability, one session.
|
|
57
|
+
|
|
58
|
+
Use [`derptun`](#tcp-tunnels) when the tunnel should live longer than a one-off
|
|
59
|
+
share.
|
|
41
60
|
|
|
42
61
|
### Stream a Raw File
|
|
43
62
|
|
|
@@ -47,7 +66,8 @@ Receiver:
|
|
|
47
66
|
npx -y derphole@latest listen > received.img
|
|
48
67
|
```
|
|
49
68
|
|
|
50
|
-
`listen` prints a token to stderr, keeping stdout clean. Copy the token to the
|
|
69
|
+
`listen` prints a token to stderr, keeping stdout clean. Copy the token to the
|
|
70
|
+
sender.
|
|
51
71
|
|
|
52
72
|
Sender:
|
|
53
73
|
|
|
@@ -75,7 +95,8 @@ npx -y derphole@latest send ./photo.jpg
|
|
|
75
95
|
npx -y derphole@latest receive <code>
|
|
76
96
|
```
|
|
77
97
|
|
|
78
|
-
Known-size files and directories show progress on stderr. Use `--hide-progress`
|
|
98
|
+
Known-size files and directories show progress on stderr. Use `--hide-progress`
|
|
99
|
+
when quiet output matters more than watching the counter move.
|
|
79
100
|
|
|
80
101
|
Text uses the same flow:
|
|
81
102
|
|
|
@@ -141,11 +162,24 @@ npx -y derpssh@latest share
|
|
|
141
162
|
npx -y derpssh@latest connect <invite>
|
|
142
163
|
```
|
|
143
164
|
|
|
144
|
-
The host approves the guest as read-only or read/write. The session uses the
|
|
165
|
+
The host approves the guest as read-only or read/write. The session uses the
|
|
166
|
+
`derptun` transport path, so neither side needs an inbound port.
|
|
167
|
+
|
|
168
|
+
Optional local lookup keeps the invite behind a service name on the connecting
|
|
169
|
+
machine:
|
|
170
|
+
|
|
171
|
+
```bash
|
|
172
|
+
npx -y derpssh@latest service set ops-shell <invite>
|
|
173
|
+
npx -y derpssh@latest connect --service ops-shell
|
|
174
|
+
```
|
|
175
|
+
|
|
176
|
+
The host still approves the guest. The service name only finds the invite; it
|
|
177
|
+
does not bypass approval.
|
|
145
178
|
|
|
146
179
|
### TCP Tunnels
|
|
147
180
|
|
|
148
|
-
`derptun` exposes a local TCP service without
|
|
181
|
+
`derptun` exposes a local TCP service without asking either side to open an
|
|
182
|
+
inbound port. Start with a one-off tunnel:
|
|
149
183
|
|
|
150
184
|
On the serving machine:
|
|
151
185
|
|
|
@@ -159,9 +193,11 @@ npx -y derptun@latest serve --tcp 127.0.0.1:3000
|
|
|
159
193
|
npx -y derptun@latest open --token DT1...
|
|
160
194
|
```
|
|
161
195
|
|
|
162
|
-
Run that command on the connecting machine. It opens a local listener and
|
|
196
|
+
Run that command on the connecting machine. It opens a local listener and
|
|
197
|
+
forwards connections through the tunnel.
|
|
163
198
|
|
|
164
|
-
For a persistent tunnel, create both tokens on the serving machine and keep the
|
|
199
|
+
For a persistent tunnel, create both tokens on the serving machine and keep the
|
|
200
|
+
server token there:
|
|
165
201
|
|
|
166
202
|
```bash
|
|
167
203
|
npx -y derptun@latest token server > server.dts
|
|
@@ -177,16 +213,32 @@ On the connecting machine:
|
|
|
177
213
|
npx -y derptun@latest open --token-file client.dt1 --listen 127.0.0.1:3001
|
|
178
214
|
```
|
|
179
215
|
|
|
180
|
-
The server token is serving authority. Keep it on the serving machine or in a
|
|
216
|
+
The server token is serving authority. Keep it on the serving machine or in a
|
|
217
|
+
secret manager. Client tokens can connect until expiry, but cannot serve or mint
|
|
218
|
+
tokens.
|
|
181
219
|
|
|
182
|
-
Server tokens default to 180 days. Client tokens default to 90 days and cannot
|
|
220
|
+
Server tokens default to 180 days. Client tokens default to 90 days and cannot
|
|
221
|
+
outlive their server token. Set a relative lifetime with `--days`, or use an
|
|
222
|
+
absolute expiry:
|
|
183
223
|
|
|
184
224
|
```bash
|
|
185
225
|
npx -y derptun@latest token server --expires 2026-05-01T00:00:00Z > server.dts
|
|
186
226
|
npx -y derptun@latest token client --token-file server.dts --expires 2026-04-25T00:00:00Z > client.dt1
|
|
187
227
|
```
|
|
188
228
|
|
|
189
|
-
Use `--token TOKEN` for inline one-off commands. Prefer `--token-file PATH` for
|
|
229
|
+
Use `--token TOKEN` for inline one-off commands. Prefer `--token-file PATH` for
|
|
230
|
+
durable tokens. `--token-stdin` reads the token from the first stdin line.
|
|
231
|
+
|
|
232
|
+
Optional local lookup keeps the client token behind a service name on the
|
|
233
|
+
connecting machine:
|
|
234
|
+
|
|
235
|
+
```bash
|
|
236
|
+
npx -y derptun@latest service set web --token-file client.dt1
|
|
237
|
+
npx -y derptun@latest open --service web --listen 127.0.0.1:3001
|
|
238
|
+
```
|
|
239
|
+
|
|
240
|
+
The registry is local name-to-token storage. It is not a hosted control plane,
|
|
241
|
+
and no lookup server is contacted by default.
|
|
190
242
|
|
|
191
243
|
### Useful Extras
|
|
192
244
|
|
|
@@ -198,7 +250,9 @@ npx -y derptun@dev version
|
|
|
198
250
|
npx -y derpssh@dev version
|
|
199
251
|
```
|
|
200
252
|
|
|
201
|
-
Default output stays quiet: tokens, bind addresses, receive commands, and
|
|
253
|
+
Default output stays quiet: tokens, bind addresses, receive commands, and
|
|
254
|
+
progress only. Use `--hide-progress` to suppress progress, or `--verbose` to see
|
|
255
|
+
path changes such as `connected-relay` and `connected-direct`:
|
|
202
256
|
|
|
203
257
|
```bash
|
|
204
258
|
npx -y derphole@latest --verbose listen
|
|
@@ -206,93 +260,161 @@ npx -y derphole@latest --verbose pipe <token>
|
|
|
206
260
|
npx -y derphole@latest --verbose send ./photo.jpg
|
|
207
261
|
```
|
|
208
262
|
|
|
209
|
-
For transport details, see [Transport Model](#transport-model),
|
|
263
|
+
For transport details, see [Transport Model](#transport-model),
|
|
264
|
+
[Behavior](#behavior), and [Security Model](#security-model).
|
|
210
265
|
|
|
211
266
|
## Transport Model
|
|
212
267
|
|
|
213
|
-
|
|
268
|
+
The session flow is deliberately boring. Boring is good here.
|
|
214
269
|
|
|
215
|
-
1. `listen`, `share`, or `receive` creates a session and prints an opaque bearer
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
270
|
+
1. `listen`, `share`, or `receive` creates a session and prints an opaque bearer
|
|
271
|
+
token or receive code.
|
|
272
|
+
2. The token carries session ID, expiry, DERP bootstrap hints, listener public
|
|
273
|
+
identity, bearer secret, and allowed capability.
|
|
274
|
+
3. `pipe`, `send`, or `open` uses that token to contact the listener through
|
|
275
|
+
DERP and claim the session.
|
|
276
|
+
4. The listener validates the claim, checks the requested capability, and returns
|
|
277
|
+
current direct-path candidates.
|
|
219
278
|
5. Both sides start on the first working path, including DERP relay if needed.
|
|
220
|
-
6. Both sides keep probing for a better direct path. Successful direct paths
|
|
279
|
+
6. Both sides keep probing for a better direct path. Successful direct paths
|
|
280
|
+
upgrade the live session in place.
|
|
221
281
|
|
|
222
282
|
### Data Plane Selection
|
|
223
283
|
|
|
224
|
-
DERP provides **rendezvous** and **relay fallback**. See
|
|
284
|
+
DERP provides **rendezvous** and **relay fallback**. See
|
|
285
|
+
[What Is DERP?](#what-is-derp):
|
|
225
286
|
|
|
226
|
-
- rendezvous: exchange claim, decision, and direct-path coordination messages
|
|
227
|
-
|
|
287
|
+
- rendezvous: exchange claim, decision, and direct-path coordination messages
|
|
288
|
+
without an account-backed control plane
|
|
289
|
+
- relay fallback: keep the session working when NAT traversal fails or direct
|
|
290
|
+
connectivity is not ready
|
|
228
291
|
|
|
229
292
|
The data plane is selected per session:
|
|
230
293
|
|
|
231
|
-
- `share/open` uses multiplexed QUIC streams over `derphole`'s relay/direct UDP
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
- `
|
|
235
|
-
|
|
294
|
+
- `share/open` uses multiplexed QUIC streams over `derphole`'s relay/direct UDP
|
|
295
|
+
transport. One claimed session can carry many TCP connections to the shared
|
|
296
|
+
service.
|
|
297
|
+
- `derptun` uses a stable tunnel token and the same transport for reconnectable
|
|
298
|
+
TCP streams. It is built for longer-lived access, such as a private service
|
|
299
|
+
behind NAT.
|
|
300
|
+
- `derpssh` uses the `derptun` app mux for approved terminal streams and
|
|
301
|
+
side-channel control.
|
|
302
|
+
- `listen/pipe` uses a one-shot byte stream. It coordinates through DERP,
|
|
303
|
+
promotes to rate-adaptive direct UDP when traversal succeeds, and stays on
|
|
304
|
+
encrypted relay fallback when direct paths fail.
|
|
305
|
+
- `send/receive` wraps the same one-shot stream with text, file, directory, and
|
|
306
|
+
progress metadata.
|
|
236
307
|
|
|
237
308
|
Candidate discovery splits into two phases:
|
|
238
309
|
|
|
239
|
-
- fast local candidates first: advertise local sockets, interfaces, and cached
|
|
240
|
-
|
|
310
|
+
- fast local candidates first: advertise local sockets, interfaces, and cached
|
|
311
|
+
port mappings immediately
|
|
312
|
+
- background traversal discovery: run STUN and UPnP / NAT-PMP / PCP refresh,
|
|
313
|
+
then send updated candidates and `call-me-maybe` probes
|
|
241
314
|
|
|
242
315
|
This keeps startup latency low while preserving relay-to-direct promotion.
|
|
243
316
|
|
|
244
317
|
## How This Differs From Tailscale / WireGuard
|
|
245
318
|
|
|
246
|
-
Tailscale uses WireGuard for a secure general-purpose network: durable machine
|
|
319
|
+
Tailscale uses WireGuard for a secure general-purpose network: durable machine
|
|
320
|
+
connectivity, private addresses, ACLs, subnet routing, exit nodes, and
|
|
321
|
+
long-lived overlays.
|
|
322
|
+
|
|
323
|
+
That is the right tool when you want a network.
|
|
247
324
|
|
|
248
|
-
`derphole` is narrower. It creates session-scoped transport for one transfer or
|
|
325
|
+
`derphole` is narrower. It creates session-scoped transport for one transfer or
|
|
326
|
+
one shared service:
|
|
249
327
|
|
|
250
328
|
- no WireGuard tunnel device
|
|
251
329
|
- no overlay network interface
|
|
252
330
|
- no persistent mesh control plane
|
|
253
331
|
- no need to route arbitrary traffic through a general encrypted network
|
|
254
332
|
|
|
255
|
-
Instead, `derphole` authorizes one session with a bearer token, uses DERP to
|
|
333
|
+
Instead, `derphole` authorizes one session with a bearer token, uses DERP to get
|
|
334
|
+
peers connected immediately, then promotes onto the best direct path it can
|
|
335
|
+
establish. See [Transport Model](#transport-model) and
|
|
336
|
+
[Security Model](#security-model).
|
|
256
337
|
|
|
257
|
-
For `listen/pipe`, `send/receive`, and `share/open`, this can beat routing the
|
|
338
|
+
For `listen/pipe`, `send/receive`, and `share/open`, this can beat routing the
|
|
339
|
+
same traffic through a WireGuard-based overlay because `derphole` optimizes one
|
|
340
|
+
active session instead of maintaining a whole private network. Not magic. Less
|
|
341
|
+
machinery.
|
|
258
342
|
|
|
259
343
|
## Why It Is Fast
|
|
260
344
|
|
|
261
|
-
Performance comes from transport shape:
|
|
345
|
+
Performance comes from the transport shape:
|
|
262
346
|
|
|
263
347
|
- DERP handles rendezvous and fallback, not preferred steady-state data.
|
|
264
|
-
- Sessions can start relayed, then promote in place to direct without
|
|
265
|
-
|
|
266
|
-
-
|
|
267
|
-
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
348
|
+
- Sessions can start relayed, then promote in place to direct without
|
|
349
|
+
restarting.
|
|
350
|
+
- `listen/pipe` and `send/receive` can scale across direct UDP lanes, run
|
|
351
|
+
path-rate probes, then use paced sending, adaptive rate control, and targeted
|
|
352
|
+
replay/repair. Fast links can run near WAN ceiling without forcing slower
|
|
353
|
+
links into the same send rate.
|
|
354
|
+
- Direct UDP payloads use AEAD with a per-session key derived from the bearer
|
|
355
|
+
secret. Headers stay visible for sequencing and repair; user bytes stay
|
|
356
|
+
encrypted and authenticated.
|
|
357
|
+
- `share/open` keeps QUIC stream multiplexing for service sharing, where many
|
|
358
|
+
independent TCP streams need one claimed session.
|
|
359
|
+
- Candidate discovery starts with local interfaces and cached mappings, then
|
|
360
|
+
refines in the background with STUN and port mapping refresh.
|
|
361
|
+
|
|
362
|
+
The practical result: move bytes early, keep relay fallback, and shift live
|
|
363
|
+
sessions to direct paths when ready.
|
|
271
364
|
|
|
272
365
|
## Security Model
|
|
273
366
|
|
|
274
|
-
Tokens are **bearer capabilities**. Anyone with a token can claim the matching
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
367
|
+
Tokens are **bearer capabilities**. Anyone with a token can claim the matching
|
|
368
|
+
session or tunnel until expiry, so share tokens over a trusted channel.
|
|
369
|
+
|
|
370
|
+
`derphole` session tokens expire after one hour. `derptun` server tokens default
|
|
371
|
+
to 180 days and can mint shorter-lived client tokens. Client tokens default to
|
|
372
|
+
90 days and cannot serve.
|
|
373
|
+
|
|
374
|
+
Local service registry entries are bearer secrets because they contain derptun
|
|
375
|
+
client tokens or derpssh invites. Protect the registry file like token files.
|
|
376
|
+
List output redacts token and invite values, and no lookup server is contacted
|
|
377
|
+
by default.
|
|
378
|
+
|
|
379
|
+
Payload bytes are always end-to-end encrypted between token holders. Session and
|
|
380
|
+
tunnel encryption is pinned to token-derived identity, so DERP relays do **not**
|
|
381
|
+
get keys needed to read or impersonate sessions. DERP can see routing metadata
|
|
382
|
+
and packet timing, but not plaintext user payload bytes:
|
|
383
|
+
|
|
384
|
+
- On `listen/pipe` and `send/receive`, direct UDP and relay fallback both encrypt
|
|
385
|
+
and authenticate user payloads with session AEAD derived from the bearer
|
|
386
|
+
secret.
|
|
387
|
+
- Relay-prefix startup frames leave frame kind and byte offsets visible for flow
|
|
388
|
+
control, but encrypt user payload bytes.
|
|
389
|
+
- On `share/open`, stream traffic uses authenticated QUIC streams for the
|
|
390
|
+
claimed session.
|
|
391
|
+
- On `derptun`, stream traffic uses authenticated QUIC streams pinned to the
|
|
392
|
+
stable tunnel identity in the token.
|
|
393
|
+
- On `derpssh`, terminal streams use authenticated QUIC streams pinned to the
|
|
394
|
+
invite identity.
|
|
395
|
+
|
|
396
|
+
Simple rule: token possession authorizes the session. Relays move packets; they
|
|
397
|
+
do not hold decrypt keys for user payloads.
|
|
285
398
|
|
|
286
399
|
## Behavior
|
|
287
400
|
|
|
288
|
-
Sessions can start on DERP relay and later promote to direct paths without
|
|
401
|
+
Sessions can start on DERP relay and later promote to direct paths without
|
|
402
|
+
restarting. By default, CLI output stays minimal. Use `--verbose` for path
|
|
403
|
+
changes, NAT traversal state, and direct-path tuning.
|
|
289
404
|
|
|
290
405
|
## Use Cases
|
|
291
406
|
|
|
407
|
+
Use this when you need:
|
|
408
|
+
|
|
292
409
|
- cross-host transfer with no account setup
|
|
293
|
-
- NAT-heavy networks where direct connectivity may or may not
|
|
410
|
+
- useful behavior on NAT-heavy networks where direct connectivity may or may not
|
|
411
|
+
work
|
|
294
412
|
- quick sharing of local web apps, APIs, and admin interfaces
|
|
295
|
-
- `npx`
|
|
413
|
+
- `npx` execution without manual install
|
|
414
|
+
|
|
415
|
+
Do not use this as a replacement for a real private network when you actually
|
|
416
|
+
need one. That is how small tools become infrastructure nobody remembers
|
|
417
|
+
owning. Oops.
|
|
296
418
|
|
|
297
419
|
## Development
|
|
298
420
|
|
|
@@ -331,13 +453,22 @@ REMOTE_HOST=my-server.example.com mise run promotion-1g
|
|
|
331
453
|
|
|
332
454
|
## What Is DERP?
|
|
333
455
|
|
|
334
|
-
DERP stands for **Designated Encrypted Relay for Packets**. It is a globally
|
|
456
|
+
DERP stands for **Designated Encrypted Relay for Packets**. It is a globally
|
|
457
|
+
reachable relay network that both peers can use when they cannot yet talk
|
|
458
|
+
directly.
|
|
335
459
|
|
|
336
|
-
DERP was built by Tailscale for the Tailscale networking stack. The public
|
|
460
|
+
DERP was built by Tailscale for the Tailscale networking stack. The public
|
|
461
|
+
Tailscale-operated DERP network is reachable without running your own relays.
|
|
462
|
+
Headscale, the open-source Tailscale control server, can also serve DERP maps
|
|
463
|
+
and DERP servers.
|
|
337
464
|
|
|
338
465
|
In `derphole`, DERP has two jobs:
|
|
339
466
|
|
|
340
|
-
- rendezvous: carry claim, decision, and direct-path coordination messages
|
|
341
|
-
|
|
467
|
+
- rendezvous: carry claim, decision, and direct-path coordination messages
|
|
468
|
+
without a separate account-backed control plane
|
|
469
|
+
- fallback relay: carry encrypted session traffic when NAT traversal has not
|
|
470
|
+
succeeded or direct connectivity is unavailable
|
|
342
471
|
|
|
343
|
-
DERP is not the preferred steady-state path. It starts the session and keeps it
|
|
472
|
+
DERP is not the preferred steady-state path. It starts the session and keeps it
|
|
473
|
+
working. If direct UDP becomes available, `derphole` promotes the live session.
|
|
474
|
+
DERP forwards bytes; it does not get session decrypt keys.
|
package/package.json
CHANGED
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|