Skip to content

Define Nowhere protocol 2.0 and enhance Morph transport integration - #3

Merged
yosebyte merged 63 commits into
mainfrom
dev/2
Sep 11, 2026
Merged

yosebyte merged 63 commits into
mainfrom
dev/2

Conversation

@yosebyte

Copy link
Copy Markdown
Contributor

This pull request updates Nowhere to version 2.0.0-dev and significantly revises both the project documentation and public interface descriptions. The main focus is on clarifying terminology, improving the explanation of carrier and routing options, and introducing the new "Morph" feature for wire masking. The documentation is now more concise, better structured, and provides clearer guidance for configuration, deployment, and protocol details.

Documentation and Interface Clarifications

  • Updated the README.md to clarify terminology (e.g., "carrier" instead of "transport"), explain independent uplink/downlink routing, and provide improved quick start and operations instructions. Added a new section for the Morph feature, and restructured endpoint and data path explanations. [1] [2] [3] [4]
  • Revised the documentation index in docs/README.md for clearer mapping of user needs to documentation, and added a summary of endpoint grammar and usage. [1] [2]

Feature and Protocol Updates

  • Added the Morph feature, which uses ChaCha20 to mask the TLS/QUIC wire image when enabled on both endpoints. This is now described in the documentation and reflected in the dependency list. [1] [2]
  • Updated the protocol summary to reflect the new fixed ALPN (nw2) for Nowhere 2, and clarified the route-policy matrix and endpoint configuration rules.

Dependency and Metadata Changes

  • Bumped the crate version to 2.0.0-dev and added the chacha20 dependency in Cargo.toml to support the Morph feature.

Cleanup and Removal

  • Removed the outdated interoperability and protocol details from docs/compatibility.md, consolidating protocol and compatibility information in other documentation files.

These changes collectively modernize the documentation, clarify the product's capabilities, and introduce new features for the upcoming major release.

# Conflicts:
#	Cargo.lock
#	Cargo.toml
#	docs/README.md
#	docs/compatibility.md
#	docs/configuration.md
#	docs/operations.md
#	docs/quick-start.md
#	src/main.rs
#	src/vector/flow/tcp.rs
#	src/vector/udp_flow.rs
Copilot AI lite review requested due to automatic review settings September 11, 2026 06:18

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Changes recommended

Unresolved critical Mux/SOCKS admission findings and a moderate datagram-reassembly issue remain; the README statement also needs qualification.

Once you've addressed the issues Copilot identified, you can request another Copilot review.

Pull request overview

This PR defines the Nowhere 2.0.0-dev protocol, adds ChaCha20-based Morph masking, standardizes nw2 ALPN, and updates routing and operational documentation.

Changes:

  • Revised protocol, endpoint, routing, deployment, and compatibility documentation.
  • Added Morph transport integration and dependency metadata.
  • Reworked Mux, flow, portal, SOCKS, telemetry, and resource-management behavior.

Open findings: README.md has a nit (1 vote); Mux admission has critical findings (1 vote each); datagram reassembly has a moderate finding (1 vote); and SOCKS TCP/UDP admission has critical findings (2 votes each).

