Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
63 commits
Select commit Hold shift + click to select a range
4ee171b
Define Nowhere protocol versions
yosebyte Aug 30, 2026
feb8712
Negotiate versions across client transports
yosebyte Aug 30, 2026
e93acb5
Isolate Portal sessions by protocol version
yosebyte Aug 30, 2026
fb3e523
Report negotiated wire versions
yosebyte Aug 30, 2026
95ed210
Document Nowhere 2.0 compatibility
yosebyte Aug 30, 2026
b4e5818
Bump version to 2.0.0-dev
yosebyte Aug 30, 2026
4d812e8
Merge branch 'main' into dev/2
yosebyte Sep 1, 2026
4c3c54b
Align telemetry identity with Nowhere 2
yosebyte Sep 1, 2026
04bd3b1
Define carrier-specific service endpoints
yosebyte Sep 5, 2026
a47401d
Route Vector through configured carriers
yosebyte Sep 5, 2026
d7f0974
Bind Portal carriers independently
yosebyte Sep 5, 2026
fa0e32b
Reject invalid service URLs early
yosebyte Sep 5, 2026
b702f5c
Document service endpoint configuration
yosebyte Sep 5, 2026
e62a859
Align endpoint fixtures with protocol ports
yosebyte Sep 5, 2026
d00fdea
Expand service endpoint documentation
yosebyte Sep 5, 2026
a2cb4d0
Document listener deployment behavior
yosebyte Sep 5, 2026
53ec045
Clarify endpoint interoperability contracts
yosebyte Sep 5, 2026
75237f7
Redesign Nowhere artwork
yosebyte Sep 6, 2026
203b969
Default native routes to TCP
yosebyte Sep 6, 2026
53be4f5
Cover TCP route defaults
yosebyte Sep 6, 2026
bcafd52
Document TCP route defaults
yosebyte Sep 6, 2026
2ba26a5
Cover independent route defaults and explicit Mux
yosebyte Sep 6, 2026
99068f2
Redesign TLS Mux flow control and relay path
yosebyte Sep 7, 2026
525a5c3
Adapt TLS Mux scheduling and buffer reuse
yosebyte Sep 7, 2026
cc3457a
Make nw2 the sole wire protocol
yosebyte Sep 8, 2026
ba30375
Add packet-level TLS Mux benchmark matrix
yosebyte Sep 8, 2026
17905d0
Record nw2 Mux smoke benchmark
yosebyte Sep 8, 2026
39906bb
Keep Mux benchmark tooling under tests
yosebyte Sep 8, 2026
cc5623a
Fix Mux shutdown waits and benchmark readiness
yosebyte Sep 8, 2026
f31276f
Rework TLS Mux pooling and stream admission
yosebyte Sep 8, 2026
34f8caa
Remove fixed application flow limits and grow QUIC stream credit
yosebyte Sep 8, 2026
68fc872
Remove completed Mux benchmark artifacts
yosebyte Sep 8, 2026
ae7653b
Restructure current protocol documentation
yosebyte Sep 8, 2026
b8c7780
Derive Morph transport keys
yosebyte Sep 9, 2026
79c2778
Add Morph TCP stream transform
yosebyte Sep 9, 2026
7dc448d
Add Morph UDP socket transform
yosebyte Sep 9, 2026
664eec5
Wire Morph into Portal and Vector
yosebyte Sep 9, 2026
496d526
Document Morph wire and security contracts
yosebyte Sep 9, 2026
5c20e31
Document Morph endpoint configuration
yosebyte Sep 9, 2026
60cd912
Refine project overview and data path
yosebyte Sep 9, 2026
8fb0d7f
Reseed Morph UDP nonces before exhaustion
yosebyte Sep 10, 2026
083f481
Avoid redundant Morph TCP transforms under backpressure
yosebyte Sep 10, 2026
50ed83e
Drop malformed Morph UDP receive records
yosebyte Sep 10, 2026
bc20074
Keep Morph regression helpers test-local
yosebyte Sep 10, 2026
03ba09b
Fix Morph regression test access and assertions
yosebyte Sep 10, 2026
956d268
Fuse Morph TCP copy and transform into reusable buffers
yosebyte Sep 10, 2026
96d7f2a
Fuse Morph UDP transforms and reuse initialized buffers
yosebyte Sep 10, 2026
7481020
Document Morph buffer reuse and fused transforms
yosebyte Sep 10, 2026
54ddf44
Constrain V2 flow IDs to 30 bits
yosebyte Sep 11, 2026
e899f6e
Shrink Mux frame headers to seven bytes
yosebyte Sep 11, 2026
fc65b9d
Pack QUIC UDP frames into 30-bit IDs
yosebyte Sep 11, 2026
7eb01fd
Document compact V2 frame layouts
yosebyte Sep 11, 2026
3fc6b96
Stabilize Mux full-duplex credit test
yosebyte Sep 11, 2026
df168c1
Bound Mux OPEN resource admission
yosebyte Sep 11, 2026
bda06e2
Bound Vector SOCKS ingress resources
yosebyte Sep 11, 2026
4b09656
Preserve reassembly state on admission failure
yosebyte Sep 11, 2026
a9c273c
Document V2 resource admission ceilings
yosebyte Sep 11, 2026
fead3ee
Bound pending Mux delivery across OPEN RESET churn
yosebyte Sep 11, 2026
6d7fa56
Chunk full-duplex test IO and isolate carrier failures
yosebyte Sep 11, 2026
6d08c9c
Bound Mux terminal delivery queue
yosebyte Sep 11, 2026
1449d24
Bound Portal flow claim admission
yosebyte Sep 11, 2026
4c777da
Document terminal and claim resource ceilings
yosebyte Sep 11, 2026
cfabb09
Normalize legacy Portal wildcard syntax
yosebyte Sep 11, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 23 additions & 1 deletion Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 3 additions & 2 deletions Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,15 +1,16 @@
[package]
name = "nowhere"
version = "1.8.3"
version = "2.0.0-dev"
edition = "2024"
description = "One-port, two-transport encrypted relay with independently split directions"
description = "Two-transport encrypted relay with independently split directions"
license = "GPL-3.0-only"
repository = "https://github.com/NodePassProject/Nowhere"
readme = "README.md"

