MEHS / Knowledge base

MEHS - Multiplexed Encrypted Hybrid Stack

MEHS is a proxy/tunnel core for MehtorVPN. It carries TCP, UDP, and DNS traffic over an authenticated, encrypted TLS 1.3 session on TLS/TCP or QUIC, using the mehs-data/1 profile.

The protocol is evolving, and no independent security audit has been completed. Matching protocol numbers do not certify mixed-release compatibility. Use matching client and server packages. See the security policy before handling real user traffic.

Downloads and runtime requirements

Obtain prebuilt packages and SHA256SUMS.txt from Releases & downloads.

Package Contents
mehs-server-VERSION-linux-x86_64.tar.gz Server for Debian 13 Linux x86_64.
mehs-client-VERSION-linux-x86_64.tar.gz mehs, libmehs_client_ffi.so, C API header.
mehs-client-VERSION-windows-{x64,x86,arm64}.zip mehs.exe, mehs_client_ffi.dll, matching wintun.dll, C API header.
mehs-client-VERSION-android.zip jniLibs/{arm64-v8a,armeabi-v7a,x86_64}/{libmehs_client_ffi.so,libc++_shared.so}, C API header, NDK notices.
mehs-client-VERSION-ios.zip Device and universal simulator MEHS.xcframework, C API header.

Linux release binaries need the system C++ runtime (libstdc++6 on Debian). Compatibility with distributions older than Debian 13 is not certified. Windows requires the Microsoft Visual C++ v14 Redistributable matching the package architecture. Wintun must match the executable architecture.

Quick start

Prepare certificates, credentials, listener addresses, and policy using the server guide. Replace all sample credentials. On Debian/Linux:

sudo MEHS_SERVER_CONFIG=/etc/mehs/server.json ./mehs-server

Start the client in local proxy mode:

export MEHS_CLIENT_SECRET='your-client-secret'
./mehs --control vpn.example.com:8443 --client-id laptop --ca-file ca.pem \
  --socks-bind 127.0.0.1:1080 --http-bind 127.0.0.1:8080 --remote-dns

Start a system-wide TUN (root/administrator required; Windows needs wintun.dll beside mehs.exe):

sudo -E ./mehs --control vpn.example.com:8443 --client-id laptop --ca-file ca.pem \
  --mode tun --tun-exclude 192.168.0.0/16 --tun-exclude 10.0.0.0/8 \
  --tun-exclude 172.16.0.0/12

Adjust LAN exclusions for your network. Add --udp-associate in proxy mode for SOCKS5 calls or games. Remote DNS and SOCKS5 UDP are opt-in. TUN handles UDP and DNS transparently. For QUIC, use --transport quic --data vpn.example.com:8444. TUN routes are removed on exit. See all CLI options and recovery rules.

Operating principles and design targets

The host supplies configuration; MEHS owns upstream connections, transport selection, reconnect/recovery, session lifecycle, and local proxy listeners. Platform adapters integrate with the operating system. The following are design targets, not a claim that every target is verified on every platform.

An underlying TCP connection cannot become QUIC. Continuity means preserving logical-session traffic semantics over separate connections. No system can guarantee zero delay or loss through permanent server failure, process termination, device suspension, exhausted buffers, or indefinite network loss.

Transport modes

The default path is TLS 1.3 with ALPN mehs-data/1. QUIC uses its TLS 1.3 handshake. Older TLS versions must not be used as downgrade fallbacks.

Profile Carrier shape
mehs-data/1 Raw MEHS frames over TLS/TCP or QUIC.
trusttunnel HTTP CONNECT tunnel.
xhttp Streaming POST on http_path.
notmehs POST with x-padding; CONNECT tolerated; decoy page on other requests.

HTTP profiles use HTTP/2 over TCP or HTTP/3 over QUIC. A server may enable several profiles in transport_profiles and dispatch by ALPN. These are MEHS-native carriers, not compatible with third-party TrustTunnel/XHTTP servers or clients. Unknown profiles fail without fallback.

Connection workflow (design targets)

  1. Authorize: HTTPS POST validates supplied credentials and returns a random UUIDv4 session_id, a bearer token for one negotiation. Finalize within 120 seconds; never reuse it for another connection.
  2. Resolve policy: report the explicit transport or probe eligible automatic candidates. Server restrictions, overrides, and pins win; corrections or rejections must be explicit and reported to the host.
  3. Check connectivity: https://www.google.com/generate_204 is a proposed general reachability signal, not proof of MEHS health. Filtering, DNS, captive portals, and policy can affect it. Pair it with authenticated server-path checks.
  4. Probe: measure independent connections with multiple authenticated, nonce/request-ID-bound samples. Distinguish direct measurements from estimates. Use median RTT, robust jitter, loss, and enough transfer time/bytes for throughput.
  5. Choose and report: POST the selected mode and effective policy using the negotiation ID. Stability and loss matter more than peak throughput.
  6. Connect: automatic mode starts TCP and QUIC candidates concurrently, subject to server policy, with a 15-second setup window. One failed candidate is not server-wide failure while another path is healthy.
  7. Publish: distinguish a raw path ready to carry packets from a fully established selection workflow.
  8. Monitor: track path quality, keepalive, and health. A 30-second unhealthy-response interval triggers diagnostics; the design's terminal threshold is 15 consecutive seconds with no eligible server path, not a grace period extended by the health interval. Packaged-client reconnect behavior is specified in the CLI guide.
  9. Cache: retain selection for up to 24 hours, keyed to static configuration and effective policy. Invalidate on credentials, trust, configuration, policy, protocol, or transport-availability changes. A cache hit skips the full startup benchmark, never health monitoring or failure recovery.

