get all external ips
This commit is contained in:
parent
c41fdbc906
commit
0a3b457583
16
index.js
16
index.js
|
@ -1,7 +1,6 @@
|
|||
'use strict';
|
||||
|
||||
var PromiseA = require('bluebird');
|
||||
var requestAsync = PromiseA.promisify(require('request'));
|
||||
|
||||
module.exports.create = function (args) {
|
||||
var promises = [];
|
||||
|
@ -14,17 +13,16 @@ module.exports.create = function (args) {
|
|||
// TODO determine if we have a AAAA local ip or not
|
||||
// TODO get A and AAAA records
|
||||
if (-1 !== args.protocols.indexOf('none')) {
|
||||
promises.push(PromiseA.some(args.ipifyUrls.map(function (ipifyUrl) {
|
||||
return requestAsync('https://' + ipifyUrl).then(function (resp) {
|
||||
var ip = (resp.body || '').toString('ascii');
|
||||
|
||||
if (!/\d+\.\d+\.\d+\.\d+/.test(ip) && !/\w+\:\w+/.test(ip)) {
|
||||
return PromiseA.reject(new Error("bad response '" + resp.body + "'"));
|
||||
}
|
||||
promises.push(PromiseA.any(args.ipifyUrls.map(function (ipifyUrl) {
|
||||
var getIp = require('./lib/external-ip');
|
||||
|
||||
return getIp({ hostname: ipifyUrl, debug: args.debug });
|
||||
})).then(function (ips) {
|
||||
return ips.map(function (ip) {
|
||||
// TODO attempt loopback
|
||||
return ip;
|
||||
});
|
||||
}), 1));
|
||||
}));
|
||||
}
|
||||
|
||||
return PromiseA.all(promises).then(function (results) {
|
||||
|
|
|
@ -0,0 +1,144 @@
|
|||
'use strict';
|
||||
|
||||
var PromiseA = require('bluebird');
|
||||
//var dns = PromiseA.promisifyAll(require('dns'));
|
||||
var https = PromiseA.promisifyAll(require('https'));
|
||||
var os = require('os');
|
||||
|
||||
function requestAsync(opts) {
|
||||
return new PromiseA(function (resolve, reject) {
|
||||
var req = https.request(opts, function (res) {
|
||||
var data = '';
|
||||
|
||||
res.on('error', function (err) {
|
||||
if (opts.debug) {
|
||||
console.error('[Error] HP: bad request:');
|
||||
console.error(err);
|
||||
}
|
||||
reject(err);
|
||||
});
|
||||
res.on('data', function (chunk) {
|
||||
if (opts.debug > 2) {
|
||||
console.log('HP: request chunk:');
|
||||
console.log(chunk);
|
||||
}
|
||||
data += chunk.toString('utf8');
|
||||
});
|
||||
res.on('end', function () {
|
||||
if (opts.debug > 2) {
|
||||
console.log('HP: request complete:');
|
||||
console.log(data);
|
||||
}
|
||||
resolve(data);
|
||||
});
|
||||
});
|
||||
|
||||
req.on('error', reject);
|
||||
req.end();
|
||||
});
|
||||
}
|
||||
|
||||
module.exports = function (opts) {
|
||||
var promises = [];
|
||||
var interfaces = os.networkInterfaces();
|
||||
var ifacenames = Object.keys(interfaces).filter(function (ifacename) {
|
||||
// http://www.freedesktop.org/wiki/Software/systemd/PredictableNetworkInterfaceNames/
|
||||
// https://wiki.archlinux.org/index.php/Network_configuration#Device_names
|
||||
// we do not include tun and bridge devices because we're trying
|
||||
// to see if any physical interface is internet-connected first
|
||||
return /^(en|sl|wl|ww|eth|net|lan|wifi|inet)/.test(ifacename);
|
||||
});
|
||||
var ifaces = ifacenames.reduce(function (all, ifacename) {
|
||||
var ifs = interfaces[ifacename];
|
||||
|
||||
ifs.forEach(function (iface) {
|
||||
if (!iface.internal && !/^fe80/.test(iface.address)) {
|
||||
all.push(iface);
|
||||
}
|
||||
});
|
||||
|
||||
return all;
|
||||
}, []);
|
||||
|
||||
/*
|
||||
// TODO how to support servername
|
||||
promises.push(dns.resolve4Async(hostname).then(function (ips) {
|
||||
return ips.map(function (ip) {
|
||||
return {
|
||||
address: ip
|
||||
, family: 'IPv4'
|
||||
};
|
||||
});
|
||||
}));
|
||||
|
||||
promises.push(dns.resolve6Async(hostname).then(function (ips) {
|
||||
return ips.map(function (ip) {
|
||||
return {
|
||||
address: ip
|
||||
, family: 'IPv6'
|
||||
};
|
||||
});
|
||||
}));
|
||||
*/
|
||||
|
||||
function parseIp(ip) {
|
||||
if (!/\d+\.\d+\.\d+\.\d+/.test(ip) && !/\w+\:\w+/.test(ip)) {
|
||||
return PromiseA.reject(new Error("bad response '" + ip + "'"));
|
||||
}
|
||||
|
||||
return ip;
|
||||
}
|
||||
|
||||
function ignoreEinval(err) {
|
||||
if ('EINVAL' === err.code) {
|
||||
if (opts.debug) {
|
||||
console.warn('[HP] tried to bind to invalid address:');
|
||||
console.warn(err.stack);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
return PromiseA.reject(err);
|
||||
}
|
||||
|
||||
if (opts.debug) {
|
||||
console.log('[HP] external ip opts:');
|
||||
console.log(opts);
|
||||
|
||||
console.log('[HP] external ifaces:');
|
||||
console.log(ifaces);
|
||||
}
|
||||
|
||||
ifaces.forEach(function (iface) {
|
||||
promises.push(requestAsync({
|
||||
family: iface.family
|
||||
, method: 'GET'
|
||||
, headers: {
|
||||
Host: opts.hostname
|
||||
}
|
||||
, localAddress: iface.address
|
||||
, servername: opts.hostname // is this actually sent to tls.connect()?
|
||||
, hostname: opts.hostname // if so we could do the DNS ourselves
|
||||
// and use the ip address here
|
||||
, port: opts.port || 443
|
||||
, pathname: opts.pathname || opts.path || '/'
|
||||
}).then(parseIp, ignoreEinval).then(function (addr) {
|
||||
return {
|
||||
family: iface.family
|
||||
, address: addr
|
||||
};
|
||||
}));
|
||||
});
|
||||
|
||||
return PromiseA.all(promises).then(function (results) {
|
||||
if (opts.debug) {
|
||||
console.log('[HP] got all ip address types');
|
||||
console.log(results);
|
||||
}
|
||||
|
||||
return results;
|
||||
}, function (err) {
|
||||
console.error('[HP] error');
|
||||
console.error(err);
|
||||
});
|
||||
};
|
Loading…
Reference in New Issue