holepunch.js/lib/external-ip.js

90 lines
2.1 KiB
JavaScript
Raw Normal View History

2015-12-30 02:47:38 +00:00
'use strict';
var PromiseA = require('bluebird');
//var dns = PromiseA.promisifyAll(require('dns'));
2015-12-30 03:36:14 +00:00
var requestAsync = require('./request');
2015-12-30 02:47:38 +00:00
module.exports = function (opts) {
var promises = [];
/*
// 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);
}
2015-12-31 02:21:29 +00:00
opts.ifaces.forEach(function (iface) {
2015-12-30 02:47:38 +00:00
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
2015-12-30 03:36:14 +00:00
, localAddress: iface.address
2015-12-30 02:47:38 +00:00
};
}));
});
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);
});
};