Browse Source

TLS: Simplify code from suck and blow

v0.7.4-release
Ryan Dahl 14 years ago
parent
commit
6636bfaa0a
  1. 196
      lib/tls.js

196
lib/tls.js

@ -93,73 +93,58 @@ CryptoStream.prototype.destroy = function(err) {
}; };
function CleartextStream (pair) {
CryptoStream.call(this, pair);
}
util.inherits(CleartextStream, CryptoStream);
// Push in any clear data coming from the application.
// This arrives via some code like this:
//
// pair.cleartext.write("hello world");
//
CleartextStream.prototype._suck = function() {
var tmp, rv;
var havePending = this._pending.length > 0;
while (this._pending.length > 0) {
tmp = this._pending.shift();
try {
debug('writng from clearIn');
rv = this.pair._ssl.clearIn(tmp, 0, tmp.length);
} catch (e) {
return this.pair._error(e);
}
if (rv === 0) {
this._pending.unshift(tmp);
break;
}
assert(rv === tmp.length);
}
// If we've cleared all of incoming cleartext data, emit drain.
if (havePending && this._pending.length === 0) {
debug('cleartext drain');
this.emit('drain');
}
};
// Move decrypted, clear data out into the application. // Move decrypted, clear data out into the application.
// From the user's perspective this occurs as a 'data' event // From the user's perspective this occurs as a 'data' event
// on the pair.cleartext. // on the pair.cleartext.
CleartextStream.prototype._blow = function() { // also
var self = this; // Move encrypted data to the stream. From the user's perspective this
self.pair._mover( // occurs as a 'data' event on the pair.encrypted. Usually the application
function(pool, offset, length) { // will have some code which pipes the stream to a socket:
debug('reading from clearOut'); //
return self.pair._ssl.clearOut(pool, offset, length); // pair.encrypted.on('data', function (d) {
}, // socket.write(d);
function(chunk) { // });
self.emit('data', chunk); //
}, CryptoStream.prototype._blow = function() {
function() { var bytesRead;
return self._writeState === true; var pool;
}); var chunkBytes;
}; var chunk;
do {
bytesRead = 0;
chunkBytes = 0;
pool = new Buffer(4096); // alloc every time?
pool.used = 0;
do {
try {
chunkBytes = this._blower(pool,
pool.used + bytesRead,
pool.length - pool.used - bytesRead);
} catch (e) {
return this.pair._error(e);
}
if (chunkBytes >= 0) {
bytesRead += chunkBytes;
}
} while ((chunkBytes > 0) && (pool.used + bytesRead < pool.length));
function EncryptedStream (pair) { if (bytesRead > 0) {
CryptoStream.call(this, pair); chunk = pool.slice(0, bytesRead);
} this.emit('data', chunk);
util.inherits(EncryptedStream, CryptoStream); }
} while (bytesRead > 0 && this._writeState === true);
};
// Push in any clear data coming from the application.
// This arrives via some code like this:
//
// pair.cleartext.write("hello world");
//
// also
//
// Push in incoming encrypted data from the socket. // Push in incoming encrypted data from the socket.
// This arrives via some code like this: // This arrives via some code like this:
// //
@ -167,15 +152,14 @@ util.inherits(EncryptedStream, CryptoStream);
// pair.encrypted.write(d) // pair.encrypted.write(d)
// }); // });
// //
EncryptedStream.prototype._suck = function() { CryptoStream.prototype._suck = function() {
var tmp, rv; var tmp, rv;
var havePending = this._pending.length > 0; var havePending = this._pending.length > 0;
while (this._pending.length > 0) { while (this._pending.length > 0) {
tmp = this._pending.shift(); tmp = this._pending.shift();
try { try {
debug('writing from encIn'); rv = this._sucker(tmp);
rv = this.pair._ssl.encIn(tmp, 0, tmp.length);
} catch (e) { } catch (e) {
return this.pair._error(e); return this.pair._error(e);
} }
@ -190,39 +174,48 @@ EncryptedStream.prototype._suck = function() {
// If we've cleared all of incoming encrypted data, emit drain. // If we've cleared all of incoming encrypted data, emit drain.
if (havePending && this._pending && this._pending.length === 0) { if (havePending && this._pending && this._pending.length === 0) {
debug('encrypted drain'); debug('drain');
this.emit('drain'); this.emit('drain');
} }
};
function CleartextStream (pair) {
CryptoStream.call(this, pair);
} }
util.inherits(CleartextStream, CryptoStream);
// Move encrypted data to the stream. From the user's perspective this CleartextStream.prototype._sucker = function(b) {
// occurs as a 'data' event on the pair.encrypted. Usually the application debug('writng from clearIn');
// will have some code which pipes the stream to a socket: return this.pair._ssl.clearIn(b, 0, b.length);
// };
// pair.encrypted.on('data', function (d) {
// socket.write(d);
// }); CleartextStream.prototype._blower = function(pool, offset, length) {
// debug('reading from clearOut');
EncryptedStream.prototype._blow = function () { return this.pair._ssl.clearOut(pool, offset, length);
var self = this; };
self.pair._mover( function EncryptedStream (pair) {
function(pool, offset, length) { CryptoStream.call(this, pair);
debug('reading from encOut'); }
if (!self.pair._ssl) return -1; util.inherits(EncryptedStream, CryptoStream);
return self.pair._ssl.encOut(pool, offset, length);
},
function(chunk) { EncryptedStream.prototype._sucker = function(b) {
self.emit('data', chunk); debug('writing from encIn');
}, return this.pair._ssl.encIn(b, 0, b.length);
function() {
if (!self.pair._ssl) return false;
return self._writeState === true;
});
}; };
EncryptedStream.prototype._blower = function(pool, offset, length) {
debug('reading from encOut');
if (!this.pair._ssl) return -1;
return this.pair._ssl.encOut(pool, offset, length);
};
/** /**
* Provides a pair of streams to do encrypted communication. * Provides a pair of streams to do encrypted communication.
@ -304,37 +297,6 @@ exports.createSecurePair = function(credentials,
}; };
SecurePair.prototype._mover = function(reader, writer, checker) {
var bytesRead;
var pool;
var chunkBytes;
var chunk;
do {
bytesRead = 0;
chunkBytes = 0;
pool = new Buffer(4096); // alloc every time?
pool.used = 0;
do {
try {
chunkBytes = reader(pool,
pool.used + bytesRead,
pool.length - pool.used - bytesRead);
} catch (e) {
return this._error(e);
}
if (chunkBytes >= 0) {
bytesRead += chunkBytes;
}
} while ((chunkBytes > 0) && (pool.used + bytesRead < pool.length));
if (bytesRead > 0) {
chunk = pool.slice(0, bytesRead);
writer(chunk);
}
} while (bytesRead > 0 && checker());
};
/** /**

Loading…
Cancel
Save