Skip to content

Latest commit

 

History

History
838 lines (641 loc) · 36.3 KB

DEVELOPMENT_REPORT.md

File metadata and controls

838 lines (641 loc) · 36.3 KB

Network Accelerator: Development and Learning Blueprint

1. Purpose

This document describes how to build an educational network accelerator in small, measurable phases. The finished laboratory system consists of two Linux user-space agents:

  • an ingress agent near the application;
  • an egress agent near the destination; and
  • one authenticated, multiplexed QUIC session across the impaired WAN.

The first useful interface is a local SOCKS5 proxy for TCP applications. A transparent Linux TUN interface is deliberately deferred until the explicit proxy is correct and well measured.

The project is not intended to be sold or deployed as a production WAN appliance. It is a vehicle for learning network behavior, systems programming, measurement, and the difference between an attractive benchmark and a defensible result.

Central rule: a tunnel is not automatically an accelerator. A feature earns the name only when a repeatable experiment shows an improvement in a stated metric without unacceptable regressions in fairness, correctness, security, CPU use, or memory use.

2. What can and cannot be accelerated

2.1 The unavoidable propagation floor

Latency has several components:

total delay =
    propagation + transmission + serialization + queueing + processing

An accelerator cannot make radio waves or light travel faster. It can reduce avoidable round trips, use the available pipe more effectively, isolate independent flows from one another, recover from loss efficiently, and prevent queues from growing without bound.

2.2 Important terms

Round-trip time (RTT) is the time for a signal to reach the peer and for a response to return. Protocol handshakes and request/response exchanges often cost whole RTTs, so a 500 ms path makes even tiny sequential exchanges slow.

Bandwidth-delay product (BDP) is the amount of data needed in flight to fill a path:

BDP (bytes) = bandwidth (bits/s) * RTT (seconds) / 8

For a 100 Mbit/s path with 600 ms RTT, the BDP is 7.5 MB. A sender whose effective window is only 1 MB cannot fill that path, regardless of available bandwidth. Buffers should not simply be set to enormous values: excess buffering can create large queueing delay, commonly called bufferbloat.

Jitter is variation in delay. It makes timers and interactive behavior less predictable. Loss triggers retransmission and usually reduces a congestion controller's sending rate. Burst loss is generally more damaging than the same number of isolated losses.

Congestion means offered load exceeds a path's current capacity. Congestion control is a safety and fairness requirement, not an optional speed limiter. This project must never disable it to manufacture a benchmark win.

TCP slow start begins with a limited congestion window and grows it as acknowledgements arrive. A long RTT therefore slows convergence to the available capacity. Short transfers may finish before reaching full rate.

Acknowledgements (ACKs) provide evidence of delivery and drive loss detection, timers, and congestion-window growth. A delayed or bandwidth-constrained return path can reduce forward progress. ACK spoofing or acknowledging data before the far endpoint has accepted responsibility changes end-to-end failure semantics and is outside this project.

Head-of-line (HOL) blocking occurs when missing earlier data prevents later data from being delivered. Multiplexing many logical flows inside one TCP connection creates tunnel-wide HOL blocking: one lost TCP segment can stall every logical flow. QUIC uses independent streams, so loss normally blocks only streams whose data was in the lost packet, although all streams still share connection flow control and congestion capacity.

2.3 Satellite and asymmetric links

GEO satellite paths commonly have very high propagation delay. LEO paths generally have lower but more variable delay and may undergo path changes. Satellite links may also have:

  • a much slower return channel than forward channel;
  • intermittent or burst loss;
  • variable capacity and scheduling delay;
  • large BDP;
  • link-layer retransmission hidden from endpoints; and
  • periods of outage rather than independent random loss.

No single impairment profile represents all satellite systems. The laboratory therefore uses named, version-controlled test profiles, not claims that a single netem command accurately models every real link.

