From 776ea07d3b8aacc518928434343aef09567128bf Mon Sep 17 00:00:00 2001 From: Bob van der Linden Date: Tue, 15 Dec 2015 22:19:01 +0100 Subject: [PATCH] use ipv6 if that is actually supported This makes the calls to getaddrinfo use the right address families. The supported address families depend on the NodeJS version as well as the OS. --- lib/resolver_sequence_tasks.js | 60 +++++++++++++++++++++++++++++++++- 1 file changed, 59 insertions(+), 1 deletion(-) diff --git a/lib/resolver_sequence_tasks.js b/lib/resolver_sequence_tasks.js index f823627e..1d60df86 100644 --- a/lib/resolver_sequence_tasks.js +++ b/lib/resolver_sequence_tasks.js @@ -3,6 +3,56 @@ var dns_sd = require('./dns_sd') , MDNSService = require('./mdns_service').MDNSService ; +// Converts a versionString (v0.11.5) to an array of numbers [0,11,5] +function versionStringToArray(versionString) { + return /^v(\d+(\.\d+)*)/.exec(versionString)[1].split('.').map(Number); +} + +// Accepts versions in the form of v0.11.5. +// Returns 1 if versionStringA is higher than versionStringB, -1 if lower, 0 if equal. +function compareVersions(versionStringA, versionStringB) { + var versionA = versionStringToArray(versionStringA); + var versionB = versionStringToArray(versionStringB); + + // Make sure the versions have just as segments, fill them up with 0's. + // Ex. Comparing v0.11 with v0.11.5 will become v0.11.0 and v0.11.5 + while(versionA.length < versionB.length) { versionA.push(0); } + while(versionB.length < versionA.length) { versionB.push(0); } + + var versionLength = versionA.length; + + for(var i=0;i versionB[i]) { + return 1; + } else if (versionA[i] < versionB[i]) { + return -1; + } + } + + return 0; +} + +// Checks whether Ipv6 is supported on the OS. +function hasIpv6Support() { + // We presume only Linux has the capability to disable ipv6. + if (process.platform !== 'linux') { + return true; + } + // Determine ipv6 support on Linux by checking whether if_inet6 exists. + try { + fs.statSync('/proc/net/if_inet6') + return true; + } catch(e) { + return false; + } +} + +// Checks whether we can use { families: [0] } for getaddrinfo. +// Support was added in NodeJS v0.11.5 +function hasGetaddrinfoZeroFamilySupport() { + return compareVersions(process.version, 'v0.11.5') >= 0; +} + exports.DNSServiceResolve = function DNSServiceResolve(options) { options = options || {}; options.flags = options.flags || 0; @@ -141,9 +191,17 @@ try { _getaddrinfo = process.binding('net').getaddrinfo; } +// Depending on the support for NodeJS and the OS, we use the most supported +// address families as default for getaddrinfo. +var defaultFamilies = hasGetaddrinfoZeroFamilySupport() + ? [0] + : hasIpv6Support() + ? [4, 6] + : [4]; + exports.getaddrinfo = function getaddrinfo(options) { options = options || {}; - var families = options.families || [4, 6]; + var families = options.families || defaultFamilies; return function getaddrinfo(service, next) { var last_error , counter = 0