Skip to content

Commit 872518d

Browse files
committed
client support for udp tracker error message
1 parent 3d50193 commit 872518d

File tree

1 file changed

+38
-28
lines changed

1 file changed

+38
-28
lines changed

index.js

Lines changed: 38 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -17,14 +17,14 @@ var string2compact = require('string2compact')
1717
var url = require('url')
1818

1919
var CONNECTION_ID = Buffer.concat([ toUInt32(0x417), toUInt32(0x27101980) ])
20-
var ACTIONS = { CONNECT: 0, ANNOUNCE: 1, SCRAPE: 2 }
20+
var ACTIONS = { CONNECT: 0, ANNOUNCE: 1, SCRAPE: 2, ERROR: 3 }
2121
var EVENTS = { completed: 1, started: 2, stopped: 3 }
2222
var MAX_UINT = 4294967295
2323

2424
inherits(Tracker, EventEmitter)
2525

2626
/**
27-
* An individual torrent tracker
27+
* An individual torrent tracker (used by Client)
2828
*
2929
* @param {Client} client parent bittorrent tracker client
3030
* @param {string} announceUrl announce url of tracker
@@ -176,35 +176,34 @@ Tracker.prototype._requestUdp = function (requestUrl, opts) {
176176
timeout.unref()
177177
}
178178

179-
function error (message) {
180-
self.client.emit('error', new Error(message + ' (connecting to tracker ' + requestUrl + ')'))
181-
try { socket.close() } catch (e) { }
182-
clearTimeout(timeout)
183-
}
179+
send(Buffer.concat([
180+
CONNECTION_ID,
181+
toUInt32(ACTIONS.CONNECT),
182+
transactionId
183+
]))
184184

185185
socket.on('error', error)
186186

187-
socket.on('message', function (message, rinfo) {
188-
189-
if (message.length < 8 || message.readUInt32BE(4) !== transactionId.readUInt32BE(0)) {
187+
socket.on('message', function (msg, rinfo) {
188+
if (msg.length < 8 || msg.readUInt32BE(4) !== transactionId.readUInt32BE(0)) {
190189
return error('tracker sent back invalid transaction id')
191190
}
192191

193-
var action = message.readUInt32BE(0)
192+
var action = msg.readUInt32BE(0)
194193
switch (action) {
195194
case 0: // handshake
196-
if (message.length < 16) {
195+
if (msg.length < 16) {
197196
return error('invalid udp handshake')
198197
}
199-
announce(message.slice(8, 16), opts)
198+
announce(msg.slice(8, 16), opts)
200199
return
201200

202201
case 1: // announce
203-
if (message.length < 20) {
202+
if (msg.length < 20) {
204203
return error('invalid announce message')
205204
}
206205

207-
var interval = message.readUInt32BE(8)
206+
var interval = msg.readUInt32BE(8)
208207
if (interval && !self._opts.interval && self._intervalMs !== 0) {
209208
// use the interval the tracker recommends, UNLESS the user manually specifies an
210209
// interval they want to use
@@ -213,11 +212,11 @@ Tracker.prototype._requestUdp = function (requestUrl, opts) {
213212

214213
self.client.emit('update', {
215214
announce: self._announceUrl,
216-
complete: message.readUInt32BE(16),
217-
incomplete: message.readUInt32BE(12)
215+
complete: msg.readUInt32BE(16),
216+
incomplete: msg.readUInt32BE(12)
218217
})
219218

220-
compact2string.multi(message.slice(20)).forEach(function (addr) {
219+
compact2string.multi(msg.slice(20)).forEach(function (addr) {
221220
self.client.emit('peer', addr)
222221
})
223222

@@ -226,23 +225,40 @@ Tracker.prototype._requestUdp = function (requestUrl, opts) {
226225
return
227226

228227
case 2: // scrape
229-
if (message.length < 20) {
228+
if (msg.length < 20) {
230229
return error('invalid scrape message')
231230
}
232231

233232
self.client.emit('scrape', {
234233
announce: self._announceUrl,
235-
complete: message.readUInt32BE(8),
236-
downloaded: message.readUInt32BE(12),
237-
incomplete: message.readUInt32BE(16)
234+
complete: msg.readUInt32BE(8),
235+
downloaded: msg.readUInt32BE(12),
236+
incomplete: msg.readUInt32BE(16)
238237
})
239238

239+
clearTimeout(timeout)
240+
socket.close()
241+
return
242+
243+
case 3: // error
244+
if (msg.length < 8) {
245+
return error('invalid error message')
246+
}
247+
248+
self.client.emit('error', new Error(msg.slice(8).toString()))
249+
240250
clearTimeout(timeout)
241251
socket.close()
242252
return
243253
}
244254
})
245255

256+
function error (message) {
257+
self.client.emit('error', new Error(message + ' (connecting to tracker ' + requestUrl + ')'))
258+
try { socket.close() } catch (e) { }
259+
clearTimeout(timeout)
260+
}
261+
246262
function send (message) {
247263
if (!parsedUrl.port) {
248264
parsedUrl.port = 80;
@@ -285,12 +301,6 @@ Tracker.prototype._requestUdp = function (requestUrl, opts) {
285301
self.client._infoHash
286302
]))
287303
}
288-
289-
send(Buffer.concat([
290-
CONNECTION_ID,
291-
toUInt32(ACTIONS.CONNECT),
292-
transactionId
293-
]))
294304
}
295305

296306
Tracker.prototype._handleResponse = function (requestUrl, data) {

0 commit comments

Comments
 (0)