v0.15.0
This release aligns the library with PROXY protocol spec 3.4 (2026/04/27). It tightens parsing and trust behavior to match the spec's requirements — which makes some previously accepted inputs and configurations fail loudly — and adds first-class support for the PROXY protocol over UDP.
⚠️ Breaking changes
The PROXY header is now required by default (2cd5f00)
- A new
DefaultPolicypackage variable, set toREQUIRE, is applied byNewConnandListener.Acceptwhen no policy is configured. The spec forbids guessing whether a header is present, so headerless connections now fail their firstReadwithErrNoProxyProtocol. - To restore the previous lax behavior:
proxyproto.DefaultPolicy = proxyproto.USE. TrustProxyHeaderFromis now strict: trusted peers getREQUIREand untrusted peers are dropped byAcceptwith an error wrappingErrInvalidUpstream. Previously, untrusted headerless clients could slip through as raw connections.
Stricter v1/v2 header parsing per spec 3.4 (5914db8)
- v1: the full
PROXYtoken is validated; IPv6 zone IDs are rejected; plain IPv4 addresses inTCP6lines are rejected (setV1AcceptIPv4InTCP6for nginx interop); ports are parsed with leading zeros rejected and ranges validated on formatting. - v2: the family/transport whitelist now applies to
LOCALcommands too, rejecting undefined bytes per spec 2.2.LOCALheaders with a valid address block decode addresses and TLVs and round-trip; ill-fitting ones are normalized toUNSPEC. - New
MaxV2HeaderSizevariable bounds the declared v2 length (default 4096) — raise it if you carry large TLVs such asPP2_SUBTYPE_SSL_CLIENT_CERT.
✨ New features
PROXY protocol over UDP (499ef90, fixes #79)
- New
ParseUDPDatagramandHeader.FormatUDPDatagramimplement the spec's per-datagram semantics (header and payload share a single datagram) for use with anynet.PacketConn. - The library deliberately ships no
net.PacketConnwrapper — reply routing needs an application-policy flow table — butexamples/udppacketconnis a runnable sketch of that pattern, alongsideexamples/udpserverandexamples/udpclientfor the plain paths.
Reworked trust policies (2cd5f00)
- New
PolicyFromRanges(ranges, matched, unmatched)andMustPolicyFromRangessupersede the whitelist policy family, which is deprecated and now delegates to them. The(REQUIRE, IGNORE)combination covers mixed proxied/direct traffic the old family couldn't express. - New CIDR-capable
TrustProxyHeaderFromRanges. - All built-in policies wrap address-classification failures in
ErrInvalidUpstream, so a single unclassifiable peer can no longer stop an accept loop.
TLV registry and PP2SSL caught up to spec 3.4 (4e80228)
Registered()now includesPP2_TYPE_GROUP,PP2_SUBTYPE_SSL_SIG_SCHEME, andPP2_SUBTYPE_SSL_CLIENT_CERT.- New
PP2SSLaccessors:SSLSigAlg,SSLKeyAlg,SSLGroup,SSLSigScheme.
🐛 Fixes
Header.EqualsTono longer panics on nil addresses (5914db8).formatVersion2folds TLV length into the declared length for Unix families instead of emitting TLVs past it (5914db8).
🧪 Testing & CI
- New fuzz/table suites: exhaustive 256-transport-byte sweeps for both v2 commands, a
LOCALdecode matrix, byte-for-byte round-trip stability, andFuzzReadparse–format–reparse invariants (5914db8). - CI gains a fuzz job that auto-discovers fuzz targets and uploads crashers as artifacts; workflow actions bumped across the board (af4b18c).
- Coverage for the http2
serveConnTLS handshake-failure branch (b01bea4).
📚 Documentation
- README rewritten against spec 3.4: new Security section with the spec's trust requirements, a UDP section, an examples table, and warnings about the new
REQUIREdefault (bd986c0).