diff --git a/protocol/src/main/java/org/geysermc/mcprotocollib/network/helper/NettyHelper.java b/protocol/src/main/java/org/geysermc/mcprotocollib/network/helper/NettyHelper.java index fdbee4c73..818ccca71 100644 --- a/protocol/src/main/java/org/geysermc/mcprotocollib/network/helper/NettyHelper.java +++ b/protocol/src/main/java/org/geysermc/mcprotocollib/network/helper/NettyHelper.java @@ -30,8 +30,10 @@ import org.slf4j.LoggerFactory; import java.net.Inet4Address; +import java.net.Inet6Address; import java.net.InetAddress; import java.net.InetSocketAddress; +import java.net.SocketAddress; import java.net.UnknownHostException; public class NettyHelper { @@ -102,12 +104,33 @@ public static void initializeHAProxySupport(Session session, Channel channel) { channel.pipeline().addLast("proxy-protocol-packet-sender", new ChannelInboundHandlerAdapter() { @Override public void channelActive(ChannelHandlerContext ctx) throws Exception { - InetSocketAddress remoteAddress = (InetSocketAddress) ctx.channel().remoteAddress(); - HAProxyProxiedProtocol proxiedProtocol = clientAddress.getAddress() instanceof Inet4Address ? HAProxyProxiedProtocol.TCP4 : HAProxyProxiedProtocol.TCP6; + HAProxyProxiedProtocol proxiedProtocol = getProxiedProtocol(clientAddress); + + SocketAddress remoteAddress = ctx.channel().remoteAddress(); + String destinationAddress; + int destinationPort; + if (remoteAddress instanceof InetSocketAddress inetRemoteAddress && getProxiedProtocol(inetRemoteAddress) == proxiedProtocol) { + destinationAddress = inetRemoteAddress.getAddress().getHostAddress(); + destinationPort = inetRemoteAddress.getPort(); + } else { + // Fill in arbitrary values for the destination address and port if the remote address is not of the same type + switch (proxiedProtocol) { + case TCP4 -> { + destinationAddress = "0.0.0.0"; + destinationPort = 0; + } + case TCP6 -> { + destinationAddress = "::"; + destinationPort = 0; + } + default -> throw new UnsupportedOperationException("Unsupported proxied protocol: " + proxiedProtocol); + }; + } + ctx.channel().writeAndFlush(new HAProxyMessage( HAProxyProtocolVersion.V2, HAProxyCommand.PROXY, proxiedProtocol, - clientAddress.getAddress().getHostAddress(), remoteAddress.getAddress().getHostAddress(), - clientAddress.getPort(), remoteAddress.getPort() + clientAddress.getAddress().getHostAddress(), destinationAddress, + clientAddress.getPort(), destinationPort )).addListener(future -> channel.pipeline().remove("proxy-protocol-encoder")); ctx.pipeline().remove(this); @@ -116,6 +139,16 @@ public void channelActive(ChannelHandlerContext ctx) throws Exception { }); } + private static HAProxyProxiedProtocol getProxiedProtocol(InetSocketAddress socketAddress) { + if (socketAddress.getAddress() instanceof Inet4Address) { + return HAProxyProxiedProtocol.TCP4; + } else if (socketAddress.getAddress() instanceof Inet6Address) { + return HAProxyProxiedProtocol.TCP6; + } else { + return HAProxyProxiedProtocol.UNKNOWN; + } + } + public static void addProxy(ProxyInfo proxy, ChannelPipeline pipeline) { if (proxy == null) { return;