Add support for PROXY protocol
This commit is contained in:
parent
a5ffeae757
commit
daac8d85e2
@ -3,15 +3,15 @@ package net.md_5.bungee.api.config;
|
||||
import java.net.InetSocketAddress;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import lombok.AccessLevel;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Data;
|
||||
import lombok.Getter;
|
||||
|
||||
/**
|
||||
* Class representing the configuration of a server listener. Used for allowing
|
||||
* multiple listeners on different ports.
|
||||
*/
|
||||
@Data
|
||||
@AllArgsConstructor
|
||||
public class ListenerInfo
|
||||
{
|
||||
|
||||
@ -67,6 +67,16 @@ public class ListenerInfo
|
||||
* Whether to enable udp query.
|
||||
*/
|
||||
private final boolean queryEnabled;
|
||||
/**
|
||||
* Whether to support HAProxy PROXY protocol.
|
||||
*/
|
||||
private final boolean proxyProtocol;
|
||||
|
||||
@Deprecated
|
||||
public ListenerInfo(InetSocketAddress host, String motd, int maxPlayers, int tabListSize, List<String> serverPriority, boolean forceDefault, Map<String, String> forcedHosts, String tabListType, boolean setLocalAddress, boolean pingPassthrough, int queryPort, boolean queryEnabled)
|
||||
{
|
||||
this( host, motd, maxPlayers, tabListSize, serverPriority, forceDefault, forcedHosts, tabListType, setLocalAddress, pingPassthrough, queryPort, queryEnabled, false );
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the highest priority server to join.
|
||||
|
@ -29,6 +29,12 @@
|
||||
<version>1.0.0</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>io.netty</groupId>
|
||||
<artifactId>netty-codec-haproxy</artifactId>
|
||||
<version>${netty.version}</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>io.netty</groupId>
|
||||
<artifactId>netty-codec-http</artifactId>
|
||||
|
@ -296,6 +296,11 @@ public class BungeeCord extends ProxyServer
|
||||
{
|
||||
for ( final ListenerInfo info : config.getListeners() )
|
||||
{
|
||||
if ( info.isProxyProtocol() )
|
||||
{
|
||||
getLogger().log( Level.WARNING, "Using PROXY protocol for listener {0}, please ensure this listener is adequately firewalled.", info.getHost() );
|
||||
}
|
||||
|
||||
ChannelFutureListener listener = new ChannelFutureListener()
|
||||
{
|
||||
@Override
|
||||
|
@ -452,7 +452,7 @@ public final class UserConnection implements ProxiedPlayer
|
||||
@Override
|
||||
public InetSocketAddress getAddress()
|
||||
{
|
||||
return (InetSocketAddress) ch.getHandle().remoteAddress();
|
||||
return ch.getRemoteAddress();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -247,6 +247,7 @@ public class YamlConfig implements ConfigurationAdapter
|
||||
boolean query = get( "query_enabled", false, val );
|
||||
int queryPort = get( "query_port", 25577, val );
|
||||
|
||||
boolean proxyProtocol = get( "proxy_protocol", false, val );
|
||||
List<String> serverPriority = new ArrayList<>( get( "priorities", Collections.EMPTY_LIST, val ) );
|
||||
|
||||
// Default server list migration
|
||||
@ -271,7 +272,7 @@ public class YamlConfig implements ConfigurationAdapter
|
||||
}
|
||||
set( "priorities", serverPriority, val );
|
||||
|
||||
ListenerInfo info = new ListenerInfo( address, motd, maxPlayers, tabListSize, serverPriority, forceDefault, forced, value.toString(), setLocalAddress, pingPassthrough, queryPort, query );
|
||||
ListenerInfo info = new ListenerInfo( address, motd, maxPlayers, tabListSize, serverPriority, forceDefault, forced, value.toString(), setLocalAddress, pingPassthrough, queryPort, query, proxyProtocol );
|
||||
ret.add( info );
|
||||
}
|
||||
|
||||
|
@ -574,7 +574,7 @@ public class InitialHandler extends PacketHandler implements PendingConnection
|
||||
@Override
|
||||
public InetSocketAddress getAddress()
|
||||
{
|
||||
return (InetSocketAddress) ch.getHandle().remoteAddress();
|
||||
return ch.getRemoteAddress();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -5,8 +5,10 @@ import io.netty.channel.Channel;
|
||||
import io.netty.channel.ChannelFutureListener;
|
||||
import io.netty.channel.ChannelHandler;
|
||||
import io.netty.channel.ChannelHandlerContext;
|
||||
import java.net.InetSocketAddress;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
import net.md_5.bungee.compress.PacketCompressor;
|
||||
import net.md_5.bungee.compress.PacketDecompressor;
|
||||
import net.md_5.bungee.protocol.MinecraftDecoder;
|
||||
@ -20,6 +22,9 @@ public class ChannelWrapper
|
||||
|
||||
private final Channel ch;
|
||||
@Getter
|
||||
@Setter
|
||||
private InetSocketAddress remoteAddress;
|
||||
@Getter
|
||||
private volatile boolean closed;
|
||||
@Getter
|
||||
private volatile boolean closing;
|
||||
@ -27,6 +32,7 @@ public class ChannelWrapper
|
||||
public ChannelWrapper(ChannelHandlerContext ctx)
|
||||
{
|
||||
this.ch = ctx.channel();
|
||||
this.remoteAddress = (InetSocketAddress) this.ch.remoteAddress();
|
||||
}
|
||||
|
||||
public void setProtocol(Protocol protocol)
|
||||
|
@ -4,8 +4,10 @@ import com.google.common.base.Preconditions;
|
||||
import io.netty.channel.ChannelHandlerContext;
|
||||
import io.netty.channel.ChannelInboundHandlerAdapter;
|
||||
import io.netty.handler.codec.DecoderException;
|
||||
import io.netty.handler.codec.haproxy.HAProxyMessage;
|
||||
import io.netty.handler.timeout.ReadTimeoutException;
|
||||
import java.io.IOException;
|
||||
import java.net.InetSocketAddress;
|
||||
import java.util.logging.Level;
|
||||
import net.md_5.bungee.api.ProxyServer;
|
||||
import net.md_5.bungee.connection.CancelSendSignal;
|
||||
@ -65,6 +67,20 @@ public class HandlerBoss extends ChannelInboundHandlerAdapter
|
||||
@Override
|
||||
public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception
|
||||
{
|
||||
if ( msg instanceof HAProxyMessage )
|
||||
{
|
||||
HAProxyMessage proxy = (HAProxyMessage) msg;
|
||||
InetSocketAddress newAddress = new InetSocketAddress( proxy.sourceAddress(), proxy.sourcePort() );
|
||||
|
||||
ProxyServer.getInstance().getLogger().log( Level.FINE, "Set remote address via PROXY {0} -> {1}", new Object[]
|
||||
{
|
||||
channel.getRemoteAddress(), newAddress
|
||||
} );
|
||||
|
||||
channel.setRemoteAddress( newAddress );
|
||||
return;
|
||||
}
|
||||
|
||||
if ( handler != null )
|
||||
{
|
||||
PacketWrapper packet = (PacketWrapper) msg;
|
||||
|
@ -16,6 +16,7 @@ import io.netty.channel.nio.NioEventLoopGroup;
|
||||
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 io.netty.util.AttributeKey;
|
||||
import io.netty.util.internal.PlatformDependent;
|
||||
@ -48,12 +49,19 @@ public class PipelineUtils
|
||||
@Override
|
||||
protected void initChannel(Channel ch) throws Exception
|
||||
{
|
||||
ListenerInfo listener = ch.attr( LISTENER ).get();
|
||||
|
||||
BASE.initChannel( ch );
|
||||
ch.pipeline().addBefore( FRAME_DECODER, LEGACY_DECODER, new LegacyDecoder() );
|
||||
ch.pipeline().addAfter( FRAME_DECODER, PACKET_DECODER, new MinecraftDecoder( Protocol.HANDSHAKE, true, ProxyServer.getInstance().getProtocolVersion() ) );
|
||||
ch.pipeline().addAfter( FRAME_PREPENDER, PACKET_ENCODER, new MinecraftEncoder( Protocol.HANDSHAKE, true, ProxyServer.getInstance().getProtocolVersion() ) );
|
||||
ch.pipeline().addBefore( FRAME_PREPENDER, LEGACY_KICKER, new KickStringWriter() );
|
||||
ch.pipeline().get( HandlerBoss.class ).setHandler( new InitialHandler( BungeeCord.getInstance(), ch.attr( LISTENER ).get() ) );
|
||||
ch.pipeline().get( HandlerBoss.class ).setHandler( new InitialHandler( BungeeCord.getInstance(), listener ) );
|
||||
|
||||
if ( listener.isProxyProtocol() )
|
||||
{
|
||||
ch.pipeline().addFirst( new HAProxyMessageDecoder() );
|
||||
}
|
||||
}
|
||||
};
|
||||
public static final Base BASE = new Base();
|
||||
|
Loading…
Reference in New Issue
Block a user