diff --git a/lib/bcoin/peer.js b/lib/bcoin/peer.js index dbf5dad0..f87173d0 100644 --- a/lib/bcoin/peer.js +++ b/lib/bcoin/peer.js @@ -312,7 +312,45 @@ Peer.prototype._handleGetData = function handleGetData(items) { }; Peer.prototype._handleAddr = function handleAddr(addr) { - // No-op for now + var count, date, network, ipv4, ipv6, port, i; + + // count + count = addr[0]; + addr = addr.slice(1); + + for (i = 0; i < count; i++) { + // date - LE + date = utils.readU32(addr, 0); + + // NODE_NETWORK service - LE + network = utils.readU64(addr, 4); + + // ipv4 - BE + ipv4 = utils.readU32BE(addr, 24); + + // ipv6 - BE + ipv6 = utils.toHex(addr.slice(12, 24)); + ipv6 = ipv6.replace(/(.{4})/g, '$1:').replace(/:$/, ''); + + // port - BE + port = utils.readU16BE(addr, 28); + + this.emit('addr', { + date: new Date(date * 1000), + network: network, + ipv4: ipv4, + ipv6: ipv6, + port: port, + host: ((ipv4 >> 24) & 0xff) + '.' + + ((ipv4 >> 16) & 0xff) + '.' + + ((ipv4 >> 8) & 0xff) + '.' + + ((ipv4 >> 0) & 0xff) + ':' + + port, + host6: '[' + ipv6 + ']:' + port + }); + + addr = addr.slice(30); + } }; Peer.prototype._handlePing = function handlePing() { diff --git a/lib/bcoin/utils.js b/lib/bcoin/utils.js index 1adf947e..e8cf23d8 100644 --- a/lib/bcoin/utils.js +++ b/lib/bcoin/utils.js @@ -168,6 +168,30 @@ utils.writeU32 = function writeU32(dst, num, off) { return 4; }; +utils.readU16BE = function readU16BE(arr, off) { + if (!off) + off = 0; + return (arr[off] << 8) | arr[off + 1]; +}; + +utils.readU32BE = function readU32BE(arr, off) { + if (!off) + off = 0; + var r = (arr[off] << 24) | + (arr[off + 1] << 16) | + (arr[off + 2] << 8) | + arr[off + 3]; + if (r < 0) + r += 0x100000000; + return r; +}; + +utils.readU64BE = function readU64BE(arr, off) { + if (!off) + off = 0; + return utils.readU32BE(arr, off) * 0x100000000 + utils.readU32BE(arr, off + 4); +}; + utils.writeAscii = function writeAscii(dst, str, off) { for (var i = 0; i < str.length; i++) { var c = str.charCodeAt(i);