peer: handle address timestamp better.
Signed-off-by: Fedor Indutny <fedor@indutny.com>
This commit is contained in:
parent
a0c2f66169
commit
44fab2b58a
@ -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) {
|
||||
|
||||
@ -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);
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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);
|
||||
|
||||
Loading…
Reference in New Issue
Block a user