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