diff --git a/lib/server/swarm.js b/lib/server/swarm.js index 84c2705b..43df8106 100644 --- a/lib/server/swarm.js +++ b/lib/server/swarm.js @@ -7,6 +7,7 @@ var randomIterate = require('random-iterate') // need to support when overriding Server.getSwarm() function Swarm (infoHash, server) { this.peers = {} + this.interval = server.intervalMs this.complete = 0 this.incomplete = 0 } @@ -54,7 +55,8 @@ Swarm.prototype._onAnnounceStarted = function (params, peer) { peerId: params.peer_id, // as hex ip: params.ip, // only http, udp port: params.port, // only http, udp - socket: params.socket // only websocket + socket: params.socket, // only websocket + lastSeen: Date.now() } } @@ -89,6 +91,8 @@ Swarm.prototype._onAnnounceUpdate = function (params, peer) { debug('unexpected `update` event from peer that is not in swarm') return this._onAnnounceStarted(params, peer) // treat as a start } + + peer.lastSeen = Date.now() if (!peer.complete && params.left === 0) { this.complete += 1 @@ -101,9 +105,19 @@ Swarm.prototype._getPeers = function (numwant, isWebRTC) { var peers = [] var ite = randomIterate(Object.keys(this.peers)) var peerId + + // allow peers to skip one announce interval before blacklisting + var blacklistMaximum = Date.now() - 2 * this.interval + while ((peerId = ite()) && peers.length < numwant) { var peer = this.peers[peerId] if (!peer) continue + + // blacklist peers which aren't announing + // changing their ports to another + if (peer.lastSeen < blacklistMaximum) { + peer.port = 1 + } if ((isWebRTC && peer.socket) || (!isWebRTC && peer.ip)) peers.push(peer) } return peers