Skip to content
This repository was archived by the owner on Apr 22, 2023. It is now read-only.

Commit 8e0c830

Browse files
committed
tls: async session storage
1 parent 790d651 commit 8e0c830

5 files changed

Lines changed: 392 additions & 12 deletions

File tree

doc/api/tls.markdown

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -373,6 +373,25 @@ When a client connection emits an 'error' event before secure connection is
373373
established - it will be forwarded here.
374374

375375

376+
### Event: 'newSession'
377+
378+
`function (sessionId, sessionData) { }`
379+
380+
Emitted on creation of TLS session. May be used to store sessions in external
381+
storage.
382+
383+
384+
### Event: 'resumeSession'
385+
386+
`function (sessionId, callback) { }`
387+
388+
Emitted when client wants to resume previous TLS session. Event listener may
389+
perform lookup in external storage using given `sessionId`, and invoke
390+
`callback(null, sessionData)` once finished. If session can't be resumed
391+
(i.e. doesn't exist in storage) one may call `callback(null, null)`. Calling
392+
`callback(err)` will terminate incoming connection and destroy socket.
393+
394+
376395
### server.listen(port, [host], [callback])
377396

378397
Begin accepting connections on the specified `port` and `host`. If the

lib/tls.js

Lines changed: 39 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -725,6 +725,37 @@ function onhandshakedone() {
725725
debug('onhandshakedone');
726726
}
727727

728+
function onclienthello(hello) {
729+
var self = this,
730+
once = false;
731+
732+
this.encrypted.pause();
733+
this.cleartext.pause();
734+
function callback(err, session) {
735+
if (once) return;
736+
once = true;
737+
738+
if (err) return self.socket.destroy(err);
739+
740+
self.ssl.loadSession(session);
741+
742+
self.encrypted.resume();
743+
self.cleartext.resume();
744+
}
745+
746+
if (hello.sessionId.length <= 0 ||
747+
!this.server ||
748+
!this.server.emit('resumeSession', hello.sessionId, callback)) {
749+
callback(null, null);
750+
}
751+
}
752+
753+
754+
function onnewsession(key, session) {
755+
if (!this.server) return;
756+
this.server.emit('newSession', key, session);
757+
}
758+
728759

729760
/**
730761
* Provides a pair of streams to do encrypted communication.
@@ -746,6 +777,7 @@ function SecurePair(credentials, isServer, requestCert, rejectUnauthorized,
746777

747778
events.EventEmitter.call(this);
748779

780+
this.server = options.server;
749781
this._secureEstablished = false;
750782
this._isServer = isServer ? true : false;
751783
this._encWriteState = true;
@@ -768,13 +800,16 @@ function SecurePair(credentials, isServer, requestCert, rejectUnauthorized,
768800
this._requestCert = requestCert ? true : false;
769801

770802
this.ssl = new Connection(this.credentials.context,
771-
this._isServer ? true : false,
772-
this._isServer ? this._requestCert : options.servername,
773-
this._rejectUnauthorized);
803+
this._isServer ? true : false,
804+
this._isServer ? this._requestCert :
805+
options.servername,
806+
this._rejectUnauthorized);
774807

775808
if (this._isServer) {
776809
this.ssl.onhandshakestart = onhandshakestart.bind(this);
777810
this.ssl.onhandshakedone = onhandshakedone.bind(this);
811+
this.ssl.onclienthello = onclienthello.bind(this);
812+
this.ssl.onnewsession = onnewsession.bind(this);
778813
this.ssl.handshakes = 0;
779814
this.ssl.timer = null;
780815
}
@@ -1084,6 +1119,7 @@ function Server(/* [options], listener */) {
10841119
self.requestCert,
10851120
self.rejectUnauthorized,
10861121
{
1122+
server: self,
10871123
NPNProtocols: self.NPNProtocols,
10881124
SNICallback: self.SNICallback
10891125
});

0 commit comments

Comments
 (0)