File summaries
File Review status
src/vector/udp_flow.rs Reviewed; no final finding.
src/vector/tls.rs Reviewed; no final finding.
src/vector/socks/server/udp.rs Critical finding (2 votes): retain bounded active-target admission.
src/vector/socks/server.rs Critical finding (2 votes): retain accepted-client resource admission.
src/vector/session/quic.rs Reviewed; no final finding.
src/vector/session.rs Reviewed; no final finding.
src/vector/mod.rs Reviewed; no final finding.
src/vector/flow/tcp.rs Reviewed; no final finding.
src/vector/flow.rs Reviewed; no final finding.
src/vector/flow_id.rs Reviewed; no final finding.
src/tui/render/feed.rs Reviewed; no final finding.
src/tui/model/types.rs Reviewed; no final finding.
src/tui/client/adapter.rs Reviewed; no final finding.
src/transport/quic.rs Reviewed; no final finding.
src/transport/owned_io.rs Reviewed; no final finding.
src/transport/morph.rs Reviewed; no final finding.
src/transport/mod.rs Reviewed; no final finding.
src/transport/buffers.rs Reviewed; no final finding.
src/tests/vector/tls.rs Reviewed; no final finding.
src/tests/vector/session.rs Reviewed; no final finding.
src/tests/vector/flow.rs Reviewed; no final finding.
src/tests/vector/flow_id.rs Reviewed; no final finding.
src/tests/vector.rs Reviewed; no final finding.
src/tests/tui/render.rs Reviewed; no final finding.
src/tests/tui/client.rs Reviewed; no final finding.
src/tests/transport/quic.rs Reviewed; no final finding.
src/tests/transport/owned_io.rs Reviewed; no final finding.
src/tests/transport/morph/keys.rs Reviewed; no final finding.
src/tests/transport/morph.rs Reviewed; no final finding.
src/tests/telemetry/ipc.rs Reviewed; no final finding.
src/tests/telemetry/hub.rs Reviewed; no final finding.
src/tests/protocol/flow.rs Reviewed; no final finding.
src/tests/protocol/auth.rs Reviewed; no final finding.
src/tests/portal/runtime.rs Reviewed; no final finding.
src/tests/portal/pairing/udp.rs Reviewed; no final finding.
src/tests/portal/pairing/replacement.rs Reviewed; no final finding.
src/tests/portal/pairing/rejection.rs Reviewed; no final finding.
src/tests/portal/pairing/lifecycle.rs Reviewed; no final finding.
src/tests/portal/pairing.rs Reviewed; no final finding.
src/tests/portal/listener.rs Reviewed; no final finding.
src/tests/portal/conn/support.rs Reviewed; no final finding.
src/tests/portal/conn/relay.rs Reviewed; no final finding.
src/tests/portal/conn/quic.rs Reviewed; no final finding.
src/tests/portal/conn/asymmetric.rs Reviewed; no final finding.
src/tests/portal/config.rs Reviewed; no final finding.
src/tests/mux/wire.rs Reviewed; no final finding.
src/tests/common/tls.rs Reviewed; no final finding.
src/tests/common/network.rs Reviewed; no final finding.
src/tests/common/endpoint.rs Reviewed; no final finding.
src/tests/common/config.rs Reviewed; no final finding.
src/tests/common/alpn.rs Reviewed; no final finding.
src/telemetry/wire.rs Reviewed; no final finding.
src/telemetry/mod.rs Reviewed; no final finding.
src/telemetry/ipc.rs Reviewed; no final finding.
src/telemetry/hub.rs Reviewed; no final finding.
src/protocol/util.rs Reviewed; no final finding.
src/protocol/mod.rs Reviewed; no final finding.
src/protocol/flow.rs Reviewed; no final finding.
src/protocol/datagram/reassembly.rs Moderate finding (1 vote): make reservation admission transactional.
src/protocol/datagram.rs Reviewed; no final finding.
src/protocol/auth.rs Reviewed; no final finding.
src/portal/runtime.rs Reviewed; no final finding.
src/portal/pairing/udp.rs Reviewed; no final finding.
src/portal/pairing/tcp.rs Reviewed; no final finding.
src/portal/pairing/state.rs Reviewed; no final finding.
src/portal/pairing/link.rs Reviewed; no final finding.
src/portal/pairing/lifecycle.rs Reviewed; no final finding.
src/portal/mode.rs Reviewed; no final finding.
src/portal/mod.rs Reviewed; no final finding.
src/portal/listener.rs Reviewed; no final finding.
src/portal/conn/tcp/mod.rs Reviewed; no final finding.
src/portal/conn/tcp/flow.rs Reviewed; no final finding.
src/portal/conn/session.rs Reviewed; no final finding.
src/portal/conn/session_datagram.rs Reviewed; no final finding.
src/portal/conn/relay_uot.rs Reviewed; no final finding.
src/portal/conn/relay_tcp.rs Reviewed; no final finding.
src/portal/conn/relay_stream.rs Reviewed; no final finding.
src/portal/conn.rs Reviewed; no final finding.
src/portal/config.rs Reviewed; no final finding.
src/mux/wire.rs Reviewed; no final finding.
src/mux/stream.rs Reviewed; no final finding.
src/mux/handle.rs Critical finding (1 vote): bound Mux OPEN admission before flow allocation.
src/common/tls.rs Reviewed; no final finding.
src/common/socks/config.rs Reviewed; no final finding.
src/common/network.rs Reviewed; no final finding.
src/common/mod.rs Reviewed; no final finding.
src/common/config.rs Reviewed; no final finding.
src/common/alpn.rs Reviewed; no final finding.
docs/security.md Reviewed; no final finding.
docs/README.md Reviewed; no final finding.
docs/quick-start.md Reviewed; no final finding.
docs/platforms.md Reviewed; no final finding.
docs/operations.md Reviewed; no final finding.
docs/interoperability.md Reviewed; no final finding.
docs/integrations.md Reviewed; no final finding.
docs/compatibility.md Reviewed; no final finding.
Cargo.toml Reviewed; no final finding.
Cargo.lock Reviewed; no final finding.
Review details

