bittorrent-dht
Advanced tools
Comparing version 4.0.1 to 4.0.2
156
client.js
@@ -22,3 +22,2 @@ module.exports = DHT | ||
var sha = require('sha.js') | ||
var isarray = require('isarray') | ||
var bufcmp = require('buffer-equal') | ||
@@ -321,3 +320,3 @@ | ||
? sha1(opts.salt ? Buffer.concat([ opts.salt, opts.k ]) : opts.k) | ||
: sha1(opts.v) | ||
: sha1(bencode.encode(opts.v)) | ||
@@ -329,3 +328,3 @@ if (self.nodes.toArray().length === 0) { | ||
} else { | ||
self.lookup(hash, onLookup) | ||
self.lookup(hash, {findNode: true}, onLookup) | ||
} | ||
@@ -368,21 +367,39 @@ | ||
pending += 1 | ||
var t = self._getTransactionId(node.addr, next(node)) | ||
var data = { | ||
var t = self._getTransactionId(node.addr, putOnGet) | ||
self._send(node.addr, { | ||
a: { | ||
id: opts.id || self.nodeId, | ||
v: opts.v | ||
id: self.nodeId, | ||
target: hash | ||
}, | ||
t: transactionIdToBuffer(t), | ||
y: 'q', | ||
q: 'put' | ||
q: 'get' | ||
}) | ||
function putOnGet (err, res) { | ||
if (err) return next(node)(err) | ||
var t = self._getTransactionId(node.addr, next(node)) | ||
var data = { | ||
a: { | ||
id: opts.id || self.nodeId, | ||
v: opts.v, | ||
token: res && res.token | ||
}, | ||
t: transactionIdToBuffer(t), | ||
y: 'q', | ||
q: 'put' | ||
} | ||
if (isMutable) { | ||
data.a.token = opts.token || self._generateToken(node.addr) | ||
data.a.seq = opts.seq | ||
data.a.sig = opts.sign(encodeSigData(opts)) | ||
data.a.k = opts.k | ||
if (opts.salt) data.a.salt = opts.salt | ||
if (opts.cas) data.a.cas = opts.cas | ||
} | ||
self._send(node.addr, data) | ||
} | ||
if (isMutable) { | ||
data.a.token = opts.token || self._generateToken(node.addr) | ||
data.a.seq = opts.seq | ||
data.a.sig = opts.sign(encodeSigData(opts)) | ||
data.a.k = opts.k | ||
if (opts.salt) data.a.salt = opts.salt | ||
if (opts.cas) data.a.cas = opts.cas | ||
} | ||
self._send(node.addr, data) | ||
} | ||
@@ -410,54 +427,3 @@ | ||
self.lookup(hash, fromNodes) | ||
function fromNodes (err, nodes) { | ||
if (err) return cb(err) | ||
var pending = nodes.length | ||
var match = false | ||
var nextNodes = {} | ||
nodes.forEach(function (node) { | ||
var t = self._getTransactionId(node.addr, next) | ||
self._send(node.addr, { | ||
a: { | ||
id: self.nodeId, | ||
target: hash | ||
}, | ||
t: transactionIdToBuffer(t), | ||
y: 'q', | ||
q: 'get' | ||
}) | ||
function next (err, res) { | ||
if (err) {} // not important | ||
if (match) return | ||
if (res && res.v) { | ||
var isMutable = res.k || res.sig | ||
var sdata = encodeSigData(res) | ||
if (isMutable && !self._verify) { | ||
self._debug('ed25519 verify not provided') | ||
} else if (isMutable && !self._verify(res.sig, sdata, res.k)) { | ||
self._debug('invalid mutable hash from %s', node.addr) | ||
} else if (!isMutable && !bufcmp(sha1(res.v), hash)) { | ||
self._debug('invalid immutable hash from %s', node.addr) | ||
} else { | ||
match = true | ||
return cb(null, res) | ||
} | ||
} | ||
if (res && isarray(res.nodes)) { | ||
res.nodes.forEach(function (n) { | ||
nextNodes[n] = true | ||
}) | ||
} | ||
if (--pending === 0) { | ||
var keys = Object.keys(nextNodes) | ||
if (keys.length === 0) cb(new Error('hash not found')) | ||
else fromNodes(keys.map(function (key) { return { addr: key } })) | ||
} | ||
} | ||
}) | ||
} | ||
self.lookup(hash, {get: true}, cb) | ||
} | ||
@@ -493,3 +459,3 @@ | ||
} else { | ||
hash = sha1(data.v) | ||
hash = sha1(bencode.encode(data.v)) | ||
} | ||
@@ -505,3 +471,3 @@ if (isMutable) { | ||
var prev = self.nodes.get(hash) | ||
if (prev && prev.data.seq !== undefined && msg.cas) { | ||
if (prev && prev.data && prev.data.seq !== undefined && msg.cas) { | ||
if (msg.cas !== prev.data.seq) { | ||
@@ -512,3 +478,3 @@ return self._sendError(addr, message.t, 301, | ||
} | ||
if (prev && prev.data.seq !== undefined) { | ||
if (prev && prev.data && prev.data.seq !== undefined) { | ||
if (msg.seq === undefined || msg.seq <= prev.data.seq) { | ||
@@ -544,2 +510,3 @@ return self._sendError(addr, message.t, 302, | ||
var addrData = addrToIPPort(addr) | ||
var hash = message.a.target | ||
@@ -581,2 +548,3 @@ var rec = self.nodes.get(hash) | ||
r: { | ||
token: self._generateToken(addrData[0]), | ||
id: self.nodeId, | ||
@@ -946,3 +914,5 @@ nodes: nodes.map(function (node) { | ||
if (opts.findNode) { | ||
if (opts.get) { | ||
self._sendGet(addr, id, onResponse.bind(null, addr)) | ||
} else if (opts.findNode) { | ||
self._sendFindNode(addr, id, onResponse.bind(null, addr)) | ||
@@ -963,3 +933,17 @@ } else { | ||
function onResponse (addr, err, res) { | ||
if (cb.called) return | ||
if (self.destroyed) return cb(new Error('dht is destroyed')) | ||
if (opts.get && res && res.v) { | ||
var isMutable = res.k || res.sig | ||
var sdata = encodeSigData(res) | ||
if (isMutable && !self._verify) { | ||
self._debug('ed25519 verify not provided') | ||
} else if (isMutable && !self._verify(res.sig, sdata, res.k)) { | ||
self._debug('invalid mutable hash from %s', addr) | ||
} else if (!isMutable && !bufcmp(sha1(bencode.encode(res.v)), id)) { | ||
self._debug('invalid immutable hash from %s', addr) | ||
} else { | ||
return cb(null, res) | ||
} | ||
} | ||
@@ -1010,2 +994,3 @@ pending -= 1 | ||
}) | ||
if (opts.get) return cb(new Error('hash not found')) | ||
cb(null, closest) | ||
@@ -1226,2 +1211,27 @@ } | ||
DHT.prototype._sendGet = function (addr, nodeId, cb) { | ||
var self = this | ||
function onResponse (err, res) { | ||
if (err) return cb(err) | ||
if (res.nodes) { | ||
res.nodes = parseNodeInfo(res.nodes) | ||
res.nodes.forEach(function (node) { | ||
self._addNode(node.addr, node.id, addr) | ||
}) | ||
} | ||
cb(null, res) | ||
} | ||
var data = { | ||
q: 'get', | ||
a: { | ||
id: self.nodeId, | ||
target: nodeId | ||
} | ||
} | ||
self._query(data, addr, onResponse) | ||
} | ||
/** | ||
@@ -1228,0 +1238,0 @@ * Called when another node sends a "find_node" query. |
{ | ||
"name": "bittorrent-dht", | ||
"description": "Simple, robust, BitTorrent DHT implementation", | ||
"version": "4.0.1", | ||
"version": "4.0.2", | ||
"author": { | ||
@@ -6,0 +6,0 @@ "name": "Feross Aboukhadijeh", |
@@ -21,3 +21,3 @@ var common = require('./common') | ||
hash.toString('hex'), | ||
'3ab87d68b1be9dc63da13faf18a7d2376ccd938a' // sha1 of the value | ||
'3a34a097641348623d123acfba3aa589028f241e' // sha1 of the value | ||
) | ||
@@ -65,3 +65,3 @@ dht.get(hash, function (err, res) { | ||
hash.toString('hex'), | ||
'3ab87d68b1be9dc63da13faf18a7d2376ccd938a' // sha1 of the value | ||
'3a34a097641348623d123acfba3aa589028f241e' // sha1 of the value | ||
) | ||
@@ -68,0 +68,0 @@ dht2.get(hash, function (err, res) { |
@@ -180,11 +180,10 @@ var common = require('./common') | ||
dht2._sendAnnouncePeer('127.0.0.1:' + port, infoHash, 9999, res1.token, function (err, res2) { | ||
t.error(err) | ||
t.deepEqual(res2.id, dht1.nodeId) | ||
t.error(err) | ||
t.deepEqual(res2.id, dht1.nodeId) | ||
dht1.destroy() | ||
dht2.destroy() | ||
} | ||
) | ||
dht1.destroy() | ||
dht2.destroy() | ||
}) | ||
}) | ||
}) | ||
}) |
94483
2643