Browse Source

TLS: Simplify code from suck and blow

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

186
lib/tls.js

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