[dependencies]
anyhow = "1.0.104"
bytes = "1.12.1"
chacha20 = "0.10.1"
chrono = { version = "0.4.45", default-features = false, features = ["clock"] }
crossterm = "0.29.0"
getrandom = "0.4.3"
Expand Down
196 changes: 110 additions & 86 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,48 +3,34 @@
</p>

<p align="center">
<strong>One port. Two transports. Split directions.</strong>
<strong>One relay. Two carriers. Independent directions.</strong>
</p>

<p align="center">
A cross-platform encrypted relay that composes TLS/TCP and QUIC/UDP<br>
independently for upload and download.
A cross-platform relay that composes TLS/TCP and QUIC/UDP<br>
independently for every flow.
</p>

<p align="center">
<a href="#live-operations">Live operations</a> &middot;
<a href="#how-it-works">Architecture</a> &middot;
<a href="#quick-start">Quick start</a> &middot;
<a href="#live-operations">Live operations</a> &middot;
<a href="docs/README.md">Documentation</a> &middot;
<a href="docs/protocol.md">Wire protocol</a>
</p>

Nowhere gives one service edge two encrypted carrier families. A local
**Vector** accepts SOCKS5 traffic; a remote **Portal** authenticates carriers,
opens targets, and relays data. Every logical flow chooses its uplink and
downlink independently instead of forcing both directions onto one transport.
Nowhere joins TLS/TCP and QUIC/UDP behind one service edge. **Vector** accepts
local SOCKS5 traffic; **Portal** authenticates carriers and reaches the target.
Each flow selects its uplink and downlink independently.

| Core property | What it means |
| --- | --- |
| One service edge | TLS/TCP and QUIC/UDP share one address, port number, credential, and lifecycle |
| Split directions | Uplink and downlink independently select TLS/TCP or QUIC/UDP |
| Complete ingress | SOCKS5 CONNECT carries TCP; UDP ASSOCIATE carries UDP |
| Native chaining | A Portal can forward directly to another Portal without a loopback SOCKS5 conversion |
| Local observability | The same binary discovers running instances and renders live telemetry metrics |

## Live operations

<p align="center">
<img src="assets/nowhere.gif" width="1280" alt="Nowhere TUI showing live traffic histories, connection and carrier metrics, privacy-aware access logs, runtime events, filtering, pause, and help">
</p>

The read-only TUI discovers Portal and Vector instances for the current user.
It presents traffic, carriers, process metrics, Access logs, and Runtime logs
without owning the service lifecycle. Start it from another terminal:

```bash
nowhere tui
```
| Unified edge | TLS/TCP and QUIC/UDP share one identity and lifecycle |
| Split routing | Uplink and downlink choose their carrier independently |
| Optional Morph | A keyed transform masks the TLS/QUIC wire image |
| TCP and UDP | SOCKS5 CONNECT and UDP ASSOCIATE are both supported |
| Native chaining | Portal forwards directly to Portal with no local proxy loop |
| Built-in telemetry | The same binary discovers and inspects live instances |

## How it works

