diff --git a/api/pom.xml b/api/pom.xml
index 30eef5dc..5d782001 100644
--- a/api/pom.xml
+++ b/api/pom.xml
@@ -43,5 +43,11 @@
${project.version}
compile
+
+ io.netty
+ netty-transport-native-unix-common
+ ${netty.version}
+ compile
+
diff --git a/api/src/main/java/net/md_5/bungee/Util.java b/api/src/main/java/net/md_5/bungee/Util.java
index 5e5b53a7..31101f6b 100644
--- a/api/src/main/java/net/md_5/bungee/Util.java
+++ b/api/src/main/java/net/md_5/bungee/Util.java
@@ -2,7 +2,9 @@ package net.md_5.bungee;
import com.google.common.base.Joiner;
import com.google.common.primitives.UnsignedLongs;
+import io.netty.channel.unix.DomainSocketAddress;
import java.net.InetSocketAddress;
+import java.net.SocketAddress;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.UUID;
@@ -21,15 +23,30 @@ public class Util
* @param hostline in the format of 'host:port'
* @return the constructed hostname + port.
*/
- public static InetSocketAddress getAddr(String hostline)
+ public static SocketAddress getAddr(String hostline)
{
- URI uri;
+ URI uri = null;
try
{
- uri = new URI( "tcp://" + hostline );
+ uri = new URI( hostline );
} catch ( URISyntaxException ex )
{
- throw new IllegalArgumentException( "Bad hostline: " + hostline, ex );
+ }
+
+ if ( uri != null && "unix".equals( uri.getScheme() ) )
+ {
+ return new DomainSocketAddress( uri.getPath() );
+ }
+
+ if ( uri == null || uri.getHost() == null )
+ {
+ try
+ {
+ uri = new URI( "tcp://" + hostline );
+ } catch ( URISyntaxException ex )
+ {
+ throw new IllegalArgumentException( "Bad hostline: " + hostline, ex );
+ }
}
if ( uri.getHost() == null )
diff --git a/api/src/main/java/net/md_5/bungee/api/ProxyServer.java b/api/src/main/java/net/md_5/bungee/api/ProxyServer.java
index 490a0944..1f330bd2 100644
--- a/api/src/main/java/net/md_5/bungee/api/ProxyServer.java
+++ b/api/src/main/java/net/md_5/bungee/api/ProxyServer.java
@@ -3,6 +3,7 @@ package net.md_5.bungee.api;
import com.google.common.base.Preconditions;
import java.io.File;
import java.net.InetSocketAddress;
+import java.net.SocketAddress;
import java.util.Collection;
import java.util.Map;
import java.util.UUID;
@@ -206,6 +207,18 @@ public abstract class ProxyServer
*/
public abstract ServerInfo constructServerInfo(String name, InetSocketAddress address, String motd, boolean restricted);
+ /**
+ * Factory method to construct an implementation specific server info
+ * instance.
+ *
+ * @param name name of the server
+ * @param address connectable Minecraft address + port of the server
+ * @param motd the motd when used as a forced server
+ * @param restricted whether the server info restricted property will be set
+ * @return the constructed instance
+ */
+ public abstract ServerInfo constructServerInfo(String name, SocketAddress address, String motd, boolean restricted);
+
/**
* Returns the console overlord for this proxy. Being the console, this
* command server cannot have permissions or groups, and will be able to
diff --git a/api/src/main/java/net/md_5/bungee/api/config/ListenerInfo.java b/api/src/main/java/net/md_5/bungee/api/config/ListenerInfo.java
index 42b84063..71abdc87 100644
--- a/api/src/main/java/net/md_5/bungee/api/config/ListenerInfo.java
+++ b/api/src/main/java/net/md_5/bungee/api/config/ListenerInfo.java
@@ -1,6 +1,7 @@
package net.md_5.bungee.api.config;
import java.net.InetSocketAddress;
+import java.net.SocketAddress;
import java.util.List;
import java.util.Map;
import lombok.AllArgsConstructor;
@@ -18,7 +19,7 @@ public class ListenerInfo
/**
* Host to bind to.
*/
- private final InetSocketAddress host;
+ private final SocketAddress socketAddress;
/**
* Displayed MOTD.
*/
@@ -102,4 +103,16 @@ public class ListenerInfo
{
return ( serverPriority.size() > 1 ) ? serverPriority.get( 1 ) : getDefaultServer();
}
+
+ /**
+ * Gets the bind address as an InetSocketAddress if possible.
+ *
+ * @return bind host
+ * @deprecated BungeeCord can listen via Unix domain sockets
+ */
+ @Deprecated
+ public InetSocketAddress getHost()
+ {
+ return (InetSocketAddress) socketAddress;
+ }
}
diff --git a/api/src/main/java/net/md_5/bungee/api/config/ServerInfo.java b/api/src/main/java/net/md_5/bungee/api/config/ServerInfo.java
index 19773843..d90e30a2 100644
--- a/api/src/main/java/net/md_5/bungee/api/config/ServerInfo.java
+++ b/api/src/main/java/net/md_5/bungee/api/config/ServerInfo.java
@@ -1,6 +1,7 @@
package net.md_5.bungee.api.config;
import java.net.InetSocketAddress;
+import java.net.SocketAddress;
import java.util.Collection;
import net.md_5.bungee.api.Callback;
import net.md_5.bungee.api.CommandSender;
@@ -26,9 +27,20 @@ public interface ServerInfo
* class.
*
* @return the IP and port pair for this server
+ * @deprecated BungeeCord can connect via Unix domain sockets
*/
+ @Deprecated
InetSocketAddress getAddress();
+ /**
+ * Gets the connectable address this server. Implementations
+ * expect this to be used as the unique identifier per each instance of this
+ * class.
+ *
+ * @return the address for this server
+ */
+ SocketAddress getSocketAddress();
+
/**
* Get the set of all players on this server.
*
diff --git a/api/src/main/java/net/md_5/bungee/api/connection/Connection.java b/api/src/main/java/net/md_5/bungee/api/connection/Connection.java
index bfafaa86..f59b49c7 100644
--- a/api/src/main/java/net/md_5/bungee/api/connection/Connection.java
+++ b/api/src/main/java/net/md_5/bungee/api/connection/Connection.java
@@ -1,6 +1,7 @@
package net.md_5.bungee.api.connection;
import java.net.InetSocketAddress;
+import java.net.SocketAddress;
import net.md_5.bungee.api.chat.BaseComponent;
import net.md_5.bungee.protocol.DefinedPacket;
@@ -16,9 +17,18 @@ public interface Connection
* Gets the remote address of this connection.
*
* @return the remote address
+ * @deprecated BungeeCord can accept connections via Unix domain sockets
*/
+ @Deprecated
InetSocketAddress getAddress();
+ /**
+ * Gets the remote address of this connection.
+ *
+ * @return the remote address
+ */
+ SocketAddress getSocketAddress();
+
/**
* Disconnects this end of the connection for the specified reason. If this
* is an {@link ProxiedPlayer} the respective server connection will be
diff --git a/api/src/test/java/net/md_5/bungee/api/ServerConnectRequestTest.java b/api/src/test/java/net/md_5/bungee/api/ServerConnectRequestTest.java
index 0d1f801a..3bae8064 100644
--- a/api/src/test/java/net/md_5/bungee/api/ServerConnectRequestTest.java
+++ b/api/src/test/java/net/md_5/bungee/api/ServerConnectRequestTest.java
@@ -1,6 +1,7 @@
package net.md_5.bungee.api;
import java.net.InetSocketAddress;
+import java.net.SocketAddress;
import java.util.Collection;
import net.md_5.bungee.api.config.ServerInfo;
import net.md_5.bungee.api.connection.ProxiedPlayer;
@@ -19,6 +20,12 @@ public class ServerConnectRequestTest
return null;
}
+ @Override
+ public SocketAddress getSocketAddress()
+ {
+ return null;
+ }
+
@Override
public InetSocketAddress getAddress()
{
diff --git a/api/src/test/java/net/md_5/bungee/util/AddressParseTest.java b/api/src/test/java/net/md_5/bungee/util/AddressParseTest.java
index 256c8d58..a0752255 100644
--- a/api/src/test/java/net/md_5/bungee/util/AddressParseTest.java
+++ b/api/src/test/java/net/md_5/bungee/util/AddressParseTest.java
@@ -1,6 +1,8 @@
package net.md_5.bungee.util;
+import io.netty.channel.unix.DomainSocketAddress;
import java.net.InetSocketAddress;
+import java.net.SocketAddress;
import java.util.Arrays;
import java.util.Collection;
import lombok.RequiredArgsConstructor;
@@ -44,6 +46,9 @@ public class AddressParseTest
},
{
"[0:0:0:0:0:0:0:1]:1337", "0:0:0:0:0:0:0:1", 1337
+ },
+ {
+ "unix:///var/run/bungee.sock", "/var/run/bungee.sock", -1
}
} );
}
@@ -54,8 +59,23 @@ public class AddressParseTest
@Test
public void test()
{
- InetSocketAddress parsed = Util.getAddr( line );
- Assert.assertEquals( host, parsed.getHostString() );
- Assert.assertEquals( port, parsed.getPort() );
+ SocketAddress parsed = Util.getAddr( line );
+
+ if ( parsed instanceof InetSocketAddress )
+ {
+ InetSocketAddress tcp = (InetSocketAddress) parsed;
+
+ Assert.assertEquals( host, tcp.getHostString() );
+ Assert.assertEquals( port, tcp.getPort() );
+ } else if ( parsed instanceof DomainSocketAddress )
+ {
+ DomainSocketAddress unix = (DomainSocketAddress) parsed;
+
+ Assert.assertEquals( host, unix.path() );
+ Assert.assertEquals( -1, port );
+ } else
+ {
+ throw new AssertionError( "Unknown socket " + parsed );
+ }
}
}
diff --git a/proxy/src/main/java/net/md_5/bungee/BungeeCord.java b/proxy/src/main/java/net/md_5/bungee/BungeeCord.java
index ad24d012..97568416 100644
--- a/proxy/src/main/java/net/md_5/bungee/BungeeCord.java
+++ b/proxy/src/main/java/net/md_5/bungee/BungeeCord.java
@@ -23,6 +23,7 @@ import java.io.FileReader;
import java.io.IOException;
import java.io.PrintStream;
import java.net.InetSocketAddress;
+import java.net.SocketAddress;
import java.text.MessageFormat;
import java.util.ArrayList;
import java.util.Collection;
@@ -304,7 +305,7 @@ public class BungeeCord extends ProxyServer
{
if ( info.isProxyProtocol() )
{
- getLogger().log( Level.WARNING, "Using PROXY protocol for listener {0}, please ensure this listener is adequately firewalled.", info.getHost() );
+ getLogger().log( Level.WARNING, "Using PROXY protocol for listener {0}, please ensure this listener is adequately firewalled.", info.getSocketAddress() );
if ( connectionThrottle != null )
{
@@ -321,24 +322,26 @@ public class BungeeCord extends ProxyServer
if ( future.isSuccess() )
{
listeners.add( future.channel() );
- getLogger().log( Level.INFO, "Listening on {0}", info.getHost() );
+ getLogger().log( Level.INFO, "Listening on {0}", info.getSocketAddress() );
} else
{
- getLogger().log( Level.WARNING, "Could not bind to host " + info.getHost(), future.cause() );
+ getLogger().log( Level.WARNING, "Could not bind to host " + info.getSocketAddress(), future.cause() );
}
}
};
new ServerBootstrap()
- .channel( PipelineUtils.getServerChannel() )
+ .channel( PipelineUtils.getServerChannel( info.getSocketAddress() ) )
.option( ChannelOption.SO_REUSEADDR, true ) // TODO: Move this elsewhere!
.childAttr( PipelineUtils.LISTENER, info )
.childHandler( PipelineUtils.SERVER_CHILD )
.group( eventLoops )
- .localAddress( info.getHost() )
+ .localAddress( info.getSocketAddress() )
.bind().addListener( listener );
if ( info.isQueryEnabled() )
{
+ Preconditions.checkArgument( info.getSocketAddress() instanceof InetSocketAddress, "Can only create query listener on UDP address" );
+
ChannelFutureListener bindListener = new ChannelFutureListener()
{
@Override
@@ -350,7 +353,7 @@ public class BungeeCord extends ProxyServer
getLogger().log( Level.INFO, "Started query on {0}", future.channel().localAddress() );
} else
{
- getLogger().log( Level.WARNING, "Could not bind to host " + info.getHost(), future.cause() );
+ getLogger().log( Level.WARNING, "Could not bind to host " + info.getSocketAddress(), future.cause() );
}
}
};
@@ -643,6 +646,12 @@ public class BungeeCord extends ProxyServer
@Override
public ServerInfo constructServerInfo(String name, InetSocketAddress address, String motd, boolean restricted)
+ {
+ return constructServerInfo( name, (SocketAddress) address, motd, restricted );
+ }
+
+ @Override
+ public ServerInfo constructServerInfo(String name, SocketAddress address, String motd, boolean restricted)
{
return new BungeeServerInfo( name, address, motd, restricted );
}
diff --git a/proxy/src/main/java/net/md_5/bungee/BungeeServerInfo.java b/proxy/src/main/java/net/md_5/bungee/BungeeServerInfo.java
index 3ff3446b..cab2c21b 100644
--- a/proxy/src/main/java/net/md_5/bungee/BungeeServerInfo.java
+++ b/proxy/src/main/java/net/md_5/bungee/BungeeServerInfo.java
@@ -6,6 +6,7 @@ import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelFutureListener;
import io.netty.channel.ChannelOption;
import java.net.InetSocketAddress;
+import java.net.SocketAddress;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
@@ -41,7 +42,7 @@ public class BungeeServerInfo implements ServerInfo
@Getter
private final String name;
@Getter
- private final InetSocketAddress address;
+ private final SocketAddress socketAddress;
private final Collection players = new ArrayList<>();
@Getter
private final String motd;
@@ -91,7 +92,7 @@ public class BungeeServerInfo implements ServerInfo
@Override
public int hashCode()
{
- return address.hashCode();
+ return socketAddress.hashCode();
}
@Override
@@ -122,6 +123,12 @@ public class BungeeServerInfo implements ServerInfo
}
}
+ @Override
+ public InetSocketAddress getAddress()
+ {
+ return (InetSocketAddress) socketAddress;
+ }
+
@Override
public void ping(final Callback callback)
{
@@ -147,11 +154,11 @@ public class BungeeServerInfo implements ServerInfo
}
};
new Bootstrap()
- .channel( PipelineUtils.getChannel() )
+ .channel( PipelineUtils.getChannel( socketAddress ) )
.group( BungeeCord.getInstance().eventLoops )
.handler( PipelineUtils.BASE )
.option( ChannelOption.CONNECT_TIMEOUT_MILLIS, 5000 ) // TODO: Configurable
- .remoteAddress( getAddress() )
+ .remoteAddress( socketAddress )
.connect()
.addListener( listener );
}
diff --git a/proxy/src/main/java/net/md_5/bungee/ConnectionThrottle.java b/proxy/src/main/java/net/md_5/bungee/ConnectionThrottle.java
index b6c66dce..39724a85 100644
--- a/proxy/src/main/java/net/md_5/bungee/ConnectionThrottle.java
+++ b/proxy/src/main/java/net/md_5/bungee/ConnectionThrottle.java
@@ -6,6 +6,8 @@ import com.google.common.cache.CacheBuilder;
import com.google.common.cache.CacheLoader;
import com.google.common.cache.LoadingCache;
import java.net.InetAddress;
+import java.net.InetSocketAddress;
+import java.net.SocketAddress;
import java.util.concurrent.TimeUnit;
public class ConnectionThrottle
@@ -38,14 +40,26 @@ public class ConnectionThrottle
this.throttleLimit = throttleLimit;
}
- public void unthrottle(InetAddress address)
+ public void unthrottle(SocketAddress socketAddress)
{
+ if ( !( socketAddress instanceof InetSocketAddress ) )
+ {
+ return;
+ }
+
+ InetAddress address = ( (InetSocketAddress) socketAddress ).getAddress();
int throttleCount = throttle.getUnchecked( address ) - 1;
throttle.put( address, throttleCount );
}
- public boolean throttle(InetAddress address)
+ public boolean throttle(SocketAddress socketAddress)
{
+ if ( !( socketAddress instanceof InetSocketAddress ) )
+ {
+ return false;
+ }
+
+ InetAddress address = ( (InetSocketAddress) socketAddress ).getAddress();
int throttleCount = throttle.getUnchecked( address ) + 1;
throttle.put( address, throttleCount );
diff --git a/proxy/src/main/java/net/md_5/bungee/ServerConnection.java b/proxy/src/main/java/net/md_5/bungee/ServerConnection.java
index d11d601e..06a0afd5 100644
--- a/proxy/src/main/java/net/md_5/bungee/ServerConnection.java
+++ b/proxy/src/main/java/net/md_5/bungee/ServerConnection.java
@@ -2,6 +2,7 @@ package net.md_5.bungee;
import com.google.common.base.Preconditions;
import java.net.InetSocketAddress;
+import java.net.SocketAddress;
import lombok.Getter;
import lombok.RequiredArgsConstructor;
import lombok.Setter;
@@ -65,6 +66,12 @@ public class ServerConnection implements Server
@Override
public InetSocketAddress getAddress()
+ {
+ return (InetSocketAddress) getSocketAddress();
+ }
+
+ @Override
+ public SocketAddress getSocketAddress()
{
return getInfo().getAddress();
}
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 cc171600..2ebfef5e 100644
--- a/proxy/src/main/java/net/md_5/bungee/ServerConnector.java
+++ b/proxy/src/main/java/net/md_5/bungee/ServerConnector.java
@@ -3,6 +3,7 @@ package net.md_5.bungee;
import com.google.common.base.Preconditions;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.ByteBufAllocator;
+import java.net.InetSocketAddress;
import java.util.Locale;
import java.util.Queue;
import java.util.Set;
@@ -96,7 +97,7 @@ public class ServerConnector extends PacketHandler
Handshake originalHandshake = user.getPendingConnection().getHandshake();
Handshake copiedHandshake = new Handshake( originalHandshake.getProtocolVersion(), originalHandshake.getHost(), originalHandshake.getPort(), 2 );
- if ( BungeeCord.getInstance().config.isIpForward() )
+ if ( BungeeCord.getInstance().config.isIpForward() && user.getSocketAddress() instanceof InetSocketAddress )
{
String newHost = copiedHandshake.getHost() + "\00" + user.getAddress().getHostString() + "\00" + user.getUUID();
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 5b72efea..3d7e9043 100644
--- a/proxy/src/main/java/net/md_5/bungee/UserConnection.java
+++ b/proxy/src/main/java/net/md_5/bungee/UserConnection.java
@@ -10,6 +10,7 @@ import io.netty.channel.ChannelInitializer;
import io.netty.channel.ChannelOption;
import io.netty.util.internal.PlatformDependent;
import java.net.InetSocketAddress;
+import java.net.SocketAddress;
import java.util.Collection;
import java.util.Collections;
import java.util.HashSet;
@@ -359,13 +360,13 @@ public final class UserConnection implements ProxiedPlayer
}
};
Bootstrap b = new Bootstrap()
- .channel( PipelineUtils.getChannel() )
+ .channel( PipelineUtils.getChannel( target.getAddress() ) )
.group( ch.getHandle().eventLoop() )
.handler( initializer )
.option( ChannelOption.CONNECT_TIMEOUT_MILLIS, request.getConnectTimeout() )
.remoteAddress( target.getAddress() );
// Windows is bugged, multi homed users will just have to live with random connecting IPs
- if ( getPendingConnection().getListener().isSetLocalAddress() && !PlatformDependent.isWindows() )
+ if ( getPendingConnection().getListener().isSetLocalAddress() && !PlatformDependent.isWindows() && getPendingConnection().getListener().getSocketAddress() instanceof InetSocketAddress )
{
b.localAddress( getPendingConnection().getListener().getHost().getHostString(), 0 );
}
@@ -497,6 +498,12 @@ public final class UserConnection implements ProxiedPlayer
@Override
public InetSocketAddress getAddress()
+ {
+ return (InetSocketAddress) getSocketAddress();
+ }
+
+ @Override
+ public SocketAddress getSocketAddress()
{
return ch.getRemoteAddress();
}
diff --git a/proxy/src/main/java/net/md_5/bungee/command/CommandIP.java b/proxy/src/main/java/net/md_5/bungee/command/CommandIP.java
index 8fd4975b..1fd5a546 100644
--- a/proxy/src/main/java/net/md_5/bungee/command/CommandIP.java
+++ b/proxy/src/main/java/net/md_5/bungee/command/CommandIP.java
@@ -26,7 +26,7 @@ public class CommandIP extends PlayerCommand
sender.sendMessage( ProxyServer.getInstance().getTranslation( "user_not_online" ) );
} else
{
- sender.sendMessage( ProxyServer.getInstance().getTranslation( "command_ip", args[0], user.getAddress() ) );
+ sender.sendMessage( ProxyServer.getInstance().getTranslation( "command_ip", args[0], user.getSocketAddress() ) );
}
}
}
diff --git a/proxy/src/main/java/net/md_5/bungee/conf/YamlConfig.java b/proxy/src/main/java/net/md_5/bungee/conf/YamlConfig.java
index 4cfb13c0..bc7e3a0d 100644
--- a/proxy/src/main/java/net/md_5/bungee/conf/YamlConfig.java
+++ b/proxy/src/main/java/net/md_5/bungee/conf/YamlConfig.java
@@ -6,7 +6,7 @@ import java.io.FileInputStream;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStream;
-import java.net.InetSocketAddress;
+import java.net.SocketAddress;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
@@ -215,7 +215,7 @@ public class YamlConfig implements ConfigurationAdapter
String addr = get( "address", "localhost:25565", val );
String motd = ChatColor.translateAlternateColorCodes( '&', get( "motd", "&1Just another BungeeCord - Forced Host", val ) );
boolean restricted = get( "restricted", false, val );
- InetSocketAddress address = Util.getAddr( addr );
+ SocketAddress address = Util.getAddr( addr );
ServerInfo info = ProxyServer.getInstance().constructServerInfo( name, address, motd, restricted );
ret.put( name, info );
}
@@ -246,7 +246,7 @@ public class YamlConfig implements ConfigurationAdapter
boolean forceDefault = get( "force_default_server", false, val );
String host = get( "host", "0.0.0.0:25577", val );
int tabListSize = get( "tab_size", 60, val );
- InetSocketAddress address = Util.getAddr( host );
+ SocketAddress address = Util.getAddr( host );
Map forced = new CaseInsensitiveMap<>( get( "forced_hosts", forcedDef, val ) );
String tabListName = get( "tab_list", "GLOBAL_PING", val );
DefaultTabList value = DefaultTabList.valueOf( tabListName.toUpperCase( Locale.ROOT ) );
diff --git a/proxy/src/main/java/net/md_5/bungee/connection/DownstreamBridge.java b/proxy/src/main/java/net/md_5/bungee/connection/DownstreamBridge.java
index 63162de0..b66712d2 100644
--- a/proxy/src/main/java/net/md_5/bungee/connection/DownstreamBridge.java
+++ b/proxy/src/main/java/net/md_5/bungee/connection/DownstreamBridge.java
@@ -15,7 +15,9 @@ import com.mojang.brigadier.tree.LiteralCommandNode;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.ByteBufAllocator;
import io.netty.buffer.Unpooled;
+import io.netty.channel.unix.DomainSocketAddress;
import java.io.DataInput;
+import java.net.InetSocketAddress;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
@@ -359,8 +361,15 @@ public class DownstreamBridge extends PacketHandler
if ( subChannel.equals( "IP" ) )
{
out.writeUTF( "IP" );
- out.writeUTF( con.getAddress().getHostString() );
- out.writeInt( con.getAddress().getPort() );
+ if ( con.getSocketAddress() instanceof InetSocketAddress )
+ {
+ out.writeUTF( con.getAddress().getHostString() );
+ out.writeInt( con.getAddress().getPort() );
+ } else
+ {
+ out.writeUTF( "unix://" + ( (DomainSocketAddress) con.getSocketAddress() ).path() );
+ out.writeInt( 0 );
+ }
}
if ( subChannel.equals( "PlayerCount" ) )
{
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 18c9fa6f..a53b113c 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
@@ -5,6 +5,7 @@ import com.google.common.base.Preconditions;
import com.google.gson.Gson;
import java.math.BigInteger;
import java.net.InetSocketAddress;
+import java.net.SocketAddress;
import java.net.URLEncoder;
import java.security.MessageDigest;
import java.util.List;
@@ -236,7 +237,7 @@ public class InitialHandler extends PacketHandler implements PendingConnection
unsafe.sendPacket( new StatusResponse( gson.toJson( pingResult.getResponse() ) ) );
if ( bungee.getConnectionThrottle() != null )
{
- bungee.getConnectionThrottle().unthrottle( getAddress().getAddress() );
+ bungee.getConnectionThrottle().unthrottle( getSocketAddress() );
}
}
};
@@ -418,7 +419,7 @@ public class InitialHandler extends PacketHandler implements PendingConnection
}
String encodedHash = URLEncoder.encode( new BigInteger( sha.digest() ).toString( 16 ), "UTF-8" );
- String preventProxy = ( ( BungeeCord.getInstance().config.isPreventProxyConnections() ) ? "&ip=" + URLEncoder.encode( getAddress().getAddress().getHostAddress(), "UTF-8" ) : "" );
+ String preventProxy = ( BungeeCord.getInstance().config.isPreventProxyConnections() && getSocketAddress() instanceof InetSocketAddress ) ? "&ip=" + URLEncoder.encode( getAddress().getAddress().getHostAddress(), "UTF-8" ) : "";
String authURL = "https://sessionserver.mojang.com/session/minecraft/hasJoined?username=" + encName + "&serverId=" + encodedHash + preventProxy;
Callback handler = new Callback()
@@ -591,6 +592,12 @@ public class InitialHandler extends PacketHandler implements PendingConnection
@Override
public InetSocketAddress getAddress()
+ {
+ return (InetSocketAddress) getSocketAddress();
+ }
+
+ @Override
+ public SocketAddress getSocketAddress()
{
return ch.getRemoteAddress();
}
@@ -625,7 +632,7 @@ public class InitialHandler extends PacketHandler implements PendingConnection
@Override
public String toString()
{
- return "[" + ( ( getName() != null ) ? getName() : getAddress() ) + "] <-> InitialHandler";
+ return "[" + ( ( getName() != null ) ? getName() : getSocketAddress() ) + "] <-> InitialHandler";
}
@Override
diff --git a/proxy/src/main/java/net/md_5/bungee/http/HttpClient.java b/proxy/src/main/java/net/md_5/bungee/http/HttpClient.java
index f95d5b6f..e0c52f21 100644
--- a/proxy/src/main/java/net/md_5/bungee/http/HttpClient.java
+++ b/proxy/src/main/java/net/md_5/bungee/http/HttpClient.java
@@ -92,7 +92,7 @@ public class HttpClient
}
};
- new Bootstrap().channel( PipelineUtils.getChannel() ).group( eventLoop ).handler( new HttpInitializer( callback, ssl, uri.getHost(), port ) ).
+ new Bootstrap().channel( PipelineUtils.getChannel( null ) ).group( eventLoop ).handler( new HttpInitializer( callback, ssl, uri.getHost(), port ) ).
option( ChannelOption.CONNECT_TIMEOUT_MILLIS, TIMEOUT ).remoteAddress( inetHost, port ).connect().addListener( future );
}
}
diff --git a/proxy/src/main/java/net/md_5/bungee/netty/ChannelWrapper.java b/proxy/src/main/java/net/md_5/bungee/netty/ChannelWrapper.java
index 0ef21887..6be2d942 100644
--- a/proxy/src/main/java/net/md_5/bungee/netty/ChannelWrapper.java
+++ b/proxy/src/main/java/net/md_5/bungee/netty/ChannelWrapper.java
@@ -5,7 +5,7 @@ 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.net.SocketAddress;
import java.util.concurrent.TimeUnit;
import lombok.Getter;
import lombok.Setter;
@@ -23,7 +23,7 @@ public class ChannelWrapper
private final Channel ch;
@Getter
@Setter
- private InetSocketAddress remoteAddress;
+ private SocketAddress remoteAddress;
@Getter
private volatile boolean closed;
@Getter
@@ -32,7 +32,7 @@ public class ChannelWrapper
public ChannelWrapper(ChannelHandlerContext ctx)
{
this.ch = ctx.channel();
- this.remoteAddress = (InetSocketAddress) this.ch.remoteAddress();
+ this.remoteAddress = ( this.ch.remoteAddress() == null ) ? this.ch.parent().localAddress() : this.ch.remoteAddress();
}
public void setProtocol(Protocol protocol)
diff --git a/proxy/src/main/java/net/md_5/bungee/netty/PipelineUtils.java b/proxy/src/main/java/net/md_5/bungee/netty/PipelineUtils.java
index f75ec97d..44e28846 100644
--- a/proxy/src/main/java/net/md_5/bungee/netty/PipelineUtils.java
+++ b/proxy/src/main/java/net/md_5/bungee/netty/PipelineUtils.java
@@ -1,5 +1,6 @@
package net.md_5.bungee.netty;
+import com.google.common.base.Preconditions;
import io.netty.buffer.PooledByteBufAllocator;
import io.netty.channel.Channel;
import io.netty.channel.ChannelException;
@@ -10,18 +11,22 @@ import io.netty.channel.ServerChannel;
import io.netty.channel.WriteBufferWaterMark;
import io.netty.channel.epoll.Epoll;
import io.netty.channel.epoll.EpollDatagramChannel;
+import io.netty.channel.epoll.EpollDomainSocketChannel;
import io.netty.channel.epoll.EpollEventLoopGroup;
+import io.netty.channel.epoll.EpollServerDomainSocketChannel;
import io.netty.channel.epoll.EpollServerSocketChannel;
import io.netty.channel.epoll.EpollSocketChannel;
import io.netty.channel.nio.NioEventLoopGroup;
+import io.netty.channel.socket.DatagramChannel;
import io.netty.channel.socket.nio.NioDatagramChannel;
import io.netty.channel.socket.nio.NioServerSocketChannel;
import io.netty.channel.socket.nio.NioSocketChannel;
+import io.netty.channel.unix.DomainSocketAddress;
import io.netty.handler.codec.haproxy.HAProxyMessageDecoder;
import io.netty.handler.timeout.ReadTimeoutHandler;
import io.netty.util.AttributeKey;
import io.netty.util.internal.PlatformDependent;
-import java.net.InetSocketAddress;
+import java.net.SocketAddress;
import java.util.concurrent.ThreadFactory;
import java.util.concurrent.TimeUnit;
import java.util.logging.Level;
@@ -51,7 +56,7 @@ public class PipelineUtils
@Override
protected void initChannel(Channel ch) throws Exception
{
- if ( BungeeCord.getInstance().getConnectionThrottle() != null && BungeeCord.getInstance().getConnectionThrottle().throttle( ( (InetSocketAddress) ch.remoteAddress() ).getAddress() ) )
+ if ( BungeeCord.getInstance().getConnectionThrottle() != null && BungeeCord.getInstance().getConnectionThrottle().throttle( ch.remoteAddress() ) )
{
ch.close();
return;
@@ -109,17 +114,31 @@ public class PipelineUtils
return epoll ? new EpollEventLoopGroup( threads, factory ) : new NioEventLoopGroup( threads, factory );
}
- public static Class extends ServerChannel> getServerChannel()
+ public static Class extends ServerChannel> getServerChannel(SocketAddress address)
{
+ if ( address instanceof DomainSocketAddress )
+ {
+ Preconditions.checkState( epoll, "Epoll required to have UNIX sockets" );
+
+ return EpollServerDomainSocketChannel.class;
+ }
+
return epoll ? EpollServerSocketChannel.class : NioServerSocketChannel.class;
}
- public static Class extends Channel> getChannel()
+ public static Class extends Channel> getChannel(SocketAddress address)
{
+ if ( address instanceof DomainSocketAddress )
+ {
+ Preconditions.checkState( epoll, "Epoll required to have UNIX sockets" );
+
+ return EpollDomainSocketChannel.class;
+ }
+
return epoll ? EpollSocketChannel.class : NioSocketChannel.class;
}
- public static Class extends Channel> getDatagramChannel()
+ public static Class extends DatagramChannel> getDatagramChannel()
{
return epoll ? EpollDatagramChannel.class : NioDatagramChannel.class;
}
diff --git a/proxy/src/test/java/net/md_5/bungee/ThrottleTest.java b/proxy/src/test/java/net/md_5/bungee/ThrottleTest.java
index f4c11675..84510827 100644
--- a/proxy/src/test/java/net/md_5/bungee/ThrottleTest.java
+++ b/proxy/src/test/java/net/md_5/bungee/ThrottleTest.java
@@ -2,6 +2,7 @@ package net.md_5.bungee;
import com.google.common.base.Ticker;
import java.net.InetAddress;
+import java.net.InetSocketAddress;
import java.net.UnknownHostException;
import java.util.concurrent.TimeUnit;
import org.junit.Assert;
@@ -27,14 +28,14 @@ public class ThrottleTest
{
FixedTicker ticker = new FixedTicker();
ConnectionThrottle throttle = new ConnectionThrottle( ticker, 10, 3 );
- InetAddress address;
+ InetSocketAddress address;
try
{
- address = InetAddress.getLocalHost();
+ address = new InetSocketAddress( InetAddress.getLocalHost(), 0 );
} catch ( UnknownHostException ex )
{
- address = InetAddress.getByName( null );
+ address = new InetSocketAddress( InetAddress.getByName( null ), 0 );
}
Assert.assertFalse( "Address should not be throttled", throttle.throttle( address ) ); // 1