peer: handle address timestamp better.

Signed-off-by: Fedor Indutny <fedor@indutny.com>
This commit is contained in:
Christopher Jeffrey 2014-05-19 19:34:01 -05:00 committed by Fedor Indutny
parent a0c2f66169
commit 44fab2b58a
4 changed files with 36 additions and 39 deletions

View File

@ -27,6 +27,7 @@ function Peer(pool, createSocket, options) {
this.version = null;
this.destroyed = false;
this.ack = false;
this.ts = null;
this.options = options || {};
if (this.options.backoff) {
@ -69,6 +70,9 @@ module.exports = Peer;
Peer.prototype._init = function init() {
var self = this;
this.socket.once('connect', function() {
self.ts = Date.now() / 1000 | 0;
});
this.socket.once('error', function(err) {
self._error(err);
});
@ -99,6 +103,7 @@ Peer.prototype._init = function init() {
return self._error(err);
self.ack = true;
self.emit('ack');
self.ts = Date.now() / 1000 | 0;
});
};
@ -314,13 +319,19 @@ Peer.prototype._handleGetData = function handleGetData(items) {
};
Peer.prototype._handleAddr = function handleAddr(addrs) {
var now = Date.now();
addrs.forEach(function(addr) {
// bitcoind does this for some reason:
if (addr.ts <= 100000000 || addr.ts > now + 10 * 60)
addr.ts = now - 5 * 24 * 60 * 60;
this.emit('addr', {
date: new Date(addr.date * 1000),
network: addr.network,
address: addr.ipv4,
date: new Date(addr.ts * 1000),
ts: addr.ts,
service: addr.service,
ipv4: addr.ipv4,
ipv6: addr.ipv6,
address: addr.ipv4,
address6: addr.ipv6,
port: addr.port,
host: addr.ipv4 + ':' + addr.port,
host6: '[' + addr.ipv6 + ']:' + addr.port
@ -352,7 +363,8 @@ Peer.prototype._handleGetAddr = function handleGetAddr() {
return;
return {
host: peer.socket.remoteAddress,
port: peer.socket.remotePort || 8333
port: peer.socket.remotePort || 8333,
ts: peer.ts
};
}).filter(function(peer) {
if (!peer || ~used.indexOf(peer.host))
@ -366,11 +378,12 @@ Peer.prototype._handleGetAddr = function handleGetAddr() {
ipv4: ver === 4 ? ip : '127.0.0.1',
ipv6: ver === 6 ? ip : '0000:0000:0000:0000:0000:0000:0000:ffff',
port: peer.port,
ts: peer.ts,
ver: ver
};
});
peers = peers.map(function(peer) {
var addrs = peers.map(function(peer) {
if (peer.ver === 6) {
while (peer.ipv6.split(':').length < 8)
peer.ipv6 = '0000:' + peer.ipv6;
@ -387,7 +400,7 @@ Peer.prototype._handleGetAddr = function handleGetAddr() {
return peer;
}).filter(Boolean);
return this._write(this.framer.addr(peers));
return this._write(this.framer.addr(addrs));
};
Peer.prototype._handleInv = function handleInv(items) {

View File

@ -327,6 +327,7 @@ Framer.prototype.addr = function addr(peers) {
var i = 0;
var c = 0;
var peer;
var start = (Date.now() / 1000 | 0) - process.uptime();
// count
c += varint(p, peers.length, c);
@ -334,8 +335,8 @@ Framer.prototype.addr = function addr(peers) {
for (; i < peers.length; i++) {
peer = peers[i];
// date
c += utils.writeU32(p, Date.now() / 1000 | 0, c);
// timestamp
c += utils.writeU32(p, peer.ts || start, c);
// NODE_NETWORK service
c += utils.writeU64(p, 1, c);

View File

@ -356,7 +356,7 @@ Parser.prototype.parseAddr = function parseAddr(p) {
return this._error('Invalid addr size');
var addrs = [];
var len, off, count, date, network, ipv4, ipv6, port, i;
var len, off, count, ts, service, ipv4, ipv6, port, i;
// count
len = readIntv(p, 0);
@ -365,11 +365,11 @@ Parser.prototype.parseAddr = function parseAddr(p) {
p = p.slice(off);
for (i = 0; i < count; i++) {
// date - LE
date = utils.readU32(p, 0);
// ts - LE
ts = utils.readU32(p, 0);
// NODE_NETWORK service - LE
network = utils.readU64(p, 4);
service = utils.readU64(p, 4);
// ipv6 - BE
ipv6 = utils.toHex(p.slice(12, 24));
@ -386,8 +386,8 @@ Parser.prototype.parseAddr = function parseAddr(p) {
port = utils.readU16BE(p, 28);
addrs.push({
date: date,
network: network,
ts: ts,
service: service,
ipv6: ipv6,
ipv4: ipv4,
port: port

View File

@ -34,12 +34,14 @@ describe('Protocol', function() {
{
ipv6: '0000:0000:0000:0000:0000:0000:0000:ffff',
ipv4: '127.0.0.1',
port: 8333
port: 8333,
ts: Date.now() / 1000 | 0
},
{
ipv6: '0000:0000:0000:0000:0000:7f00:0001:ffff',
ipv4: '10.0.0.1',
port: 18333
port: 18333,
ts: Date.now() / 1000 | 0
}
];
@ -54,37 +56,18 @@ describe('Protocol', function() {
addr._ipv6 = '::' + addr._ipv6.split(':').slice(2).join(':');
});
packetTest('addr', peers, function(payload) {
// XXX Legacy
if (!parser.parseAddr) {
var addrs = [];
bcoin.peer.prototype._handleAddr.call({
emit: function(_, obj) {
addrs.push(obj);
}
}, payload);
payload = addrs;
payload.forEach(function(addr) {
addr.date = addr.date.getTime() / 1000 | 0;
delete addr.address;
delete addr.host;
delete addr.host6;
addr.ipv6 = '::' + addr.ipv6;
});
}
assert.equal(typeof payload.length, 'number');
assert.equal(payload.length, 2);
assert.equal(typeof payload[0].date, 'number');
assert.equal(payload[0].network, 1);
assert.equal(typeof payload[0].ts, 'number');
assert.equal(payload[0].service, 1);
assert.equal(payload[0].ipv6, peers[0]._ipv6);
assert.equal(payload[0].ipv4, peers[0]._ipv4);
assert.equal(payload[0].port, peers[0].port);
assert.equal(typeof payload[1].date, 'number');
assert.equal(payload[1].network, 1);
assert.equal(typeof payload[1].ts, 'number');
assert.equal(payload[1].service, 1);
assert.equal(payload[1].ipv6, peers[1]._ipv6);
assert.equal(payload[1].ipv4, peers[1]._ipv4);
assert.equal(payload[1].port, peers[1].port);