Skip to content

Commit 026f2c2

Browse files
committed
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 webtorrent#42
1 parent b44715d commit 026f2c2

File tree

1 file changed

+115
-116
lines changed

1 file changed

+115
-116
lines changed

server.js

Lines changed: 115 additions & 116 deletions
Original file line numberDiff line numberDiff line change
@@ -138,7 +138,6 @@ Server.prototype._getSwarm = function (binaryInfoHash) {
138138

139139
Server.prototype._onHttpRequest = function (req, res) {
140140
var self = this
141-
var warning
142141
var s = req.url.split('?')
143142
var params = common.querystringParse(s[1])
144143
var response
@@ -153,6 +152,9 @@ Server.prototype._onHttpRequest = function (req, res) {
153152
if (peerId.length !== 20) return error('invalid peer_id')
154153
if (!port) return error('invalid port')
155154

155+
var left = Number(params.left)
156+
var compact = Number(params.compact)
157+
156158
var ip = self._trustProxy
157159
? req.headers['x-forwarded-for'] || req.connection.remoteAddress
158160
: req.connection.remoteAddress.replace(REMOVE_IPV6_RE, '') // force ipv4
@@ -165,76 +167,76 @@ Server.prototype._onHttpRequest = function (req, res) {
165167
MAX_ANNOUNCE_PEERS
166168
)
167169

170+
var start = function () {
171+
if (peer) {
172+
debug('unexpected `started` event from peer that is already in swarm')
173+
return update() // treat as an update
174+
}
175+
if (left === 0) swarm.complete += 1
176+
else swarm.incomplete += 1
177+
swarm.peers[addr] = {
178+
ip: ip,
179+
port: port,
180+
peerId: peerId
181+
}
182+
self.emit('start', addr)
183+
}
184+
185+
var stop = function () {
186+
if (!peer) {
187+
debug('unexpected `stopped` event from peer that is not in swarm')
188+
return // do nothing
189+
}
190+
if (peer.complete) swarm.complete -= 1
191+
else swarm.incomplete -= 1
192+
swarm.peers[addr] = null
193+
self.emit('stop', addr)
194+
}
195+
196+
var complete = function () {
197+
if (!peer) {
198+
debug('unexpected `completed` event from peer that is not in swarm')
199+
return start() // treat as a start
200+
}
201+
if (peer.complete) {
202+
debug('unexpected `completed` event from peer that is already marked as completed')
203+
return // do nothing
204+
}
205+
swarm.complete += 1
206+
swarm.incomplete -= 1
207+
peer.complete = true
208+
self.emit('complete', addr)
209+
}
210+
211+
var update = function () {
212+
if (!peer) {
213+
debug('unexpected `update` event from peer that is not in swarm')
214+
return start() // treat as a start
215+
}
216+
self.emit('update', addr)
217+
}
218+
168219
switch (params.event) {
169220
case 'started':
170-
if (peer) {
171-
warning = 'unexpected `started` event from peer that is already in swarm'
172-
break
173-
}
174-
175-
if (Number(params.left) === 0) {
176-
swarm.complete += 1
177-
} else {
178-
swarm.incomplete += 1
179-
}
180-
181-
swarm.peers[addr] = {
182-
ip: ip,
183-
port: port,
184-
peerId: peerId
185-
}
186-
self.emit('start', addr)
221+
start()
187222
break
188-
189223
case 'stopped':
190-
if (!peer) {
191-
warning = 'unexpected `stopped` event from peer that is not in swarm'
192-
break
193-
}
194-
195-
if (peer.complete) {
196-
swarm.complete -= 1
197-
} else {
198-
swarm.incomplete -= 1
199-
}
200-
201-
swarm.peers[addr] = null
202-
self.emit('stop', addr)
224+
stop()
203225
break
204-
205226
case 'completed':
206-
if (!peer) {
207-
warning = 'unexpected `completed` event from peer that is not in swarm'
208-
break
209-
}
210-
if (peer.complete) {
211-
warning = 'unexpected `completed` event from peer that is already marked as completed'
212-
break
213-
}
214-
215-
swarm.complete += 1
216-
swarm.incomplete -= 1
217-
218-
peer.complete = true
219-
self.emit('complete', addr)
227+
complete()
220228
break
221-
222-
case '': // update
223-
case undefined:
224-
if (!peer) {
225-
warning = 'unexpected `update` event from peer that is not in swarm'
226-
break
227-
}
228-
229-
self.emit('update', addr)
229+
case '': case undefined: // update
230+
update()
230231
break
231-
232232
default:
233233
return error('invalid event') // early return
234234
}
235235

236+
if (left === 0) peer.complete = true
237+
236238
// send peers
237-
var peers = Number(params.compact) === 1
239+
var peers = compact === 1
238240
? self._getPeersCompact(swarm, numWant)
239241
: self._getPeers(swarm, numWant)
240242

@@ -245,9 +247,6 @@ Server.prototype._onHttpRequest = function (req, res) {
245247
interval: self._intervalMs
246248
}
247249

248-
if (warning) {
249-
response['warning message'] = warning
250-
}
251250
res.end(bencode.encode(response))
252251
debug('sent response %s', response)
253252

@@ -361,74 +360,74 @@ Server.prototype._onUdpRequest = function (msg, rinfo) {
361360
// 512 bytes which is not safe
362361
numWant = Math.min(numWant || NUM_ANNOUNCE_PEERS, MAX_ANNOUNCE_PEERS)
363362

364-
var warning
363+
var start = function () {
364+
if (peer) {
365+
debug('unexpected `started` event from peer that is already in swarm')
366+
return update() // treat as an update
367+
}
368+
if (left === 0) swarm.complete += 1
369+
else swarm.incomplete += 1
370+
swarm.peers[addr] = {
371+
ip: ip,
372+
port: port,
373+
peerId: peerId
374+
}
375+
self.emit('start', addr)
376+
}
377+
378+
var stop = function () {
379+
if (!peer) {
380+
debug('unexpected `stopped` event from peer that is not in swarm')
381+
return // do nothing
382+
}
383+
if (peer.complete) swarm.complete -= 1
384+
else swarm.incomplete -= 1
385+
swarm.peers[addr] = null
386+
self.emit('stop', addr)
387+
}
388+
389+
var complete = function () {
390+
if (!peer) {
391+
debug('unexpected `completed` event from peer that is not in swarm')
392+
return start() // treat as a start
393+
}
394+
if (peer.complete) {
395+
debug('unexpected `completed` event from peer that is already marked as completed')
396+
return // do nothing
397+
}
398+
swarm.complete += 1
399+
swarm.incomplete -= 1
400+
peer.complete = true
401+
self.emit('complete', addr)
402+
}
403+
404+
var update = function () {
405+
if (!peer) {
406+
debug('unexpected `update` event from peer that is not in swarm')
407+
return start() // treat as a start
408+
}
409+
self.emit('update', addr)
410+
}
411+
365412
switch (event) {
366413
case common.EVENTS.started:
367-
if (peer) {
368-
warning = 'unexpected `started` event from peer that is already in swarm'
369-
break
370-
}
371-
372-
if (left === 0) {
373-
swarm.complete += 1
374-
} else {
375-
swarm.incomplete += 1
376-
}
377-
378-
swarm.peers[addr] = {
379-
ip: ip,
380-
port: port,
381-
peerId: peerId
382-
}
383-
self.emit('start', addr)
414+
start()
384415
break
385-
386416
case common.EVENTS.stopped:
387-
if (!peer) {
388-
warning = 'unexpected `stopped` event from peer that is not in swarm'
389-
break
390-
}
391-
392-
if (peer.complete) {
393-
swarm.complete -= 1
394-
} else {
395-
swarm.incomplete -= 1
396-
}
397-
398-
swarm.peers[addr] = null
399-
self.emit('stop', addr)
417+
stop()
400418
break
401-
402419
case common.EVENTS.completed:
403-
if (!peer) {
404-
warning = 'unexpected `completed` event from peer that is not in swarm'
405-
break
406-
}
407-
if (peer.complete) {
408-
warning = 'unexpected `completed` event from peer that is already marked as completed'
409-
break
410-
}
411-
412-
swarm.complete += 1
413-
swarm.incomplete -= 1
414-
415-
peer.complete = true
416-
self.emit('complete', addr)
420+
complete()
417421
break
418-
419422
case common.EVENTS.update: // update
420-
if (!peer) {
421-
warning = 'unexpected `update` event from peer that is not in swarm'
422-
break
423-
}
424-
425-
self.emit('update', addr)
423+
update()
426424
break
427-
428425
default:
429426
return error('invalid event') // early return
430427
}
431428

429+
if (left === 0) peer.complete = true
430+
432431
// send peers
433432
var peers = self._getPeersCompact(swarm, numWant)
434433

0 commit comments

Comments
 (0)