Skip to content

Exception in async_server_base/async_connection during port scanning (nmap) #677

@vovams

Description

@vovams

When boost::network::http::server is listening for new connections, it sometimes throws the following exception from it's run() method (or asio::io_service::run()) when the host is being port scanned using nmap:

boost::exception_detail::clone_impl<boost::exception_detail::error_info_injector<std::system_error>>
remote_endpoint: Transport endpoint is not connected

After the exception servers stops accepting connections even if event loop is restarted and has to be stop()'ed and `listen()``ed again. In my tests, depending on the system, this may happen every time the host in nmap'ed or require several consequent nmaps.

This bug actually has already been reported (issue #360), but for an old version of cpp-netlib and there was no activity, so i decided to open a new issue. I am experiencing this problem with cpp-netlib 0.12.0.

I have fixed the issue in my project with the following patch. I am unsure if i have fixed it the right way (for example, i might have introduced breaking API change in stream_handler::remote_endpoint()), but if it is ok, i can send a pull request.

diff --git a/boost/network/protocol/http/server/async_connection.hpp b/boost/network/protocol/http/server/async_connection.hpp
index 915c6fb..eca2f68 100644
--- a/boost/network/protocol/http/server/async_connection.hpp
+++ b/boost/network/protocol/http/server/async_connection.hpp
@@ -462,11 +462,18 @@ struct async_connection
   enum state_t { method, uri, version, headers };

   void start() {
-    typename ostringstream<Tag>::type ip_stream;
-    ip_stream << socket_.remote_endpoint().address().to_string() << ':'
-              << socket_.remote_endpoint().port();
-    request_.source = ip_stream.str();
-    read_more(method);
+    std::error_code ec;
+    auto remote_endpoint = socket_.remote_endpoint(ec);
+    
+    if (ec) {
+      error_encountered = in_place<std::system_error>(ec);
+    } else {
+      typename ostringstream<Tag>::type ip_stream;
+      ip_stream << remote_endpoint.address().to_string() << ':'
+                << remote_endpoint.port();
+      request_.source = ip_stream.str();
+      read_more(method);
+    }
   }

   void read_more(state_t state) {
diff --git a/boost/network/protocol/stream_handler.hpp b/boost/network/protocol/stream_handler.hpp
index 16fafc6..9d82706 100644
--- a/boost/network/protocol/stream_handler.hpp
+++ b/boost/network/protocol/stream_handler.hpp
@@ -109,11 +109,11 @@ struct stream_handler {
     }
   }

-  tcp_socket::endpoint_type remote_endpoint() const {
+  tcp_socket::endpoint_type remote_endpoint(std::error_code& ec) const {
     if (ssl_enabled) {
-      return ssl_sock_->next_layer().remote_endpoint();
+      return ssl_sock_->next_layer().remote_endpoint(ec);
     } else {
-      return tcp_sock_->remote_endpoint();
+      return tcp_sock_->remote_endpoint(ec);
     }
   }

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions