Opened 9 years ago

Last modified 5 years ago

#8795 reopened Bugs

async_connect incorrectly reports success on failure

Reported by: benpope81@… Owned by: chris_kohlhoff
Milestone: To Be Determined Component: asio
Version: Boost 1.63.0 Severity: Regression
Keywords: Cc:

Description

I've found a regression between 1.53 to 1.54; if you compile boost/libs/asio/example/cpp11/chat/chat_client.cpp and point it at a host and port that doesn't exist or refuses the connection, instead of coming back with an error, such as host not found or connection refused, it reports success (on the conversion to bool). (you might want to embellish the example with a std::cout << error_code.message() << std::endl;)

This appears to be the case across Linux, Darwin, iOS and Android.

synchronous connect seems to work correctly (i.e., echo/blocking_tcp_echo_client.cpp)

Change History (22)

comment:1 by stephen.pope@…, 9 years ago

Upgrading my own code to use 1.54.0 instead of 1.53.0, I also encountered this same problem. It appears to be due to the refactoring of the socket_ops::non_blocking_connect() function, which now calls socket_ops::connect() and then (unless getting back boost::asio::error::already_started), calls socket_ops::getsockopt with SO_ERROR. The problem is that the call to ::connect() within socket_ops::connect() has already effectively cleared the error (and set errno appropriately), and ec already contains the desired error code, so the call to getsockopt ends up clearing the error information from ec, making it appear to have succeeded.

Unfortunately I am not familiar enough with the intent of the changes to propose the correct solution, although I suspect it would be to only call socket_ops::getsockopt() if the call to socket_ops::connect() did not itself return an error.

comment:2 by naidu.trk@…, 9 years ago

I encountered this while working with websocketpp library which uses boost asio. connect returns success despite the failure to connect. websocketpp returns the same success to the application.

comment:3 by anonymous, 9 years ago

I also have same problem with boost 1.54.0. The error code from async_connect()'s callback is always success in spite of connection failed.

comment:4 by junk@…, 9 years ago

I have the same problem. I created a workaround in my code by calling connect and then posting the response to the async_connect handle. This, of course, blocks the calling thread :(.

comment:5 by Ramon Casellas <ramon.casellas@…>, 9 years ago

Confirmed also in boost trunk as of 20130801 (1.55) linux ubuntu saucy 64 bits. A regression that is causing services that are supposed to reconnect on failure to proceed.

Quite easy to reproduce using the async_client in the examples without any listening http server. Add a debug trace (should get connection refused):

root@pookie:/tmp# g++ -c -o client.o client.cpp 
root@pookie:/tmp# g++ -o client client.o -lboost_system -lboost_thread -lpthread
root@pookie:/tmp# ./client localhost /index.html
handle_connect Error: system:0
Error: Broken pipe

Thanks R.

comment:6 by jft@…, 9 years ago

You cannot even use boost::asio::ip::tcp::iostream because the connect method makes use of async_connect. I would consider this a huge bug and I am surprised there are only a few responses to this ticket. I spend a considerable amount of time debugging my projects today to find this bug (I use Arch Linux and they updated recently).

comment:7 by anonymous, 9 years ago

For my own use, I found that simply inserting:

if (ec) return true;

at line 524 of boost/asio/detail/impl/socket_ops.ipp (i.e. in non_blocking_connect() after the check for error::already_started and before calling getsockopt()) has proven to be a reasonable workaround. Again, as I do not understand the intent of the changes from 1.53.0, I am not sure that this is the correct bugfix, so YMMV.

comment:8 by mvd, 9 years ago

I confirm the bug in BOOST 1.54. The connect handler reports success although the connect attempt failed.

comment:9 by david.keegan@…, 9 years ago

Yes, I've hit this problem too on Linux.

comment:10 by anonymous, 9 years ago

I confirm the problem in 1.54.0 boost.

comment:11 by anonymous, 9 years ago

On CentOS 6.4 (64bit), upgrade from 1.49.0 to 1.54.0 introduced this issue for me. The error code in connect handler reports success and the socket appears to be is_open().

comment:12 by anonymous, 9 years ago

Summary: async_connect oncorrectly reports success on failureasync_connect incorrectly reports success on failure

comment:13 by Antonio Di Monaco <tony@…>, 9 years ago

Confirmed on Slackware64, using boost 1.54.0

comment:14 by agazso@…, 9 years ago

For me this fix worked

if (ec == asio::error::connection_refused) return true;

at line 524 of boost/asio/detail/impl/socket_ops.ipp

It seems that when connect returns ECONNREFUSED then getsockopt returns no error.

comment:15 by chris_kohlhoff, 9 years ago

Resolution: fixed
Status: newclosed

Minimal fix on trunk in [85738]. Subsequent cleanup in [85739]. Merged to release in [85838].

comment:16 by anonymous, 8 years ago

With Boost 1.55 running on Windows 8.1 I was seeing a single false connection. On Boost 1.56 I see repeated false connections, over and over again.

By "false connections" I mean that the connect handler for async_connect gets called right away (when the other end of the socket is not there), with error_code zero and where conn->socket.is_open() return true. Stepping into the boost code I see in win_iocp_io_service.ipp line 405 result_ec is 10057 (WSAENOTCONN). The next line of code (ec = boost::system::error_code();) sets ec to zero.

Does anyone else see this?

comment:17 by anonymous, 7 years ago

I am experiencing this bug using MSVC 14 and Boost 1.60.

No asynchronous solution in sight. Finnicky.

in reply to:  17 comment:18 by anonymous, 7 years ago

Replying to anonymous:

I am experiencing this bug using MSVC 14 and Boost 1.60.

No asynchronous solution in sight. Finnicky.

UPDATE: Replacing asio::ip::tcp::acceptor.cancel() with asio::ip::tcp::acceptor.close() in another thread, fixes some oddity within a shared asio::io_service...

comment:19 by anonymous, 6 years ago

Boost 1.63.0, Windows 10 64-bit.

Also shows no error despite the connection failed.

comment:20 by anonymous, 6 years ago

Resolution: fixed
Status: closedreopened
Version: Boost 1.54.0Boost 1.63.0

comment:20 by anonymous, 6 years ago

Resolution: fixed
Status: closedreopened

comment:21 by anonymous, 5 years ago

Boost 1.59 Win64 has the same issue!

Note: See TracTickets for help on using tickets.