Move connection to self detection to transport

This commit is contained in:
Kagami Hiiragi 2015-02-24 19:38:03 +03:00
parent 2bdd415835
commit 3f25744017
4 changed files with 15 additions and 21 deletions

View File

@ -107,7 +107,6 @@ var messages = require("bitmessage").messages;
// Simple encoding and decoding: // Simple encoding and decoding:
var vermsg = messages.version.encode({ var vermsg = messages.version.encode({
nonce: Buffer(8), // Hack detection connection to self
remoteHost: "1.1.1.1", remoteHost: "1.1.1.1",
remotePort: 8444, remotePort: 8444,
}); });

View File

@ -10,7 +10,6 @@
* *
* // Simple encoding and decoding: * // Simple encoding and decoding:
* var vermsg = messages.version.encode({ * var vermsg = messages.version.encode({
* nonce: Buffer(8), // Hack detection connection to self
* remoteHost: "1.1.1.1", * remoteHost: "1.1.1.1",
* remotePort: 8444, * remotePort: 8444,
* }); * });
@ -35,7 +34,6 @@
"use strict"; "use strict";
var objectAssign = Object.assign || require("object-assign"); var objectAssign = Object.assign || require("object-assign");
var bufferEqual = require("buffer-equal");
var assert = require("./_util").assert; var assert = require("./_util").assert;
var structs = require("./structs"); var structs = require("./structs");
var bmcrypto = require("./crypto"); var bmcrypto = require("./crypto");
@ -69,9 +67,6 @@ exports.getCommand = function(buf) {
return command.slice(0, firstNonNull).toString("ascii"); return command.slice(0, firstNonNull).toString("ascii");
}; };
// Random nonce used to detect connections to self.
var randomNonce = bmcrypto.randomBytes(8);
/** /**
* `version` message. * `version` message.
* @see {@link https://bitmessage.org/wiki/Protocol_specification#version} * @see {@link https://bitmessage.org/wiki/Protocol_specification#version}
@ -97,8 +92,8 @@ var version = exports.version = {
* message * message
* @property {number} port - Incoming port of the node sending this * @property {number} port - Incoming port of the node sending this
* message * message
* @property {Buffer} nonce - Random nonce used to detect connection * @property {Buffer} nonce - An 8-byte random nonce used to detect
* to self * connection to self
* @property {string} userAgent - [User agent]{@link * @property {string} userAgent - [User agent]{@link
* module:bitmessage/user-agent} of the node * module:bitmessage/user-agent} of the node
* @property {number[]} streams - Streams accepted by the node * @property {number[]} streams - Streams accepted by the node
@ -106,6 +101,12 @@ var version = exports.version = {
* @memberof module:bitmessage/messages.version * @memberof module:bitmessage/messages.version
*/ */
/**
* Random nonce used to detect connections to self.
* @constant {Buffer}
*/
randomNonce: bmcrypto.randomBytes(8),
/** /**
* Decode `version` message. * Decode `version` message.
* NOTE: `nonce` is copied. * NOTE: `nonce` is copied.
@ -134,7 +135,6 @@ var version = exports.version = {
var addrFrom = structs.net_addr.decode(buf.slice(46, 72), short); var addrFrom = structs.net_addr.decode(buf.slice(46, 72), short);
var nonce = new Buffer(8); var nonce = new Buffer(8);
buf.copy(nonce, 0, 72, 80); buf.copy(nonce, 0, 72, 80);
assert(!bufferEqual(nonce, randomNonce), "Connection to self");
var decodedUa = UserAgent.decode(buf.slice(80)); var decodedUa = UserAgent.decode(buf.slice(80));
var decodedStreams = structs.var_int_list.decode(decodedUa.rest); var decodedStreams = structs.var_int_list.decode(decodedUa.rest);
return { return {
@ -169,8 +169,8 @@ var version = exports.version = {
* message * message
* @param {number=} opts.port - Incoming port of the node (8444 by * @param {number=} opts.port - Incoming port of the node (8444 by
* default) * default)
* @param {Buffer=} opts.nonce - Random nonce used to detect connection * @param {Buffer=} opts.nonce - An 8-byte random nonce used to detect
* to self (unique per node.js process by default) * connection to self (unique per node.js process by default)
* @param {(Array|string|Buffer)=} opts.userAgent - * @param {(Array|string|Buffer)=} opts.userAgent -
* [User agent]{@link module:bitmessage/user-agent} of the node * [User agent]{@link module:bitmessage/user-agent} of the node
* (user agent of bitmessage library by default) * (user agent of bitmessage library by default)
@ -192,7 +192,7 @@ var version = exports.version = {
var services = opts.services || var services = opts.services ||
ServicesBitfield().set(ServicesBitfield.NODE_NETWORK); ServicesBitfield().set(ServicesBitfield.NODE_NETWORK);
var time = opts.time || new Date(); var time = opts.time || new Date();
var nonce = opts.nonce || randomNonce; var nonce = opts.nonce || version.randomNonce;
assert(nonce.length === 8, "Bad nonce"); assert(nonce.length === 8, "Bad nonce");
var port = opts.port || 8444; var port = opts.port || 8444;
var userAgent = opts.userAgent || UserAgent.SELF; var userAgent = opts.userAgent || UserAgent.SELF;

View File

@ -12,6 +12,7 @@
var inherits = require("inherits"); var inherits = require("inherits");
var EventEmitter = require("events").EventEmitter; var EventEmitter = require("events").EventEmitter;
var bufferEqual = require("buffer-equal");
var util = require("../_util"); var util = require("../_util");
var PPromise = require("../platform").Promise; var PPromise = require("../platform").Promise;
var structs = require("../structs"); var structs = require("../structs");
@ -157,6 +158,9 @@ BaseTransport.prototype._decodeVersion = function(payload, opts) {
if (delta < -3600) { if (delta < -3600) {
throw new Error("Peer's time is too far in the past: " + delta + "s"); throw new Error("Peer's time is too far in the past: " + delta + "s");
} }
if (bufferEqual(version.nonce, messages.version.randomNonce)) {
throw new Error("Connection to self");
}
if (!intersects(this.streams, version.streams)) { if (!intersects(this.streams, version.streams)) {
throw new Error( throw new Error(
"Peer isn't interested in our streams; " + "Peer isn't interested in our streams; " +

View File

@ -514,18 +514,9 @@ describe("Message types", function() {
remotePort: 48444, remotePort: 48444,
port: 8444, port: 8444,
userAgent: "/test:0.0.1/", userAgent: "/test:0.0.1/",
nonce: Buffer(8),
})); }));
expect(res.userAgent).to.equal("/test:0.0.1/"); expect(res.userAgent).to.equal("/test:0.0.1/");
}); });
it("should fail on connection to self", function() {
expect(version.decode.bind(null, version.encode({
remoteHost: "1.2.3.4",
remotePort: 48444,
port: 8444,
}))).to.throw(/connection to self/i);
});
}); });
describe("addr", function() { describe("addr", function() {