3. System architecture

 Application
     |
     | TCP via SOCKS5 on loopback
     v
+-------------------+                         +-------------------+
| Ingress agent     |                         | Egress agent      |
|                   |                         |                   |
| SOCKS parser      |                         | destination dialer|
| stream scheduler  |==== QUIC over UDP =====>| policy checks     |
| bounded buffers   |    impaired WAN         | bounded buffers   |
| metrics/logging   |<========================| metrics/logging   |
+-------------------+                         +-------------------+
                                                      |
                                                      | ordinary TCP
                                                      v
                                                Destination

The ingress accepts a SOCKS5 CONNECT request and preserves a domain name rather than resolving it locally. It opens one bidirectional QUIC stream and sends an OPEN message containing the target host and port. The egress applies its policy, resolves the name, connects to the destination, and returns OPEN_OK or OPEN_ERROR. Only after success does ingress return a successful SOCKS reply. Bytes then move in both directions with bounded buffering and backpressure.

One long-lived QUIC connection carries many TCP flows. A lost packet containing data for one stream does not impose TCP-tunnel-wide ordering on unrelated streams. This is useful, but not magic: the flows still compete for the same path and QUIC congestion window.

3.1 Components

Component Responsibility
accelerator-ingress SOCKS5 listener, QUIC client, local policy, stream scheduling
accelerator-egress QUIC listener, authentication, destination policy and TCP dialing
accelerator-bench Controlled payload generator/receiver and result metadata
wan-lab scripts Namespaces, routes, tc/netem profiles, cleanup and verification
common library Configuration, framing, bounded buffers, logging, metrics and errors
QUIC adapter RAII ownership and translation between MsQuic callbacks and application events

The selected QUIC implementation is MsQuic. It has a cross-platform C API, Linux support, TLS integration, bidirectional streams, and a documented callback execution model. C++ code should wrap its handles in small move-only RAII types. The adapter must not leak MsQuic callback threading into all business logic: callbacks enqueue compact events, while agent-owned executors advance connection state.

3.2 Trust boundaries

[untrusted local app] -> [ingress] -> encrypted/authenticated WAN
                                   -> [egress] -> [untrusted destination]
  • Bind SOCKS5 to loopback by default. Exposing it to a LAN would create an open proxy unless separate authentication and access controls are added.
  • Authenticate both agents with certificates in the laboratory. Encrypting without authenticating the expected peer is insufficient.
  • Treat SOCKS fields, tunnel frames, DNS results, configuration, and destination responses as untrusted.
  • Egress must deny loopback, link-local, private, metadata-service, multicast, and other configured ranges by default. Check the selected address again after DNS resolution to reduce SSRF and DNS-rebinding risk.
  • QUIC protects the WAN hop only. End-to-end TLS used by an application remains end-to-end; the accelerator must not intercept or forge it.

4. Why QUIC

WAN transport Advantages Problems Decision
One TCP/TLS tunnel Familiar sockets; simple prototype Tunnel-wide HOL blocking; nested TCP control loops can behave poorly under loss Build only as a baseline
Custom reliable UDP Complete control and high learning value Requires correct recovery, flow control, congestion control, packetization, anti-amplification, cryptography and key lifecycle Reject
QUIC library Secure handshake, multiplexed streams, loss recovery, flow and congestion control, path metrics Callback integration and dependency complexity; UDP may be blocked on some networks Selected

The project builds accelerator behavior above QUIC. It does not copy QUIC loss recovery pseudocode into a home-grown protocol. The TCP relay in Phase 2 remains valuable as a control: it demonstrates whether a later improvement comes from QUIC multiplexing rather than from unrelated code changes.

QUIC fallback over TCP is not part of the first roadmap. If UDP is unavailable, the agent should fail clearly; silently falling back would contaminate experiments.

5. Proposed interfaces

These interfaces are targets for later implementation, not existing commands.

5.1 Commands

