[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: [Bug-wget] --connect-timeout doesn't work on Windows
From: |
Eli Zaretskii |
Subject: |
Re: [Bug-wget] --connect-timeout doesn't work on Windows |
Date: |
Tue, 17 Mar 2015 17:27:14 +0200 |
> Date: Sat, 14 Mar 2015 21:18:26 +0100
> From: Gisle Vanem <address@hidden>
>
> I see the from the call-stack that connect() is hanging inside
> Gnulib:
> ...
> ntdll.dll!ZwWaitForSingleObject+0xc
> ntdll.dll!RtlInterlockedPushEntrySList+0x32b
> ntdll.dll!RtlInterlockedPushEntrySList+0x355
> ntdll.dll!RtlResetNtUserPfn+0x3f
> wget.exe!close_fd_maybe_socket+0x36
> wget.exe!execute_close_hooks+0x30
> wget.exe!execute_all_close_hooks+0x17
> wget.exe!rpl_close+0x12
> wget.exe!connect_to_host+0x3ea
> wget.exe!gethttp+0x686
> wget.exe!http_loop+0x430
> wget.exe!retrieve_url+0x1cb
> ..
>
> And from the command 'wget -d --connect-timeout=4 http://192.0.2.1:12345/' +
> ^C:
>
> Setting --connect-timeout (connecttimeout) to 4
> DEBUG output created by Wget 1.15.00 (09-March-2015) on Win-8.1. Build
> 9600 (MSVC).
> ...
> seconds 0.00, Connecting to 192.0.2.1:12345... seconds 4.00,
>
> So it seems the 'run_with_timeout()' used to connect works fine since
> the thread is not running. So it seems the Gnulib's close() is blocking
> for an unknown reason.
Attaching a debugger shows that it hangs inside the call to
WSAEnumNetworkEvents, here:
/* Test whether fd refers to a socket. */
sock = FD_TO_SOCKET (fd);
ev.lNetworkEvents = 0xDEADBEEF;
WSAEnumNetworkEvents (sock, NULL, &ev); <<<<<<<<<<<<<<<<<<<<<<<
if (ev.lNetworkEvents != 0xDEADBEEF)
{
/* fd refers to a socket. */
/* FIXME: other applications, like squid, use an undocumented
_free_osfhnd free function. But this is not enough: The 'osfile'
flags for fd also needs to be cleared, but it is hard to access it.
Instead, here we just close twice the file descriptor. */
if (closesocket (sock))
This is Gnulib trying to establish that the file descriptor refers to
a socket. WSAEnumNetworkEvents waits forever, I think because we
never succeeded to connect, and perhaps also because the socket is
blocking.
The following simple kludge works around the problem for me:
--- src/connect.c~0 2014-12-02 09:49:37.000000000 +0200
+++ src/connect.c 2015-03-17 17:14:48.414375000 +0200
@@ -364,7 +364,12 @@ connect_to_ip (const ip_address *ip, int
logprintf. */
int save_errno = errno;
if (sock >= 0)
- fd_close (sock);
+ {
+#ifdef WIN32
+ if (errno != ETIMEDOUT)
+#endif
+ fd_close (sock);
+ }
if (print)
logprintf (LOG_VERBOSE, _("failed: %s.\n"), strerror (errno));
errno = save_errno;
After applying this, I get the expected results:
wget --connect-timeout=1 -t 3 http://192.0.2.1:12345/
--2015-03-17 17:18:07-- http://192.0.2.1:12345/
Connecting to 192.0.2.1:12345... failed: Connection timed out.
Retrying.
--2015-03-17 17:18:09-- (try: 2) http://192.0.2.1:12345/
Connecting to 192.0.2.1:12345... failed: Connection timed out.
Retrying.
--2015-03-17 17:18:12-- (try: 3) http://192.0.2.1:12345/
Connecting to 192.0.2.1:12345... failed: Connection timed out.
Giving up.
If there's a more elegant way of fixing this, I'm all ears.