-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathindex.js
More file actions
76 lines (74 loc) · 1.78 KB
/
index.js
File metadata and controls
76 lines (74 loc) · 1.78 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
const _ = require('./util');
const RPC = require('./rpc');
const Table = require('./table');
/**
* [DHT description]
* @docs http://bittorrent.org/beps/bep_0005.html
*/
class DHT extends RPC {
/**
* createServer
* @param {*} options
*/
static createServer(options) {
return new DHT(options);
}
constructor(options) {
super(options);
this.table = new Table(this);
this.on('ping', this.onPing.bind(this));
this.on('find_node', this.onFindNode.bind(this));
this.on('get_peers', this.onGetPeers.bind(this));
return this;
}
add(node) {
this.table.add(node);
return this;
}
get(id = this.id, k = 8) {
if (this.table.length < k) {
return this.bootstraps;
}
return this.table.get(id, k);
}
join() {
return this
.find_node(_.randomID())
.then(nodes => this.add(nodes))
.catch(e => this.emit('warning', e));
}
onPing(request, response) {
if (this.table.has(request)) {
response({ id: this.id });
} else {
this.emit('error', new Error(`ping, not found id ${request.id}`));
}
}
onFindNode(request, response) {
const { id, target } = request;
if (this.table.has(id)) {
const nodes = Buffer.concat(this.get(target).map(DHT.Node.encode));
response({ id: this.id, nodes });
}
}
onGetPeers(request, response) {
const { id, info_hash } = request;
if (this.table.has(id)) {
const nodes = Buffer.concat(this.get(info_hash).map(DHT.Node.encode));
response({ id: this.id, nodes });
}
}
/**
* listen
* @param {*} port
* @param {*} callback
*/
listen(port = this.port, callback) {
this.bind(port, callback);
return this;
}
};
DHT.Table = Table;
DHT.Node = Table.Node;
DHT.randomID = _.randomID;
module.exports = DHT;