Packets are async. Stalls at crypto.randomBytes

This commit is contained in:
roblabla 2015-02-05 18:02:34 +00:00
parent 426a01249c
commit f29f501ea7
3 changed files with 52 additions and 41 deletions

View file

@ -286,15 +286,17 @@ function createClient(options) {
} }
function onEncryptionKeyRequest(packet) { function onEncryptionKeyRequest(packet) {
debug("Generating 16 random bytes");
crypto.randomBytes(16, gotSharedSecret); crypto.randomBytes(16, gotSharedSecret);
function gotSharedSecret(err, sharedSecret) { function gotSharedSecret(err, sharedSecret) {
if (err) { if (err) {
debug(err);
client.emit('error', err); client.emit('error', err);
client.end(); client.end();
return return;
} }
debug("Got mah bytes");
if (haveCredentials) { if (haveCredentials) {
joinServerRequest(onJoinServerResponse); joinServerRequest(onJoinServerResponse);
} else { } else {

View file

@ -81,6 +81,22 @@ Client.prototype.onRaw = function(type, func) {
Client.prototype.setSocket = function(socket) { Client.prototype.setSocket = function(socket) {
var self = this; var self = this;
function afterParse(err, parsed) {
if (err || (parsed && parsed.error)) {
this.emit('error', err || parser.error);
this.end("ProtocolError");
return;
}
if (! parsed) return;
packet = parsed.results;
incomingBuffer = incomingBuffer.slice(parsed.size);
var packetName = protocol.packetNames[self.state][self.isServer ? 'toServer' : 'toClient'][packet.id];
self.emit(packetName, packet);
self.emit('packet', packet);
self.emit('raw.' + packetName, parsed.buffer);
self.emit('raw', parsed.buffer);
}
self.socket = socket; self.socket = socket;
if (self.socket.setNoDelay) if (self.socket.setNoDelay)
self.socket.setNoDelay(true); self.socket.setNoDelay(true);
@ -90,24 +106,10 @@ Client.prototype.setSocket = function(socket) {
incomingBuffer = Buffer.concat([incomingBuffer, data]); incomingBuffer = Buffer.concat([incomingBuffer, data]);
var parsed, packet; var parsed, packet;
while (true) { while (true) {
if(this.compressionThreshold == -2) if(self.compressionThreshold == -2)
parsed = parsePacket(incomingBuffer, self.state, self.isServer, self.packetsToParse); afterParse(null, parsePacket(incomingBuffer, self.state, self.isServer, self.packetsToParse));
else else
parsed = parseNewStylePacket(incomingBuffer, self.state, self.isServer, self.packetsToParse, function(){}); parseNewStylePacket(incomingBuffer, self.state, self.isServer, self.packetsToParse, afterParse);
if (! parsed) break;
if (parsed.error) {
this.emit('error', parsed.error);
this.end("ProtocolError");
return;
}
packet = parsed.results;
incomingBuffer = incomingBuffer.slice(parsed.size);
var packetName = protocol.packetNames[self.state][self.isServer ? 'toServer' : 'toClient'][packet.id];
self.emit(packetName, packet);
self.emit('packet', packet);
self.emit('raw.' + packetName, parsed.buffer);
self.emit('raw', parsed.buffer);
} }
}); });
@ -170,7 +172,6 @@ Client.prototype.write = function(packetId, params) {
var packetName = packetNames[that.state][that.isServer ? "toClient" : "toServer"][packetId]; var packetName = packetNames[that.state][that.isServer ? "toClient" : "toServer"][packetId];
debug("writing packetId " + that.state + "." + packetName + " (0x" + packetId.toString(16) + ")"); debug("writing packetId " + that.state + "." + packetName + " (0x" + packetId.toString(16) + ")");
debug(params); debug(params);
debug(buffer);
var out = that.encryptionEnabled ? new Buffer(that.cipher.update(buffer), 'binary') : buffer; var out = that.encryptionEnabled ? new Buffer(that.cipher.update(buffer), 'binary') : buffer;
that.socket.write(out); that.socket.write(out);
return true; return true;

View file

@ -1538,18 +1538,8 @@ function parsePacket(buffer, state, isServer, packetsToParse) {
} }
function parseNewStylePacket(buffer, state, isServer, packetsToParse, cb) { function parseNewStylePacket(buffer, state, isServer, packetsToParse, cb) {
if (state == null) state = states.PLAY;
var cursor = 0;
var lengthField = readVarInt(buffer, 0);
if (!!!lengthField) return null;
var length = lengthField.value;
cursor += lengthField.size;
if (length + lengthField.size > buffer.length) return null;
var buffer = buffer.slice(0, length + cursor); // fail early if too much is read.
var dataLengthField = readVarInt(buffer, cursor); function finishParsing(buffer) {
var finishParsing = function(buffer) {
var packetIdField = readVarInt(buffer, cursor); var packetIdField = readVarInt(buffer, cursor);
var packetId = packetIdField.value; var packetId = packetIdField.value;
cursor += packetIdField.size; cursor += packetIdField.size;
@ -1557,24 +1547,24 @@ function parseNewStylePacket(buffer, state, isServer, packetsToParse, cb) {
var results = { id: packetId }; var results = { id: packetId };
// Only parse the packet if there is a need for it, AKA if there is a listener attached to it // Only parse the packet if there is a need for it, AKA if there is a listener attached to it
var name = packetNames[state][isServer ? "toServer" : "toClient"][packetId]; var name = packetNames[state][isServer ? "toServer" : "toClient"][packetId];
var shouldParse = (!packetsToParse.hasOwnProperty(name) || packetsToParse[name] <= 0) var shouldParse = (!packetsToParse.hasOwnProperty(name) || packetsToParse[name] <= 0) &&
&& (!packetsToParse.hasOwnProperty("packet") || packetsToParse["packet"] <= 0); (!packetsToParse.hasOwnProperty("packet") || packetsToParse["packet"] <= 0);
if (shouldParse) { if (shouldParse) {
return { cb(null, {
size: length + lengthField.size, size: length + lengthField.size,
buffer: buffer, buffer: buffer,
results: results results: results
}; });
} }
var packetInfo = get(packetId, state, isServer); var packetInfo = get(packetId, state, isServer);
if (packetInfo === null) { if (packetInfo === null) {
return { cb(null, {
error: new Error("Unrecognized packetId: " + packetId + " (0x" + packetId.toString(16) + ")"), error: new Error("Unrecognized packetId: " + packetId + " (0x" + packetId.toString(16) + ")"),
size: length + lengthField.size, size: length + lengthField.size,
buffer: buffer, buffer: buffer,
results: results results: results
}; });
} else { } else {
var packetName = packetNames[state][isServer ? "toServer" : "toClient"][packetId]; var packetName = packetNames[state][isServer ? "toServer" : "toClient"][packetId];
debug("read packetId " + state + "." + packetName + " (0x" + packetId.toString(16) + ")"); debug("read packetId " + state + "." + packetName + " (0x" + packetId.toString(16) + ")");
@ -1598,22 +1588,40 @@ function parseNewStylePacket(buffer, state, isServer, packetsToParse, cb) {
}*/ }*/
if (readResults === null) continue; if (readResults === null) continue;
if (readResults.error) { if (readResults.error) {
return readResults; cb(null, readResults);
} }
results[fieldInfo.name] = readResults.value; results[fieldInfo.name] = readResults.value;
cursor += readResults.size; cursor += readResults.size;
} }
debug(results); debug(results);
cb({ cb(null, {
size: length + lengthField.size, size: length + lengthField.size,
results: results, results: results,
buffer: buffer buffer: buffer
}); });
}; };
if(dataLengthField != 0) { if (state == null) state = states.PLAY;
var cursor = 0;
var lengthField = readVarInt(buffer, 0);
if (!!!lengthField) return null;
var length = lengthField.value;
//console.log("Started reading compressed packet");
cursor += lengthField.size;
if (length + lengthField.size > buffer.length) { console.log("Stopped reading"); return null };
var buffer = buffer.slice(0, length + cursor); // fail early if too much is read.
var dataLengthField = readVarInt(buffer, cursor);
cursor += dataLengthField.size;
if(dataLengthField.value != 0) {
/*console.log("Cursor : " + cursor);
console.log("DataLength : " + dataLengthField.value);
console.log(buffer.slice(cursor, cursor + dataLengthField.value).toString('hex'));
console.log("Buffer : " + buffer.toString('hex'));*/
debug("Cursor : " + cursor);
zlib.inflateRaw(buffer.slice(cursor, cursor + dataLengthField.value), function(err, buffer) { zlib.inflateRaw(buffer.slice(cursor, cursor + dataLengthField.value), function(err, buffer) {
cursor = 0; if (err) console.log(err);
else console.log("Got a packet v2");
finishParsing(buffer); finishParsing(buffer);
}); });
} else { } else {