proxyproto: add UDP session tracking for Cloudflare Spectrum PPv2#7967
Merged
Conversation
Cloudflare Spectrum's PROXY Protocol v2 for UDP sends the PPv2 header only
in first datagram. Subsequent datagrams from the same client arrive without
any header. The existing `PacketConn` processes each packet independently
with no session state, so it never associates the real client IP with
subsequent packets.
Add opt-in UDP session tracking to `PacketConn`: when a header-only datagram
arrives, cache the parsed source address keyed by the Spectrum-side remote
address in a fixed-capacity expirable LRU (hashicorp/golang-lru/v2/expirable,
default 10,240 entries). Subsequent headerless datagrams from the same
remote address are assigned the cached source address until the configurable
TTL expires. The TTL is refreshed on every matching packet.
The feature is enabled via a new Corefile directive:
```
proxyproto {
udp_session_tracking <ttl> [max_sessions]
}
```
For example, `udp_session_tracking 28s` uses a 28-second TTL matching
Spectrum's 30-second UDP idle timeout with headroom.
Signed-off-by: Minghang Chen <chen@minghang.dev>
21bbc42 to
f0f11b7
Compare
yongtang
approved these changes
Mar 28, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
1. Why is this pull request needed and what does it do?
Cloudflare Spectrum's PROXY Protocol v2 for UDP sends the PPv2 header only in the first datagram. Subsequent datagrams from the same client arrive without any header. The existing
PacketConnin plugin/pkg/proxyproto processes each UDP packet independently with no session state, so it never associates the real client IP with subsequent packets. This means plugins likewhoamireport the Spectrum proxy address rather than the actual client address for UDP queries.This PR adds opt-in UDP session tracking to
PacketConn: when a header-only datagram arrives, the parsed source address is cached keyed by the proxy-side remote address in a fixed-capacity expirable LRU (github.com/hashicorp/golang-lru/v2/expirable, default 10,240 entries). Subsequent headerless datagrams from the same remote address are assigned the cached source address until the configurable TTL expires. The TTL is refreshed on every matching packet.The feature is enabled via a new Corefile directive:
For example,
udp_session_tracking 28suses a 28-second TTL matching Spectrum's 30-second UDP idle timeout with headroom.TCP is unaffected —
proxyproto.Listeneralready handles TCP correctly since the header is at the start of the stream.2. Which issues (if any) are related?
Client IPs are lost for UDP DNS queries behind Spectrum after start using proxyproto plugin via CoreDNS 1.14.2.
3. Which documentation changes (if any) need to be made?
plugin/proxyproto/README.md has been updated in this PR to document the new udp_session_tracking directive, its parameters, and usage examples.
4. Does this introduce a backward incompatible change or deprecation?
No. The feature is entirely opt-in. When udp_session_tracking is absent from the Corefile, behavior is identical to before. No existing fields, methods, or directive syntax have been changed or removed.