From 57c56558858f8348f938194c7fe563574cc46fd6 Mon Sep 17 00:00:00 2001 From: Raymond Feng Date: Tue, 27 May 2014 15:26:13 -0700 Subject: [PATCH] net: Ensure consistent binding to IPV6 if address is absent See https://github.com/joyent/node/issues/7675 net.server.listen() behaves inconsistently depending on whether the port number is provided. 1. port === 0 && host == '' (i.e. false-y), node creates an AF_INET socket but does not call bind(). 2. port > 0 && host == '', node creates an AF_INET6 socket and calls bind(). The fix makes 1 consistent with 2. Signed-off-by: Fedor Indutny --- lib/net.js | 4 +- test/simple/test-net-server-address.js | 62 ++++++++++++++++++++++++++ 2 files changed, 65 insertions(+), 1 deletion(-) diff --git a/lib/net.js b/lib/net.js index 3b4f7da07865f7..1af61f3bd919e8 100644 --- a/lib/net.js +++ b/lib/net.js @@ -1051,6 +1051,7 @@ var createServerHandle = exports._createServerHandle = // assign handle in listen, and clean up if bind or listen fails var handle; + var isTCP = false; if (util.isNumber(fd) && fd >= 0) { try { handle = createHandle(fd); @@ -1074,9 +1075,10 @@ var createServerHandle = exports._createServerHandle = } } else { handle = createTCP(); + isTCP = true; } - if (address || port) { + if (address || port || isTCP) { debug('bind to ' + (address || 'anycast')); if (!address) { // Try binding to ipv6 first diff --git a/test/simple/test-net-server-address.js b/test/simple/test-net-server-address.js index a9f92c448be247..671305f6621ee7 100644 --- a/test/simple/test-net-server-address.js +++ b/test/simple/test-net-server-address.js @@ -56,3 +56,65 @@ server_ipv6.listen(common.PORT, localhost_ipv6, function() { assert.strictEqual(address_ipv6.family, family_ipv6); server_ipv6.close(); }); + +// Test without hostname or ip +var anycast_ipv6 = '::'; +var server1 = net.createServer(); + +server1.on('error', function(e) { + console.log('Error on ip socket: ' + e.toString()); +}); + +// Specify the port number +server1.listen(common.PORT, function() { + var address = server1.address(); + assert.strictEqual(address.address, anycast_ipv6); + assert.strictEqual(address.port, common.PORT); + assert.strictEqual(address.family, family_ipv6); + server1.close(); +}); + +// Test without hostname or port +var server2 = net.createServer(); + +server2.on('error', function (e) { + console.log('Error on ip socket: ' + e.toString()); +}); + +// Don't specify the port number +server2.listen(function () { + var address = server2.address(); + assert.strictEqual(address.address, anycast_ipv6); + assert.strictEqual(address.family, family_ipv6); + server2.close(); +}); + +// Test without hostname, but with a false-y port +var server3 = net.createServer(); + +server3.on('error', function (e) { + console.log('Error on ip socket: ' + e.toString()); +}); + +// Specify a false-y port number +server3.listen(0, function () { + var address = server3.address(); + assert.strictEqual(address.address, anycast_ipv6); + assert.strictEqual(address.family, family_ipv6); + server3.close(); +}); + +// Test without hostname, but with port -1 +var server4 = net.createServer(); + +server4.on('error', function (e) { + console.log('Error on ip socket: ' + e.toString()); +}); + +// Specify -1 as port number +server4.listen(-1, function () { + var address = server4.address(); + assert.strictEqual(address.address, anycast_ipv6); + assert.strictEqual(address.family, family_ipv6); + server4.close(); +});