Expand All @@ -68,51 +54,88 @@ nowhere tui
+------------+ +------------+
```

Portal defaults to `net=mix`, accepting both carrier families on the same port
number. `net=tcp` and `net=udp` intentionally restrict the listener when an
operator wants only one carrier family.
Each service URL uses either a compact endpoint for both carriers on one port,
or an explicit endpoint that assigns carriers, ports, and address families.

| Endpoint | Meaning |
|---|---|
| `@*:2000` | TLS/TCP and QUIC/UDP wildcard candidates, port 2000 |
| `@*/tcp:2006` | TLS/TCP only, IPv4 and IPv6 |
| `@*/udp:2017` | QUIC/UDP only, IPv4 and IPv6 |
| `@*/tcp4:2006/udp6:2017` | TLS/TCP on IPv4 and QUIC/UDP on IPv6 |

### One flow, two transport decisions
`*` is reserved for Portal listeners; Vector and `next` require a concrete
address or hostname. On Portal, `@:2000` is shorthand for `@*:2000`. The full
grammar is documented in [Configuration](docs/configuration.md).

Vector's `up` and `down` parameters accept `tcp`, `udp`, or `mix`:
### Independent uplink and downlink

`up` and `down` accept `tcp`, `udp`, or `mix`. With both carriers available,
the default is TCP; `mux=1` enables TLS multiplexing.

| `up` ↓ / `down` → | `tcp` | `udp` | `mix` |
|---|---|---|---|
| `tcp` | TT | TQ | TT ↔ TQ |
| `udp` | QT | QQ | QT ↔ QQ |
| `mix` | TT ↔ QT | TQ ↔ QQ | TT ↔ QQ |

T means TLS/TCP and Q means QUIC/UDP, with uplink first. Each mixed cell makes
one stateless 50/50 choice per flow; `mix/mix` produces only TT or QQ. The
primary route has a `NOW_MIX_FALLBACK_TIMEOUT` budget (default `1s`), then the
other route is attempted once with a new flow ID. FlowHeader carries only the
resolved concrete pair, and no fallback occurs after its write begins. Portal
`next=` applies the same policy independently per hop.
T is TLS/TCP and Q is QUIC/UDP, with uplink first. `mix` makes one 50/50 choice
per flow and may try the alternate route once before commitment. Portal
`next=` applies the same policy independently on each hop.

## Data path

## Engineered for a small data path
Authentication belongs to each physical carrier; routing belongs to each
logical flow. Once Portal returns `READY`, application data travels as a plain
byte stream or QUIC DATAGRAM payload.

The data path uses compact binary frames, connection-bound authentication,
reusable buffers, bounded queues, and native QUIC streams and DATAGRAMs. TLS
flows use dedicated lanes or lazily opened Mux Shards. Detailed framing and
resource bounds live in [Protocol](docs/protocol.md) and
[Security](docs/security.md).
```text
Carrier bootstrap Logical flow

+----------------+ +----------------+----------+-------------+
| AuthFrame | | FlowHeader | Target? | Payload ... |
| 32 bytes | | 5 bytes | variable | after READY |
+----------------+ +----------------+----------+-------------+
| |
+-- TLS: dedicated lane or Mux +-- TCP: reliable byte stream
+-- QUIC: first stream only +-- UDP: UoT or QUIC DATAGRAM
```

### Native Portal chaining
Frames are compact, DATA payload queues are bounded by byte credit, and hot-path
buffers are reused. See
[Protocol](docs/protocol.md) for the wire contract and
[Security](docs/security.md) for trust boundaries.

A relay Portal can terminate the incoming TLS/QUIC carrier and open the next
Nowhere flow directly with the same transport engine used by Vector:
### Morph

`morph=1` masks the bare TLS/QUIC wire image with a transform derived from the
shared key:

```text
TCP client -> server [ nonce 12B ][ ChaCha20-XOR(TLS stream) ]
server -> client [ ChaCha20-XOR(TLS stream) ]