Migration and delivery

Keep the active path while establishing and authenticating the candidate. Start new traffic on the candidate only when ready; continue draining the old path. A packet is delivered only after a MEHS acknowledgement. Retransmit unacknowledged data with stable per-direction sequence IDs; receivers deduplicate and reorder it.

Drain for at most 60 seconds. Move outstanding data before retiring the old path. If migration fails while TCP is still open, cancel the close timer and roll back. If no path remains, report failure and apply documented recovery policy. UDP-like traffic needs an explicit delivery policy; arbitrary retransmission must not duplicate externally visible datagrams. See transport migration and protocol reliability and bounds.

Configuration

Client JSON is strict schema 1: unknown fields are rejected, every accepted setting is applied, and startup validates the file. Configuration is immutable until disconnect/reconnect. Server policy always wins. is_hot_change_available controls only live TCP/QUIC migration, not arbitrary configuration reloads. See the authoritative reference and client example.

These are starting profiles, not measured universal optima. Validate against server policy and target networks.

Profile Mode / pool count Health / keepalive Drain Use
Balanced auto, 2 per carrier 30 / 15 s 60 s Everyday use.
Latency-sensitive auto, 2-3 per carrier 15-20 / 10 s 20-30 s Games and SSH; higher overhead.
Bandwidth-focused auto, 3-4 per carrier 30 / 15-20 s 60 s Benchmark-driven throughput.
TCP-only tcp_tls, TCP 1 / UDP 0 30 / 15 s Not applicable Blocked or degraded QUIC.
QUIC-pinned quic, 1 QUIC 20-30 / 15 s Not applicable Known reliable QUIC path.

More connections cost sockets, memory, probes, and server load; they do not automatically improve performance. Prevent flapping with sustained improvement thresholds and cooldowns. Static changes require a reconnect; the 24-hour cache must not suppress recovery after network changes. Keep credentials and trust material out of logs and treat the negotiation ID as short-lived, not the running tunnel's long-term identity.

Architecture and responsibilities

Application / OS adapter
        configuration + status
                  |
             MEHS core
  Protocol -- Session -- Transport manager
   Framing    Delivery    TCP/TLS / QUIC
                  |
      authenticated logical session
                  |
             Server / API

Protocol processing owns frame types, lengths, IDs, ACKs, version checks, negotiation, and errors. Session handling owns authorization, expiry, replay protection, delivery, reconnect, and migration. Transport management owns probes, policy, candidate creation, rollback, and drain. Server policy centrally restricts modes, overrides, and resources. Host adapters own OS-specific proxy/VPN integration. The older raw-IP packet bridge requires a remote gateway; the current TUN flow model does not.

Supported now and not yet

Maintainer-verified: TLS/TCP and QUIC; all three MEHS HTTP profiles; automatic selection and live migration; multiple links and failover; SOCKS5 CONNECT/UDP ASSOCIATE; HTTP CONNECT; remote DNS; Linux TUN over both carriers with route cleanup after forced termination; Windows TUN and proxy; Android arm64 proxy; automatic reconnect; multi-hour keepalive sessions.

Available but not runtime-verified: macOS TUN, Android host-descriptor TUN, and iOS Network Extension packet flow. Verification is feature-specific, not a promise for every device. Consult the support matrix.

Out of scope: third-party TrustTunnel/XHTTP wire compatibility and per-app routing on macOS, iOS, or Android TUN. Open assurance gaps: no independent security audit or stable cross-release wire guarantee.

Security notes

External HTTP(S) authorization

Set external_auth_url to delegate login checks to a trusted service. The server sends JSON POST fields username, password, and package version. Require a response like {"authorized": true, "username": "canonical-user"}; both fields are mandatory even on denial and extra fields are rejected. The returned name becomes the account identity; the submitted name stays bound to the data-channel handshake.

{
  "external_auth_url": "https://auth.example.com/mehs/authorize"
}

The complete server configuration still needs listeners, certificate/key paths, and policy. Local clients may be omitted when external authorization is enabled. Passwords remain only in session memory, not the local credential store. Use HTTPS: HTTP sends passwords without transport encryption. See the frozen authorization contract for denial responses, HTTP behavior, timeouts, and limits.