# Start the far-side agent.
accelerator-egress --config config/egress.toml

# Start a local SOCKS5 listener.
accelerator-ingress --config config/ingress.toml

# Send application traffic through the accelerator.
curl --socks5-hostname 127.0.0.1:1080 https://example.com/

# Apply and later remove a versioned laboratory profile.
sudo ./scripts/wan-lab.sh apply profiles/geo-lossy.env
sudo ./scripts/wan-lab.sh status
sudo ./scripts/wan-lab.sh clear

# Run a recorded comparison.
accelerator-bench --scenario scenarios/mixed.toml --output results/run.json

--help, --version, and --check-config are required. Agents run in the foreground by default, return nonzero on configuration/startup failure, log to standard error, and shut down gracefully on SIGINT or SIGTERM.

5.2 Configuration

Use TOML and reject unknown keys so typographical mistakes cannot silently change an experiment.

schema_version = 1
role = "ingress"

[listen]
address = "127.0.0.1"
port = 1080

[peer]
host = "192.0.2.20"
port = 4433
server_name = "egress.lab"

[tls]
ca_file = "certs/lab-ca.pem"
certificate_file = "certs/ingress.pem"
private_key_file = "certs/ingress-key.pem"

[limits]
max_streams = 1024
max_buffered_bytes_per_stream = 262144
max_buffered_bytes_total = 67108864
connect_timeout_ms = 10000
idle_timeout_ms = 60000

[observability]
log_level = "info"
metrics_address = "127.0.0.1"
metrics_port = 9101

Secrets must not be accepted directly as command-line values because process arguments may be visible to other users. Validate numeric ranges, file permissions, role-specific keys, and the complete configuration before opening a listener.

5.3 Versioned tunnel protocol

Use a fixed-width network-byte-order header followed by a bounded payload:

 0                   1                   2                   3
 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+---------------+---------------+-------------------------------+
| Version (16)  | Type (16)     | Payload length (32)           |
+---------------+---------------+-------------------------------+
| Payload ...
+---------------------------------------------------------------+

Version 1 control types:

Type Direction Meaning
HELLO both, connection control stream Version and capability negotiation
HELLO_OK / HELLO_ERROR egress to ingress Negotiation outcome
OPEN ingress to egress, first stream frame Domain/IPv4/IPv6 target and port
OPEN_OK / OPEN_ERROR egress to ingress Dial result and stable error code
HALF_CLOSE either Sender will send no more application bytes
RESET either Abort stream with a stable reason code
PING / PONG control stream Application-level health measurement, not a QUIC replacement

Application data follows the successful OPEN exchange on the same bidirectional QUIC stream. It need not be wrapped in a frame per socket read; QUIC already provides an ordered byte stream. Parsers must handle split and coalesced frames, cap payload lengths before allocation, reject reserved bits, and close an incompatible connection with a protocol error.

Minor optional capabilities are negotiated as bits. An unknown mandatory capability or major version fails the handshake; unknown optional capabilities are ignored. Never reinterpret an existing field in place.

5.4 Connection lifecycle

App          Ingress                Egress              Destination
 | SOCKS hello  |                      |                      |
 |------------->|                      |                      |
 | method=noauth|                      |                      |
 |<-------------|                      |                      |
 | CONNECT name |                      |                      |
 |------------->| -- OPEN stream ---->| -- TCP connect ----->|
 |              |                      |<-- established ------|
 |              |<---- OPEN_OK --------|                      |
 | SOCKS success|                      |                      |
 |<-------------|                      |                      |
 |<========= bytes over TCP/QUIC/TCP in both directions ====>|
 | FIN          | -- HALF_CLOSE/FIN -->| -- shutdown(write) ->|

Cancel all pending work when its owning stream is reset. Preserve TCP half-close: EOF in one direction must not discard data still arriving in the other. If the QUIC connection dies, reset affected local sockets; do not claim transparent resumption. A later phase may reconnect the agent session for new flows, but replaying arbitrary live TCP bytes risks duplication and broken end-to-end semantics.

6. Resource management and fairness

Every queue must have a byte limit and an explicit full behavior. When the QUIC send side is blocked, stop reading the corresponding TCP socket. When a destination socket is blocked, stop consuming that stream. This backpressure should propagate to the original sender rather than accumulate memory.

Use per-stream and global limits. A simple first scheduler is deficit round robin with three policy classes:

  • interactive: small control and latency-sensitive streams;
  • normal: default;
  • bulk: sustained transfers.

Priority affects ordering only; every active stream receives service. Cap the interactive burst so it cannot starve bulk traffic. Do not infer priority from encrypted application contents. Initial classification is an explicit local rule by destination or SOCKS listener.

QUIC's congestion controller remains authoritative for the shared path. The accelerator schedules within the bytes the transport permits; it does not bypass congestion control.

Path MTU mistakes can create black holes, especially after adding tunnel overhead. Start with the QUIC implementation's conservative datagram sizing and path validation. Record datagram loss and avoid IP fragmentation. TUN mode later needs a deliberately smaller interface MTU and, where appropriate, TCP MSS adjustment.

7. Measurement laboratory

7.1 Topology

Use two network namespaces or two VMs, with impairment placed on the link between the agents. Keep the application's local leg and egress-to-destination leg clean unless the scenario explicitly studies them. Apply delay in both directions when the profile states an RTT; netem delay 300ms on only one direction is not the same experimental topology as 300 ms one-way on both.

Example illustrative profiles:

Profile Approximate RTT Rate Loss/jitter Purpose
clean <2 ms 1 Gbit/s none correctness and overhead
wan 80 ms 100 Mbit/s 5 ms jitter terrestrial WAN
leo-variable 80 ms 50 Mbit/s jitter + short outage variable path
geo 600 ms 25 Mbit/s down / 5 Mbit/s up none high BDP/asymmetry
geo-lossy 600 ms same random and burst loss recovery behavior
reordered 100 ms 50 Mbit/s controlled reorder parser/recovery robustness

These names are laboratory scenarios, not measurements of a particular provider. Store the exact commands, kernel version, queue discipline output, CPU model, agent commit, configuration hash, random seed, and UTC time with every result.

A Linux command might look like:

sudo tc qdisc replace dev wan0 root netem \
  delay 300ms 20ms distribution normal \
  loss 0.2% 25% \
  rate 25mbit

Production scripts must apply ingress and egress shaping intentionally, verify with tc -s qdisc show, and always provide idempotent cleanup. Combine queue disciplines carefully when exact rate and queue limits matter; netem is an emulator, not a complete satellite simulator.

7.2 Workloads

  1. Bulk: transfer a deterministic 1 GiB payload; report goodput, CPU, peak memory, retransmission/loss signals, and completion time.
  2. Small sequential requests: 1000 request/response exchanges of 1 KiB; report median, p90, p95 and p99 latency.
  3. Concurrent small flows: 100 independent connections; report completion-time distribution and failures.
  4. Mixed: one bulk flow plus periodic interactive 64-byte exchanges; report interactive tail latency and bulk throughput together.
  5. Asymmetric: repeat workloads with a constrained return path.
  6. Fault: introduce burst loss, temporary outage, reset, slow receiver and agent restart; report recovery behavior and correctness.

Use incompressible pseudorandom payloads by default. Add a separate compressible dataset only for compression experiments. Verify payload hashes at the receiver. Warm up first, randomize method order, run at least 10 measured repetitions, and report raw runs plus median and percentile summaries. Do not discard inconvenient runs without a recorded, predeclared reason.

Every optimization is compared against:

  • direct TCP with no agents;
  • the Phase 2 TCP relay;
  • QUIC tunnel with the optimization disabled; and
  • QUIC tunnel with the optimization enabled.

An improvement must identify its primary metric and guardrails before the run. For example: “reduce mixed-workload p95 interactive latency by at least 20% while bulk goodput falls by no more than 5%, with no errors and under 10% additional CPU.” Results that miss the threshold are still retained.

8. Phased implementation roadmap

Phase 1 — Reproducible measurement laboratory

Learn: RTT, BDP, queueing, directional impairment, experimental controls.

Build: namespace/VM topology; reversible netem profiles; benchmark sender/receiver; run metadata and JSON result schema.

Experiments: all baseline workloads over clean, WAN, GEO-like, asymmetric, lossy, burst-loss, and reordered profiles.

Deliverables: profile files, apply/status/clear script, topology diagram, baseline raw results, plotting notebook or script, and experiment README.

Exit criteria: repeated clean and impaired runs preserve payload hashes; applied delay/rate/loss is visible in measurements and tc statistics; cleanup restores the baseline; results include enough metadata to reproduce the run.

Known limitation: emulation cannot reproduce every satellite scheduler, radio state, or real-world cross traffic.

Next-phase prerequisite: trustworthy direct-connection baselines.

Phase 2 — Plain paired TCP relay

Learn: nonblocking sockets, event loops, framing, partial reads/writes, half-close, timeouts, RAII and graceful shutdown.

Build: paired C++20 ingress/egress relays over one TCP/TLS WAN connection; version handshake; one logical test flow initially; structured logs and counters.

Experiments: clean correctness, large payload, one-byte writes, slow receiver, half-close, abrupt disconnect, malformed/oversized frames.

Deliverables: CMake targets, unit/integration tests, configuration validator, protocol fixture files and benchmark comparison.

Exit criteria: no corruption or unbounded memory growth; sanitizer-clean test suite; deterministic error propagation; clean shutdown; documented TCP tunnel overhead. Make no acceleration claim.

Known limitation: one TCP tunnel creates tunnel-wide HOL blocking.

Next-phase prerequisite: stable application state machines independent of the underlying WAN transport.

Phase 3 — Authenticated QUIC tunnel

Learn: QUIC connection/stream model, callbacks, TLS identity, flow control, loss recovery and congestion signals.

Build: MsQuic RAII adapter; mutual authentication; ALPN netaccel/1; one QUIC stream per logical TCP flow; protocol negotiation; explicit connection and stream error mapping.

Experiments: multiple concurrent streams under isolated and burst loss; certificate rejection; incompatible version; UDP blocked; connection idle and shutdown.

Deliverables: QUIC adapter tests, development certificate script, packet-level trace instructions and TCP-relay comparison.

Exit criteria: unrelated streams continue under a lost-stream workload; untrusted certificates and ALPN mismatches fail closed; no handle leaks or callback-after-free; metrics distinguish transport and application failures.

Known limitation: QUIC avoids cross-stream ordering but shares congestion and connection-level flow-control limits.

Next-phase prerequisite: reliable creation and teardown of many QUIC streams.

Phase 4 — SOCKS5 TCP ingress

Learn: proxy negotiation, remote DNS, destination policy and translating failures between protocols.

Build: RFC 1928 no-authentication negotiation and CONNECT; IPv4, IPv6 and domain targets; domain forwarding to egress; accurate SOCKS replies; TCP half-close and connect timeout.

Experiments: curl --socks5-hostname; each address type; refused, unreachable, timeout and denied destinations; fragmented SOCKS messages; unsupported BIND and UDP ASSOCIATE.

Deliverables: SOCKS parser unit tests, end-to-end application tests and egress allow/deny policy.

Exit criteria: supported applications work without modification; domain names are resolved only at egress; unsupported commands receive correct failures; SOCKS binds to loopback by default.

Known limitation: applications must explicitly select the proxy; TCP only.

Next-phase prerequisite: trustworthy mapping of application sockets to QUIC streams.

