cURL / Mailing Lists / curl-library / Single Mail

curl-library

Re: SOCKS5 under cygwin.

From: Joe Khoobyar <joe_at_ankhcraft.com>
Date: Wed, 09 Nov 2005 19:57:57 -0500
Well, here's my patch for this, in case anybody is interested.  It should only be considered a workaround, IMO.

- jk


Joe Khoobyar wrote:
Just joined the list a few minutes ago.  I searched the archives a bit earlier today, and found a thread a few weeks ago about SOCK5 support on Windows.  I use cygwin, and I'm having similar problems.

The first download uses curl_easy_perform, and works fine.  Subsequent downloads use curl_multi_perform, and fail.  When setting CURLOPT_VERBOSE to 1, I get messages like: 

* About to connect() to proxy.roc.crcnet1.com port 1080
*   Trying 192.168.0.10... * Send failure: Transport endpoint is not connected
* Unable to send initial SOCKS5 request
* Closing connection #0

While tooling through the libcurl code trying to get an understanding of the problem (and possibly fix it), I added a extra infof() call after singleipconnect, and this actually made several of the subsequent downloads with curl_multi_perform() succeed.  Assumedly, this is related to someone previously noting that adding a call to sleep() made things work better.

Any thoughts on how I can get this to work?  The original poster's code for fixing this bug wasn't included in the message below and I couldn't find it in the archives, so maybe there's something I'm missing?

- jk

------------------------------------------------------------------------------
From
: Daniel Stenberg <daniel_at_haxx.se>

Date: 2005-10-26

On Wed, 26 Oct 2005, Shmulik Regev wrote:

>> At what point does it fail and report this error back, you know?

> The problem starts at sendf.c:251
> bytes_written = (ssize_t)swrite(sockfd, mem, len);
> this fails and return -1 for bytes_written and WSAENOTCONN as the error.

Gosh. According to this page[1] I found on microsoft.com that error would be
returned if "The socket is not connected". It would then indicate that there
is a problem in the connect code that makes libcurl proceed before it knows
that the socket is truly connected.

What speaks against that theory, is the fact that we _never_ see this error
for any other case and if it would be that stupid I can't see why we wouldn't
see this error happen all the time.

I fear we have a much more obscure and less obvious problem here.

>> The socks code is not in a perfect state. For example it always assume that
>> it can send data without blocking, as if it can't it will blatantly fail.

> What is the difference between the socks implementation and the normal
> operation as far as socket handling is concerned?

The difference is simply that the SOCKS code is not written to nicely deal
with the fact that Curl_write() might return an error in cases where the
writing would block.

> How come there are no such errors with normal HTTP activities?

Because that code _is_ written to take such considerations into account.

SOCKS is rarely used, and thus the libcurl code for it is poorly maintained
and written. There are no test cases for SOCKS so changing it is hazardous and
error prone (unless you have an actual socks proxy to test against, which I do
not).

I welcome fixes that improve this situation.

> Just for the sake of it I've added the following sleep call prior to sending
> any data. Guess what? It works.

...

> I hate the code above but I'll continue running with it enabled for a while
> and see whether the problem disappears.

If that hack works as a fix, I would say that it feels more like a Microsoft
TCP/IP stack flaw more than anything else.

[1] =
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/wcecomm5/html/wce50lrfsend.asp

diff -Naur curl-7.14.1-orig/lib/connect.c curl-7.14.1/lib/connect.c
--- curl-7.14.1-orig/lib/connect.c 2005-07-27 17:26:39.000000000 -0400
+++ curl-7.14.1/lib/connect.c 2005-11-09 19:27:07.281250000 -0500
@@ -832,5 +832,15 @@
 
   data->info.numconnects++; /* to track the number of connections made */
 
+#ifdef __CYGWIN__
+ /* A dirty hack for SOCKS5 proxies under Cygwin, when using
+ * the multi interface. There's probably a better way to get this
+ * to work. - Joe Khoobyar <joe_at_ankhcraft.com>
+ */
+ if (conn->data->set.proxytype == CURLPROXY_SOCKS5
+ && data->state.used_interface == Curl_if_multi)
+ usleep (50);
+#endif
+
   return CURLE_OK;
 }
Received on 2005-11-10