Suppressed comments (2)

README.md:105

  • The Mux incoming-stream channel is created with mpsc::unbounded_channel, and remote OPENs are queued before Portal acceptance. Thus this new statement is not true for all queues: a peer can grow the incoming OPEN queue and flow metadata without consuming byte credit. Either add bounded OPEN admission or qualify the documentation so operators do not infer a memory bound that is not implemented.
Frames are compact, queues are bounded, and hot-path buffers are reused. See
[Protocol](docs/protocol.md) for the wire contract and

src/protocol/datagram/reassembly.rs:162

  • This makes resource admission fallible, but push_with invokes reserve only after it may have evicted the oldest slot. The Portal and Vector callers use bounded semaphore reservations, so when that callback returns None, the packet is dropped while the valid partial packet has already been discarded; repeated queue-budget failures can flush in-progress datagrams without admitting any. Make the admission transactional (reserve before mutating the table, or restore/avoid eviction when reservation fails).
  • Files reviewed: 121/123 changed files
  • Comments generated: 4
  • Review effort level: Lite

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment thread src/mux/handle.rs Outdated
Comment thread src/mux/mod.rs Outdated
Comment thread src/vector/socks/server.rs
Comment thread src/vector/socks/server/udp.rs

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Changes recommended

Unbounded authenticated-flow admission and terminal queuing permit peer-driven memory and task exhaustion.

Once you've addressed the issues Copilot identified, you can request another Copilot review.

Review details
  • Files reviewed: 123/125 changed files
  • Comments generated: 2
  • Review effort level: Balanced

Comment thread src/mux/handle.rs Outdated
let (data_tx, data_rx) = mpsc::channel(config.outbound_frames);
let (terminal_tx, terminal_rx) = mpsc::channel(config.max_streams);
let (incoming_tx, incoming_rx) = mpsc::channel(config.max_streams);
let (terminal_tx, terminal_rx) = mpsc::unbounded_channel();
Comment thread src/portal/pairing.rs Outdated
Comment on lines +260 to +262
quinn::VarInt::from_u32(
live.saturating_add((live / 4).max(64))
.min(u32::MAX as usize) as u32,

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Note

Copilot was unable to run its full agentic suite in this review.

Pull request overview

Copilot reviewed 123 out of 125 changed files in this pull request and generated 1 comment.

Suppressed comments (4)

src/vector/tls.rs:1

  • Matching Some(ALPN) relies on a constant-in-pattern match for &[u8]. For clarity and to avoid subtle reference/value matching pitfalls, compare by bytes explicitly (e.g., Some(protocol) if protocol == ALPN). This also allows returning a more actionable error (e.g., include the negotiated ALPN in the message) when Some(_) is encountered.
    src/transport/quic.rs:1
  • The environment variable name is changed from NOW_QUIC_MEMORY_PROFILE to NOW_TRANSPORT_MEMORY_PROFILE, which is a breaking operational change for existing deployments and scripts. If backward compatibility is desired, consider reading the new variable first and falling back to the old name when absent (or emitting a one-time warning when the deprecated variable is used).
    src/vector/socks/server/udp.rs:1
  • Previously this map was created with a capacity hint based on the UDP flow limit (capped at 64). Switching to HashMap::new() may increase rehashing under load for many concurrent UDP targets. Consider restoring a small, bounded with_capacity (e.g., 64) or deriving the capacity from socks_udp_target_admission.available_permits().min(64).
    src/vector/flow_id.rs:1
  • The allocator no longer sizes the active HashSet up-front. If typical steady-state concurrency is known (e.g., on the order of a few thousand flows), using HashSet::with_capacity(...) can reduce reallocations and rehashing during bursts. If the previous min(4_096) sizing is still representative, consider restoring a similar initial capacity.

Comment thread src/common/endpoint.rs
Comment on lines +52 to +58
let host = url
.host_str()
.filter(|host| !host.is_empty())
.ok_or_else(|| anyhow!("{context}: missing host"))?
.trim_start_matches('[')
.trim_end_matches(']')
.to_owned();
@yosebyte
yosebyte merged commit df5391f into main Sep 11, 2026
3 checks passed
@yosebyte
yosebyte deleted the dev/2 branch September 11, 2026 10:48
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants