-
Notifications
You must be signed in to change notification settings - Fork 3k
Make sure that TLSSocketWrapper::close() is called before the transport is destroyed. #8613
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
Transport is a member of TLSSocket which is derived from TLSSocketWrapper. Make sure that TLSSocketWrapper::close() is called before the transport is destroyed.
@kjbracey-arm please review |
@cmonr This has already been reviewed by Kevin. So please set the status to "Needs: CI" or start CI. Thanks. |
/morph build |
Build : SUCCESSBuild number : 3538 Triggering tests/morph test |
Exporter Build : SUCCESSBuild number : 3149 |
Test : FAILUREBuild number : 3322 |
test failure seems unrelated, re-trying |
Build : SUCCESSBuild number : 3539 Triggering tests/morph test |
Exporter Build : SUCCESSBuild number : 3150 |
Test : FAILUREBuild number : 3323 |
/morph test |
Test : SUCCESSBuild number : 3329 |
This change is fully legit, but I would also move the _transport = NULL; assignment from the close function to the TLSSocketWrapper destructor. Otherwise we cannot reopen a closed socket... |
As this is now ready, this can be done separately |
This functionality is only coming in for 5.11 |
Is there a reason why this is still not fixed? |
Looking at the code, I believe the That would then let you close the SSL session and make a new one on the same transport. That's not a normal use case though. You'd normally have one SSL session per TCP connection - this wrapper doesn't support closing and re-opening the underlying transport. That would be a bigger job. Could be I'm misunderstanding something... |
Technically, Furthermore, why would be the pointer reset on I managed to get reconnection working without destroying the instance, I can open a PR regarding this. |
The After closing a socket, it's potentially no longer valid, eg a socket that was created by a TCP listen. The I'm not clear whether you have an issue with the complete It should be possible to It seems to me like I think we were reluctant to re-do the "constructed-but-not-opened" state for the wrapper, so wanted those things set only on construction. But you end up in that state anyway after close... Alternatively we could just remove that nulling and leave it up to users of Anyway, it does need some thought. |
I am using the
This is a good idea, I tried it out and seems to be working. Is there an argument against doing this? It is not the only change btw, for instance |
I think it's probably the best overall solution, we just maybe need to think about the lifetime model of In general I've not been hugely keen on reuse of sockets because it's (a) non standard, (b) it rather mandates having a chunk of dedicated clean up code and getting that right, increasing code size. It would be "cleaner" to destroy and reconstruct the socket, as portable BSD TCP socket code would. The counterproblem with that is that we also aren't keep on dynamic allocation. C++17's
Don't have that available in Mbed OS yet though. And arguably it's not that much clearer than placement new and delete, although partly due to novelty. And no doubt would end up bigger than placement new/delete - probably more bloat than any dedicated close-reopen support with direct calls. |
Hi @kjbracey-arm,
but I get the error:
Do you know why this is not allowed? Shouldn't this be theoretically possible? |
Hmm, that could in principle be permitted, by adding a move assignment operator. Copying is not permitted (you can't fork a socket into two sockets), but in this case the thing you're copying from is a temporary, so it could be implemented as a move. However, the code required to support that is non-trivial, and in effect recreates the same problem - having to write code to manually clean up the state for re-use. You can achieve what you want to achieve in a way that will work with any object by using placement delete and new manually:
That just uses the class's destructor and constructor, which must always exist. (And that's what the |
Yes, that was exactly what I wanted. I didn't know about the pointer argument of the new operator either. Thanks for the tip! I guess this will be the way to go for me until we have |
Another general tip is check out (We never call static object destructors, but some toolchains will insist on them being referenced. SingletonPtr avoids this). We could maybe modify that to add a So
I've just remembered I added a |
Description
Transport is a member of TLSSocket which is derived from TLSSocketWrapper.
Make sure that TLSSocketWrapper::close() is called before the transport is
destroyed.
If you deleted the
TLSSocket
class without closing it first, it lead tombed_error()
and crashed the device.Pull request type