Added frontend HAProxy support

This commit is contained in:
RaphiMC 2024-05-01 17:11:02 +02:00
parent 44987bf2d3
commit 0353a9323b
No known key found for this signature in database
GPG key ID: 0F6BB0657A03AC94
4 changed files with 75 additions and 0 deletions

View file

@ -58,6 +58,7 @@ public class ViaProxyConfig extends Config implements com.viaversion.viaversion.
private final OptionSpec<Boolean> optionBetacraftAuth;
private final OptionSpec<String> optionBackendProxyUrl;
private final OptionSpec<Boolean> optionBackendHaProxy;
private final OptionSpec<Boolean> optionFrontendHaProxy;
private final OptionSpec<Boolean> optionChatSigning;
private final OptionSpec<Integer> optionCompressionThreshold;
private final OptionSpec<Boolean> optionAllowBetaPinging;
@ -75,6 +76,7 @@ public class ViaProxyConfig extends Config implements com.viaversion.viaversion.
private boolean betacraftAuth = false;
private URI backendProxyUrl = null;
private boolean backendHaProxy = false;
private boolean frontendHaProxy = false;
private boolean chatSigning = true;
private int compressionThreshold = 256;
private boolean allowBetaPinging = false;
@ -97,6 +99,7 @@ public class ViaProxyConfig extends Config implements com.viaversion.viaversion.
this.optionBetacraftAuth = this.optionParser.accepts("betacraft-auth").withRequiredArg().ofType(Boolean.class).defaultsTo(this.betacraftAuth);
this.optionBackendProxyUrl = this.optionParser.accepts("backend-proxy-url").withRequiredArg().ofType(String.class).defaultsTo("");
this.optionBackendHaProxy = this.optionParser.accepts("backend-haproxy").withRequiredArg().ofType(Boolean.class).defaultsTo(this.backendHaProxy);
this.optionFrontendHaProxy = this.optionParser.accepts("frontend-haproxy").withRequiredArg().ofType(Boolean.class).defaultsTo(this.frontendHaProxy);
this.optionChatSigning = this.optionParser.accepts("chat-signing").withRequiredArg().ofType(Boolean.class).defaultsTo(this.chatSigning);
this.optionCompressionThreshold = this.optionParser.accepts("compression-threshold").withRequiredArg().ofType(Integer.class).defaultsTo(this.compressionThreshold);
this.optionAllowBetaPinging = this.optionParser.accepts("allow-beta-pinging").withRequiredArg().ofType(Boolean.class).defaultsTo(this.allowBetaPinging);
@ -126,6 +129,7 @@ public class ViaProxyConfig extends Config implements com.viaversion.viaversion.
this.betacraftAuth = this.getBoolean("betacraft-auth", this.betacraftAuth);
this.backendProxyUrl = this.parseProxyUrl(this.getString("backend-proxy-url", ""));
this.backendHaProxy = this.getBoolean("backend-haproxy", this.backendHaProxy);
this.frontendHaProxy = this.getBoolean("frontend-haproxy", this.frontendHaProxy);
this.chatSigning = this.getBoolean("chat-signing", this.chatSigning);
this.compressionThreshold = this.getInt("compression-threshold", this.compressionThreshold);
this.allowBetaPinging = this.getBoolean("allow-beta-pinging", this.allowBetaPinging);
@ -159,6 +163,7 @@ public class ViaProxyConfig extends Config implements com.viaversion.viaversion.
this.betacraftAuth = options.valueOf(this.optionBetacraftAuth);
this.backendProxyUrl = this.parseProxyUrl(options.valueOf(this.optionBackendProxyUrl));
this.backendHaProxy = options.valueOf(this.optionBackendHaProxy);
this.frontendHaProxy = options.valueOf(this.optionFrontendHaProxy);
this.chatSigning = options.valueOf(this.optionChatSigning);
this.compressionThreshold = options.valueOf(this.optionCompressionThreshold);
this.allowBetaPinging = options.valueOf(this.optionAllowBetaPinging);
@ -283,6 +288,15 @@ public class ViaProxyConfig extends Config implements com.viaversion.viaversion.
this.set("backend-haproxy", backendHaProxy);
}
public boolean useFrontendHaProxy() {
return this.frontendHaProxy;
}
public void setFrontendHaProxy(final boolean frontendHaProxy) {
this.frontendHaProxy = frontendHaProxy;
this.set("frontend-haproxy", frontendHaProxy);
}
public boolean shouldSignChat() {
return this.chatSigning;
}

