-
-
Notifications
You must be signed in to change notification settings - Fork 759
Add additional support for Proxy #5730
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Conversation
Tried to fix slice proxy protocol header and payload
retry to support all header mode
Based on many implementations of the proxy protocol, some applications send the proxy header as a standalone packet without payload, some applications add the proxy header to the first packet in the stream (which, unlike the first type, contains its own payload), and some applications prepend the proxy header to every packet. All header modes should now properly supported and functioning correctly.
ByteBuf content = packet.content(); | ||
GeyserBedrockPeer peer = (GeyserBedrockPeer) ctx.pipeline().get(BedrockPeer.NAME); | ||
int detectedVersion = peer != null ? -1 : ProxyProtocolDecoder.findVersion(content); | ||
ByteBuf content = packet.content().copy(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why's it copied now?
core/src/main/java/org/geysermc/geyser/network/netty/proxy/ProxyServerHandler.java
Outdated
Show resolved
Hide resolved
final HAProxyMessage decoded; | ||
try { | ||
if ((decoded = ProxyProtocolDecoder.decode(content, detectedVersion)) == null) { | ||
// PROXY header was not present in the packet, ignore. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why was this removed?
GeyserImpl.getInstance().getGeyserServer().getProxiedAddresses().put(packet.sender(), presentAddress); | ||
} else { | ||
log.trace("Reusing PROXY header: (from {}) {}", packet.sender(), presentAddress); | ||
// --- Subsequent packet processing logic --- | ||
int detectedVersion = ProxyProtocolDecoder.findVersion(content); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Given that this is used in both cases of the if block, this can be moved outside it to reduce code duplication
GeyserImpl.getInstance().getGeyserServer().getProxiedAddresses().put(packet.sender(), presentAddress); | ||
} else { | ||
log.trace("Reusing PROXY header: (from {}) {}", packet.sender(), presentAddress); | ||
// --- Subsequent packet processing logic --- |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
// --- Subsequent packet processing logic --- | |
// Some proxy protocol implementations always send the proxy protocol header, which we should strip after reading it in the first message |
Maybe also link the related issue here; that'd be useful too
// If a subsequent packet also contains a header, only strip it without using its content | ||
try { | ||
if (ProxyProtocolDecoder.decode(content, detectedVersion) == null) { | ||
content = packet.content(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
why is this re-assigning the content variable? This should already just be this value
} | ||
} catch (HAProxyProtocolException e) { | ||
log.debug("{} sent malformed subsequent PROXY header", packet.sender(), e); | ||
content = packet.content(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
why is this re-assigning the content variable? This should already just be this value
ctx.fireChannelRead(packet.retain()); | ||
// --- Unified packet reconstruction and forwarding logic --- | ||
// Regardless of whether the packet originally contained a header, `content` now represents the pure payload. | ||
// To ensure consistency in the behavior of downstream handlers, we always create a new packet instance to forward. | ||
// This avoids any issues that may arise from the difference in object instances between the original packet (retain) and a new packet. | ||
ByteBuf payloadOnly = content.copy(); | ||
DatagramPacket newPacket = new DatagramPacket(payloadOnly, packet.recipient(), packet.sender()); | ||
ctx.fireChannelRead(newPacket); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This diff doesn't seem to be of much use? The content is now a second copy of the packets' content, nor does the construction of a new datagram packet seem necessary
…xyServerHandler.java Co-authored-by: chris <github@onechris.mozmail.com>
Improves the logic for detecting, decoding, and stripping PROXY protocol headers from incoming packets. Ensures the buffer's reader index is managed correctly, avoids unnecessary buffer copies, and adds debug logging for malformed or incomplete headers. This change streamlines packet processing and reduces overhead by retaining and forwarding the original packet when possible.
Simplifies and restructures the logic for decoding and validating PROXY protocol v2 headers in UDP packets. Adds explicit whitelisting checks for proxier addresses using CIDR matchers, improves buffer handling by marking and resetting reader indices, and consolidates header decoding into a dedicated method for clarity and maintainability.
No description provided.