Opened 6 years ago
#12406 new Bugs
socket_select_interrupter throws exception when 127.0.0.1 was mapped to another IP address.
Reported by: | Owned by: | chris_kohlhoff | |
---|---|---|---|
Milestone: | To Be Determined | Component: | asio |
Version: | Boost 1.61.0 | Severity: | Problem |
Keywords: | Cc: |
Description
I’m developing an application using boost.asio for network communication under Windows. One of my customers complaints that the application crashes frequently. Later I find out that an system error exception was thrown within socket_select_interrupter::open_descriptors, at line 88, and the error code was 10061.
As the code in that method shows, an acceptor socket is bound to 127.0.0.1, and then getsockname is called to get the actual address bound with the socket. This address will be used by a client socket to connect to. The problem is that after calling getsockname, the returned address is set to 127.0.0.1 immediately, for some broken firewalls. In most case, this is all right, getting address from a socket which bound to 127.0.0.1 will return 127.0.0.1, obviously. But here is an exception. My customer makes an IP mapping in his router, maps 127.0.0.1 to another IP, causing the socket is bound to a total different address. Thus the client socket fails to connect to 127.0.0.1, and an exception is thrown.
My approach to solve this problem is setting the address to 127.0.0.1 only when it is 0.0.0.0, just like the code shows below. This fixes the crash of my customer.
// Some broken firewalls on Windows will intermittently cause getsockname to // return 0.0.0.0 when the socket is actually bound to 127.0.0.1. We // explicitly specify the target address here to work around this problem. if (addr.sin_addr.s_addr == socket_ops::host_to_network_long(INADDR_ANY)) { addr.sin_addr.s_addr = socket_ops::host_to_network_long(INADDR_LOOPBACK); }
I think my customer is not the only one who meets this problem, and I hope it will be solved in the future version of boost.