Skip to content

v0.6.3

Latest

Choose a tag to compare

@github-actions github-actions released this 21 Oct 17:17
· 9 commits to main since this release

EQProxy v0.6.3 — 2026-10-21

Patch release closing the two defects found while measuring TLS parity: a
configuration that asked for HTTP/2 could pass the gate and then fail every
request, and the container had no writable state directory, so config apply
and config rollback always failed inside it. No wire behaviour of a valid
configuration changes.

Fixed

  • alpn = ["h2"] / ["h2c"] is rejected by the config gate instead of
    silently negotiating a protocol the dataplane cannot speak.
    With
    mode = "http" rustls completed the handshake for h2, then every request
    failed (curl exit 52) while the proxy counters showed
    client[accepted=0]. The error names the field, the cause and the fix
    (alpn = ["http/1.1"]), with the file/line context of the other gate
    errors. mode = "tcp" is untouched: it relays bytes without parsing them,
    so an h2 hint there is a legitimate tunnel choice. A backend TLS entry is
    rejected only when an HTTP-mode listener routes to that backend, because
    that listener only ever sends HTTP/1.1 over the connection.
  • config apply and config rollback work in the published image. The
    state directory defaulted to ./.eqproxy, which is / in the container,
    and uid 65532 cannot write there: both commands exited 1 with
    Permission denied. The runtime stage now ships
    /var/lib/eqproxy owned by 65532 and sets EQPROXY_STATE_DIR to it, so the
    commands work out of the box; mount a volume on that path to keep history
    across container replacements. The image also exposes 8443, the port the
    documented TLS listener uses.
  • Reports no longer panic when the reader closes the pipe. println!
    aborts on EPIPE, so eqproxy config explain | head (and any long report
    piped into grep -q, as the release script does) died with "failed
    printing to stdout: Broken pipe". Reports now go through a writer that
    treats a closed reader as success; the exit code stays 0.

Documentation

  • The Docker Hub page used the 0.6.1 tag in every example, named uid
    65534 for a file-readability requirement when the image runs as
    65532, and did not mention the state directory or volume. All three are
    corrected and the page points at v0.6.3.
  • The TLS parity report's note that alpn = ["h2"] "is accepted by the
    config gate" is now historical: v0.6.3 rejects it at validation time.
  • Erratum: the v0.6.1 parity report labelled one column "glibc", but that
    column ran the release asset — which is a static musl build — inside Debian.
    Both sides were the same binary, so the report measured the image base and
    the user, not libc. The erratum is at the top of
    docs/evidence/v0.6.1-parity/README.md; its "no measurable cost" result
    stands for packaging only.
  • TLS parity measured with genuinely built glibc binaries on both
    architectures (docs/evidence/v0.6.2-tls-parity/). Findings: ECDSA P-256
    termination works and is at parity on arm64 (−2.4 %, p 0.28) but the musl
    build is 20 % behind on amd64 under load (p 0.001) and 11 % behind with
    no TLS at all
    (p 0.0001), so the gap is libc-general, not handshake cost;
    TLS 1.2 sessions resume and TLS 1.3 ones do not (no ticketer is
    configured, so no ticket is ever sent); and HTTP/2 does not exist, while
    alpn = ["h2"] was accepted by the config gate (v0.6.3 rejects it) and
    negotiates a protocol the proxy cannot serve (curl exit 52, zero accepted
    connections).
  • The published Linux binaries are musl only, so the glibc build that carries
    the tier-1 performance claims is not the artifact users download. Shipping
    glibc variants is an open decision, not a claim.