From c807287e80fef9edbadb89e8e4c9153dedf9f718 Mon Sep 17 00:00:00 2001 From: Ben Noordhuis Date: Mon, 9 May 2016 16:35:20 +0200 Subject: [PATCH] tls,https: respect address family when connecting Respect the `{ family: 6 }` address family property when connecting to a remote peer over TLS. Fixes: https://github.com/nodejs/node/issues/4139 Fixes: https://github.com/nodejs/node/issues/6440 PR-URL: https://github.com/nodejs/node/pull/6654 Reviewed-By: Colin Ihrig --- lib/_http_agent.js | 5 ++++ lib/_tls_wrap.js | 1 + test/parallel/parallel.status | 7 +++++ test/parallel/test-http-agent-getname.js | 6 ++++ .../test-https-connect-address-family.js | 28 +++++++++++++++++++ .../test-tls-connect-address-family.js | 27 ++++++++++++++++++ 6 files changed, 74 insertions(+) create mode 100644 test/parallel/test-https-connect-address-family.js create mode 100644 test/parallel/test-tls-connect-address-family.js diff --git a/lib/_http_agent.js b/lib/_http_agent.js index aac4b95563..cb52c11054 100644 --- a/lib/_http_agent.js +++ b/lib/_http_agent.js @@ -102,6 +102,11 @@ Agent.prototype.getName = function(options) { if (options.localAddress) name += options.localAddress; + // Pacify parallel/test-http-agent-getname by only appending + // the ':' when options.family is set. + if (options.family === 4 || options.family === 6) + name += ':' + options.family; + return name; }; diff --git a/lib/_tls_wrap.js b/lib/_tls_wrap.js index e340e4a041..c115555ce7 100644 --- a/lib/_tls_wrap.js +++ b/lib/_tls_wrap.js @@ -994,6 +994,7 @@ exports.connect = function(/* [port, host], options, cb */) { connect_opt = { port: options.port, host: options.host, + family: options.family, localAddress: options.localAddress }; } diff --git a/test/parallel/parallel.status b/test/parallel/parallel.status index dc71ddb361..2cdc5b7b07 100644 --- a/test/parallel/parallel.status +++ b/test/parallel/parallel.status @@ -12,6 +12,13 @@ test-tick-processor : PASS,FLAKY [$system==linux] test-tick-processor : PASS,FLAKY +# Flaky until https://github.com/nodejs/build/issues/415 is resolved. +# On some of the buildbots, AAAA queries for localhost don't resolve +# to an address and neither do any of the alternatives from the +# localIPv6Hosts list from test/common.js. +test-https-connect-address-family : PASS,FLAKY +test-tls-connect-address-family : PASS,FLAKY + [$system==macos] [$system==solaris] # Also applies to SmartOS diff --git a/test/parallel/test-http-agent-getname.js b/test/parallel/test-http-agent-getname.js index 1b80b5c36e..5f5c479dcf 100644 --- a/test/parallel/test-http-agent-getname.js +++ b/test/parallel/test-http-agent-getname.js @@ -30,3 +30,9 @@ assert.equal( }), '0.0.0.0:80:192.168.1.1' ); + +for (const family of [0, null, undefined, 'bogus']) + assert.strictEqual(agent.getName({ family }), 'localhost::'); + +for (const family of [4, 6]) + assert.strictEqual(agent.getName({ family }), 'localhost:::' + family); diff --git a/test/parallel/test-https-connect-address-family.js b/test/parallel/test-https-connect-address-family.js new file mode 100644 index 0000000000..b2f3c233cf --- /dev/null +++ b/test/parallel/test-https-connect-address-family.js @@ -0,0 +1,28 @@ +'use strict'; +const common = require('../common'); +const assert = require('assert'); +const https = require('https'); + +if (!common.hasIPv6) { + common.skip('no IPv6 support'); + return; +} + +const ciphers = 'AECDH-NULL-SHA'; +https.createServer({ ciphers }, function(req, res) { + this.close(); + res.end(); +}).listen(common.PORT, '::1', function() { + const options = { + host: 'localhost', + port: common.PORT, + family: 6, + ciphers: ciphers, + rejectUnauthorized: false, + }; + // Will fail with ECONNREFUSED if the address family is not honored. + https.get(options, common.mustCall(function() { + assert.strictEqual('::1', this.socket.remoteAddress); + this.destroy(); + })); +}); diff --git a/test/parallel/test-tls-connect-address-family.js b/test/parallel/test-tls-connect-address-family.js new file mode 100644 index 0000000000..665a71dfe6 --- /dev/null +++ b/test/parallel/test-tls-connect-address-family.js @@ -0,0 +1,27 @@ +'use strict'; +const common = require('../common'); +const assert = require('assert'); +const tls = require('tls'); + +if (!common.hasIPv6) { + common.skip('no IPv6 support'); + return; +} + +const ciphers = 'AECDH-NULL-SHA'; +tls.createServer({ ciphers }, function() { + this.close(); +}).listen(common.PORT, '::1', function() { + const options = { + host: 'localhost', + port: common.PORT, + family: 6, + ciphers: ciphers, + rejectUnauthorized: false, + }; + // Will fail with ECONNREFUSED if the address family is not honored. + tls.connect(options).once('secureConnect', common.mustCall(function() { + assert.strictEqual('::1', this.remoteAddress); + this.destroy(); + })); +});