]> granicus.if.org Git - curl/commitdiff
- "Dortik" (http://curl.haxx.se/bug/view.cgi?id=1551412) provided a patch that
authorDaniel Stenberg <daniel@haxx.se>
Sun, 3 Sep 2006 22:52:42 +0000 (22:52 +0000)
committerDaniel Stenberg <daniel@haxx.se>
Sun, 3 Sep 2006 22:52:42 +0000 (22:52 +0000)
  while not fixing things very nicely, it does make the SOCKS5 proxy
  connection slightly better as it now acknowledges the timeout for connection
  and it no longer segfaults in the case when SOCKS requires authentication
  and you did not specify username:password.

CHANGES
RELEASE-NOTES
docs/KNOWN_BUGS
lib/url.c

diff --git a/CHANGES b/CHANGES
index 1d8c39b28583d10db2b6720d099385c09c3d1b78..29ede8c5cb9880dac0fe9b3d2570f55865f25ff9 100644 (file)
--- a/CHANGES
+++ b/CHANGES
@@ -7,6 +7,13 @@
                                   Changelog
 
 
+Daniel (4 September 2006)
+- "Dortik" (http://curl.haxx.se/bug/view.cgi?id=1551412) provided a patch that
+  while not fixing things very nicely, it does make the SOCKS5 proxy
+  connection slightly better as it now acknowledges the timeout for connection
+  and it no longer segfaults in the case when SOCKS requires authentication
+  and you did not specify username:password.
+
 Daniel (31 August 2006)
 - Dmitriy Sergeyev found and fixed a multi interface flaw when using asynch
   name resolves. It could get stuck in the wrong state.
index 05fe3b1901c8ed25b37d59a1d398c0a5d610f526..6ac3a39154eb6a8e86ee6548dbfcbe367614f1bf 100644 (file)
@@ -18,6 +18,8 @@ This release includes the following changes:
 
 This release includes the following bugfixes:
 
+ o SOCKS5 proxy connects can now time-out
+ o SOCKS5 connects that require auth no longer segfaults when auth not given
  o multi interface using asynch resolves could get stuck in wrong state
  o the 'running_handles' counter wasn't always updated properly when
    curl_multi_remove_handle() was used
index 38c657f038997089688eafcfdc9f44150baab27e..d16fdbb5b45ed35e89bd534b1b9cc221e296b770 100644 (file)
@@ -3,7 +3,11 @@ join in and help us correct one or more of these! Also be sure to check the
 changelog of the current development status, as one or more of these problems
 may have been fixed since this was written!
 
-34. The SOCKS connection codes don't properly acknowledge (connect) timeouts.
+35. Both SOCKS5 and SOCKS4 proxy connections are done blocking, which is very
+  bad when used with the multi interface.
+
+34. The SOCKS4 connection codes don't properly acknowledge (connect) timeouts.
+  Also see #12.
 
 33. Doing multi-pass HTTP authentication on a non-default port does not work.
   This happens because the multi-pass code abuses the redirect following code
@@ -92,7 +96,7 @@ may have been fixed since this was written!
 
 12. When connecting to a SOCKS proxy, the (connect) timeout is not properly
   acknowledged after the actual TCP connect (during the SOCKS "negotiate"
-  phase). Pointed out by Lucas. Fix: need to select() and timeout properly.
+  phase).
 
 11. Using configure --disable-[protocol] may cause 'make test' to fail for
   tests using the disabled protocol(s).
index aaf59132aad692690aa7b4b6d98652cc5b28e190..68339790b84738d020235df3b6847d844bc7caa9 100644 (file)
--- a/lib/url.c
+++ b/lib/url.c
@@ -2115,14 +2115,49 @@ static int handleSock5Proxy(const char *proxy_name,
   int result;
   CURLcode code;
   curl_socket_t sock = conn->sock[FIRSTSOCKET];
+  struct SessionHandle *data = conn->data;
+  long timeout;
 
-  Curl_nonblock(sock, FALSE);
+  /* get timeout */
+  if(data->set.timeout && data->set.connecttimeout) {
+    if (data->set.timeout < data->set.connecttimeout)
+      timeout = data->set.timeout*1000;
+    else
+      timeout = data->set.connecttimeout*1000;
+  }
+  else if(data->set.timeout)
+    timeout = data->set.timeout*1000;
+  else if(data->set.connecttimeout)
+    timeout = data->set.connecttimeout*1000;
+  else
+    timeout = DEFAULT_CONNECT_TIMEOUT;
+
+  Curl_nonblock(sock, TRUE);
+
+  /* wait until socket gets connected */
+  result = Curl_select(CURL_SOCKET_BAD, sock, timeout);
+
+  if(-1 == result) {
+    failf(conn->data, "SOCKS5: no connection here");
+    return 1;
+  }
+  else if(0 == result) {
+    failf(conn->data, "SOCKS5: connection timeout");
+    return 1;
+  }
+
+  if(result & CSELECT_ERR) {
+    failf(conn->data, "SOCKS5: error occured during connection");
+    return 1;
+  }
 
   socksreq[0] = 5; /* version */
   socksreq[1] = (char)(proxy_name ? 2 : 1); /* number of methods (below) */
   socksreq[2] = 0; /* no authentication */
   socksreq[3] = 2; /* username/password */
 
+  Curl_nonblock(sock, FALSE);
+
   code = Curl_write(conn, sock, (char *)socksreq, (2 + (int)socksreq[1]),
                       &written);
   if ((code != CURLE_OK) || (written != (2 + (int)socksreq[1]))) {
@@ -2130,6 +2165,26 @@ static int handleSock5Proxy(const char *proxy_name,
     return 1;
   }
 
+  Curl_nonblock(sock, TRUE);
+
+  result = Curl_select(sock, CURL_SOCKET_BAD, timeout);
+
+  if(-1 == result) {
+    failf(conn->data, "SOCKS5 nothing to read");
+    return 1;
+  }
+  else if(0 == result) {
+    failf(conn->data, "SOCKS5 read timeout");
+    return 1;
+  }
+
+  if(result & CSELECT_ERR) {
+    failf(conn->data, "SOCKS5 read error occured");
+    return 1;
+  }
+
+  Curl_nonblock(sock, FALSE);
+
   result=Curl_read(conn, sock, (char *)socksreq, 2, &actualread);
   if ((result != CURLE_OK) || (actualread != 2)) {
     failf(conn->data, "Unable to receive initial SOCKS5 response.");
@@ -2146,10 +2201,16 @@ static int handleSock5Proxy(const char *proxy_name,
   }
   else if (socksreq[1] == 2) {
     /* Needs user name and password */
-    int userlen, pwlen, len;
-
-    userlen = (int)strlen(proxy_name);
-    pwlen = proxy_password?(int)strlen(proxy_password):0;
+    size_t userlen, pwlen;
+    int len;
+    if(proxy_name && proxy_password) {
+      userlen = strlen(proxy_name);
+      pwlen = proxy_password?strlen(proxy_password):0;
+    }
+    else {
+      userlen = 0;
+      pwlen = 0;
+    }
 
     /*   username/password request looks like
      * +----+------+----------+------+----------+
@@ -4209,4 +4270,3 @@ CURLcode Curl_do_more(struct connectdata *conn)
 
   return result;
 }
-