Skip to content

Commit

Permalink
tls: proper .destroySoon
Browse files Browse the repository at this point in the history
1. Emit `sslOutEnd` only when `_internallyPendingBytes() === 0`.
2. Read before checking `._halfRead`, otherwise we'll see only previous
   value, and will invoke `._write` callback improperly.
3. Wait for both `end` and `finish` events in `.destroySoon`.
4. Unpipe encrypted stream from socket to prevent write after destroy.
  • Loading branch information
indutny committed May 30, 2013
1 parent 9826b15 commit 9ee86b7
Showing 1 changed file with 33 additions and 22 deletions.
55 changes: 33 additions & 22 deletions lib/tls.js
Original file line number Diff line number Diff line change
Expand Up @@ -362,6 +362,16 @@ CryptoStream.prototype._write = function write(data, encoding, cb) {
return cb(this.pair.error(true));
}

// Force SSL_read call to cycle some states/data inside OpenSSL
this.pair.cleartext.read(0);

// Cycle encrypted data
if (this.pair.encrypted._internallyPendingBytes())
this.pair.encrypted.read(0);

// Get NPN and Server name when ready
this.pair.maybeInitFinished();

// Whole buffer was written
if (written === data.length) {
if (this === this.pair.cleartext) {
Expand All @@ -377,19 +387,6 @@ CryptoStream.prototype._write = function write(data, encoding, cb) {
} else {
cb(null);
}
}

// Force SSL_read call to cycle some states/data inside OpenSSL
this.pair.cleartext.read(0);

// Cycle encrypted data
if (this.pair.encrypted._internallyPendingBytes())
this.pair.encrypted.read(0);

// Get NPN and Server name when ready
this.pair.maybeInitFinished();

if (written === data.length) {
return;
} else if (written !== 0 && written !== -1) {
assert(!this._retryAfterPartial);
Expand Down Expand Up @@ -521,13 +518,15 @@ CryptoStream.prototype._read = function read(size) {
this._halfRead = halfRead;

// Notify listeners about internal data end
if (this === this.pair.cleartext) {
debug('cleartext.sslOutEnd');
} else {
debug('encrypted.sslOutEnd');
}
if (!halfRead) {
if (this === this.pair.cleartext) {
debug('cleartext.sslOutEnd');
} else {
debug('encrypted.sslOutEnd');
}

this.emit('sslOutEnd');
this.emit('sslOutEnd');
}
}
};

Expand Down Expand Up @@ -640,10 +639,19 @@ CryptoStream.prototype.destroySoon = function(err) {
if (this.writable)
this.end();

if (this._writableState.finished && this._opposite._ended)
if (this._writableState.finished && this._opposite._ended) {
this.destroy();
else
this.once('finish', this.destroy);
} else {
// Wait for both `finish` and `end` events to ensure that all data that
// was written on this side was read from the other side.
var self = this;
var waiting = 2;
function finish() {
if (--waiting === 0) self.destroy();
}
this._opposite.once('end', finish);
this.once('finish', finish);
}
};


Expand Down Expand Up @@ -1379,6 +1387,9 @@ function pipe(pair, socket) {

pair.encrypted.on('close', function() {
process.nextTick(function() {
// Encrypted should be unpiped from socket to prevent possible
// write after destroy.
pair.encrypted.unpipe(socket);
socket.destroy();
});
});
Expand Down

0 comments on commit 9ee86b7

Please sign in to comment.