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';
|
'use strict';
|
||||||
|
|
||||||
var PromiseA = require('bluebird');
|
var PromiseA = require('bluebird');
|
||||||
var requestAsync = PromiseA.promisify(require('request'));
|
|
||||||
|
|
||||||
module.exports.create = function (args) {
|
module.exports.create = function (args) {
|
||||||
var promises = [];
|
var promises = [];
|
||||||
|
@ -14,17 +13,16 @@ module.exports.create = function (args) {
|
||||||
// TODO determine if we have a AAAA local ip or not
|
// TODO determine if we have a AAAA local ip or not
|
||||||
// TODO get A and AAAA records
|
// TODO get A and AAAA records
|
||||||
if (-1 !== args.protocols.indexOf('none')) {
|
if (-1 !== args.protocols.indexOf('none')) {
|
||||||
promises.push(PromiseA.some(args.ipifyUrls.map(function (ipifyUrl) {
|
promises.push(PromiseA.any(args.ipifyUrls.map(function (ipifyUrl) {
|
||||||
return requestAsync('https://' + ipifyUrl).then(function (resp) {
|
var getIp = require('./lib/external-ip');
|
||||||
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 + "'"));
|
|
||||||
}
|
|
||||||
|
|
||||||
|
return getIp({ hostname: ipifyUrl, debug: args.debug });
|
||||||
|
})).then(function (ips) {
|
||||||
|
return ips.map(function (ip) {
|
||||||
|
// TODO attempt loopback
|
||||||
return ip;
|
return ip;
|
||||||
});
|
});
|
||||||
}), 1));
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
return PromiseA.all(promises).then(function (results) {
|
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