Servers should obey the numWant parameter (fix #21)

This commit is contained in:
Feross Aboukhadijeh 2014-07-11 03:51:29 -07:00
parent cdc2c5dea9
commit a685cb8088

View File

@ -12,6 +12,8 @@ var parallel = require('run-parallel')
var querystring = require('querystring') var querystring = require('querystring')
var string2compact = require('string2compact') var string2compact = require('string2compact')
var NUM_ANNOUNCE_PEERS = 50
var MAX_ANNOUNCE_PEERS = 82
var REMOVE_IPV6_RE = /^::ffff:/ var REMOVE_IPV6_RE = /^::ffff:/
inherits(Server, EventEmitter) inherits(Server, EventEmitter)
@ -141,6 +143,11 @@ Server.prototype._onHttpRequest = function (req, res) {
var swarm = self._getSwarm(infoHash) var swarm = self._getSwarm(infoHash)
var peer = swarm.peers[addr] var peer = swarm.peers[addr]
var numWant = Math.min(
Number(params.numwant) || NUM_ANNOUNCE_PEERS,
MAX_ANNOUNCE_PEERS
)
switch (params.event) { switch (params.event) {
case 'started': case 'started':
if (peer) { if (peer) {
@ -210,8 +217,8 @@ Server.prototype._onHttpRequest = function (req, res) {
// send peers // send peers
var peers = Number(params.compact) === 1 var peers = Number(params.compact) === 1
? self._getPeersCompact(swarm) ? self._getPeersCompact(swarm, numWant)
: self._getPeers(swarm) : self._getPeers(swarm, numWant)
var response = { var response = {
complete: swarm.complete, complete: swarm.complete,
@ -329,6 +336,10 @@ Server.prototype._onUdpRequest = function (msg, rinfo) {
var swarm = self._getSwarm(infoHash) var swarm = self._getSwarm(infoHash)
var peer = swarm.peers[addr] var peer = swarm.peers[addr]
// never send more than MAX_ANNOUNCE_PEERS or else the UDP packet will get bigger than
// 512 bytes which is not safe
numWant = Math.min(numWant || NUM_ANNOUNCE_PEERS, MAX_ANNOUNCE_PEERS)
switch (event) { switch (event) {
case common.EVENTS.started: case common.EVENTS.started:
if (peer) { if (peer) {
@ -394,12 +405,7 @@ Server.prototype._onUdpRequest = function (msg, rinfo) {
} }
// send peers // send peers
var peers = self._getPeersCompact(swarm) var peers = self._getPeersCompact(swarm, numWant)
// never send more than 70 peers or else the UDP packet will get too big
if (peers.length >= 70 * 6) {
peers = peers.slice(0, 70 * 6)
}
send(Buffer.concat([ send(Buffer.concat([
common.toUInt32(common.ACTIONS.ANNOUNCE), common.toUInt32(common.ACTIONS.ANNOUNCE),
@ -445,32 +451,34 @@ Server.prototype._onUdpRequest = function (msg, rinfo) {
} }
} }
Server.prototype._getPeers = function (swarm) { Server.prototype._getPeers = function (swarm, numWant) {
var self = this var self = this
var peers = [] var peers = []
for (var peerId in swarm.peers) { for (var peerId in swarm.peers) {
var peer = swarm.peers[peerId] var peer = swarm.peers[peerId]
if (!peer) continue // ignore null values
peers.push({ peers.push({
'peer id': peer.peerId, 'peer id': peer.peerId,
ip: peer.ip, ip: peer.ip,
port: peer.port port: peer.port
}) })
if (peers.length === numWant) break
} }
return peers return peers
} }
Server.prototype._getPeersCompact = function (swarm) { Server.prototype._getPeersCompact = function (swarm, numWant) {
var self = this var self = this
var addrs = [] var peers = []
Object.keys(swarm.peers).forEach(function (peerId) { for (var peerId in swarm.peers) {
var peer = swarm.peers[peerId] var peer = swarm.peers[peerId]
if (peer) { if (!peer) continue // ignore null values
addrs.push(peer.ip + ':' + peer.port) peers.push(peer.ip + ':' + peer.port)
} if (peers.length === numWant) break
}) }
return string2compact(addrs) return string2compact(peers)
} }
// HELPER FUNCTIONS // HELPER FUNCTIONS