geforkt von Mirrors/Velocity
Add PROXY protocol support (#108)
Dieser Commit ist enthalten in:
Ursprung
d6fb3a210e
Commit
6ed772ba14
@ -29,6 +29,7 @@ dependencies {
|
|||||||
compile project(':velocity-native')
|
compile project(':velocity-native')
|
||||||
|
|
||||||
compile "io.netty:netty-codec:${nettyVersion}"
|
compile "io.netty:netty-codec:${nettyVersion}"
|
||||||
|
compile "io.netty:netty-codec-haproxy:${nettyVersion}"
|
||||||
compile "io.netty:netty-codec-http:${nettyVersion}"
|
compile "io.netty:netty-codec-http:${nettyVersion}"
|
||||||
compile "io.netty:netty-handler:${nettyVersion}"
|
compile "io.netty:netty-handler:${nettyVersion}"
|
||||||
compile "io.netty:netty-transport-native-epoll:${nettyVersion}"
|
compile "io.netty:netty-transport-native-epoll:${nettyVersion}"
|
||||||
|
@ -280,6 +280,10 @@ public class VelocityConfiguration extends AnnotatedConfig implements ProxyConfi
|
|||||||
return advanced.getReadTimeout();
|
return advanced.getReadTimeout();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean isProxyProtocol() {
|
||||||
|
return advanced.isProxyProtocol();
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return MoreObjects.toStringHelper(this)
|
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."})
|
@Comment({"Specify a read timeout for connections here. The default is 30 seconds."})
|
||||||
@ConfigKey("read-timeout")
|
@ConfigKey("read-timeout")
|
||||||
private int readTimeout = 30000;
|
private int readTimeout = 30000;
|
||||||
|
@Comment("Enables compatibility with HAProxy.")
|
||||||
|
@ConfigKey("proxy-protocol")
|
||||||
|
private boolean proxyProtocol = false;
|
||||||
|
|
||||||
private Advanced() {
|
private Advanced() {
|
||||||
}
|
}
|
||||||
@ -444,6 +451,7 @@ public class VelocityConfiguration extends AnnotatedConfig implements ProxyConfi
|
|||||||
this.loginRatelimit = toml.getLong("login-ratelimit", 3000L).intValue();
|
this.loginRatelimit = toml.getLong("login-ratelimit", 3000L).intValue();
|
||||||
this.connectionTimeout = toml.getLong("connection-timeout", 5000L).intValue();
|
this.connectionTimeout = toml.getLong("connection-timeout", 5000L).intValue();
|
||||||
this.readTimeout = toml.getLong("read-timeout", 30000L).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;
|
return readTimeout;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean isProxyProtocol() {
|
||||||
|
return proxyProtocol;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return "Advanced{" +
|
return "Advanced{" +
|
||||||
@ -475,6 +487,7 @@ public class VelocityConfiguration extends AnnotatedConfig implements ProxyConfi
|
|||||||
", loginRatelimit=" + loginRatelimit +
|
", loginRatelimit=" + loginRatelimit +
|
||||||
", connectionTimeout=" + connectionTimeout +
|
", connectionTimeout=" + connectionTimeout +
|
||||||
", readTimeout=" + readTimeout +
|
", readTimeout=" + readTimeout +
|
||||||
|
", proxyProtocol=" + proxyProtocol +
|
||||||
'}';
|
'}';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -12,12 +12,15 @@ import com.velocitypowered.proxy.protocol.StateRegistry;
|
|||||||
import com.velocitypowered.proxy.protocol.netty.*;
|
import com.velocitypowered.proxy.protocol.netty.*;
|
||||||
import io.netty.buffer.ByteBuf;
|
import io.netty.buffer.ByteBuf;
|
||||||
import io.netty.channel.*;
|
import io.netty.channel.*;
|
||||||
|
import io.netty.handler.codec.haproxy.HAProxyMessage;
|
||||||
import io.netty.util.ReferenceCountUtil;
|
import io.netty.util.ReferenceCountUtil;
|
||||||
import org.apache.logging.log4j.LogManager;
|
import org.apache.logging.log4j.LogManager;
|
||||||
import org.apache.logging.log4j.Logger;
|
import org.apache.logging.log4j.Logger;
|
||||||
|
|
||||||
import javax.crypto.SecretKey;
|
import javax.crypto.SecretKey;
|
||||||
import javax.crypto.spec.SecretKeySpec;
|
import javax.crypto.spec.SecretKeySpec;
|
||||||
|
import java.net.InetSocketAddress;
|
||||||
|
import java.net.SocketAddress;
|
||||||
import java.security.GeneralSecurityException;
|
import java.security.GeneralSecurityException;
|
||||||
|
|
||||||
import static com.velocitypowered.proxy.network.Connections.*;
|
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 static final Logger logger = LogManager.getLogger(MinecraftConnection.class);
|
||||||
|
|
||||||
private final Channel channel;
|
private final Channel channel;
|
||||||
|
private SocketAddress remoteAddress;
|
||||||
private StateRegistry state;
|
private StateRegistry state;
|
||||||
private MinecraftSessionHandler sessionHandler;
|
private MinecraftSessionHandler sessionHandler;
|
||||||
private int protocolVersion;
|
private int protocolVersion;
|
||||||
@ -40,6 +44,7 @@ public class MinecraftConnection extends ChannelInboundHandlerAdapter {
|
|||||||
|
|
||||||
public MinecraftConnection(Channel channel, VelocityServer server) {
|
public MinecraftConnection(Channel channel, VelocityServer server) {
|
||||||
this.channel = channel;
|
this.channel = channel;
|
||||||
|
this.remoteAddress = channel.remoteAddress();
|
||||||
this.server = server;
|
this.server = server;
|
||||||
this.state = StateRegistry.HANDSHAKE;
|
this.state = StateRegistry.HANDSHAKE;
|
||||||
}
|
}
|
||||||
@ -77,6 +82,13 @@ public class MinecraftConnection extends ChannelInboundHandlerAdapter {
|
|||||||
if (!pkt.handle(sessionHandler)) {
|
if (!pkt.handle(sessionHandler)) {
|
||||||
sessionHandler.handleGeneric((MinecraftPacket) msg);
|
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) {
|
} else if (msg instanceof ByteBuf) {
|
||||||
try {
|
try {
|
||||||
if (sessionHandler.beforeHandle()) {
|
if (sessionHandler.beforeHandle()) {
|
||||||
@ -153,6 +165,10 @@ public class MinecraftConnection extends ChannelInboundHandlerAdapter {
|
|||||||
return !channel.isActive();
|
return !channel.isActive();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public SocketAddress getRemoteAddress() {
|
||||||
|
return remoteAddress;
|
||||||
|
}
|
||||||
|
|
||||||
public StateRegistry getState() {
|
public StateRegistry getState() {
|
||||||
return state;
|
return state;
|
||||||
}
|
}
|
||||||
|
@ -122,7 +122,7 @@ public class ConnectedPlayer implements MinecraftConnectionAssociation, Player {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public InetSocketAddress getRemoteAddress() {
|
public InetSocketAddress getRemoteAddress() {
|
||||||
return (InetSocketAddress) connection.getChannel().remoteAddress();
|
return (InetSocketAddress) connection.getRemoteAddress();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -77,7 +77,7 @@ public class HandshakeSessionHandler implements MinecraftSessionHandler {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
InetAddress address = ((InetSocketAddress) connection.getChannel().remoteAddress()).getAddress();
|
InetAddress address = ((InetSocketAddress) connection.getRemoteAddress()).getAddress();
|
||||||
if (!server.getIpAttemptLimiter().attempt(address)) {
|
if (!server.getIpAttemptLimiter().attempt(address)) {
|
||||||
connection.closeWith(Disconnect.create(TextComponent.of("You are logging in too fast, try again later.")));
|
connection.closeWith(Disconnect.create(TextComponent.of("You are logging in too fast, try again later.")));
|
||||||
return true;
|
return true;
|
||||||
@ -129,7 +129,7 @@ public class HandshakeSessionHandler implements MinecraftSessionHandler {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public InetSocketAddress getRemoteAddress() {
|
public InetSocketAddress getRemoteAddress() {
|
||||||
return (InetSocketAddress) connection.getChannel().remoteAddress();
|
return (InetSocketAddress) connection.getRemoteAddress();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -18,7 +18,7 @@ class InitialInboundConnection implements InboundConnection {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public InetSocketAddress getRemoteAddress() {
|
public InetSocketAddress getRemoteAddress() {
|
||||||
return (InetSocketAddress) connection.getChannel().remoteAddress();
|
return (InetSocketAddress) connection.getRemoteAddress();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -101,7 +101,7 @@ public class LoginSessionHandler implements MinecraftSessionHandler {
|
|||||||
byte[] decryptedSharedSecret = EncryptionUtils.decryptRsa(serverKeyPair, packet.getSharedSecret());
|
byte[] decryptedSharedSecret = EncryptionUtils.decryptRsa(serverKeyPair, packet.getSharedSecret());
|
||||||
String serverId = EncryptionUtils.generateServerId(decryptedSharedSecret, serverKeyPair.getPublic());
|
String serverId = EncryptionUtils.generateServerId(decryptedSharedSecret, serverKeyPair.getPublic());
|
||||||
|
|
||||||
String playerIp = ((InetSocketAddress) inbound.getChannel().remoteAddress()).getHostString();
|
String playerIp = ((InetSocketAddress) inbound.getRemoteAddress()).getHostString();
|
||||||
server.getHttpClient()
|
server.getHttpClient()
|
||||||
.get(new URL(String.format(MOJANG_SERVER_AUTH_URL, login.getUsername(), serverId, playerIp)))
|
.get(new URL(String.format(MOJANG_SERVER_AUTH_URL, login.getUsername(), serverId, playerIp)))
|
||||||
.thenAcceptAsync(profileResponse -> {
|
.thenAcceptAsync(profileResponse -> {
|
||||||
|
@ -20,6 +20,7 @@ import io.netty.channel.socket.SocketChannel;
|
|||||||
import io.netty.channel.socket.nio.NioDatagramChannel;
|
import io.netty.channel.socket.nio.NioDatagramChannel;
|
||||||
import io.netty.channel.socket.nio.NioServerSocketChannel;
|
import io.netty.channel.socket.nio.NioServerSocketChannel;
|
||||||
import io.netty.channel.socket.nio.NioSocketChannel;
|
import io.netty.channel.socket.nio.NioSocketChannel;
|
||||||
|
import io.netty.handler.codec.haproxy.HAProxyMessageDecoder;
|
||||||
import io.netty.handler.timeout.ReadTimeoutHandler;
|
import io.netty.handler.timeout.ReadTimeoutHandler;
|
||||||
import org.apache.logging.log4j.LogManager;
|
import org.apache.logging.log4j.LogManager;
|
||||||
import org.apache.logging.log4j.Logger;
|
import org.apache.logging.log4j.Logger;
|
||||||
@ -77,6 +78,10 @@ public final class ConnectionManager {
|
|||||||
connection.setState(StateRegistry.HANDSHAKE);
|
connection.setState(StateRegistry.HANDSHAKE);
|
||||||
connection.setSessionHandler(new HandshakeSessionHandler(connection, server));
|
connection.setSessionHandler(new HandshakeSessionHandler(connection, server));
|
||||||
ch.pipeline().addLast(Connections.HANDLER, connection);
|
ch.pipeline().addLast(Connections.HANDLER, connection);
|
||||||
|
|
||||||
|
if (server.getConfiguration().isProxyProtocol()) {
|
||||||
|
ch.pipeline().addFirst(new HAProxyMessageDecoder());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.childOption(ChannelOption.TCP_NODELAY, true)
|
.childOption(ChannelOption.TCP_NODELAY, true)
|
||||||
|
Laden…
In neuem Issue referenzieren
Einen Benutzer sperren