From c4050979c3bc205c66a88809fe52513efe630445 Mon Sep 17 00:00:00 2001 From: Peter Thorson Date: Sun, 24 Sep 2017 10:44:21 -0500 Subject: [PATCH] tcp_pre_bind_handler returns a lib::error_code not an asio::error_code. These are sometimes the same but not always. Fix ensures that the error code types always match correctly no matter what they are. Update test suite to reflect adjusted behavior --- test/endpoint/endpoint.cpp | 5 ++- websocketpp/transport/asio/endpoint.hpp | 53 +++++++++++++++---------- 2 files changed, 37 insertions(+), 21 deletions(-) diff --git a/test/endpoint/endpoint.cpp b/test/endpoint/endpoint.cpp index 34764d1..b4c429e 100644 --- a/test/endpoint/endpoint.cpp +++ b/test/endpoint/endpoint.cpp @@ -147,8 +147,11 @@ BOOST_AUTO_TEST_CASE( listen_after_listen_failure ) { server1.listen(ep1, ec); BOOST_CHECK(!ec); + // This should return some sort of problem. Usually either "pass through" or + // a more specific address in use error. It is hard to capture the full range + // of 'correctly wrong' values. server2.listen(ep1, ec); - BOOST_REQUIRE_EQUAL(ec, make_error_code(pass_through)); + BOOST_REQUIRE(ec); server2.listen(ep2, ec); BOOST_CHECK(!ec); diff --git a/websocketpp/transport/asio/endpoint.hpp b/websocketpp/transport/asio/endpoint.hpp index 5adb1c2..ddab2c7 100644 --- a/websocketpp/transport/asio/endpoint.hpp +++ b/websocketpp/transport/asio/endpoint.hpp @@ -425,30 +425,33 @@ public: lib::asio::error_code bec; m_acceptor->open(ep.protocol(),bec); - if (!bec) { - m_acceptor->set_option(lib::asio::socket_base::reuse_address(m_reuse_addr),bec); - } - if (!bec && m_tcp_pre_bind_handler) { - bec = m_tcp_pre_bind_handler(m_acceptor); - } - if (!bec) { - m_acceptor->bind(ep,bec); - } - if (!bec) { - m_acceptor->listen(m_listen_backlog,bec); - } - if (bec) { - if (m_acceptor->is_open()) { - m_acceptor->close(); + if (bec) {ec = clean_up_listen_after_error(bec);return;} + + m_acceptor->set_option(lib::asio::socket_base::reuse_address(m_reuse_addr),bec); + if (bec) {ec = clean_up_listen_after_error(bec);return;} + + // if a TCP pre-bind handler is present, run it + if (m_tcp_pre_bind_handler) { + ec = m_tcp_pre_bind_handler(m_acceptor); + if (ec) { + ec = clean_up_listen_after_error(ec); + return; } - log_err(log::elevel::info,"asio listen",bec); - ec = socket_con_type::translate_ec(ec); - } else { - m_state = LISTENING; - ec = lib::error_code(); } + + m_acceptor->bind(ep,bec); + if (bec) {ec = clean_up_listen_after_error(bec);return;} + + m_acceptor->listen(m_listen_backlog,bec); + if (bec) {ec = clean_up_listen_after_error(bec);return;} + + // Success + m_state = LISTENING; + ec = lib::error_code(); } + + /// Set up endpoint for listening manually /** * Bind the internal acceptor using the settings specified by the endpoint e @@ -1137,6 +1140,16 @@ private: m_elog->write(l,s.str()); } + /// Helper for cleaning up in the listen method after an error + template + lib::error_code clean_up_listen_after_error(error_type const & ec) { + if (m_acceptor->is_open()) { + m_acceptor->close(); + } + log_err(log::elevel::info,"asio listen",ec); + return socket_con_type::translate_ec(ec); + } + enum state { UNINITIALIZED = 0, READY = 1,