View file

@ -19,6 +19,7 @@ package net.raphimc.viaproxy.proxy.client2proxy;
import io.netty.channel.Channel;
import io.netty.channel.ChannelHandler;
import io.netty.handler.codec.haproxy.HAProxyMessageDecoder;
import net.raphimc.netminecraft.constants.MCPipeline;
import net.raphimc.netminecraft.netty.connection.MinecraftChannelInitializer;
import net.raphimc.netminecraft.packet.registry.PacketRegistryUtil;
@ -31,6 +32,8 @@ import java.util.function.Supplier;
public class Client2ProxyChannelInitializer extends MinecraftChannelInitializer {
public static final String VIAPROXY_HAPROXY_DECODER_NAME = "viaproxy-haproxy-decoder";
public static final String VIAPROXY_HAPROXY_HANDLER_NAME = "viaproxy-haproxy-handler";
public static final String LEGACY_PASSTHROUGH_INITIAL_HANDLER_NAME = "legacy-passthrough-initial-handler";
public Client2ProxyChannelInitializer(final Supplier<ChannelHandler> handlerSupplier) {
@ -44,6 +47,10 @@ public class Client2ProxyChannelInitializer extends MinecraftChannelInitializer
return;
}
if (ViaProxy.getConfig().useFrontendHaProxy()) {
channel.pipeline().addLast(VIAPROXY_HAPROXY_DECODER_NAME, new HAProxyMessageDecoder());
channel.pipeline().addLast(VIAPROXY_HAPROXY_HANDLER_NAME, new HAProxyHandler());
}
if (ViaProxy.getConfig().shouldAllowLegacyClientPassthrough()) {
channel.pipeline().addLast(LEGACY_PASSTHROUGH_INITIAL_HANDLER_NAME, new LegacyPassthroughInitialHandler());
}

View file

@ -0,0 +1,51 @@
/*
* This file is part of ViaProxy - https://github.com/RaphiMC/ViaProxy
* Copyright (C) 2021-2024 RK_01/RaphiMC and contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package net.raphimc.viaproxy.proxy.client2proxy;
import io.netty.channel.AbstractChannel;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.SimpleChannelInboundHandler;
import io.netty.handler.codec.haproxy.HAProxyCommand;
import io.netty.handler.codec.haproxy.HAProxyMessage;
import net.lenni0451.reflect.stream.RStream;
import java.net.InetSocketAddress;
public class HAProxyHandler extends SimpleChannelInboundHandler<HAProxyMessage> {
@Override
public void channelActive(ChannelHandlerContext ctx) {
}
@Override
protected void channelRead0(ChannelHandlerContext ctx, HAProxyMessage message) throws Exception {
if (message.command() != HAProxyCommand.PROXY) {
throw new UnsupportedOperationException("Unsupported HAProxy command: " + message.command());
}
if (message.sourceAddress() != null) {
final InetSocketAddress sourceAddress = new InetSocketAddress(message.sourceAddress(), message.sourcePort());
if (ctx.channel() instanceof AbstractChannel) {
RStream.of(AbstractChannel.class, ctx.channel()).fields().by("remoteAddress").set(sourceAddress);
}
}
ctx.pipeline().remove(this);
super.channelActive(ctx);
}
}

View file

@ -36,6 +36,9 @@ backend-proxy-url: ""
# Send HAProxy protocol messages to the target server.
backend-haproxy: false
#
# Read HAProxy protocol messages from client connections.
frontend-haproxy: false
#
# Enables sending signed chat messages on >= 1.19 servers.
chat-signing: true
#