UDP each datagram [ nonce 12B ][ ChaCha20-XOR(QUIC datagram) ]
```

Both endpoints on a hop must enable it. Morph is wire masking, with no protocol
camouflage or added security semantics. See [Protocol](docs/protocol.md).

### Native chaining

A Portal can open the next Nowhere hop directly:

```bash
nowhere \
'portal://relay-key@:2077?next=origin-key@origin.example:2077&up=udp&down=udp'
'portal://relay-key@:2000?next=origin-key@origin.example:2000&up=udp&down=udp'
```

`next` is lazy and mutually exclusive with outbound `socks`. Portal forwarding
uses the native flow protocol and is bounded to seven hops.
`next` is lazy, mutually exclusive with outbound `socks`, and bounded to seven
hops.

## Quick start

Building from source requires a supported target and a stable Rust toolchain.
Use a stable Rust toolchain on a supported target.

### 1. Build

Expand All @@ -122,62 +145,68 @@ cargo build --release --locked

### 2. Start Portal

The default `net=mix` mode accepts TLS/TCP and QUIC/UDP on port `2077`:
Listen on TLS/TCP and QUIC/UDP at port `2000`:

```bash
./target/release/nowhere 'portal://change-me@127.0.0.1:2077'
./target/release/nowhere 'portal://change-me@127.0.0.1:2000'
```

### 3. Start Vector

This Vector exposes SOCKS5 on `127.0.0.1:1080`:
Expose SOCKS5 on `127.0.0.1:1080`:

```bash
./target/release/nowhere \
'vector://change-me@127.0.0.1:2077?up=tcp&down=tcp&socks=127.0.0.1:1080'
'vector://change-me@127.0.0.1:2000?up=tcp&down=tcp&socks=127.0.0.1:1080'
```

Mux, split-carrier, certificate, and chaining examples are in the
[configuration guide](docs/configuration.md) and
[quick start](docs/quick-start.md).
More examples are available in [Configuration](docs/configuration.md) and the
[extended quick start](docs/quick-start.md).

### 4. Inspect

Open another terminal and run:
Open the local TUI from another terminal:

```bash
./target/release/nowhere tui
```

## Before public deployment
## Live operations

<p align="center">
<img src="assets/nowhere.gif" width="1280" alt="Nowhere TUI showing live traffic histories, connection and carrier metrics, privacy-aware access logs, runtime events, filtering, pause, and help">
</p>

The read-only TUI discovers local Portal and Vector instances and presents
traffic, carrier, process, and log data without controlling their lifecycle.

The local examples omit `sni`, which disables certificate verification. A
public Portal should use a CA-trusted certificate with strict verification:
## Public deployment

The local examples disable certificate verification by omitting `sni`. Public
deployments should use a trusted certificate and verified server name:

```bash
nowhere 'portal://change-me@:2077?tls=2&crt=/etc/nowhere/cert.pem&key=/etc/nowhere/key.pem'
nowhere 'vector://change-me@relay.example:2077?sni=relay.example&socks=127.0.0.1:1080'
nowhere 'portal://change-me@:2000?tls=2&crt=/etc/nowhere/cert.pem&key=/etc/nowhere/key.pem'
nowhere 'vector://change-me@relay.example:2000?sni=relay.example&socks=127.0.0.1:1080'
```

Certificate pinning is also available. Review the
[security model](docs/security.md) and [configuration](docs/configuration.md)
before exposing a Portal publicly.
Certificate pinning is also available. Review [Security](docs/security.md) and
[Configuration](docs/configuration.md) before exposing a Portal.

## Operational boundaries
## Platform scope

Portal, Vector, relay, TUI, and local discovery run on every supported
platform; process telemetry varies by operating system. See
[Platforms](docs/platforms.md) and [Operations](docs/operations.md).
Portal, Vector, relay, TUI, and discovery share the supported platform matrix;
process telemetry varies by operating system. See [Platforms](docs/platforms.md)
and [Operations](docs/operations.md).

## Documentation map
## Documentation

Start with the [documentation index](docs/README.md). It links the focused
guides for configuration, protocol, security, operations, platforms, and
integrations.
The [documentation index](docs/README.md) covers configuration, protocol,
security, operations, platforms, and integrations.

## Development

Run the project checks on a supported host:
Run the standard checks on a supported host:

```bash
cargo fmt --all -- --check
Expand All @@ -186,25 +215,20 @@ cargo clippy --all-targets --locked -- -D warnings
cargo build --release --locked
```

On macOS with [Apple Container](https://github.com/apple/container), the
reusable Linux check environment remains available:
On macOS, [Apple Container](https://github.com/apple/container) provides the
reusable Linux check environment:

```bash
./scripts/check-linux.sh
```

CI runs the project on Linux, macOS, and Windows. Release packaging covers
Linux GNU/musl on x86-64 and AArch64, macOS on Apple Silicon, and Windows
x86-64 MSVC.

Protocol changes must update the normative wire document and protocol-vector
tests in the same change.
CI covers Linux, macOS, and Windows. Release packaging covers Linux GNU/musl on
x86-64 and AArch64, macOS on Apple Silicon, and Windows x86-64 MSVC. Protocol
changes must update the wire document and protocol vectors together.

## License

Nowhere is licensed under the [GNU General Public License v3.0](LICENSE).
Distributions of original or modified binaries must comply with the GPLv3
source and notice requirements.

---

Expand Down
Binary file modified assets/nowhere.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading