Browse files

tls: do graceful shutdown

  • Loading branch information...
1 parent 0506d29 commit bd2a783504b747c6a549fa8962cff50f30cb62f8 @indutny committed Dec 2, 2012
Showing with 35 additions and 4 deletions.
  1. +35 −3 lib/tls.js
  2. +0 −1 src/node_crypto.cc
View
38 lib/tls.js
@@ -221,6 +221,8 @@ function CryptoStream(pair) {
this._paused = false;
this._needDrain = false;
+ this._shutdown = 0;
+ this._shutdownTimeout = null;
this._pending = [];
this._pendingCallbacks = [];
this._pendingBytes = 0;
@@ -546,15 +548,15 @@ CryptoStream.prototype._pull = function() {
assert(havePending || this._pendingBytes == 0);
- while (this._pending.length > 0) {
+ while (this._shutdown > 0 || this._pending.length > 0) {
if (!this.pair.ssl) break;
var tmp = this._pending.shift();
var cb = this._pendingCallbacks.shift();
assert(this._pending.length === this._pendingCallbacks.length);
- if (tmp === END_OF_FILE) {
+ if (this._shutdown > 0 || tmp === END_OF_FILE) {
// Sending EOF
if (this === this.pair.encrypted) {
debug('end encrypted ' + this.pair.fd);
@@ -564,7 +566,36 @@ CryptoStream.prototype._pull = function() {
assert(this === this.pair.cleartext);
debug('end cleartext');
- this.pair.ssl.shutdown();
+ if (!this._shutdownTimeout) {
+ var self = this;
+ this._shutdownTimeout = setTimeout(function() {
+ self._shutdown = 4;
+ self.pair.cycle();
+ }, this.pair._shutdownTimeout);
+ }
+
+ switch (this._shutdown) {
+ case 0:
+ this._shutdown = 1;
+ if (this.pair.ssl.shutdown() == 1) {
+ this._shutdown = 2;
+ break;
+ }
+ this.pair.cycle();
+ case 1:
+ if (this.pair.ssl.shutdown() == 1) {
+ this._shutdown = 2;
+ break;
+ }
+ return;
+ case 2:
+ break;
+ }
+
+ if (this._shutdownTimeout) {
+ clearTimeout(this._shutdownTimeout);
+ this._shutdownTimeout = null;
+ }
// TODO check if we get EAGAIN From shutdown, would have to do it
// again. should unshift END_OF_FILE back onto pending and wait for
@@ -784,6 +815,7 @@ function SecurePair(credentials, isServer, requestCert, rejectUnauthorized,
events.EventEmitter.call(this);
this.server = options.server;
+ this._shutdownTimeout = options.shutdownTimeout || 5000;
this._secureEstablished = false;
this._isServer = isServer ? true : false;
this._encWriteState = true;
View
1 src/node_crypto.cc
@@ -1725,7 +1725,6 @@ Handle<Value> Connection::Shutdown(const Arguments& args) {
if (ss->ssl_ == NULL) return False();
int rv = SSL_shutdown(ss->ssl_);
- ss->HandleSSLError("SSL_shutdown", rv, kZeroIsNotAnError);
ss->SetShutdownFlags();
return scope.Close(Integer::New(rv));

0 comments on commit bd2a783

Please sign in to comment.