From 4809f1f80ace9ae87b91453c8887c70f5e098bd0 Mon Sep 17 00:00:00 2001 From: Daniel Naylor Date: Sun, 21 Dec 2014 10:31:07 +0000 Subject: [PATCH] Update IP forwarding to ignore FML and other null character delimited tokens (for now) For Forge 1.8, a new \0FML\0 token is included in the handshake packet host field. Whilst from a Forge <-> Bungee standpoint, this is good in the long run (we can detect Forge/FML clients right from the off, allowing us to expose a reliable API for detecting modded 1.8+ clients), it plays havoc with IP forwarding on Spigot servers, as they expect a very specific format. Until we can look at improving this situation (probably by creating an updated IP forwarding protocol on the server side), this removes the FML marker from the handshake whenever IP forwarding is on. If you have a FML 1.8 network, IP forwarding MUST be off. With thanks to @geNAZt for finding the issue. --- .../main/java/net/md_5/bungee/ServerConnector.java | 7 +++++++ .../main/java/net/md_5/bungee/UserConnection.java | 9 +++++++++ .../net/md_5/bungee/connection/InitialHandler.java | 14 ++++++++++++++ .../net/md_5/bungee/forge/ForgeClientHandler.java | 12 +++++++++++- .../java/net/md_5/bungee/forge/ForgeConstants.java | 5 +++++ 5 files changed, 46 insertions(+), 1 deletion(-) diff --git a/proxy/src/main/java/net/md_5/bungee/ServerConnector.java b/proxy/src/main/java/net/md_5/bungee/ServerConnector.java index 9b1ac0fb..257606d6 100644 --- a/proxy/src/main/java/net/md_5/bungee/ServerConnector.java +++ b/proxy/src/main/java/net/md_5/bungee/ServerConnector.java @@ -92,6 +92,13 @@ public class ServerConnector extends PacketHandler } copiedHandshake.setHost( newHost ); } + else if ( !user.getExtraDataInHandshake().isEmpty() ) + { + // Only restore the extra data if IP forwarding is off. + // TODO: Add support for this data with IP forwarding. + copiedHandshake.setHost( copiedHandshake.getHost() + user.getExtraDataInHandshake() ); + } + channel.write( copiedHandshake ); channel.setProtocol( Protocol.LOGIN ); diff --git a/proxy/src/main/java/net/md_5/bungee/UserConnection.java b/proxy/src/main/java/net/md_5/bungee/UserConnection.java index e69544d1..936e6845 100644 --- a/proxy/src/main/java/net/md_5/bungee/UserConnection.java +++ b/proxy/src/main/java/net/md_5/bungee/UserConnection.java @@ -38,6 +38,7 @@ import net.md_5.bungee.chat.ComponentSerializer; import net.md_5.bungee.connection.InitialHandler; import net.md_5.bungee.entitymap.EntityMap; import net.md_5.bungee.forge.ForgeClientHandler; +import net.md_5.bungee.forge.ForgeConstants; import net.md_5.bungee.forge.ForgeServerHandler; import net.md_5.bungee.netty.ChannelWrapper; import net.md_5.bungee.netty.HandlerBoss; @@ -166,6 +167,9 @@ public final class UserConnection implements ProxiedPlayer } forgeClientHandler = new ForgeClientHandler( this ); + + // Set whether the connection has a 1.8 FML marker in the handshake. + forgeClientHandler.setFmlTokenInHandshake( this.getPendingConnection().getExtraDataInHandshake().contains( ForgeConstants.FML_HANDSHAKE_TOKEN ) ); } public void sendPacket(PacketWrapper packet) @@ -567,6 +571,11 @@ public final class UserConnection implements ProxiedPlayer title.send( this ); } + public String getExtraDataInHandshake() + { + return this.getPendingConnection().getExtraDataInHandshake(); + } + public void setCompressionThreshold(int compressionThreshold) { if ( this.compressionThreshold == -1 ) diff --git a/proxy/src/main/java/net/md_5/bungee/connection/InitialHandler.java b/proxy/src/main/java/net/md_5/bungee/connection/InitialHandler.java index 5bee22ca..8dfcc3cb 100644 --- a/proxy/src/main/java/net/md_5/bungee/connection/InitialHandler.java +++ b/proxy/src/main/java/net/md_5/bungee/connection/InitialHandler.java @@ -94,6 +94,8 @@ public class InitialHandler extends PacketHandler implements PendingConnection private LoginResult loginProfile; @Getter private boolean legacy; + @Getter + private String extraDataInHandshake = ""; private enum State { @@ -250,6 +252,18 @@ public class InitialHandler extends PacketHandler implements PendingConnection this.handshake = handshake; ch.setVersion( handshake.getProtocolVersion() ); + // Starting with FML 1.8, a "\0FML\0" token is appended to the handshake. This interferes + // with Bungee's IP forwarding, so we detect it, and remove it from the host string, for now. + // We know FML appends \00FML\00. However, we need to also consider that other systems might + // add their own data to the end of the string. So, we just take everything from the \0 character + // and save it for later. + if ( handshake.getHost().contains( "\0" ) ) + { + String[] split = handshake.getHost().split( "\0", 2 ); + handshake.setHost( split[0] ); + extraDataInHandshake = "\0" + split[1]; + } + // SRV records can end with a . depending on DNS / client. if ( handshake.getHost().endsWith( "." ) ) { diff --git a/proxy/src/main/java/net/md_5/bungee/forge/ForgeClientHandler.java b/proxy/src/main/java/net/md_5/bungee/forge/ForgeClientHandler.java index c624ee0c..ebde27ea 100644 --- a/proxy/src/main/java/net/md_5/bungee/forge/ForgeClientHandler.java +++ b/proxy/src/main/java/net/md_5/bungee/forge/ForgeClientHandler.java @@ -41,6 +41,14 @@ public class ForgeClientHandler private PluginMessage serverModList = null; private PluginMessage serverIdList = null; + /** + * Gets or sets a value indicating whether the '\00FML\00' token was found in + * the handshake. + */ + @Getter + @Setter + private boolean fmlTokenInHandshake = false; + /** * Handles the Forge packet. * @@ -143,12 +151,14 @@ public class ForgeClientHandler /** * Returns whether we know if the user is a forge user. + * In FML 1.8, a "FML" token is included in the initial handshake. + * We can use that to determine if the user is a Forge 1.8 user. * * @return true if the user is a forge user. */ public boolean isForgeUser() { - return clientModList != null; + return fmlTokenInHandshake || clientModList != null; } /** diff --git a/proxy/src/main/java/net/md_5/bungee/forge/ForgeConstants.java b/proxy/src/main/java/net/md_5/bungee/forge/ForgeConstants.java index e78bda6a..6dca2048 100644 --- a/proxy/src/main/java/net/md_5/bungee/forge/ForgeConstants.java +++ b/proxy/src/main/java/net/md_5/bungee/forge/ForgeConstants.java @@ -14,6 +14,11 @@ public class ForgeConstants public static final String FML_HANDSHAKE_TAG = "FML|HS"; public static final String FML_REGISTER = "REGISTER"; + /** + * The FML 1.8 handshake token. + */ + public static final String FML_HANDSHAKE_TOKEN = "\0FML\0"; + public static final PluginMessage FML_RESET_HANDSHAKE = new PluginMessage( FML_HANDSHAKE_TAG, new byte[] { -2, 0