3
0
Mirror von https://github.com/PaperMC/Velocity.git synchronisiert 2024-12-23 23:00:35 +01:00

Add PROXY protocol support (#108)

Dieser Commit ist enthalten in:
Alex Thomson 2018-10-05 07:33:27 +13:00 committet von Andrew Steinborn
Ursprung d6fb3a210e
Commit 6ed772ba14
8 geänderte Dateien mit 40 neuen und 5 gelöschten Zeilen

Datei anzeigen

@ -29,6 +29,7 @@ dependencies {
compile project(':velocity-native')
compile "io.netty:netty-codec:${nettyVersion}"
compile "io.netty:netty-codec-haproxy:${nettyVersion}"
compile "io.netty:netty-codec-http:${nettyVersion}"
compile "io.netty:netty-handler:${nettyVersion}"
compile "io.netty:netty-transport-native-epoll:${nettyVersion}"

Datei anzeigen

@ -280,6 +280,10 @@ public class VelocityConfiguration extends AnnotatedConfig implements ProxyConfi
return advanced.getReadTimeout();
}
public boolean isProxyProtocol() {
return advanced.isProxyProtocol();
}
@Override
public String toString() {
return MoreObjects.toStringHelper(this)
@ -433,6 +437,9 @@ public class VelocityConfiguration extends AnnotatedConfig implements ProxyConfi
@Comment({"Specify a read timeout for connections here. The default is 30 seconds."})
@ConfigKey("read-timeout")
private int readTimeout = 30000;
@Comment("Enables compatibility with HAProxy.")
@ConfigKey("proxy-protocol")
private boolean proxyProtocol = false;
private Advanced() {
}
@ -444,6 +451,7 @@ public class VelocityConfiguration extends AnnotatedConfig implements ProxyConfi
this.loginRatelimit = toml.getLong("login-ratelimit", 3000L).intValue();
this.connectionTimeout = toml.getLong("connection-timeout", 5000L).intValue();
this.readTimeout = toml.getLong("read-timeout", 30000L).intValue();
this.proxyProtocol = toml.getBoolean("proxy-protocol", false);
}
}
@ -467,6 +475,10 @@ public class VelocityConfiguration extends AnnotatedConfig implements ProxyConfi
return readTimeout;
}
public boolean isProxyProtocol() {
return proxyProtocol;
}
@Override
public String toString() {
return "Advanced{" +
@ -475,6 +487,7 @@ public class VelocityConfiguration extends AnnotatedConfig implements ProxyConfi
", loginRatelimit=" + loginRatelimit +
", connectionTimeout=" + connectionTimeout +
", readTimeout=" + readTimeout +
", proxyProtocol=" + proxyProtocol +
'}';
}
}

Datei anzeigen

