Skip to content
This repository has been archived by the owner on Oct 30, 2018. It is now read-only.

Commit

Permalink
Merge pull request #184 from bookchin/master
Browse files Browse the repository at this point in the history
v1.2.7
  • Loading branch information
bookchin committed Jun 17, 2016
2 parents ab424e4 + 72fa190 commit 6c61609
Show file tree
Hide file tree
Showing 4 changed files with 130 additions and 2 deletions.
2 changes: 2 additions & 0 deletions lib/constants.js
Expand Up @@ -17,6 +17,8 @@ module.exports = {
CLEAN_INTERVAL: 10800000,
/** @constant {Number} TUNNEL_ANNOUNCE_INTERVAL - Announce tunnel state */
TUNNEL_ANNOUNCE_INTERVAL: 900000,
/** @constant {Number} ROUTER_CLEAN_INTERVAL - Drop bad contacts */
ROUTER_CLEAN_INTERVAL: 60000,
/** @constant {Number} OPCODE_TUNRPC_PREFIX - Opcode for tunnel rpc message */
OPCODE_TUNRPC_PREFIX: 0x0c,
/** @constant {Number} OPCODE_TUNDCX_PREFIX - Opcode for tunnel datachannel */
Expand Down
52 changes: 51 additions & 1 deletion lib/network/index.js
Expand Up @@ -86,6 +86,12 @@ Network.DEFAULTS = {
gateways: { min: 0, max: 0 } // NB: Port range for gatways - default any
};

Network.RPC_VALIDATION_EXEMPT = [
'PROBE',
'FIND_TUNNEL',
'OPEN_TUNNEL'
];

/**
* Check the options supplied to the constructor
* @private
Expand Down Expand Up @@ -283,7 +289,9 @@ Network.prototype._initNetworkInterface = function() {
logger: this._logger
});
this._limiter = new RateLimiter(this._options.limiter);

this._transport.after('open', this._onTransportOpen.bind(this));
this._startRouterCleaner();
};

/**
Expand Down Expand Up @@ -377,7 +385,7 @@ Network.prototype._verifyMessage = function(message, contact, callback) {
var self = this;

this._validateContact(contact, function(err) {
if (err) {
if (err && Network.RPC_VALIDATION_EXEMPT.indexOf(message.method) === -1) {
return callback(err);
}

Expand Down Expand Up @@ -701,4 +709,46 @@ Network.prototype._establishTunnel = function(tunnels, callback) {
});
};

/**
* Cleans invalid contacts from routing table
* @private
*/
Network.prototype._cleanRoutingTable = function() {
var dropped = [];

for (var k in this._router._buckets) {
var bucket = this._router._buckets[k];
var bucketList = bucket.getContactList();

for (var i = 0; i < bucketList.length; i++) {
var isValidContact = utils.isValidContact(
bucketList[i],
process.env.STORJ_ALLOW_LOOPBACK
);
var isValidProtocol = utils.isCompatibleVersion(bucketList[i].protocol);

if (!isValidContact || !isValidProtocol) {
dropped.push(bucketList[i]);
bucket.removeContact(bucketList[i]);
}
}
}

return dropped;
};

/**
* Cleans the routing table on an interval
* @private
*/
Network.prototype._startRouterCleaner = function() {
var self = this;

setInterval(function() {
self._logger.debug('cleaning bad contacts from routing table');
var dropped = self._cleanRoutingTable();
self._logger.debug('dropping %s bad contacts from router', dropped.length);
}, constants.ROUTER_CLEAN_INTERVAL);
};

module.exports = Network;
2 changes: 1 addition & 1 deletion package.json
@@ -1,6 +1,6 @@
{
"name": "storj",
"version": "1.2.6",
"version": "1.2.7",
"description": "implementation of the storj protocol for node.js and the browser",
"main": "index.js",
"directories": {
Expand Down
76 changes: 76 additions & 0 deletions test/network/index.unit.js
Expand Up @@ -12,6 +12,8 @@ var sinon = require('sinon');
var version = require('../../lib/version');
var utils = require('../../lib/utils');
var version = require('../../lib/version');
var Contact = require('../../lib/network/contact');
var constants = require('../../lib/constants');

describe('Network (public)', function() {

Expand Down Expand Up @@ -797,3 +799,77 @@ describe('Network (private)', function() {
});

});

describe('Network (private/jobs)', function() {

describe('#_startRouterCleaner', function() {

it('should call _cleanRoutingTable', function(done) {
constants.ROUTER_CLEAN_INTERVAL = 10;
var _cleanRoutingTable = sinon.stub(
Network.prototype,
'_cleanRoutingTable'
).returns([]);
Network({
keypair: KeyPair(),
manager: Manager(RAMStorageAdapter()),
logger: kad.Logger(0),
seeds: [],
bridge: false,
address: '127.0.0.1',
port: 0,
noforward: true
});
setTimeout(function() {
_cleanRoutingTable.restore();
constants.ROUTER_CLEAN_INTERVAL = 60000;
expect(_cleanRoutingTable.called).to.equal(true);
done();
}, 20);
});

});

describe('#_cleanRoutingTable', function() {

it('should drop the contacts with bad address or version', function() {
var net = Network({
keypair: KeyPair(),
manager: Manager(RAMStorageAdapter()),
logger: kad.Logger(0),
seeds: [],
bridge: false,
address: '127.0.0.1',
port: 0,
noforward: true
});
net._router._buckets[0] = new kad.Bucket();
net._router._buckets[2] = new kad.Bucket();
net._router._buckets[0].addContact(Contact({
address: 'some.public.ip',
port: 80,
nodeID: kad.utils.createID('node1'),
protocol: version.protocol
}));
net._router._buckets[2].addContact(Contact({
address: 'some.public.ip',
port: 81,
nodeID: kad.utils.createID('node2'),
protocol: '0.0.0'
}));
net._router._buckets[2].addContact(Contact({
address: '127.0.0.1',
port: 0,
nodeID: kad.utils.createID('node3'),
protocol: version.protocol
}));
var dropped = net._cleanRoutingTable();
expect(dropped).to.have.lengthOf(2);
expect(net._router._buckets[0].getSize()).to.equal(1);
expect(net._router._buckets[2].getSize()).to.equal(0);
});

});


});

0 comments on commit 6c61609

Please sign in to comment.