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

tls: async session storage #3661

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
19 changes: 19 additions & 0 deletions doc/api/tls.markdown
Expand Up @@ -373,6 +373,25 @@ When a client connection emits an 'error' event before secure connection is
established - it will be forwarded here.


### Event: 'newSession'

`function (sessionId, sessionData) { }`

Emitted on creation of TLS session. May be used to store sessions in external
storage.


### Event: 'resumeSession'

`function (sessionId, callback) { }`

Emitted when client wants to resume previous TLS session. Event listener may
perform lookup in external storage using given `sessionId`, and invoke
`callback(null, sessionData)` once finished. If session can't be resumed
(i.e. doesn't exist in storage) one may call `callback(null, null)`. Calling
`callback(err)` will terminate incoming connection and destroy socket.


### server.listen(port, [host], [callback])

Begin accepting connections on the specified `port` and `host`. If the
Expand Down
42 changes: 39 additions & 3 deletions lib/tls.js
Expand Up @@ -725,6 +725,37 @@ function onhandshakedone() {
debug('onhandshakedone');
}

function onclienthello(hello) {
var self = this,
once = false;

this.encrypted.pause();
this.cleartext.pause();
function callback(err, session) {
if (once) return;
once = true;

if (err) return self.socket.destroy(err);

self.ssl.loadSession(session);

self.encrypted.resume();
self.cleartext.resume();
}

if (hello.sessionId.length <= 0 ||
!this.server ||
!this.server.emit('resumeSession', hello.sessionId, callback)) {
callback(null, null);
}
}


function onnewsession(key, session) {
if (!this.server) return;
this.server.emit('newSession', key, session);
}


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

events.EventEmitter.call(this);

this.server = options.server;
this._secureEstablished = false;
this._isServer = isServer ? true : false;
this._encWriteState = true;
Expand All @@ -768,13 +800,16 @@ function SecurePair(credentials, isServer, requestCert, rejectUnauthorized,
this._requestCert = requestCert ? true : false;

this.ssl = new Connection(this.credentials.context,
this._isServer ? true : false,
this._isServer ? this._requestCert : options.servername,
this._rejectUnauthorized);
this._isServer ? true : false,
this._isServer ? this._requestCert :
options.servername,
this._rejectUnauthorized);

if (this._isServer) {
this.ssl.onhandshakestart = onhandshakestart.bind(this);
this.ssl.onhandshakedone = onhandshakedone.bind(this);
this.ssl.onclienthello = onclienthello.bind(this);
this.ssl.onnewsession = onnewsession.bind(this);
this.ssl.handshakes = 0;
this.ssl.timer = null;
}
Expand Down Expand Up @@ -1084,6 +1119,7 @@ function Server(/* [options], listener */) {
self.requestCert,
self.rejectUnauthorized,
{
server: self,
NPNProtocols: self.NPNProtocols,
SNICallback: self.SNICallback
});
Expand Down