]> granicus.if.org Git - curl/commitdiff
- Constantine Sapuntzakis fixed bug report #2784055
authorDaniel Stenberg <daniel@haxx.se>
Fri, 8 May 2009 10:59:40 +0000 (10:59 +0000)
committerDaniel Stenberg <daniel@haxx.se>
Fri, 8 May 2009 10:59:40 +0000 (10:59 +0000)
  (http://curl.haxx.se/bug/view.cgi?id=2784055) identifying a problem to
  connect to SOCKS proxies when using the multi interface. It turned out to
  almost not work at all previously. We need to wait for the TCP connect to
  be properly verified before doing the SOCKS magic.

  There's still a flaw in the FTP code for this.

CHANGES
RELEASE-NOTES
lib/multi.c
lib/url.c
lib/url.h

diff --git a/CHANGES b/CHANGES
index f1a644fd4d33ff25369702bdf7e2909076ef8b6e..e3ad05c6907371ed6a7b4cc45f233e855ef939d7 100644 (file)
--- a/CHANGES
+++ b/CHANGES
@@ -6,6 +6,15 @@
 
                                   Changelog
 
+Daniel Stenberg (8 May 2009)
+- Constantine Sapuntzakis fixed bug report #2784055
+  (http://curl.haxx.se/bug/view.cgi?id=2784055) identifying a problem to
+  connect to SOCKS proxies when using the multi interface. It turned out to
+  almost not work at all previously. We need to wait for the TCP connect to
+  be properly verified before doing the SOCKS magic.
+
+  There's still a flaw in the FTP code for this.
+
 Daniel Stenberg (7 May 2009)
 - Made the SO_SNDBUF setting for the data connection socket for ftp uploads as
   well. See change 28 Apr 2009.
index 31f89956ac4a9d451e777dee03e4cf93fa0ca883..3770f15be981aadcd3b60d443785bc8a340ee389 100644 (file)
@@ -42,6 +42,7 @@ This release includes the following bugfixes:
  o Rejected SSL session ids are killed properly (for OpenSSL and GnuTLS builds)
  o Deal with the TFTP OACK packet
  o fixed roff mistakes in man pages
+ o use SOCKS proxy with the multi interface
 
 This release includes the following known bugs:
 
index 95d386f855d3c2401da883c1232874804e0a5358..c5712f619df41c0b98fa772c9b859a6849e33575 100644 (file)
@@ -1055,9 +1055,16 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi,
       easy->result = Curl_is_connected(easy->easy_conn,
                                        FIRSTSOCKET,
                                        &connected);
-      if(connected)
-        easy->result = Curl_protocol_connect(easy->easy_conn,
-                                             &protocol_connect);
+      if(connected) {
+        /* see if we need to do any proxy magic first once we connected */
+        easy->result = Curl_connected_proxy(easy->easy_conn);
+
+        if(!easy->result)
+          /* if everything is still fine we do the protocol-specific connect
+             setup */
+          easy->result = Curl_protocol_connect(easy->easy_conn,
+                                               &protocol_connect);
+      }
 
       if(CURLE_OK != easy->result) {
         /* failure detected */
index f177b7ffe1bada331f2a5c998aff46a0d0fd0496..6843580678d19b50fc794334cd5280dbbfd7d371 100644 (file)
--- a/lib/url.c
+++ b/lib/url.c
@@ -2814,6 +2814,47 @@ ConnectionStore(struct SessionHandle *data,
   return i;
 }
 
+/* after a TCP connection to the proxy has been verified, this function does
+   the next magic step.
+
+   Note: this function (and its sub-functions) calls failf()
+
+*/
+CURLcode Curl_connected_proxy(struct connectdata *conn)
+{
+  CURLcode result = CURLE_OK;
+  struct SessionHandle *data = conn->data;
+
+  switch(data->set.proxytype) {
+#ifndef CURL_DISABLE_PROXY
+  case CURLPROXY_SOCKS5:
+  case CURLPROXY_SOCKS5_HOSTNAME:
+    result = Curl_SOCKS5(conn->proxyuser, conn->proxypasswd,
+                         conn->host.name, conn->remote_port,
+                         FIRSTSOCKET, conn);
+    break;
+  case CURLPROXY_SOCKS4:
+    result = Curl_SOCKS4(conn->proxyuser, conn->host.name,
+                         conn->remote_port, FIRSTSOCKET, conn, FALSE);
+    break;
+  case CURLPROXY_SOCKS4A:
+    result = Curl_SOCKS4(conn->proxyuser, conn->host.name,
+                         conn->remote_port, FIRSTSOCKET, conn, TRUE);
+    break;
+#endif /* CURL_DISABLE_PROXY */
+  case CURLPROXY_HTTP:
+  case CURLPROXY_HTTP_1_0:
+    /* do nothing here. handled later. */
+    break;
+  default:
+    failf(data, "unknown proxytype option given");
+      result = CURLE_COULDNT_CONNECT;
+      break;
+  } /* switch proxytype */
+
+  return result;
+}
+
 static CURLcode ConnectPlease(struct SessionHandle *data,
                               struct connectdata *conn,
                               struct Curl_dns_entry *hostaddr,
@@ -2838,39 +2879,14 @@ static CURLcode ConnectPlease(struct SessionHandle *data,
                            &addr,
                            connected);
   if(CURLE_OK == result) {
-    /* All is cool, then we store the current information */
+    /* All is cool, we store the current information */
     conn->dns_entry = hostaddr;
     conn->ip_addr = addr;
 
-    switch(data->set.proxytype) {
-#ifndef CURL_DISABLE_PROXY
-    case CURLPROXY_SOCKS5:
-    case CURLPROXY_SOCKS5_HOSTNAME:
-      result = Curl_SOCKS5(conn->proxyuser, conn->proxypasswd,
-                           conn->host.name, conn->remote_port,
-                           FIRSTSOCKET, conn);
-      break;
-    case CURLPROXY_SOCKS4:
-      result = Curl_SOCKS4(conn->proxyuser, conn->host.name,
-                           conn->remote_port, FIRSTSOCKET, conn, FALSE);
-      break;
-    case CURLPROXY_SOCKS4A:
-      result = Curl_SOCKS4(conn->proxyuser, conn->host.name,
-                           conn->remote_port, FIRSTSOCKET, conn, TRUE);
-      break;
-#endif /* CURL_DISABLE_PROXY */
-    case CURLPROXY_HTTP:
-    case CURLPROXY_HTTP_1_0:
-      /* do nothing here. handled later. */
-      break;
-    default:
-      failf(data, "unknown proxytype option given");
-      result = CURLE_COULDNT_CONNECT;
-      break;
-    } /* switch proxytype */
-  } /* if result is ok */
-
-  if(result)
+    if(*connected)
+      result = Curl_connected_proxy(conn);
+  }
+  else
     *connected = FALSE; /* mark it as not connected */
 
   return result;
@@ -4761,8 +4777,6 @@ CURLcode Curl_done(struct connectdata **connp,
 
   Curl_expire(data, 0); /* stop timer */
 
-  Curl_getoff_all_pipelines(data, conn);
-
   if(conn->bits.done ||
      (conn->send_pipe->size + conn->recv_pipe->size != 0 &&
       !data->set.reuse_forbid &&
@@ -4773,6 +4787,8 @@ CURLcode Curl_done(struct connectdata **connp,
 
   conn->bits.done = TRUE; /* called just now! */
 
+  Curl_getoff_all_pipelines(data, conn);
+
   /* Cleanup possible redirect junk */
   if(data->req.newurl) {
     free(data->req.newurl);
index 7e22b73974fb414fbff9a3272b967c20b8e00775..35900812f212a5c014e0507790db691efa56b875 100644 (file)
--- a/lib/url.h
+++ b/lib/url.h
@@ -85,4 +85,6 @@ void Curl_reset_reqproto(struct connectdata *conn);
 #define CURL_DEFAULT_PROXY_PORT 1080 /* default proxy port unless specified */
 #define CURL_DEFAULT_SOCKS5_GSSAPI_SERVICE "rcmd" /* default socks5 gssapi service */
 
+CURLcode Curl_connected_proxy(struct connectdata *conn);
+
 #endif