Phase 5 — Multiplexing, scheduling and backpressure

Learn: queueing, fairness, flow-control interaction and overload behavior.

Build: bounded per-stream/global buffers; read throttling; deficit-round-robin scheduler; three explicit priority classes; stream and connection admission limits.

Experiments: bulk plus interactive workload; thousands of idle streams; slow destination; slow local app; connection flood; one priority class under constant load.

Deliverables: scheduler unit tests, memory-bound tests, queue metrics and fairness report.

Exit criteria: memory stays within configured bounds; overload rejects work cleanly; no active class starves; interactive tail latency improves against FIFO within its predeclared throughput guardrail.

Known limitation: static classification cannot infer an encrypted application's intent.

Next-phase prerequisite: stable queue and transport metrics.

Phase 6 — WAN tuning and adaptive policy

Learn: pacing, keepalive cost, idle state, hysteresis and measurement-driven control.

Build: connection reuse; safe keepalive/idle policy; metric sampling; bounded adaptation of scheduling/coalescing using smoothed RTT, loss, queue depth and goodput; reconnect for new streams.

Experiments: changing RTT/rate, intermittent outages, idle-then-burst traffic, flapping conditions and constrained return path.

Deliverables: documented policy states and thresholds, transition metrics, static-versus-adaptive results.

Exit criteria: adaptation is observable, bounded, stable under noisy samples, and no worse than the configured static fallback outside an accepted tolerance.

Known limitation: existing TCP connections are reset on QUIC session loss; they are not replayed.

Next-phase prerequisite: repeatable evidence that adaptation helps at least one profile without oscillation.

Phase 7 — Optional optimization experiments

Learn: workload dependence and why optimization must be opt-in and measurable.

Build independently: streaming compression for explicitly eligible plaintext; small-write coalescing with a strict maximum delay; destination-based bypass; experimental application-level FEC for selected messages.

Experiments: compressible and incompressible data; already-compressed formats; interactive writes; varying loss; CPU-constrained runs; FEC overhead versus recovery latency.

Deliverables: one feature flag and benchmark report per optimization.

Exit criteria: features default off; memory and latency are bounded; compression is never selected by inspecting secrets; each enabled feature passes its own predeclared benefit and guardrail thresholds.

Known limitations: TLS ciphertext is effectively incompressible; compression can leak information when attacker-controlled and secret data share a context; deduplication has similar confidentiality and memory risks; redundant FEC consumes capacity and must not replace congestion control.

Next-phase prerequisite: none of these features is required for the core accelerator.

Phase 8 — Observability and evaluation

Learn: service-level versus transport metrics, cardinality, reproducibility and honest comparisons.

Build: Prometheus text endpoint on loopback; stable metric definitions; structured JSON logs with correlation IDs; result comparison and plots.

Experiments: long soak, scrape overhead, counter reset, clock changes, many streams and failure injection.

Deliverables: metric catalog, sample dashboard, benchmark report containing positive and negative results.

Exit criteria: every failure is classifiable; metrics add negligible measured overhead; labels have bounded cardinality; no destination names, payloads, keys or tokens appear in default logs.

Known limitation: application-observed latency remains the source of truth; transport metrics alone do not prove a user-visible improvement.

Next-phase prerequisite: operational evidence sufficient for security and resilience testing.

Phase 9 — Resilience and security

Learn: threat modeling, identity lifecycle, resource exhaustion and fault containment.

Build: mutual certificate validation and rotation procedure; privilege drop; strict configuration and frame validation; destination ACLs; connection/rate limits; fuzz targets; fault-injection hooks.

Experiments: expired/wrong certificates; malformed frames; DNS rebinding; restricted destination; file-descriptor exhaustion; memory pressure; repeated connect/disconnect; process termination and restart.

Deliverables: threat model, certificate runbook, fuzz corpus, dependency inventory and resilience report.

