From 40d40c55aa576b8e782a9a86a271c2b34fdf8a8a Mon Sep 17 00:00:00 2001 From: Kagami Hiiragi Date: Thu, 5 Feb 2015 22:55:36 +0300 Subject: [PATCH] TCP bootstrap --- lib/net/tcp.js | 49 ++++++++++++++++++++++++++++++++++++----- tests/functional.js | 31 ++++++++++++++++++++++++++ tests/run-test-nodes.js | 2 +- 3 files changed, 76 insertions(+), 6 deletions(-) diff --git a/lib/net/tcp.js b/lib/net/tcp.js index d60b807..eea2e51 100644 --- a/lib/net/tcp.js +++ b/lib/net/tcp.js @@ -8,6 +8,7 @@ var inherits = require("inherits"); var net = require("net"); +var dns = require("dns"); var assert = require("../_util").assert; var PPromise = require("../platform").Promise; var BaseTransport = require("./base").BaseTransport; @@ -22,9 +23,8 @@ var sockIdCounter = 0; function Transport(opts) { Transport.super_.call(this); opts = opts || {}; - if (opts.seeds) { - this.seeds = opts.seeds; - } + this.seeds = opts.seeds || []; + this.dnsSeeds = opts.dnsSeeds || []; if (opts.client) { this._setupClient(opts.client); } @@ -62,9 +62,47 @@ Transport.prototype._setupClient = function(client) { }); }; +function resolveDnsSeed(seed) { + var host = seed[0]; + var port = seed[1]; + var nodes = []; + // NOTE(Kagami): + // 1) Node's `getaddrinfo` (`dns.lookup`) returns only one address so + // we can't use it. + // 2) Node's `dig host any` (`dns.resolve`) doesn't return type of the + // record! So we resolve twice for A and AAAA. + // 3) We ignore any errors here, promise's result is always a list. + return new PPromise(function(resolve) { + dns.resolve4(host, function(err, nodes4) { + if (!err) { + nodes4.forEach(function(n) { + nodes.push([n, port]); + }); + } + dns.resolve6(host, function(err, nodes6) { + if (!err) { + nodes6.forEach(function(n) { + nodes.push([n, port]); + }); + } + resolve(nodes); + }); + }); + }); +} + Transport.prototype.bootstrap = function() { - // TODO(Kagami): Think how to set up DNS/IP nodes. Do we need to - // hardcode them? + var promises = this.dnsSeeds.map(resolveDnsSeed); + var hardcodedNodes = this.seeds; + // FIXME(Kagami): Filter incorrect/private IP range nodes? + // See also: . + return PPromise.all(promises).then(function(dnsNodes) { + // Add hardcoded nodes to the end of list because DNS nodes should + // be more up-to-date. + // Flatten array of array of arrays. + dnsNodes = Array.prototype.concat.apply([], dnsNodes); + return dnsNodes.concat(hardcodedNodes); + }); }; Transport.prototype.connect = function() { @@ -92,6 +130,7 @@ Transport.prototype.listen = function() { var transport = new self.constructor({ client: sock, seeds: this.seeds, + dnsSeeds: this.dnsSeeds, }); self.emit("connection", transport); }); diff --git a/tests/functional.js b/tests/functional.js index 1dc6ac0..0de3817 100644 --- a/tests/functional.js +++ b/tests/functional.js @@ -1,3 +1,5 @@ +var expect = require("chai").expect; + var bitmessage = require("../lib"); var structs = bitmessage.structs; var message = structs.message; @@ -18,6 +20,35 @@ if (!process.browser) { setTimeout(done, 1000); }); + it("should return nothing on bootstrap by default", function() { + return tcp.bootstrap().then(function(nodes) { + expect(nodes).to.be.empty; + }); + }); + + it("should resolve DNS seeds on bootstrap", function() { + var tcp2 = new TcpTransport({ + dnsSeeds: [["bootstrap8444.bitmessage.org", 8444]], + }); + return tcp2.bootstrap().then(function(nodes) { + expect(nodes).to.be.not.empty; + expect(nodes[0][1]).to.be.equal(8444); + }); + }); + + it("should return hardcoded seeds on bootstrap", function() { + var tcp3 = new TcpTransport({ + seeds: [["1.1.1.1", 8080]], + dnsSeeds: [["bootstrap8444.bitmessage.org", 8444]], + }); + return tcp3.bootstrap().then(function(nodes) { + expect(nodes).to.have.length.at.least(2); + expect(nodes[0][1]).to.be.equal(8444); + expect(nodes[nodes.length - 1][0]).to.equal("1.1.1.1"); + expect(nodes[nodes.length - 1][1]).to.equal(8080); + }); + }); + it("should allow to interconnect two nodes", function(done) { tcp.connect(22333, "127.0.0.1"); tcp.on("open", function() { diff --git a/tests/run-test-nodes.js b/tests/run-test-nodes.js index e246f1f..e602716 100644 --- a/tests/run-test-nodes.js +++ b/tests/run-test-nodes.js @@ -30,7 +30,7 @@ module.exports = function() { } catch(e) { console.log(e.stack); } - if (err) console.log(err.stack); + if (err && err.stack) console.log(err.stack); if (doExit) process.exit(1); }; }