From 3dcc0df5ccac15275f612f5c275ea320f5f41cd4 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Mon, 8 Aug 2011 11:10:17 +0200 Subject: 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" --- TODO-RELEASE | 4 ---- lib/socks.c | 35 +++++++++++------------------------ lib/socks.h | 3 +-- lib/socks_gssapi.c | 16 ++++------------ lib/socks_sspi.c | 16 ++++------------ 5 files changed, 20 insertions(+), 54 deletions(-) diff --git a/TODO-RELEASE b/TODO-RELEASE index 7255985b6..5a3801534 100644 --- a/TODO-RELEASE +++ b/TODO-RELEASE @@ -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 diff --git a/lib/socks.c b/lib/socks.c index 34de02865..ac13ed866 100644 --- a/lib/socks.c +++ b/lib/socks.c @@ -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; diff --git a/lib/socks.h b/lib/socks.h index 42b8080b0..fc4cc7f02 100644 --- a/lib/socks.h +++ b/lib/socks.h @@ -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 diff --git a/lib/socks_gssapi.c b/lib/socks_gssapi.c index c62bdc9c3..d23a944d7 100644 --- a/lib/socks_gssapi.c +++ b/lib/socks_gssapi.c @@ -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."); diff --git a/lib/socks_sspi.c b/lib/socks_sspi.c index 5b9376211..d96a82e8a 100644 --- a/lib/socks_sspi.c +++ b/lib/socks_sspi.c @@ -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."); -- cgit v1.2.3