Exit criteria: agents fail closed; fuzz/sanitizer runs find no known crash; resource limits preserve control-plane responsiveness; rotation works without disabling identity checks.

Known limitation: this is hardening for a lab, not a claim of production security or an external audit.

Next-phase prerequisite: a stable core before privileged TUN operation.

Phase 10 — Advanced TUN/IP mode

Learn: layer-3 routing, IP/UDP semantics, MTU, packet loops and privilege separation.

Build: optional Linux TUN frontend; IPv4 then IPv6; UDP datagram mapping; route-table isolation; interface MTU/MSS policy; loop prevention; a minimal privileged setup helper that hands the descriptor to an unprivileged agent.

Experiments: TCP and UDP; IPv4/IPv6; packets at MTU boundaries; PMTU black holes; fragmented input; route changes; tunnel endpoint exclusion; multiqueue scaling.

Deliverables: isolated namespace demo, routing/cleanup scripts, privilege model, packet tests and SOCKS-versus-TUN comparison.

Exit criteria: setup is reversible; accelerator traffic cannot recursively enter its own TUN route; oversized packets fail or adapt predictably; the main process runs without unnecessary privilege; SOCKS mode remains supported.

Known limitation: arbitrary IP transport greatly expands policy, security and compatibility scope and is still not a production VPN.

9. Metrics catalog

Use a netaccel_ prefix. Counters are monotonic; gauges describe current state; histograms use fixed, documented buckets.

Metric Type Meaning
netaccel_connections_total{result} counter QUIC connection outcomes
netaccel_active_streams gauge Current proxied streams
netaccel_streams_total{result} counter Stream outcomes with bounded result values
netaccel_bytes_total{direction} counter Application bytes accepted
netaccel_buffered_bytes{direction} gauge Current application queue occupancy
netaccel_queue_delay_seconds histogram Time waiting in the application scheduler
netaccel_stream_open_seconds histogram SOCKS request to destination result
netaccel_rtt_seconds gauge Latest smoothed transport RTT
netaccel_packets_lost_total counter Loss signal reported by QUIC
netaccel_goodput_bytes_total{direction} counter Useful delivered bytes
netaccel_compression_bytes_total{stage} counter Input/output bytes when enabled
netaccel_rejected_total{reason} counter Admission and policy rejection
netaccel_protocol_errors_total{type} counter Bounded protocol error classes

Never label metrics with stream IDs, domain names, IP addresses, certificate subjects, or error text. Those create unbounded cardinality or expose sensitive data. A short-lived correlation ID may appear in debug logs, not metric labels.

10. Proposed repository layout

Network-Accelerator/
├── CMakeLists.txt
├── README.md
├── cmake/
├── config/
│   ├── ingress.example.toml
│   └── egress.example.toml
├── docs/
│   ├── DEVELOPMENT_REPORT.md
│   ├── PROTOCOL.md
│   └── THREAT_MODEL.md
├── include/netaccel/
├── src/
│   ├── common/
│   ├── ingress/
│   ├── egress/
│   ├── protocol/
│   ├── quic/
│   └── socks/
├── tests/
│   ├── unit/
│   ├── integration/
│   ├── fuzz/
│   └── fixtures/
├── scripts/
├── profiles/
├── scenarios/
└── results/              # ignored raw local runs; curated reports are committed

Dependencies should be few and pinned:

  • C++20 compiler and CMake;
  • MsQuic for QUIC and TLS integration;
  • a small TOML parser;
  • a small formatting/logging library, or a single logging library that supplies both;
  • GoogleTest or Catch2 for tests;
  • Prometheus exposition implemented directly or via a small maintained library;
  • system tools ip, tc, ss, nstat, ethtool, and optionally tcpdump.

Use compiler warnings as errors in CI for project code, AddressSanitizer and UndefinedBehaviorSanitizer in tests, and ThreadSanitizer in a separate compatible job. Pin dependency revisions and record their licenses.

