cURL / Mailing Lists / curl-library / Single Mail

curl-library

Race Condition in Curl_proxyCONNECT()

From: Steffen Rumler <steffen.rumler_at_siemens.com>
Date: Tue, 09 Jan 2007 14:49:18 +0100

Hi,

I'm using libcurl version 7.15.3.

I found the following race condition using the HTTP connect request via

    curl_easy_setopt(curlPtr, CURLOPT_PROXY, proxyIpPort);
    curl_easy_setopt(curlPtr, CURLOPT_HTTPPROXYTUNNEL, true);

in conclusion with a subsequent FTP session:

    (1) libcurl sends the 'HTTP CONNECT' request to the proxy

    (2) the proxy acknowledges the 'HTTP CONNECT' positive

    (3) directly afterwards, the proxy forwards the FTP server's
         banner message to the libcurl

    (4) if the time gap between (2) and (3) is too small, the libcurl reads also the
         FTP server's banner message still in Curl_proxyCONNECT() without processing it;
         the data are lost after finishing of Curl_proxyCONNECT()

         subsequently, the FTP processing tries to read the FTP server's banner message
         without any success; a timeout occurs

Below you can find a patch suitable for version 7.15.3.
Basically, I keep the data not yet processed in the TCP socket buffer.

Steffen

--
diff -Naur curl-7.15.3/lib/http.c curl-7.15.3-new/lib/http.c
--- curl-7.15.3/lib/http.c      2006-02-11 23:35:17.000000000 +0100
+++ curl-7.15.3-new/lib/http.c  2006-12-27 14:08:38.000000000 +0100
@@ -1207,7 +1207,17 @@
        case 0: /* timeout */
          break;
        default:
+#if 0
          res = Curl_read(conn, tunnelsocket, ptr, BUFSIZE-nread, &gotbytes);
+#else
+        /*  S.R.: Read byte per byte, in order to keep the data in TCP
+         *        we are currently not interested in !!!
+         *        This is important for ftp, because directly after the
+         *        proxy's connect reply the FTP server's banner message
+         *        follows.
+         */
+        res = Curl_read(conn, tunnelsocket, ptr, 1, &gotbytes);
+#endif
          if(res< 0)
            /* EWOULDBLOCK */
            continue; /* go loop yourself */
-- 
Steffen
Received on 2007-01-09