@ -12,12 +12,15 @@ import com.velocitypowered.proxy.protocol.StateRegistry;
import com.velocitypowered.proxy.protocol.netty.*;
import io.netty.buffer.ByteBuf;
import io.netty.channel.*;
import io.netty.handler.codec.haproxy.HAProxyMessage;
import io.netty.util.ReferenceCountUtil;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;
import java.net.InetSocketAddress;
import java.net.SocketAddress;
import java.security.GeneralSecurityException;
import static com.velocitypowered.proxy.network.Connections.*;
@ -30,6 +33,7 @@ public class MinecraftConnection extends ChannelInboundHandlerAdapter {
private static final Logger logger = LogManager.getLogger(MinecraftConnection.class);
private final Channel channel;
private SocketAddress remoteAddress;
private StateRegistry state;
private MinecraftSessionHandler sessionHandler;
private int protocolVersion;
@ -40,6 +44,7 @@ public class MinecraftConnection extends ChannelInboundHandlerAdapter {
public MinecraftConnection(Channel channel, VelocityServer server) {
this.channel = channel;
this.remoteAddress = channel.remoteAddress();
this.server = server;
this.state = StateRegistry.HANDSHAKE;
}
@ -77,6 +82,13 @@ public class MinecraftConnection extends ChannelInboundHandlerAdapter {
if (!pkt.handle(sessionHandler)) {
sessionHandler.handleGeneric((MinecraftPacket) msg);
}
} else if (msg instanceof HAProxyMessage) {
if (sessionHandler.beforeHandle()) {
return;
}
HAProxyMessage proxyMessage = (HAProxyMessage) msg;
this.remoteAddress = new InetSocketAddress(proxyMessage.sourceAddress(), proxyMessage.sourcePort());
} else if (msg instanceof ByteBuf) {
try {
if (sessionHandler.beforeHandle()) {
@ -153,6 +165,10 @@ public class MinecraftConnection extends ChannelInboundHandlerAdapter {
return !channel.isActive();
}
public SocketAddress getRemoteAddress() {
return remoteAddress;
}
public StateRegistry getState() {
return state;
}

Datei anzeigen

@ -122,7 +122,7 @@ public class ConnectedPlayer implements MinecraftConnectionAssociation, Player {
@Override
public InetSocketAddress getRemoteAddress() {
return (InetSocketAddress) connection.getChannel().remoteAddress();
return (InetSocketAddress) connection.getRemoteAddress();
}
@Override

Datei anzeigen

@ -77,7 +77,7 @@ public class HandshakeSessionHandler implements MinecraftSessionHandler {
return true;
}
InetAddress address = ((InetSocketAddress) connection.getChannel().remoteAddress()).getAddress();
InetAddress address = ((InetSocketAddress) connection.getRemoteAddress()).getAddress();
if (!server.getIpAttemptLimiter().attempt(address)) {
connection.closeWith(Disconnect.create(TextComponent.of("You are logging in too fast, try again later.")));
return true;
@ -129,7 +129,7 @@ public class HandshakeSessionHandler implements MinecraftSessionHandler {
@Override
public InetSocketAddress getRemoteAddress() {
return (InetSocketAddress) connection.getChannel().remoteAddress();
return (InetSocketAddress) connection.getRemoteAddress();
}
@Override

Datei anzeigen

@ -18,7 +18,7 @@ class InitialInboundConnection implements InboundConnection {
@Override
public InetSocketAddress getRemoteAddress() {
return (InetSocketAddress) connection.getChannel().remoteAddress();
return (InetSocketAddress) connection.getRemoteAddress();
}
@Override

Datei anzeigen

@ -101,7 +101,7 @@ public class LoginSessionHandler implements MinecraftSessionHandler {
byte[] decryptedSharedSecret = EncryptionUtils.decryptRsa(serverKeyPair, packet.getSharedSecret());
String serverId = EncryptionUtils.generateServerId(decryptedSharedSecret, serverKeyPair.getPublic());
String playerIp = ((InetSocketAddress) inbound.getChannel().remoteAddress()).getHostString();
String playerIp = ((InetSocketAddress) inbound.getRemoteAddress()).getHostString();
server.getHttpClient()
.get(new URL(String.format(MOJANG_SERVER_AUTH_URL, login.getUsername(), serverId, playerIp)))
.thenAcceptAsync(profileResponse -> {

Datei anzeigen

@ -20,6 +20,7 @@ import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioDatagramChannel;
import io.netty.channel.socket.nio.NioServerSocketChannel;
import io.netty.channel.socket.nio.NioSocketChannel;
import io.netty.handler.codec.haproxy.HAProxyMessageDecoder;
import io.netty.handler.timeout.ReadTimeoutHandler;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
@ -77,6 +78,10 @@ public final class ConnectionManager {
connection.setState(StateRegistry.HANDSHAKE);
connection.setSessionHandler(new HandshakeSessionHandler(connection, server));
ch.pipeline().addLast(Connections.HANDLER, connection);
if (server.getConfiguration().isProxyProtocol()) {
ch.pipeline().addFirst(new HAProxyMessageDecoder());
}
}
})
.childOption(ChannelOption.TCP_NODELAY, true)