From edd095bfaecef45979a9fd7567179d5c7680c714 Mon Sep 17 00:00:00 2001 From: Christopher Jeffrey Date: Mon, 26 Jun 2017 04:27:21 -0700 Subject: [PATCH] pool: refactor http ip discovery. --- lib/net/external-browser.js | 29 ++++++++++ lib/net/external.js | 102 ++++++++++++++++++++++++++++++++++++ lib/net/pool.js | 86 ++++++------------------------ package.json | 1 + 4 files changed, 148 insertions(+), 70 deletions(-) create mode 100644 lib/net/external-browser.js create mode 100644 lib/net/external.js diff --git a/lib/net/external-browser.js b/lib/net/external-browser.js new file mode 100644 index 00000000..33b865b2 --- /dev/null +++ b/lib/net/external-browser.js @@ -0,0 +1,29 @@ +/*! + * external.js - external ip address discovery for bcoin + * Copyright (c) 2017, Christopher Jeffrey (MIT License). + * https://github.com/bcoin-org/bcoin + */ + +'use strict'; + +var external = exports; + +/** + * Attempt to retrieve external IP from icanhazip.com. + * @method + * @returns {Promise} + */ + +external.getIPv4 = async function getIPv4() { + throw new Error('Could not find IP.'); +}; + +/** + * Attempt to retrieve external IP from icanhazip.com. + * @method + * @returns {Promise} + */ + +external.getIPv6 = async function getIPv6() { + throw new Error('Could not find IP.'); +}; diff --git a/lib/net/external.js b/lib/net/external.js new file mode 100644 index 00000000..a39f4a41 --- /dev/null +++ b/lib/net/external.js @@ -0,0 +1,102 @@ +/*! + * external.js - external ip address discovery for bcoin + * Copyright (c) 2017, Christopher Jeffrey (MIT License). + * https://github.com/bcoin-org/bcoin + */ + +'use strict'; + +var request = require('../http/request'); +var IP = require('../utils/ip'); +var external = exports; + +/** + * Attempt to retrieve external IP from icanhazip.com. + * @method + * @returns {Promise} + */ + +external.getIPv4 = async function getIPv4() { + var res, ip; + + if (request.unsupported) + throw new Error('Could not find IP.'); + + try { + res = await request({ + method: 'GET', + uri: 'http://ipv4.icanhazip.com', + expect: 'txt', + timeout: 2000 + }); + } catch (e) { + return await external.getIPv42(); + } + + ip = res.body.trim(); + + try { + ip = IP.normalize(ip); + } catch (e) { + return await external.getIPv42(); + } + + return ip; +}; + +/** + * Attempt to retrieve external IP from dyndns.org. + * @method + * @returns {Promise} + */ + +external.getIPv42 = async function getIPv42() { + var res, match, ip, raw; + + if (request.unsupported) + throw new Error('Could not find IP.'); + + res = await request({ + method: 'GET', + uri: 'http://checkip.dyndns.org', + expect: 'html', + timeout: 2000 + }); + + match = /IP Address:\s*([0-9a-f.:]+)/i.exec(res.body); + + if (!match) + throw new Error('Could not find IP.'); + + ip = match[1]; + raw = IP.toBuffer(ip); + + if (!IP.isMapped(raw)) + throw new Error('Could not find IP.'); + + return IP.toString(raw); +}; + +/** + * Attempt to retrieve external IP from icanhazip.com. + * @method + * @returns {Promise} + */ + +external.getIPv6 = async function getIPv6() { + var res, ip; + + if (request.unsupported) + throw new Error('Could not find IP.'); + + res = await request({ + method: 'GET', + uri: 'http://ipv6.icanhazip.com', + expect: 'txt', + timeout: 2000 + }); + + ip = res.body.trim(); + + return IP.normalize(ip); +}; diff --git a/lib/net/pool.js b/lib/net/pool.js index 56332b3f..75a3fe8f 100644 --- a/lib/net/pool.js +++ b/lib/net/pool.js @@ -24,7 +24,7 @@ var ec = require('../crypto/ec'); var Lock = require('../utils/lock'); var Network = require('../protocol/network'); var Peer = require('./peer'); -var request = require('../http/request'); +var external = require('./external'); var List = require('../utils/list'); var tcp = require('./tcp'); var dns = require('./dns'); @@ -563,7 +563,7 @@ Pool.prototype.discoverSeeds = async function discoverSeeds(checkPeers) { Pool.prototype.discoverExternal = async function discoverExternal() { var port = this.options.publicPort; - var host; + var host4, host6; // Pointless if we're not listening. if (!this.options.listen) @@ -579,15 +579,24 @@ Pool.prototype.discoverExternal = async function discoverExternal() { return; try { - host = await this.getIP(); + host4 = await external.getIPv4(); } catch (e) { - this.logger.debug('Could not find external IP (http).'); + this.logger.debug('Could not find external IPv4 (http).'); this.logger.debug(e); - return; } - if (this.hosts.addLocal(host, port, scores.HTTP)) - this.logger.info('External IP found (http): %s.', host); + if (host4 && this.hosts.addLocal(host4, port, scores.HTTP)) + this.logger.info('External IPv4 found (http): %s.', host4); + + try { + host6 = await external.getIPv6(); + } catch (e) { + this.logger.debug('Could not find external IPv6 (http).'); + this.logger.debug(e); + } + + if (host6 && this.hosts.addLocal(host6, port, scores.HTTP)) + this.logger.info('External IPv6 found (http): %s.', host6); }; /** @@ -3702,69 +3711,6 @@ Pool.prototype.announceTX = function announceTX(msg) { peer.announceTX(msg); }; -/** - * Attempt to retrieve external IP from icanhazip.com. - * @method - * @returns {Promise} - */ - -Pool.prototype.getIP = async function getIP() { - var res, ip; - - if (request.unsupported) - throw new Error('Could not find IP.'); - - try { - res = await request({ - method: 'GET', - uri: 'http://icanhazip.com', - expect: 'txt', - timeout: 2000 - }); - } catch (e) { - return await this.getIP2(); - } - - ip = res.body.trim(); - - try { - ip = IP.normalize(ip); - } catch (e) { - return await this.getIP2(); - } - - return ip; -}; - -/** - * Attempt to retrieve external IP from dyndns.org. - * @method - * @returns {Promise} - */ - -Pool.prototype.getIP2 = async function getIP2() { - var res, match, ip; - - if (request.unsupported) - throw new Error('Could not find IP.'); - - res = await request({ - method: 'GET', - uri: 'http://checkip.dyndns.org', - expect: 'html', - timeout: 2000 - }); - - match = /IP Address:\s*([0-9a-f.:]+)/i.exec(res.body); - - if (!match) - throw new Error('Could not find IP.'); - - ip = match[1]; - - return IP.normalize(ip); -}; - /** * PoolOptions * @alias module:net.PoolOptions diff --git a/package.json b/package.json index 6c626ee2..26c4b5da 100644 --- a/package.json +++ b/package.json @@ -81,6 +81,7 @@ "./lib/http/wallet": "./browser/empty.js", "./lib/mempool/layout": "./lib/mempool/layout-browser.js", "./lib/net/dns": "./lib/net/dns-browser.js", + "./lib/net/external": "./lib/net/external-browser.js", "./lib/net/tcp": "./lib/net/tcp-browser.js", "./lib/net/upnp": "./lib/net/upnp-browser.js", "./lib/utils/fs": "./browser/empty.js",