-
Notifications
You must be signed in to change notification settings - Fork 7.3k
tls: Closing parent socket also closes the tls sock #25642
Conversation
@@ -238,6 +238,7 @@ function TLSSocket(socket, options) { | |||
|
|||
if (socket) { | |||
this._parent = socket; | |||
socket._destroy = function(exception){self._destroy(exception)}; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why not simply this._destroy.bind(this);
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm newish to javascript and I didn't know that was a thing
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would do:
function(err) {
self._destroy(err);
}
Last time I check it - bind
was kind of slow.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@indutny Oh, okay. Thanks for the info :-)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This one is still there ;)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This one wasn't fixed. Please make it span multiple lines.
@indutny could you review this as well since one of your recent commits ( dnakamura/node@bada87b#diff-04c3a6bcf355f2e05e7700c1b253d475) looks like it addressed a similar parent/child related issue. |
@@ -456,7 +456,8 @@ Socket.prototype._destroy = function(exception, cb) { | |||
if (cb) cb(exception); | |||
if (exception && !self._writableState.errorEmitted) { | |||
process.nextTick(function() { | |||
self.emit('error', exception); | |||
for(var s = self; s !== null; s = s._parent) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
for (
@dnakamura I wonder if we may consider backporting nodejs/node@9b6b05556 instead? |
@Induty As far as I can tell, nodejs/node@9b6b055 does not fix the problem (still able to reproduce on latest io.js). Also I have to double check the code but I think it may already be backported |
}); | ||
this._handle.onread = noop; | ||
this._handle = null; | ||
for(var s = this; s !== null; s = s._parent){ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
for (...)
@dnakamura you are absolutely right. It just looked strikingly similar, so I thought it might need the backport. Looked through the changes and they are looking good to me except few nits. |
@indutny , @thefourtheye took your changes into account, can you take another look. |
for (var s = this; s !== null; s = s._parent){ | ||
timers.unenroll(s); | ||
s._connecting = false; | ||
s.readable = s.writable = false; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If we are writing like this, why not just
s._connecting = s.readable = s.writable = false;
then?
LGTM, except some style nits. May I ask you to fix them before I will land this PR? (It is going to be fun to forward-port it to io.js. I should probably do it myself right after landing it in v0.12) |
@indutny Fixed style nits, can you take a look? |
|
||
for (var s = this; s !== null; s = s._parent) | ||
timers.unenroll(s); | ||
for (var s = this; s !== null; s = s._parent){ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Space between )
and {
. Didn't make lint
complain about it?
Few last nits, thanks! |
8884c5c
to
be30464
Compare
@indutny ok that should be all of them |
@indutny ok, hopefully now I've got it 😄 |
@@ -238,6 +239,9 @@ function TLSSocket(socket, options) { | |||
|
|||
if (socket) { | |||
this._parent = socket; | |||
socket._destroy = function(exception) { | |||
self._destroy(exception) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Semicolon at the end?
@thefourtheye fixed. |
Awesome LGTM. @thefourtheye may I have your LGTM as well? ;) |
@indutny Changes are straight forward. LGTMT :) |
@mhdawson @thefourtheye where should I land this? |
@indutny I am not familiar with this repo's pr landing process but going by the tags on this PR I would say v0.12 |
I can get it landed. FWIW, we use the node-accept-pull-request job in https://jenkins-iojs.nodesource.com/ to land in joyent/node. @orangemocha has all the necessary details on that. |
@jasnell Thanks for the info :-) |
@thefourtheye ... btw, I can't seem to find your full name anywhere for the sign off ;-) |
@jasnell Its in nodejs/node's collaborator's list. Sakthipriyan Vairamani :-) It is nice working with you :-) |
The pleasure is mine. |
@dnakamura ... if you're seeing this problem on io.js master also, can I ask for you to go ahead and port this and open a new PR against master on nodejs/node if you haven't done so already? :-) |
Hmm.. @dnakamura getting some failures in CI. Not clear if they are related to the change. Same failure on both Windows platforms. https://jenkins-iojs.nodesource.com/job/node-test-commit-windows/nodes=win2008r2/181/ |
@jasnell: yup it does seem to be me (except test-dns), looking into the root cause now |
So as it turns out the issue is because now if the socket is destroyed from an error, both sockets (tls, and parent) emit an error. Since nobody is listening for errors on the parent socket it causes an unhandled error event. My first instinct is to only change the code so it only fires the error event on the lowest socket (from a parent-child view, highest from a protocol stack view). However I'm wondering if it might make more sense to always fire the error event on the same object |
@dnakamura or we may call it a breaking change, land it in nodejs/node repo. And watch for the |
Or just not emit errors on parent socket in v0.12. Technically, emitting |
@jasnell Ok that should fix it now. I have a couple tests still failing here, but they also fail on official builds, so I dont think its my fault |
As long as it passes CI, LGTM. I'll run it through the checker now. |
PR-URL: #25642 Reviewed-By: jasnell - James M Snell <jasnell@gmail.com>
Landed in 0363cf4 |
PR-URL: nodejs#25642 Reviewed-By: jasnell - James M Snell <jasnell@gmail.com>
Fixes #25365 . At the moment if you close the parent socket of a a TLS socket the TLS socket is not aware of this and will segfault when you attempt to perform and IO operation on it. Further, if you close the parent socket and then the TLS socket, the parent socket will emit the close event twice (and the TLS socket wont fire at all). If you change the order the results are reversed, ie. closing the TLS then the parent socket will result in the TLS socket firing the close event twice and the parent socket wont fire at all.
This patch moves toward linking the parent and tls sockets. Calling
destroy()
on either of the the sockets causes both sockets to be destroyed and the close event emitted for both of them