need to call ssl::stream::shutdown when closing boost asio ssl socket?
Asked Answered
B

3

6

My code is as follows:

declaration: boost::asio::ssl::stream<boost::asio::ip::tcp::socket> m_remote_socket;

m_remote_socket.shutdown(ec);
if (ec)
{      
    cdbug<<"id: "<<m_id<<", error when ssl shutdown: "    <<boost::system::system_category().message(ec.value()).c_str(); 
}
m_remote_socket.lowest_layer().shutdown(boost::asio::ip::tcp::socket::shutdown_both, ec);
if (ec)
{
    cdbug<<"id: "<<m_id<<", error when tcp shutdown: "<<boost::system::system_category().message(ec.value()).c_str(); 
}

Each time I call m_remote_socket.shutdown, it will get an error. Such kind of unknown error with a really big error value.

But it is ok to call m_remote_socket.lowest_layer().shutdown() directly without calling m_remote_socket.shutdown.

Could anybody tell me how to close a ssl streaming socket?

Bes answered 9/3, 2013 at 15:10 Comment(1)
What is the error code and message when shutdown fails?Closet
W
6

It is cleanest to make shutdown() calls on both the ssl::stream and its lowest_layer(). The first ends the SSL connection and the second ends the TCP connection. If you're getting an error on the SSL shutdown, it may be that the other side is not being as graceful in ending the connection.

Weighty answered 9/3, 2013 at 15:32 Comment(5)
That's not correct. It isn't legal for the TCP connection underlying an SSL connection to be half-closed. See RFC 2246.Acaulescent
@EJP, I'm not sure I understand what you mean. The fact that SSL connections should be closed before the lower protocol layers doesn't prevent the side you're communicating with from closing or dropping TCP. I'm just trying to explain why you may get an error when trying to shut down SSL.Weighty
@rashimodo There is no such thing as a half-closed SSL connection. Once one side receives a close_notify, it must close the connection. I'm surprised the library under discussion even provides an SSL shutdown, but if it does and it works the result must be a completely closed connection. Shutting down one side of the underlying TCP connection leaves SSL in an invalid state. This answer is not correct.Acaulescent
Thanks, Finally i know why it has the error: there is still unfinished io operation pending on thisBes
socket. and the error disappear after i move the close operation to the destructorBes
J
3

I do highly recommend that you should not use shutdown method and don't respect SSL layer + TCP layer (lowest_layer). be in safe side and close the tcp lowest_layer as

m_remote_socket.lowest_layer().close(ec);

The problem i faced that the time you respect the SSL or TCP, the application resources(socket handler) will stock in memory till server side send close session ack.

Jochbed answered 9/6, 2018 at 2:4 Comment(0)
A
1

Just call close(). It isn't legal to shutdown SSL sockets: there is no such thing as a half-close in SSL. See RFC 2246, discussion of close_notify.

Acaulescent answered 10/3, 2013 at 23:6 Comment(9)
What is your definition of "shutdown"? I think one of us has a semantic misunderstanding. The OpenSSL concept of shutdown is sending close_notify, and this is what boost::asio invokes.Weighty
The TCP notion of shutdown is a half close: sending a FIN in one direction while keeping the other direction open. This is what 'shutdown(SHUT_WR)' does. The SSL notion of close_notify is a full close. 'The currently open session is considered closed'. They are not reconcilable.Acaulescent
That's why my answer says to call shutdown() on the ssl::stream. That does not send FIN and end the TCP connection; it calls OpenSSL SSL_shutdown which sends close_notify. ssl::stream::shutdown() == close_notfify. SSL_shutdown() != TCP FIN.Weighty
Quite, so you should not also do the TCP shutdown. I would also observe that if this shutdown method doesn't do a half close, it is badly misnamed.Acaulescent
We now agree calling ssl::stream::shutdown() (which sends close_notify) is correct, yes? After this are you going to leave the TCP connection idle forever? The connection should be ended cleanly with FIN, and TLS section 7.2.1 explicitly permits immediate TCP shutdown after sending close_notify. As for the naming of "shutdown", this is the term used by both OpenSSL and NSS for alerting close_notify without closing the TCP transport.Weighty
@Weighty My answer clearly says 'just call close(). This is not the same thing as 'leav[ing] the TCP connection idle forever'. Your point eludes me.Acaulescent
Your comment above says "you should not also do the TCP shutdown" and "if this shutdown method doesn't do a half close, it is badly misnamed". This implied to me that you are saying that if you call shutdown() at the SSL layer then you do not need to call close() at the TCP layer. If you want to go back to your answer, only calling close() is incorrect. close() is a method on boost::asio::ip::tcp::socket() and does nothing at the SSL/TLS layer.Weighty
@Weighty You cannot by any convolution of logic derive 'you do not need to call close()' from an answer that says just call close()'. If boost::asio`'s SSL close is called shutdown it is badly misdesigned.Acaulescent
It looks like you're ignoring the context of my comment, which begins with referencing your comment where you say, "you should not also do the TCP shutdown", which contradicts your original answer. It looks like your issue is with the boost::asio API design. Perhaps you are also unfamiliar with the OpenSSL API, as the shutdown concept is identical there (as my very first comment points out). Even if you don't like the API, your answer does not send close_notify.Weighty

© 2022 - 2024 — McMap. All rights reserved.