From 9043e99f7ad749d69fa9179ff722f52cd5b7da84 Mon Sep 17 00:00:00 2001 From: Andrzej Kapolka Date: Fri, 7 May 2010 01:12:55 +0000 Subject: [PATCH] Separated TCP and UDP bind hostnames (we want to be able to bind to the wildcard address for TCP in order to accept connections on both the public hostname and the internal hostname used for peers, but bind to the public hostname for UDP because binding to the wildcard address seems to cause problems receiving packets). git-svn-id: svn+ssh://src.earth.threerings.net/narya/trunk@6066 542714f4-19e9-0310-aa3c-eee0fc999fb1 --- .../presents/server/PresentsServer.java | 16 +++++++++--- .../server/net/ConnectionManager.java | 25 +++++++++++-------- 2 files changed, 28 insertions(+), 13 deletions(-) diff --git a/src/java/com/threerings/presents/server/PresentsServer.java b/src/java/com/threerings/presents/server/PresentsServer.java index fa31814b6..8c07a64d8 100644 --- a/src/java/com/threerings/presents/server/PresentsServer.java +++ b/src/java/com/threerings/presents/server/PresentsServer.java @@ -157,7 +157,8 @@ public class PresentsServer _clmgr.setInjector(injector); // configure our connection manager - _conmgr.init(getBindHostname(), getListenPorts(), getDatagramPorts()); + _conmgr.init(getBindHostname(), getDatagramHostname(), + getListenPorts(), getDatagramPorts()); // initialize the time base services TimeBaseProvider.init(_invmgr, _omgr); @@ -224,14 +225,23 @@ public class PresentsServer } /** - * Returns the hostname on which the connection manager will listen for TCP and datagram - * traffic, or null to bind to the wildcard address. + * Returns the hostname on which the connection manager will listen for TCP traffic, or + * null to bind to the wildcard address. */ protected String getBindHostname () { return null; } + /** + * Returns the hostname on which the connection will listen for datagram traffic, or + * null to bind to the wildcard address. + */ + protected String getDatagramHostname () + { + return null; + } + /** * Returns the port on which the connection manager will listen for client connections. */ diff --git a/src/java/com/threerings/presents/server/net/ConnectionManager.java b/src/java/com/threerings/presents/server/net/ConnectionManager.java index 6c93663a3..c8df0416b 100644 --- a/src/java/com/threerings/presents/server/net/ConnectionManager.java +++ b/src/java/com/threerings/presents/server/net/ConnectionManager.java @@ -105,12 +105,16 @@ public class ConnectionManager extends LoopingThread * socket connections and datagram packets. This must be called before the connection manager * is started (via {@via #start}) as the sockets will be bound at that time. * - * @param bindHostname the port to which to bind our sockets or null to bind to all interfaces. + * @param bindHostname the hostname to which we bind our sockets or null to bind to all + * interfaces. + * @param datagramHostname the hostname to which we bind our datagram socket or null to bind + * to all interfaces. * @param ports the ports on which to listen for TCP connection. * @param datagramPorts the ports on which to listen for datagram packets. */ - public void init (String bindHostname, int[] ports, int[] datagramPorts) - throws IOException + public void init ( + String bindHostname, String datagramHostname, int[] ports, int[] datagramPorts) + throws IOException { Preconditions.checkArgument(ports != null, "Ports must be non-null."); Preconditions.checkArgument(datagramPorts != null, "Datagram ports must be non-null. " + @@ -118,6 +122,7 @@ public class ConnectionManager extends LoopingThread Preconditions.checkState(!super.isRunning(), "Must initialize before starting."); _bindHostname = bindHostname; + _datagramHostname = datagramHostname; _ports = ports; _datagramPorts = datagramPorts; _selector = SelectorProvider.provider().openSelector(); @@ -362,7 +367,7 @@ public class ConnectionManager extends LoopingThread _ssocket = ServerSocketChannel.open(); _ssocket.configureBlocking(false); - InetSocketAddress isa = getAddress(port); + InetSocketAddress isa = getAddress(_bindHostname, port); _ssocket.socket().bind(isa); registerChannel(_ssocket); successes++; @@ -414,23 +419,23 @@ public class ConnectionManager extends LoopingThread _datagramChannel = DatagramChannel.open(); _datagramChannel.socket().setTrafficClass(0x10); // IPTOS_LOWDELAY _datagramChannel.configureBlocking(false); - InetSocketAddress isa = getAddress(port); + InetSocketAddress isa = getAddress(_datagramHostname, port); _datagramChannel.socket().bind(isa); registerChannel(_datagramChannel); log.info("Server accepting datagrams on " + isa + "."); } catch (IOException ioe) { - log.warning("Failure opening datagram channel", "hostname", _bindHostname, + log.warning("Failure opening datagram channel", "hostname", _datagramHostname, "port", port, ioe); } } } /** Helper function for creating proper bindable socket addresses. */ - protected InetSocketAddress getAddress (int port) + protected InetSocketAddress getAddress (String hostname, int port) { - return StringUtil.isBlank(_bindHostname) ? - new InetSocketAddress(port) : new InetSocketAddress(_bindHostname, port); + return StringUtil.isBlank(hostname) ? + new InetSocketAddress(port) : new InetSocketAddress(hostname, port); } /** Helper function for {@link #willStart}. */ @@ -1217,7 +1222,7 @@ public class ConnectionManager extends LoopingThread protected List _authors = Lists.newArrayList(); protected int[] _ports, _datagramPorts; - protected String _bindHostname; + protected String _bindHostname, _datagramHostname; protected Selector _selector; protected ServerSocketChannel _ssocket; protected DatagramChannel _datagramChannel;