11. Test strategy and project-wide acceptance

Unit tests

Cover frame parsing, incremental SOCKS parsing, configuration validation, bounded queues, scheduler fairness, error mapping, address policy, state transitions, statistics and integer overflow. Table-test every truncated input and maximum length.

Integration tests

Run agents and echo/HTTP destinations in namespaces. Exercise clean links, delay, jitter, random and burst loss, reordering, bandwidth limits, asymmetric paths, slow readers, half-close, resets, certificate errors and incompatible versions.

Fuzz and dynamic analysis

Fuzz SOCKS, configuration and control-frame parsers. Run unit and integration tests with sanitizers. Use deterministic seeds in CI and retain new crashing inputs as regression fixtures.

System acceptance

The project is successful when:

  1. payload correctness holds in every supported scenario;
  2. resource use remains within configured bounds under overload;
  3. authentication and destination policy fail closed;
  4. direct, TCP-relay and QUIC results are reproducible and preserved;
  5. at least one defined WAN workload shows a statistically repeatable improvement against its predeclared guardrails;
  6. workloads that regress are documented rather than hidden; and
  7. no documentation claims reduced propagation delay or universal acceleration.

12. Feature matrix

Feature Phase Default at completion Evidence required
Reproducible WAN emulation 1 On in lab Profile verification and repeatability
TCP relay baseline 2 Test-only Correctness and overhead
QUIC multiplexing and mTLS 3 On Loss isolation and authentication
SOCKS5 CONNECT 4 On, loopback Application interoperability
Bounded fair scheduling 5 On Memory limits and mixed workload
Adaptive policy 6 Conservative Static comparison and stability
Compression 7 Off Dataset-specific gain and CPU guardrail
Coalescing 7 Off Latency/overhead trade-off
Bypass rules 7 Off Direct-versus-tunnel evidence
Experimental FEC 7 Off Loss-latency gain net of overhead
Metrics endpoint 8 Loopback Defined low-cardinality metrics
Hardened lab mode 9 On Threat and fault tests
TUN/IP mode 10 Off Routing, MTU and privilege tests

13. Common traps

  • Reporting socket write speed instead of receiver-verified goodput.
  • Comparing unlike congestion controllers, routes, warm-up states, or payloads.
  • Calling connection pooling “lower latency” without separating saved handshakes from steady-state transfer time.
  • Hiding retransmission or redundancy bytes when reporting throughput.
  • Applying netem in only one direction and labelling its delay as RTT.
  • Allowing queues to grow until a bulk test appears fast while interactive latency collapses.
  • Compressing encrypted or already-compressed data and ignoring CPU cost.
  • Retrying non-idempotent byte streams after reconnect and duplicating data.
  • Logging destination names or certificate details by default.
  • Treating QUIC streams as independent paths; they share a connection and path.

14. Glossary

Term Meaning
ACK Acknowledgement indicating received data or packets
ALPN TLS mechanism selecting the application protocol, here netaccel/1
BDP Bandwidth-delay product; bytes required in flight to fill a path
Congestion window Transport limit on unacknowledged data in flight
FEC Forward error correction; redundant data used to recover some loss
Goodput Correct application payload delivered per unit time
HOL blocking Later data waiting for earlier missing data
mTLS TLS in which both peers present authenticated certificates
MTU / PMTU Maximum packet size on an interface / complete path
PEP Performance-enhancing proxy
QUIC Secure UDP-based multiplexed transport
RAII C++ ownership pattern tying resource lifetime to object lifetime
RTT Round-trip time
SOCKS5 Application proxy protocol defined by RFC 1928
TUN Linux virtual layer-3 network interface exposed to user space

15. Primary references

Read the RFCs as protocol specifications and the implementation documentation for the exact pinned MsQuic release. Revisit dependency APIs and defaults when the project reaches Phase 3; they may change independently of this roadmap.