Commit 3dcc0df5 authored by Daniel Stenberg's avatar Daniel Stenberg
Browse files

SOCKS: fix the connect timeout

The connect timeout logic when using SOCKS was done wrong

Bug: http://curl.haxx.se/mail/lib-2011-07/0177.html
Reported by: "Spoon Man"
parent da3ae20d
Loading
Loading
Loading
Loading
+0 −4
Original line number Diff line number Diff line
@@ -46,8 +46,4 @@ To be addressed in 7.21.8 (or 7.22.0?)
306 - SSL Sessions shared by Alejandro Alvarez Ayllon
      http://curl.haxx.se/mail/lib-2011-08/0002.html

307 - "ftp downloading operation result" by Spoon Man, multi fix and SOCKS
      timeout fix
      http://curl.haxx.se/mail/lib-2011-07/0177.html

308 -
 No newline at end of file
+11 −24
Original line number Diff line number Diff line
@@ -56,28 +56,21 @@ int Curl_blockread_all(struct connectdata *conn, /* connection data */
                       curl_socket_t sockfd,     /* read from this socket */
                       char *buf,                /* store read data here */
                       ssize_t buffersize,       /* max amount to read */
                       ssize_t *n,               /* amount bytes read */
                       long conn_timeout)        /* timeout for data wait
                                                    relative to
                                                    conn->created */
                       ssize_t *n)               /* amount bytes read */
{
  ssize_t nread;
  ssize_t allread = 0;
  int result;
  struct timeval tvnow;
  long conntime;
  long timeleft;
  *n = 0;
  for(;;) {
    tvnow = Curl_tvnow();
    /* calculating how long connection is establishing */
    conntime = Curl_tvdiff(tvnow, conn->created);
    if(conntime > conn_timeout) {
    timeleft = Curl_timeleft(conn->data, NULL, TRUE);
    if(timeleft < 0) {
      /* we already got the timeout */
      result = CURLE_OPERATION_TIMEDOUT;
      break;
    }
    if(Curl_socket_ready(sockfd, CURL_SOCKET_BAD,
                         conn_timeout - conntime) <= 0) {
    if(Curl_socket_ready(sockfd, CURL_SOCKET_BAD, timeleft) <= 0) {
      result = ~CURLE_OK;
      break;
    }
@@ -129,13 +122,9 @@ CURLcode Curl_SOCKS4(const char *proxy_name,
  int result;
  CURLcode code;
  curl_socket_t sock = conn->sock[sockindex];
  long timeout;
  struct SessionHandle *data = conn->data;

  /* get timeout */
  timeout = Curl_timeleft(data, NULL, TRUE);

  if(timeout < 0) {
  if(Curl_timeleft(data, NULL, TRUE) < 0) {
    /* time-out, bail out, go home */
    failf(data, "Connection time-out");
    return CURLE_OPERATION_TIMEDOUT;
@@ -260,7 +249,7 @@ CURLcode Curl_SOCKS4(const char *proxy_name,

    /* Receive response */
    result = Curl_blockread_all(conn, sock, (char *)socksreq, packetsize,
                           &actualread, timeout);
                                &actualread);
    if((result != CURLE_OK) || (actualread != packetsize)) {
      failf(data, "Failed to receive SOCKS4 connect request ack.");
      return CURLE_COULDNT_CONNECT;
@@ -462,8 +451,7 @@ CURLcode Curl_SOCKS5(const char *proxy_name,

  curlx_nonblock(sock, FALSE);

  result=Curl_blockread_all(conn, sock, (char *)socksreq, 2, &actualread,
                            timeout);
  result=Curl_blockread_all(conn, sock, (char *)socksreq, 2, &actualread);
  if((result != CURLE_OK) || (actualread != 2)) {
    failf(data, "Unable to receive initial SOCKS5 response.");
    return CURLE_COULDNT_CONNECT;
@@ -523,8 +511,7 @@ CURLcode Curl_SOCKS5(const char *proxy_name,
      return CURLE_COULDNT_CONNECT;
    }

    result=Curl_blockread_all(conn, sock, (char *)socksreq, 2, &actualread,
                         timeout);
    result=Curl_blockread_all(conn, sock, (char *)socksreq, 2, &actualread);
    if((result != CURLE_OK) || (actualread != 2)) {
      failf(data, "Unable to receive SOCKS5 sub-negotiation response.");
      return CURLE_COULDNT_CONNECT;
@@ -660,7 +647,7 @@ CURLcode Curl_SOCKS5(const char *proxy_name,
  else
#endif
    result = Curl_blockread_all(conn, sock, (char *)socksreq, packetsize,
                           &actualread, timeout);
                                &actualread);
  if((result != CURLE_OK) || (actualread != packetsize)) {
    failf(data, "Failed to receive SOCKS5 connect request ack.");
    return CURLE_COULDNT_CONNECT;
@@ -716,7 +703,7 @@ CURLcode Curl_SOCKS5(const char *proxy_name,
    if(packetsize > 10) {
      packetsize -= 10;
      result = Curl_blockread_all(conn, sock, (char *)&socksreq[10],
                                  packetsize, &actualread, timeout);
                                  packetsize, &actualread);
      if((result != CURLE_OK) || (actualread != packetsize)) {
        failf(data, "Failed to receive SOCKS5 connect request ack.");
        return CURLE_COULDNT_CONNECT;
+1 −2
Original line number Diff line number Diff line
@@ -39,8 +39,7 @@ int Curl_blockread_all(struct connectdata *conn,
                       curl_socket_t sockfd,
                       char *buf,
                       ssize_t buffersize,
                       ssize_t *n,
                       long conn_timeout);
                       ssize_t *n);

/*
 * This function logs in to a SOCKS4(a) proxy and sends the specifics to the
+4 −12
Original line number Diff line number Diff line
@@ -118,7 +118,6 @@ CURLcode Curl_SOCKS5_gssapi_negotiate(int sockindex,
  ssize_t actualread;
  ssize_t written;
  int result;
  long timeout;
  OM_uint32 gss_major_status, gss_minor_status, gss_status;
  OM_uint32 gss_ret_flags;
  int gss_conf_state, gss_enc;
@@ -134,9 +133,6 @@ CURLcode Curl_SOCKS5_gssapi_negotiate(int sockindex,
  unsigned char socksreq[4]; /* room for gssapi exchange header only */
  char *serviceptr = data->set.str[STRING_SOCKS5_GSSAPI_SERVICE];

  /* get timeout */
  timeout = Curl_timeleft(data, NULL, TRUE);

  /*   GSSAPI request looks like
   * +----+------+-----+----------------+
   * |VER | MTYP | LEN |     TOKEN      |
@@ -245,8 +241,7 @@ CURLcode Curl_SOCKS5_gssapi_negotiate(int sockindex,
     * +----+------+-----+----------------+
     */

    result=Curl_blockread_all(conn, sock, (char *)socksreq, 4,
                              &actualread, timeout);
    result=Curl_blockread_all(conn, sock, (char *)socksreq, 4, &actualread);
    if(result != CURLE_OK || actualread != 4) {
      failf(data, "Failed to receive GSSAPI authentication response.");
      gss_release_name(&gss_status, &server);
@@ -286,8 +281,7 @@ CURLcode Curl_SOCKS5_gssapi_negotiate(int sockindex,
    }

    result=Curl_blockread_all(conn, sock, (char *)gss_recv_token.value,
                              gss_recv_token.length,
                              &actualread, timeout);
                              gss_recv_token.length, &actualread);

    if(result != CURLE_OK || actualread != us_length) {
      failf(data, "Failed to receive GSSAPI authentication token.");
@@ -444,8 +438,7 @@ CURLcode Curl_SOCKS5_gssapi_negotiate(int sockindex,
    gss_release_buffer(&gss_status, &gss_w_token);
  }

  result=Curl_blockread_all(conn, sock, (char *)socksreq, 4,
                            &actualread, timeout);
  result=Curl_blockread_all(conn, sock, (char *)socksreq, 4, &actualread);
  if(result != CURLE_OK || actualread != 4) {
    failf(data, "Failed to receive GSSAPI encryption response.");
    gss_delete_sec_context(&gss_status, &gss_context, NULL);
@@ -477,8 +470,7 @@ CURLcode Curl_SOCKS5_gssapi_negotiate(int sockindex,
    return CURLE_OUT_OF_MEMORY;
  }
  result=Curl_blockread_all(conn, sock, (char *)gss_recv_token.value,
                            gss_recv_token.length,
                            &actualread, timeout);
                            gss_recv_token.length, &actualread);

  if(result != CURLE_OK || actualread != us_length) {
    failf(data, "Failed to receive GSSAPI encryptrion type.");
+4 −12
Original line number Diff line number Diff line
@@ -160,7 +160,6 @@ CURLcode Curl_SOCKS5_gssapi_negotiate(int sockindex,
  ssize_t actualread;
  ssize_t written;
  int result;
  long timeout;
  /* Needs GSSAPI authentication */
  SECURITY_STATUS sspi_major_status, sspi_minor_status=0;
  unsigned long sspi_ret_flags=0;
@@ -179,9 +178,6 @@ CURLcode Curl_SOCKS5_gssapi_negotiate(int sockindex,
  unsigned char socksreq[4]; /* room for gssapi exchange header only */
  char *service = data->set.str[STRING_SOCKS5_GSSAPI_SERVICE];

  /* get timeout */
  timeout = Curl_timeleft(data, NULL, TRUE);

  /*   GSSAPI request looks like
   * +----+------+-----+----------------+
   * |VER | MTYP | LEN |     TOKEN      |
@@ -337,8 +333,7 @@ CURLcode Curl_SOCKS5_gssapi_negotiate(int sockindex,
     * +----+------+-----+----------------+
     */

    result=Curl_blockread_all(conn, sock, (char *)socksreq, 4,
                              &actualread, timeout);
    result=Curl_blockread_all(conn, sock, (char *)socksreq, 4, &actualread);
    if(result != CURLE_OK || actualread != 4) {
      failf(data, "Failed to receive SSPI authentication response.");
      free(service_name);
@@ -383,8 +378,7 @@ CURLcode Curl_SOCKS5_gssapi_negotiate(int sockindex,
      return CURLE_OUT_OF_MEMORY;
    }
    result = Curl_blockread_all(conn, sock, (char *)sspi_recv_token.pvBuffer,
                                sspi_recv_token.cbBuffer,
                                &actualread, timeout);
                                sspi_recv_token.cbBuffer, &actualread);

    if(result != CURLE_OK || actualread != us_length) {
      failf(data, "Failed to receive SSPI authentication token.");
@@ -585,8 +579,7 @@ CURLcode Curl_SOCKS5_gssapi_negotiate(int sockindex,
    s_pSecFn->FreeContextBuffer(sspi_send_token.pvBuffer);
  }

  result=Curl_blockread_all(conn, sock, (char *)socksreq, 4,
                            &actualread, timeout);
  result=Curl_blockread_all(conn, sock, (char *)socksreq, 4, &actualread);
  if(result != CURLE_OK || actualread != 4) {
    failf(data, "Failed to receive SSPI encryption response.");
    s_pSecFn->DeleteSecurityContext(&sspi_context);
@@ -619,8 +612,7 @@ CURLcode Curl_SOCKS5_gssapi_negotiate(int sockindex,
  }

  result=Curl_blockread_all(conn, sock, (char *)sspi_w_token[0].pvBuffer,
                            sspi_w_token[0].cbBuffer,
                            &actualread, timeout);
                            sspi_w_token[0].cbBuffer, &actualread);

  if(result != CURLE_OK || actualread != us_length) {
    failf(data, "Failed to receive SSPI encryption type.");