Modify

Ticket #8795 (closed Bugs: fixed)

Opened 10 months ago

Last modified 7 months ago

async_connect incorrectly reports success on failure

Reported by: benpope81@… Owned by: chris_kohlhoff
Milestone: To Be Determined Component: asio
Version: Boost 1.54.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)

Attachments

Change History

comment:1 Changed 9 months ago by stephen.pope@…

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 Changed 9 months ago by naidu.trk@…

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 Changed 9 months ago by anonymous

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 Changed 9 months ago by junk@…

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 Changed 9 months ago by Ramon Casellas <ramon.casellas@…>

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 Changed 8 months ago by jft@…

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 Changed 8 months ago by anonymous

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 Changed 8 months ago by mvd

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

comment:9 Changed 8 months ago by david.keegan@…

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

comment:10 Changed 8 months ago by anonymous

I confirm the problem in 1.54.0 boost.

comment:11 Changed 8 months ago by anonymous

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 Changed 8 months ago by anonymous

  • Summary changed from async_connect oncorrectly reports success on failure to async_connect incorrectly reports success on failure

comment:13 Changed 8 months ago by Antonio Di Monaco <tony@…>

Confirmed on Slackware64, using boost 1.54.0

comment:14 Changed 7 months ago by agazso@…

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 Changed 7 months ago by chris_kohlhoff

  • Status changed from new to closed
  • Resolution set to fixed

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

View

Add a comment

Modify Ticket

Change Properties
<Author field>
Action
as closed
The resolution will be deleted. Next status will be 'reopened'
Author


E-mail address and user name can be saved in the Preferences.

 
Note: See TracTickets for help on using tickets.