TCP bootstrap
This commit is contained in:
parent
84ab3ec3a0
commit
40d40c55aa
|
@ -8,6 +8,7 @@
|
||||||
|
|
||||||
var inherits = require("inherits");
|
var inherits = require("inherits");
|
||||||
var net = require("net");
|
var net = require("net");
|
||||||
|
var dns = require("dns");
|
||||||
var assert = require("../_util").assert;
|
var assert = require("../_util").assert;
|
||||||
var PPromise = require("../platform").Promise;
|
var PPromise = require("../platform").Promise;
|
||||||
var BaseTransport = require("./base").BaseTransport;
|
var BaseTransport = require("./base").BaseTransport;
|
||||||
|
@ -22,9 +23,8 @@ var sockIdCounter = 0;
|
||||||
function Transport(opts) {
|
function Transport(opts) {
|
||||||
Transport.super_.call(this);
|
Transport.super_.call(this);
|
||||||
opts = opts || {};
|
opts = opts || {};
|
||||||
if (opts.seeds) {
|
this.seeds = opts.seeds || [];
|
||||||
this.seeds = opts.seeds;
|
this.dnsSeeds = opts.dnsSeeds || [];
|
||||||
}
|
|
||||||
if (opts.client) {
|
if (opts.client) {
|
||||||
this._setupClient(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() {
|
Transport.prototype.bootstrap = function() {
|
||||||
// TODO(Kagami): Think how to set up DNS/IP nodes. Do we need to
|
var promises = this.dnsSeeds.map(resolveDnsSeed);
|
||||||
// hardcode them?
|
var hardcodedNodes = this.seeds;
|
||||||
|
// FIXME(Kagami): Filter incorrect/private IP range nodes?
|
||||||
|
// See also: <https://github.com/Bitmessage/PyBitmessage/issues/768>.
|
||||||
|
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() {
|
Transport.prototype.connect = function() {
|
||||||
|
@ -92,6 +130,7 @@ Transport.prototype.listen = function() {
|
||||||
var transport = new self.constructor({
|
var transport = new self.constructor({
|
||||||
client: sock,
|
client: sock,
|
||||||
seeds: this.seeds,
|
seeds: this.seeds,
|
||||||
|
dnsSeeds: this.dnsSeeds,
|
||||||
});
|
});
|
||||||
self.emit("connection", transport);
|
self.emit("connection", transport);
|
||||||
});
|
});
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
var expect = require("chai").expect;
|
||||||
|
|
||||||
var bitmessage = require("../lib");
|
var bitmessage = require("../lib");
|
||||||
var structs = bitmessage.structs;
|
var structs = bitmessage.structs;
|
||||||
var message = structs.message;
|
var message = structs.message;
|
||||||
|
@ -18,6 +20,35 @@ if (!process.browser) {
|
||||||
setTimeout(done, 1000);
|
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) {
|
it("should allow to interconnect two nodes", function(done) {
|
||||||
tcp.connect(22333, "127.0.0.1");
|
tcp.connect(22333, "127.0.0.1");
|
||||||
tcp.on("open", function() {
|
tcp.on("open", function() {
|
||||||
|
|
|
@ -30,7 +30,7 @@ module.exports = function() {
|
||||||
} catch(e) {
|
} catch(e) {
|
||||||
console.log(e.stack);
|
console.log(e.stack);
|
||||||
}
|
}
|
||||||
if (err) console.log(err.stack);
|
if (err && err.stack) console.log(err.stack);
|
||||||
if (doExit) process.exit(1);
|
if (doExit) process.exit(1);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user