mirror of
https://github.com/webtorrent/bittorrent-tracker.git
synced 2025-01-19 04:31:36 +00:00
Recover from unexpected events better
When you restart the tracker server, all peers it's tracking are discarded. Then, clients that are already running will continue to send `update` events, but the tracker throws them away because it was expected to get a `start` event first. This should only be a warning, and not a fatal error. I just made the following changes: - unexpected `started` event (for peer already in swarm) is treated as an `update` - unexpected `stopped` event is discarded - unexpected `completed` event is treated as a `start` - unexpected `update` event (from peer not in swarm) is treated as `start` Fixes #42
This commit is contained in:
parent
b44715d37a
commit
026f2c2de0
161
server.js
161
server.js
@ -138,7 +138,6 @@ Server.prototype._getSwarm = function (binaryInfoHash) {
|
|||||||
|
|
||||||
Server.prototype._onHttpRequest = function (req, res) {
|
Server.prototype._onHttpRequest = function (req, res) {
|
||||||
var self = this
|
var self = this
|
||||||
var warning
|
|
||||||
var s = req.url.split('?')
|
var s = req.url.split('?')
|
||||||
var params = common.querystringParse(s[1])
|
var params = common.querystringParse(s[1])
|
||||||
var response
|
var response
|
||||||
@ -153,6 +152,9 @@ Server.prototype._onHttpRequest = function (req, res) {
|
|||||||
if (peerId.length !== 20) return error('invalid peer_id')
|
if (peerId.length !== 20) return error('invalid peer_id')
|
||||||
if (!port) return error('invalid port')
|
if (!port) return error('invalid port')
|
||||||
|
|
||||||
|
var left = Number(params.left)
|
||||||
|
var compact = Number(params.compact)
|
||||||
|
|
||||||
var ip = self._trustProxy
|
var ip = self._trustProxy
|
||||||
? req.headers['x-forwarded-for'] || req.connection.remoteAddress
|
? req.headers['x-forwarded-for'] || req.connection.remoteAddress
|
||||||
: req.connection.remoteAddress.replace(REMOVE_IPV6_RE, '') // force ipv4
|
: req.connection.remoteAddress.replace(REMOVE_IPV6_RE, '') // force ipv4
|
||||||
@ -165,76 +167,76 @@ Server.prototype._onHttpRequest = function (req, res) {
|
|||||||
MAX_ANNOUNCE_PEERS
|
MAX_ANNOUNCE_PEERS
|
||||||
)
|
)
|
||||||
|
|
||||||
switch (params.event) {
|
var start = function () {
|
||||||
case 'started':
|
|
||||||
if (peer) {
|
if (peer) {
|
||||||
warning = 'unexpected `started` event from peer that is already in swarm'
|
debug('unexpected `started` event from peer that is already in swarm')
|
||||||
break
|
return update() // treat as an update
|
||||||
}
|
}
|
||||||
|
if (left === 0) swarm.complete += 1
|
||||||
if (Number(params.left) === 0) {
|
else swarm.incomplete += 1
|
||||||
swarm.complete += 1
|
|
||||||
} else {
|
|
||||||
swarm.incomplete += 1
|
|
||||||
}
|
|
||||||
|
|
||||||
swarm.peers[addr] = {
|
swarm.peers[addr] = {
|
||||||
ip: ip,
|
ip: ip,
|
||||||
port: port,
|
port: port,
|
||||||
peerId: peerId
|
peerId: peerId
|
||||||
}
|
}
|
||||||
self.emit('start', addr)
|
self.emit('start', addr)
|
||||||
break
|
}
|
||||||
|
|
||||||
case 'stopped':
|
var stop = function () {
|
||||||
if (!peer) {
|
if (!peer) {
|
||||||
warning = 'unexpected `stopped` event from peer that is not in swarm'
|
debug('unexpected `stopped` event from peer that is not in swarm')
|
||||||
break
|
return // do nothing
|
||||||
}
|
}
|
||||||
|
if (peer.complete) swarm.complete -= 1
|
||||||
if (peer.complete) {
|
else swarm.incomplete -= 1
|
||||||
swarm.complete -= 1
|
|
||||||
} else {
|
|
||||||
swarm.incomplete -= 1
|
|
||||||
}
|
|
||||||
|
|
||||||
swarm.peers[addr] = null
|
swarm.peers[addr] = null
|
||||||
self.emit('stop', addr)
|
self.emit('stop', addr)
|
||||||
break
|
}
|
||||||
|
|
||||||
case 'completed':
|
var complete = function () {
|
||||||
if (!peer) {
|
if (!peer) {
|
||||||
warning = 'unexpected `completed` event from peer that is not in swarm'
|
debug('unexpected `completed` event from peer that is not in swarm')
|
||||||
break
|
return start() // treat as a start
|
||||||
}
|
}
|
||||||
if (peer.complete) {
|
if (peer.complete) {
|
||||||
warning = 'unexpected `completed` event from peer that is already marked as completed'
|
debug('unexpected `completed` event from peer that is already marked as completed')
|
||||||
break
|
return // do nothing
|
||||||
}
|
}
|
||||||
|
|
||||||
swarm.complete += 1
|
swarm.complete += 1
|
||||||
swarm.incomplete -= 1
|
swarm.incomplete -= 1
|
||||||
|
|
||||||
peer.complete = true
|
peer.complete = true
|
||||||
self.emit('complete', addr)
|
self.emit('complete', addr)
|
||||||
break
|
|
||||||
|
|
||||||
case '': // update
|
|
||||||
case undefined:
|
|
||||||
if (!peer) {
|
|
||||||
warning = 'unexpected `update` event from peer that is not in swarm'
|
|
||||||
break
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var update = function () {
|
||||||
|
if (!peer) {
|
||||||
|
debug('unexpected `update` event from peer that is not in swarm')
|
||||||
|
return start() // treat as a start
|
||||||
|
}
|
||||||
self.emit('update', addr)
|
self.emit('update', addr)
|
||||||
break
|
}
|
||||||
|
|
||||||
|
switch (params.event) {
|
||||||
|
case 'started':
|
||||||
|
start()
|
||||||
|
break
|
||||||
|
case 'stopped':
|
||||||
|
stop()
|
||||||
|
break
|
||||||
|
case 'completed':
|
||||||
|
complete()
|
||||||
|
break
|
||||||
|
case '': case undefined: // update
|
||||||
|
update()
|
||||||
|
break
|
||||||
default:
|
default:
|
||||||
return error('invalid event') // early return
|
return error('invalid event') // early return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (left === 0) peer.complete = true
|
||||||
|
|
||||||
// send peers
|
// send peers
|
||||||
var peers = Number(params.compact) === 1
|
var peers = compact === 1
|
||||||
? self._getPeersCompact(swarm, numWant)
|
? self._getPeersCompact(swarm, numWant)
|
||||||
: self._getPeers(swarm, numWant)
|
: self._getPeers(swarm, numWant)
|
||||||
|
|
||||||
@ -245,9 +247,6 @@ Server.prototype._onHttpRequest = function (req, res) {
|
|||||||
interval: self._intervalMs
|
interval: self._intervalMs
|
||||||
}
|
}
|
||||||
|
|
||||||
if (warning) {
|
|
||||||
response['warning message'] = warning
|
|
||||||
}
|
|
||||||
res.end(bencode.encode(response))
|
res.end(bencode.encode(response))
|
||||||
debug('sent response %s', response)
|
debug('sent response %s', response)
|
||||||
|
|
||||||
@ -361,74 +360,74 @@ Server.prototype._onUdpRequest = function (msg, rinfo) {
|
|||||||
// 512 bytes which is not safe
|
// 512 bytes which is not safe
|
||||||
numWant = Math.min(numWant || NUM_ANNOUNCE_PEERS, MAX_ANNOUNCE_PEERS)
|
numWant = Math.min(numWant || NUM_ANNOUNCE_PEERS, MAX_ANNOUNCE_PEERS)
|
||||||
|
|
||||||
var warning
|
var start = function () {
|
||||||
switch (event) {
|
|
||||||
case common.EVENTS.started:
|
|
||||||
if (peer) {
|
if (peer) {
|
||||||
warning = 'unexpected `started` event from peer that is already in swarm'
|
debug('unexpected `started` event from peer that is already in swarm')
|
||||||
break
|
return update() // treat as an update
|
||||||
}
|
}
|
||||||
|
if (left === 0) swarm.complete += 1
|
||||||
if (left === 0) {
|
else swarm.incomplete += 1
|
||||||
swarm.complete += 1
|
|
||||||
} else {
|
|
||||||
swarm.incomplete += 1
|
|
||||||
}
|
|
||||||
|
|
||||||
swarm.peers[addr] = {
|
swarm.peers[addr] = {
|
||||||
ip: ip,
|
ip: ip,
|
||||||
port: port,
|
port: port,
|
||||||
peerId: peerId
|
peerId: peerId
|
||||||
}
|
}
|
||||||
self.emit('start', addr)
|
self.emit('start', addr)
|
||||||
break
|
}
|
||||||
|
|
||||||
case common.EVENTS.stopped:
|
var stop = function () {
|
||||||
if (!peer) {
|
if (!peer) {
|
||||||
warning = 'unexpected `stopped` event from peer that is not in swarm'
|
debug('unexpected `stopped` event from peer that is not in swarm')
|
||||||
break
|
return // do nothing
|
||||||
}
|
}
|
||||||
|
if (peer.complete) swarm.complete -= 1
|
||||||
if (peer.complete) {
|
else swarm.incomplete -= 1
|
||||||
swarm.complete -= 1
|
|
||||||
} else {
|
|
||||||
swarm.incomplete -= 1
|
|
||||||
}
|
|
||||||
|
|
||||||
swarm.peers[addr] = null
|
swarm.peers[addr] = null
|
||||||
self.emit('stop', addr)
|
self.emit('stop', addr)
|
||||||
break
|
}
|
||||||
|
|
||||||
case common.EVENTS.completed:
|
var complete = function () {
|
||||||
if (!peer) {
|
if (!peer) {
|
||||||
warning = 'unexpected `completed` event from peer that is not in swarm'
|
debug('unexpected `completed` event from peer that is not in swarm')
|
||||||
break
|
return start() // treat as a start
|
||||||
}
|
}
|
||||||
if (peer.complete) {
|
if (peer.complete) {
|
||||||
warning = 'unexpected `completed` event from peer that is already marked as completed'
|
debug('unexpected `completed` event from peer that is already marked as completed')
|
||||||
break
|
return // do nothing
|
||||||
}
|
}
|
||||||
|
|
||||||
swarm.complete += 1
|
swarm.complete += 1
|
||||||
swarm.incomplete -= 1
|
swarm.incomplete -= 1
|
||||||
|
|
||||||
peer.complete = true
|
peer.complete = true
|
||||||
self.emit('complete', addr)
|
self.emit('complete', addr)
|
||||||
break
|
|
||||||
|
|
||||||
case common.EVENTS.update: // update
|
|
||||||
if (!peer) {
|
|
||||||
warning = 'unexpected `update` event from peer that is not in swarm'
|
|
||||||
break
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var update = function () {
|
||||||
|
if (!peer) {
|
||||||
|
debug('unexpected `update` event from peer that is not in swarm')
|
||||||
|
return start() // treat as a start
|
||||||
|
}
|
||||||
self.emit('update', addr)
|
self.emit('update', addr)
|
||||||
break
|
}
|
||||||
|
|
||||||
|
switch (event) {
|
||||||
|
case common.EVENTS.started:
|
||||||
|
start()
|
||||||
|
break
|
||||||
|
case common.EVENTS.stopped:
|
||||||
|
stop()
|
||||||
|
break
|
||||||
|
case common.EVENTS.completed:
|
||||||
|
complete()
|
||||||
|
break
|
||||||
|
case common.EVENTS.update: // update
|
||||||
|
update()
|
||||||
|
break
|
||||||
default:
|
default:
|
||||||
return error('invalid event') // early return
|
return error('invalid event') // early return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (left === 0) peer.complete = true
|
||||||
|
|
||||||
// send peers
|
// send peers
|
||||||
var peers = self._getPeersCompact(swarm, numWant)
|
var peers = self._getPeersCompact(swarm, numWant)
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user