Skip to content

Commit

Permalink
Metadata data requests coming back, need to handle mix of bencode tai…
Browse files Browse the repository at this point in the history
…led by binary data.
  • Loading branch information
superafroman committed Mar 6, 2013
1 parent 7be59e6 commit a30e2ba
Show file tree
Hide file tree
Showing 3 changed files with 43 additions and 30 deletions.
7 changes: 4 additions & 3 deletions lib/client.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,10 @@ var LOGGER = log4js.getLogger('client.js');
* Create a new torrent client.
*
* Options:
* { id: '-NT0000-' | Buffer,
* { id: '-NT0000-' || Buffer,
* downloadPath: '.',
* portRange: { start: 6881, end: 6889 } }
* portRange: { start: 6881, end: 6889 },
* logLevel: 'TRACE' || 'DEBUG' || 'INFO' || ... }
*/
var Client = function(options) {

Expand All @@ -29,7 +30,7 @@ var Client = function(options) {
}
this.id = id;
} else {
this.id = padId;
this.id = padId(id);
}

this.torrents = {};
Expand Down
27 changes: 15 additions & 12 deletions lib/peer.js
Original file line number Diff line number Diff line change
Expand Up @@ -180,21 +180,24 @@ Peer.prototype.sendMessage = function(message) {
}
};

Peer.prototype.sendExtendedMessage = function(code, data) {
Peer.prototype.sendExtendedMessage = function(type, data) {

if (this.extensions[code] !== undefined) {
LOGGER.debug('Peer [%s] sending extended message of type %j', this.getIdentifier(), type);

if (this.extensions[type] !== undefined) {

var codeAsBuffer = new Buffer(1);
codeAsBuffer[0] = this.extensions[code]
codeAsBuffer[0] = this.extensions[type]

LOGGER.debug('Peer [%s] extended request code = %j', this.getIdentifier(), codeAsBuffer[0]);

var payload = new Buffer(bencode.encode(data));

var message = new Message(Message.EXTENDED, BufferUtils.concat(codeAsBuffer, payload));

this.sendMessage(message);
} else {
// throw ?
console.log('no extension ', code);
throw new Error("Peer doesn't support extended request of type " + type);
}
};

Expand Down Expand Up @@ -557,23 +560,23 @@ function processData(self) {
case Message.EXTENDED:
LOGGER.debug('Received EXTENDED from ' + Peer.getIdentifier(self));

var extendedCode = message.payload[0];
var data = message.payload.slice(1);
var payload = bencode.decode(data.toString('binary'));
var extendedCode = message.payload[0]
, data = message.payload.slice(1)
, payload = null
;

if (extendedCode === 0) {
payload = bencode.decode(data.toString('binary'));
// handshake
// TODO: don't merge, peer should only hold extension info about itself
Object.keys(payload.m).forEach(function(key) {
self.extensions[key] = payload.m[key];
});
// TODO: store details differently
if (payload.m['ut_metadata']) {
self.hasMetadata = true;
self.metadataSize = +payload['metadata_size'];
}
if (!self.choked && self.amInterested) {
console.log('emitting ready');
self.emit(Peer.READY);
}
} else {
Object.keys(self.extensions).some(function(key) {
if (self.extensions[key] === extendedCode) {
Expand Down
39 changes: 24 additions & 15 deletions lib/requeststrategy/metadata.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@

var bencode = require('../util/bencode');

var Message = require('../message');
var bencode = require('../util/bencode')
, BitField = require('../util/bitfield')
, Message = require('../message')
, Peer = require('../peer')
;

var LOGGER = require('log4js').getLogger('requeststrategy/metadata.js');

Expand All @@ -13,6 +15,8 @@ function MetadataRequestStrategy(metadata) {

MetadataRequestStrategy.prototype.handleMessage = function(peer, messageCode, payload) {

LOGGER.debug('Peer [%s] notified of message %j', peer.getIdentifier(), messageCode);

if (messageCode !== Message.EXTENDED_METADATA) {
return;
}
Expand All @@ -23,27 +27,27 @@ MetadataRequestStrategy.prototype.handleMessage = function(peer, messageCode, pa

switch (messageType) {
case MetadataRequestStrategy.REQUEST:
LOGGER.debug('Ignoring REQUEST message.');
LOGGER.debug('Peer [%s] ignoring REQUEST message.', peer.getIdentifier());
break;

case MetadataRequestStrategy.DATA:
LOGGER.debug('Recieved DATA message.');
LOGGER.debug('Peer [%s] recieved DATA message.', peer.getIdentifier());
var piece = payload['piece'];
this._cleanupPieceRequest(peer, piece);

console.log(message.payload.toString('binary'));
console.log(payload.toString('binary'));
console.log(payload);
break;

case MetadataRequestStrategy.REJECT:
LOGGER.debug('Recieved REJECT message.');
LOGGER.debug('Peer [%s] recieved REJECT message.', peer.getIdentifier());
var piece = payload['piece'];
this._cleanupPieceRequest(peer, piece);
activePieces.unset(piece);
break;

default:
LOGGER.warn('Unknown metadata message recieved. messageType = ' + messageType);
LOGGER.warn('Unknown metadata message recieved. messageType = %j', messageType);
}
};

Expand All @@ -62,30 +66,35 @@ MetadataRequestStrategy.prototype.peerDisconnected = function(peer) {

MetadataRequestStrategy.prototype.peerReady = function(peer) {

LOGGER.debug('Peer ready, hasMetadata = ' + peer.hasMetadata + ', metadataSize = ' + peer.metadataSize);
LOGGER.debug('Peer [%s] hasMetadata: %j, metadataSize: %j ', peer.getIdentifier(),
peer.hasMetadata, peer.metadataSize);

if (peer.hasMetadata) {

var metadata = this._metadata,
activePieces = this._activePieces,
activePeers = this._activePeers,
availableBlocks = null,
activePieces = this._activePieces,
availableBlocks = activePieces && activePieces.unsetIndices(),
pieceToRequest = -1;

if (!metadata.hasLength()) {
metadata.setLength(peer.metadataSize);
this._activePieces = activePieces = new BitField(metadata.bitfield.length);
availableBlocks = activePieces.unsetIndices();
}

if (availableBlocks.length === 0) {
return;
}

availableBlocks = activePieces.unsetIndices();
pieceToRequest = availableBlocks[Math.round(Math.random() * (availableBlocks.length - 1))];
activePieces.set(pieceToRequest);

LOGGER.debug('Requesting piece ' + pieceToRequest + ' from peer ' + peer.getIdentifier());
LOGGER.debug('Peer [%s] requesting piece %j', peer.getIdentifier(), pieceToRequest);

if (!activePeers[peer.getIdentifier()]) {
activePeers[peer.getIdentifier()] = [];
peer.on(Peer.EXTENDED_METADATA, this.handleMessage.bind(this));
peer.on(Peer.EXTENDED, this.handleMessage.bind(this));
}
activePeers[peer.getIdentifier()].push(pieceToRequest);

Expand All @@ -94,7 +103,7 @@ MetadataRequestStrategy.prototype.peerReady = function(peer) {
piece: pieceToRequest
});
} else {
LOGGER.debug("Peer doesn't support metadata requests. peer id: " + peer.getIdentifier());
LOGGER.debug("Peer [%s] doesn't support metadata requests.", peer.getIdentifier());
}
};

Expand Down

0 comments on commit a30e2ba

Please sign in to comment.