From 86325b18387f2ee55e5760887f34f2aa4a34b415 Mon Sep 17 00:00:00 2001 From: Peter Thorson Date: Fri, 28 Feb 2014 09:02:26 -0600 Subject: [PATCH] cleans up the handling of TLS related transport errors MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Specifically: TLS short read is separated from other TLS errors. Other TLS errors are also not separated from generic “pass through” errors. TLS short read is now considered “expected” during socket shutdown and is not reported as an error. --- websocketpp/transport/asio/connection.hpp | 54 ++++++++++++++--------- 1 file changed, 34 insertions(+), 20 deletions(-) diff --git a/websocketpp/transport/asio/connection.hpp b/websocketpp/transport/asio/connection.hpp index 62075c9db2..a4ed4d133a 100644 --- a/websocketpp/transport/asio/connection.hpp +++ b/websocketpp/transport/asio/connection.hpp @@ -807,26 +807,28 @@ protected: ); } - void handle_async_read(const boost::system::error_code& ec, + void handle_async_read(boost::system::error_code const & ec, size_t bytes_transferred) { - if (!ec) { - m_read_handler(lib::error_code(), bytes_transferred); - return; - } - // translate boost error codes into more lib::error_codes + lib::error_code tec; if (ec == boost::asio::error::eof) { - m_read_handler(make_error_code(transport::error::eof), - bytes_transferred); - } else if (ec.value() == 335544539) { - m_read_handler(make_error_code(transport::error::tls_short_read), - bytes_transferred); - } else { - log_err(log::elevel::info,"asio async_read_at_least",ec); - m_read_handler(make_error_code(transport::error::pass_through), - bytes_transferred); + tec = make_error_code(transport::error::eof); + } else if (ec) { + // We don't know much more about the error at this point. As our + // socket/security policy if it knows more: + tec = socket_con_type::translate_ec(ec); + + if (tec == transport::error::tls_error || + tec == transport::error::pass_through) + { + // These are aggregate/catch all errors. Log some human readable + // information to the info channel to give library users some + // more details about why the upstream method may have failed. + log_err(log::elevel::info,"asio async_read_at_least",ec); + } } + m_read_handler(tec,bytes_transferred); } void async_write(const char* buf, size_t len, write_handler handler) { @@ -998,25 +1000,37 @@ protected: shutdown_timer->cancel(); + lib::error_code tec; if (ec) { - log_err(log::elevel::devel,"asio async_shutdown",ec); if (ec == boost::asio::error::not_connected) { // The socket was already closed when we tried to close it. This // happens periodically (usually if a read or write fails // earlier and if it is a real error will be caught at another // level of the stack. - callback(lib::error_code()); } else { - callback(make_error_code(transport::error::pass_through)); + // We don't know anything more about this error, give our + // socket/security policy a crack at it. + tec = socket_con_type::translate_ec(ec); + + if (tec == transport::error::tls_short_read) { + // TLS short read at this point is somewhat expected if both + // sides try and end the connection at the same time or if + // SSLv2 is being used. In general there is nothing that can + // be done here other than a low level development log. + } else { + // all other errors are effectively pass through errors of + // some sort so print some detail on the info channel for + // library users to look up if needed. + log_err(log::elevel::info,"asio async_shutdown",ec); + } } } else { if (m_alog.static_test(log::alevel::devel)) { m_alog.write(log::alevel::devel, "asio con handle_async_shutdown"); } - - callback(lib::error_code()); } + callback(tec); } private: /// Convenience method for logging the code and message for an error_code