Menu

#808 connect-timeout not working on Windows

closed-invalid
libcurl (356)
3
2013-06-21
2009-02-19
Erik Weidel
No

I have been playing around with curl and connection-timeouts on windows.
To test the connect-timeout, i used a second machine with linux and dropped all packets for the ftp port using iptables.
When i try to connect from my Windows XP SP3 box using
"curl.exe --connect-timeout 5 ftp://linuxbox", curl will hang forever.
When i use the "--max-time 5" option instead, it aborts after 5 seconds.

I have traced the packets on the linux box using tcpdump and could see three SYN-packets. The second was three seconds after the first and the third was six seconds after the second.
No more than three packets arrive, no matter how long the timeout is set.
This seems to be, because the windows default for retransmissions is "3" (found here: http://support.microsoft.com/?scid=kb%3Ben-us%3B175523&x=6&y=7 Option TcpMaxConnectRetransmissions)

So even with "--max-time 50", only three SYN-Packets are sent by the Windows TCP/IP stack. Therefore every timeout greater 20 seconds is useless with windows.

I have tried this with the last-curl version, i found:
curl 7.19.3 (i686-pc-mingw32) libcurl/7.19.3 OpenSSL/0.9.8j zlib/1.2.3 libidn/1.11 libssh2/1.0
Protocols: tftp ftp telnet dict ldap http file https ftps scp sftp
Features: IDN Largefile NTLM SSL libz

To summarize everything:
1. The connect-timeout does not work at all.
2. The max-time option works, but setting it to higher than 20 seconds is useless, because only three SYN-Packets are sent anyway with the default windows setting.

Let me clarify, that i am only talking about the connection phase!

Discussion

  • Daniel Stenberg

    Daniel Stenberg - 2009-02-20
    • labels: --> libcurl
    • priority: 5 --> 3
    • assigned_to: nobody --> bagder
     
  • Daniel Stenberg

    Daniel Stenberg - 2009-02-20

    First, I know very little windows stuff so I've tried to get some help on this by forwarding this bug report to the libcurl mailing list: http://curl.haxx.se/mail/lib-2009-02/0225.html

    I cannot understand how --max-time and --connect-timeout can differ for this case since they do the same things internally until the connect moment.

    Regdarding the "TcpMaxConnectRetransmissions" that seems like a blatant windows stupidity that I'm not sure is our business to bother about. We use the TCP/IP stack as supposed and we do it the same for all platforms and if Windows decide to cripple their approach how are we going to deal with that?

     
  • Yang Tse

    Yang Tse - 2009-02-20

    A couple of questions...

    You mention that you are using the last-curl version you've found. Where have you downloaded the binary from, please provide link? Or is it self-built?

    Can you repeat the problem with a server publicly available so that others can repeat the problem that you're facing? Or is it enough to use a non-existing server to trigger the problem?

    Does anything change if you use the IP address instead of the server name?

    -=[Yang]=-

     
  • Erik Weidel

    Erik Weidel - 2009-02-20

    Thanks for your quick response!

    I have investigated this a little further this morning by adding some debug infos and recompiling curl and libcurl and by using the "-v" commandline option.

    The reason, why --max-time and --connect-timeout differ, is because curl obviously "thinks" it is connected so that the --connect-timeout is ignored. The --max-time simply aborts the connection because no data is transmitted.

    I really agree with you, that this whole problem is just another "windows stupidity" !!
    And i am, just like you, not sure, how to deal with it. Especially, since the "TcpMaxConnectRetransmissions" seems only to be changeable in the registry which would affect ALL connections (another "windows stupidity"!).
    On the other hand is a not working "--connect-timeout" option not so nice too. So something should be done about this. If someone can confirm, what I have found out: what do you think about adding some hints to the documentation at least? I could provide you with that, if you wish.

    Apart from that, I have at least found a workaround, which prevents curl from hanging forever.
    It is in the Curl_socket_ready function in lib/select.c:

    $ diff -p select.c.orig select.c
    *** select.c.orig Mon May 26 17:16:34 2008
    --- select.c Fri Feb 20 12:54:56 2009
    *************** int Curl_socket_ready(curl_socket_t read
    *** 285,290 ****
    --- 285,297 ----
    pending_tv.tv_usec = 0;
    }
    r = select((int)maxfd + 1, &fds_read, &fds_write, &fds_err, ptimeout);
    +
    + #if defined(USE_WINSOCK)
    + if (WSAGetLastError() == WSAECONNRESET) {
    + r = -1;
    + }
    + #endif /* USE_WINSOCK */
    +
    if(r != -1)
    break;
    error = SOCKERRNO;

    With this change, curl still thinks it is connected but aborts after the 20 seconds, when windows stops sending SYN-Packets.
    I am not sure, if
    "if (WSAGetLastError() == WSAECONNRESET) {"
    can or should be
    "if (WSAGetLastError() != ERROR_SUCCESS && WSAGetLastError() != WSAEWOULDBLOCK) {"
    But maybe we can discuss this on the mailing list.

     
  • Erik Weidel

    Erik Weidel - 2009-02-20

    Dear Yang,

    concerning your questions:
    I used the precompiled version 7.19.2 from the Curl-Homepage and the source-code 7.19.3 which I have compiled myself using mingw.

    I just tried it with a IP address that does not exist in my local network and got the same behaviour:
    c:\programme\curl-7.19\bin\curl.exe -v --connect-timeout 5 ftp://10.42.254.169/
    * About to connect() to 10.42.254.169 port 21 (#0)
    * Trying 10.42.254.169... connected
    * Connected to 10.42.254.169 (10.42.254.169) port 21 (#0)

    Hanging forever ...
    Using IP address or name makes no difference.

    As you can see, curl thinks to be connected!

     
  • Yang Tse

    Yang Tse - 2009-02-20

    These are my findings so far...

    All tests I mention here are done on a Windows 2000 SP4 box with _all_ WindowsUpdate patches applied.

    Testing this binary http://curl.haxx.se/download/curl-7.19.3-win32-nossl.zip to a system which sends back a RST packet:

    C:\test>curl.exe --version
    curl 7.19.3 (i586-pc-mingw32msvc) libcurl/7.19.3 zlib/1.2.3
    Protocols: tftp ftp telnet dict ldap http file
    Features: Largefile libz

    C:\test>curl.exe -v --trace-time --connect-timeout 8 ftp://192.168.1.100
    04:46:15.390000 * About to connect() to 192.168.1.100 port 21 (#0)
    04:46:15.390000 * Trying 192.168.1.100... Connection refused
    04:46:16.331000 * couldn't connect to host
    04:46:16.331000 * Closing connection #0
    curl: (7) couldn't connect to host

    C:\test>curl.exe -v --trace-time --max-time 77 ftp://192.168.1.100
    05:04:19.619000 * About to connect() to 192.168.1.100 port 21 (#0)
    05:04:19.629000 * Trying 192.168.1.100... Connection refused
    05:04:20.590000 * couldn't connect to host
    05:04:20.590000 * Closing connection #0
    curl: (7) couldn't connect to host

    Testing the same binary http://curl.haxx.se/download/curl-7.19.3-win32-nossl.zip to a non-existing system:

    C:\test>curl.exe --version
    curl 7.19.3 (i586-pc-mingw32msvc) libcurl/7.19.3 zlib/1.2.3
    Protocols: tftp ftp telnet dict ldap http file
    Features: Largefile libz

    C:\test>curl.exe -v --trace-time --connect-timeout 8 ftp://192.168.1.101
    04:49:17.952000 * About to connect() to 192.168.1.101 port 21 (#0)
    04:49:17.952000 * Trying 192.168.1.101... Timeout
    04:49:25.964000 * connect() timed out!
    04:49:25.964000 * Closing connection #0
    curl: (28) connect() timed out!

    C:\test>curl.exe -v --trace-time --max-time 77 ftp://192.168.1.101
    05:05:39.834000 * About to connect() to 192.168.1.101 port 21 (#0)
    05:05:39.834000 * Trying 192.168.1.101... Timed out
    05:06:00.834000 * couldn't connect to host
    05:06:00.834000 * Closing connection #0
    curl: (7) couldn't connect to host

    None of the above tests hang. --connect-timeout works in both cases.

    curl --max-time effective upper limit down by the winsock TCP stack and as you have already stated controlled by TCP/IP TcpMaxConnectRetransmissions registry parameter.

    TCP/IP and NetBT configuration parameters for Windows 2000 or Windows NT (KB120642)
    http://support.microsoft.com/kb/120642/EN-US/

    TCP/IP and NBT configuration parameters for Windows XP (KB314053)
    http://support.microsoft.com/kb/314053/EN-US/

    I'll repeat tests on a Windows XP SP3 box this weekend.

    -=[Yang]=-

     
  • Yang Tse

    Yang Tse - 2009-02-22

    Testing on a Windows XP SP3 box the same binary
    http://curl.haxx.se/download/curl-7.19.3-win32-nossl.zip to a system which
    sends back a RST packet:

    C:\test>curl.exe --version
    curl 7.19.3 (i586-pc-mingw32msvc) libcurl/7.19.3 zlib/1.2.3
    Protocols: tftp ftp telnet dict ldap http file
    Features: Largefile libz

    C:\test>curl.exe -v --trace-time --connect-timeout 8 ftp://192.168.1.30
    01:17:24.265000 * About to connect() to 192.168.1.30 port 21 (#0)
    01:17:24.265000 * Trying 192.168.1.30... Connection refused
    01:17:25.203000 * couldn't connect to host
    01:17:25.203000 * Closing connection #0
    curl: (7) couldn't connect to host

    C:\test>curl.exe -v --trace-time --max-time 77 ftp://192.168.1.30
    01:17:46.515000 * About to connect() to 192.168.1.30 port 21 (#0)
    01:17:46.531000 * Trying 192.168.1.30... Connection refused
    01:17:47.515000 * couldn't connect to host
    01:17:47.515000 * Closing connection #0
    curl: (7) couldn't connect to host

    Testing on a Windows XP SP3 box the same binary
    http://curl.haxx.se/download/curl-7.19.3-win32-nossl.zip to a non-existing
    system:

    C:\test>curl.exe --version
    curl 7.19.3 (i586-pc-mingw32msvc) libcurl/7.19.3 zlib/1.2.3
    Protocols: tftp ftp telnet dict ldap http file
    Features: Largefile libz

    C:\test>curl.exe -v --trace-time --connect-timeout 8 ftp://192.168.1.101
    01:11:02.140000 * About to connect() to 192.168.1.101 port 21 (#0)
    01:11:02.156000 * Trying 192.168.1.101... Timeout
    01:11:10.156000 * connect() timed out!
    01:11:10.156000 * Closing connection #0
    curl: (28) connect() timed out!

    C:\test>curl.exe -v --trace-time --max-time 77 ftp://192.168.1.101
    01:08:32.078000 * About to connect() to 192.168.1.101 port 21 (#0)
    01:08:32.093000 * Trying 192.168.1.101... Timed out
    01:08:53.328000 * couldn't connect to host
    01:08:53.328000 * Closing connection #0
    curl: (7) couldn't connect to host

    It doesn't hang either.

    I can not reproduce the problem with this binary http://curl.haxx.se/download/curl-7.19.3-win32-nossl.zip

    I cannot help any further unless a link to the problematic binary is provided.

    -=[Yang]=-

     
  • Daniel Stenberg

    Daniel Stenberg - 2009-02-23

    So is this some weirdo firewall, virus checker, magic thing sitting there and messing things up?

     
  • Erik Weidel

    Erik Weidel - 2009-02-23

    Yes it is.
    It is our "wonderful" McAfee Antivirus Solution which acts like a proxy for port 21 to be able to scan the ftp-data.
    I have disabled it today and the connect-timeout works. I came across some postings over the weekend where others had the same problems with other tools.

    Thanks, Yang, for checking it on your system! I have tried the same at the weekend on different computers, too and there I could not reproduce this effect just like you. I really appreciate your efforts, Yang! Thanks for helping and thank you, Daniel, for caring about this stuff!

    So I think we can close this "bug report". Sorry for having bothered you!

    Would it make sense to add some hints to the documentation of the "connect-timeout" option?
    First hint might be, that with win32, a timeout greater than 21 seconds might not make sense because, as already stated and agreed by Yang, win32 only sends three SYNs.
    Second hint might be, that with win32 some antivirus products cause the connect-timeout to be useless because they act like a proxy for ftp and accept the connection anyway.
    Then maybe at least for others it will not take three days to find out :-)

     
  • Daniel Stenberg

    Daniel Stenberg - 2009-02-23

    Thanks for providing all this info back. I'm closing this report now as "invalid" as it wasn't truly a curl bug.

    I've added a new "question" to the FAQ about this issuse.

     
  • Daniel Stenberg

    Daniel Stenberg - 2009-02-23
    • status: open --> closed-invalid
     
MongoDB Logo MongoDB