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
This commit is contained in:
Andrzej Kapolka
2010-05-07 01:12:55 +00:00
parent 45694bc0f0
commit 9043e99f7a
2 changed files with 28 additions and 13 deletions
@@ -157,7 +157,8 @@ public class PresentsServer
_clmgr.setInjector(injector); _clmgr.setInjector(injector);
// configure our connection manager // configure our connection manager
_conmgr.init(getBindHostname(), getListenPorts(), getDatagramPorts()); _conmgr.init(getBindHostname(), getDatagramHostname(),
getListenPorts(), getDatagramPorts());
// initialize the time base services // initialize the time base services
TimeBaseProvider.init(_invmgr, _omgr); 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 * Returns the hostname on which the connection manager will listen for TCP traffic, or
* traffic, or <code>null</code> to bind to the wildcard address. * <code>null</code> to bind to the wildcard address.
*/ */
protected String getBindHostname () protected String getBindHostname ()
{ {
return null; return null;
} }
/**
* Returns the hostname on which the connection will listen for datagram traffic, or
* <code>null</code> to bind to the wildcard address.
*/
protected String getDatagramHostname ()
{
return null;
}
/** /**
* Returns the port on which the connection manager will listen for client connections. * Returns the port on which the connection manager will listen for client connections.
*/ */
@@ -105,12 +105,16 @@ public class ConnectionManager extends LoopingThread
* socket connections and datagram packets. This must be called before the connection manager * 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. * 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 ports the ports on which to listen for TCP connection.
* @param datagramPorts the ports on which to listen for datagram packets. * @param datagramPorts the ports on which to listen for datagram packets.
*/ */
public void init (String bindHostname, int[] ports, int[] datagramPorts) public void init (
throws IOException String bindHostname, String datagramHostname, int[] ports, int[] datagramPorts)
throws IOException
{ {
Preconditions.checkArgument(ports != null, "Ports must be non-null."); Preconditions.checkArgument(ports != null, "Ports must be non-null.");
Preconditions.checkArgument(datagramPorts != null, "Datagram 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."); Preconditions.checkState(!super.isRunning(), "Must initialize before starting.");
_bindHostname = bindHostname; _bindHostname = bindHostname;
_datagramHostname = datagramHostname;
_ports = ports; _ports = ports;
_datagramPorts = datagramPorts; _datagramPorts = datagramPorts;
_selector = SelectorProvider.provider().openSelector(); _selector = SelectorProvider.provider().openSelector();
@@ -362,7 +367,7 @@ public class ConnectionManager extends LoopingThread
_ssocket = ServerSocketChannel.open(); _ssocket = ServerSocketChannel.open();
_ssocket.configureBlocking(false); _ssocket.configureBlocking(false);
InetSocketAddress isa = getAddress(port); InetSocketAddress isa = getAddress(_bindHostname, port);
_ssocket.socket().bind(isa); _ssocket.socket().bind(isa);
registerChannel(_ssocket); registerChannel(_ssocket);
successes++; successes++;
@@ -414,23 +419,23 @@ public class ConnectionManager extends LoopingThread
_datagramChannel = DatagramChannel.open(); _datagramChannel = DatagramChannel.open();
_datagramChannel.socket().setTrafficClass(0x10); // IPTOS_LOWDELAY _datagramChannel.socket().setTrafficClass(0x10); // IPTOS_LOWDELAY
_datagramChannel.configureBlocking(false); _datagramChannel.configureBlocking(false);
InetSocketAddress isa = getAddress(port); InetSocketAddress isa = getAddress(_datagramHostname, port);
_datagramChannel.socket().bind(isa); _datagramChannel.socket().bind(isa);
registerChannel(_datagramChannel); registerChannel(_datagramChannel);
log.info("Server accepting datagrams on " + isa + "."); log.info("Server accepting datagrams on " + isa + ".");
} catch (IOException ioe) { } catch (IOException ioe) {
log.warning("Failure opening datagram channel", "hostname", _bindHostname, log.warning("Failure opening datagram channel", "hostname", _datagramHostname,
"port", port, ioe); "port", port, ioe);
} }
} }
} }
/** Helper function for creating proper bindable socket addresses. */ /** Helper function for creating proper bindable socket addresses. */
protected InetSocketAddress getAddress (int port) protected InetSocketAddress getAddress (String hostname, int port)
{ {
return StringUtil.isBlank(_bindHostname) ? return StringUtil.isBlank(hostname) ?
new InetSocketAddress(port) : new InetSocketAddress(_bindHostname, port); new InetSocketAddress(port) : new InetSocketAddress(hostname, port);
} }
/** Helper function for {@link #willStart}. */ /** Helper function for {@link #willStart}. */
@@ -1217,7 +1222,7 @@ public class ConnectionManager extends LoopingThread
protected List<ChainedAuthenticator> _authors = Lists.newArrayList(); protected List<ChainedAuthenticator> _authors = Lists.newArrayList();
protected int[] _ports, _datagramPorts; protected int[] _ports, _datagramPorts;
protected String _bindHostname; protected String _bindHostname, _datagramHostname;
protected Selector _selector; protected Selector _selector;
protected ServerSocketChannel _ssocket; protected ServerSocketChannel _ssocket;
protected DatagramChannel _datagramChannel; protected DatagramChannel _datagramChannel;