1
0
mirror of https://github.com/moparisthebest/curl synced 2024-12-21 23:58:49 -05:00

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"
This commit is contained in:
Daniel Stenberg 2011-08-08 11:10:17 +02:00
parent da3ae20da5
commit 3dcc0df5cc
5 changed files with 20 additions and 54 deletions

View File

@ -46,8 +46,4 @@ To be addressed in 7.21.8 (or 7.22.0?)
306 - SSL Sessions shared by Alejandro Alvarez Ayllon 306 - SSL Sessions shared by Alejandro Alvarez Ayllon
http://curl.haxx.se/mail/lib-2011-08/0002.html 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 - 308 -

View File

@ -56,28 +56,21 @@ int Curl_blockread_all(struct connectdata *conn, /* connection data */
curl_socket_t sockfd, /* read from this socket */ curl_socket_t sockfd, /* read from this socket */
char *buf, /* store read data here */ char *buf, /* store read data here */
ssize_t buffersize, /* max amount to read */ ssize_t buffersize, /* max amount to read */
ssize_t *n, /* amount bytes read */ ssize_t *n) /* amount bytes read */
long conn_timeout) /* timeout for data wait
relative to
conn->created */
{ {
ssize_t nread; ssize_t nread;
ssize_t allread = 0; ssize_t allread = 0;
int result; int result;
struct timeval tvnow; long timeleft;
long conntime;
*n = 0; *n = 0;
for(;;) { for(;;) {
tvnow = Curl_tvnow(); timeleft = Curl_timeleft(conn->data, NULL, TRUE);
/* calculating how long connection is establishing */ if(timeleft < 0) {
conntime = Curl_tvdiff(tvnow, conn->created);
if(conntime > conn_timeout) {
/* we already got the timeout */ /* we already got the timeout */
result = CURLE_OPERATION_TIMEDOUT; result = CURLE_OPERATION_TIMEDOUT;
break; break;
} }
if(Curl_socket_ready(sockfd, CURL_SOCKET_BAD, if(Curl_socket_ready(sockfd, CURL_SOCKET_BAD, timeleft) <= 0) {
conn_timeout - conntime) <= 0) {
result = ~CURLE_OK; result = ~CURLE_OK;
break; break;
} }
@ -129,13 +122,9 @@ CURLcode Curl_SOCKS4(const char *proxy_name,
int result; int result;
CURLcode code; CURLcode code;
curl_socket_t sock = conn->sock[sockindex]; curl_socket_t sock = conn->sock[sockindex];
long timeout;
struct SessionHandle *data = conn->data; struct SessionHandle *data = conn->data;
/* get timeout */ if(Curl_timeleft(data, NULL, TRUE) < 0) {
timeout = Curl_timeleft(data, NULL, TRUE);
if(timeout < 0) {
/* time-out, bail out, go home */ /* time-out, bail out, go home */
failf(data, "Connection time-out"); failf(data, "Connection time-out");
return CURLE_OPERATION_TIMEDOUT; return CURLE_OPERATION_TIMEDOUT;
@ -260,7 +249,7 @@ CURLcode Curl_SOCKS4(const char *proxy_name,
/* Receive response */ /* Receive response */
result = Curl_blockread_all(conn, sock, (char *)socksreq, packetsize, result = Curl_blockread_all(conn, sock, (char *)socksreq, packetsize,
&actualread, timeout); &actualread);
if((result != CURLE_OK) || (actualread != packetsize)) { if((result != CURLE_OK) || (actualread != packetsize)) {
failf(data, "Failed to receive SOCKS4 connect request ack."); failf(data, "Failed to receive SOCKS4 connect request ack.");
return CURLE_COULDNT_CONNECT; return CURLE_COULDNT_CONNECT;
@ -462,8 +451,7 @@ CURLcode Curl_SOCKS5(const char *proxy_name,
curlx_nonblock(sock, FALSE); curlx_nonblock(sock, FALSE);
result=Curl_blockread_all(conn, sock, (char *)socksreq, 2, &actualread, result=Curl_blockread_all(conn, sock, (char *)socksreq, 2, &actualread);
timeout);
if((result != CURLE_OK) || (actualread != 2)) { if((result != CURLE_OK) || (actualread != 2)) {
failf(data, "Unable to receive initial SOCKS5 response."); failf(data, "Unable to receive initial SOCKS5 response.");
return CURLE_COULDNT_CONNECT; return CURLE_COULDNT_CONNECT;
@ -523,8 +511,7 @@ CURLcode Curl_SOCKS5(const char *proxy_name,
return CURLE_COULDNT_CONNECT; return CURLE_COULDNT_CONNECT;
} }
result=Curl_blockread_all(conn, sock, (char *)socksreq, 2, &actualread, result=Curl_blockread_all(conn, sock, (char *)socksreq, 2, &actualread);
timeout);
if((result != CURLE_OK) || (actualread != 2)) { if((result != CURLE_OK) || (actualread != 2)) {
failf(data, "Unable to receive SOCKS5 sub-negotiation response."); failf(data, "Unable to receive SOCKS5 sub-negotiation response.");
return CURLE_COULDNT_CONNECT; return CURLE_COULDNT_CONNECT;
@ -660,7 +647,7 @@ CURLcode Curl_SOCKS5(const char *proxy_name,
else else
#endif #endif
result = Curl_blockread_all(conn, sock, (char *)socksreq, packetsize, result = Curl_blockread_all(conn, sock, (char *)socksreq, packetsize,
&actualread, timeout); &actualread);
if((result != CURLE_OK) || (actualread != packetsize)) { if((result != CURLE_OK) || (actualread != packetsize)) {
failf(data, "Failed to receive SOCKS5 connect request ack."); failf(data, "Failed to receive SOCKS5 connect request ack.");
return CURLE_COULDNT_CONNECT; return CURLE_COULDNT_CONNECT;
@ -716,7 +703,7 @@ CURLcode Curl_SOCKS5(const char *proxy_name,
if(packetsize > 10) { if(packetsize > 10) {
packetsize -= 10; packetsize -= 10;
result = Curl_blockread_all(conn, sock, (char *)&socksreq[10], result = Curl_blockread_all(conn, sock, (char *)&socksreq[10],
packetsize, &actualread, timeout); packetsize, &actualread);
if((result != CURLE_OK) || (actualread != packetsize)) { if((result != CURLE_OK) || (actualread != packetsize)) {
failf(data, "Failed to receive SOCKS5 connect request ack."); failf(data, "Failed to receive SOCKS5 connect request ack.");
return CURLE_COULDNT_CONNECT; return CURLE_COULDNT_CONNECT;

View File

@ -39,8 +39,7 @@ int Curl_blockread_all(struct connectdata *conn,
curl_socket_t sockfd, curl_socket_t sockfd,
char *buf, char *buf,
ssize_t buffersize, ssize_t buffersize,
ssize_t *n, ssize_t *n);
long conn_timeout);
/* /*
* This function logs in to a SOCKS4(a) proxy and sends the specifics to the * This function logs in to a SOCKS4(a) proxy and sends the specifics to the

View File

@ -118,7 +118,6 @@ CURLcode Curl_SOCKS5_gssapi_negotiate(int sockindex,
ssize_t actualread; ssize_t actualread;
ssize_t written; ssize_t written;
int result; int result;
long timeout;
OM_uint32 gss_major_status, gss_minor_status, gss_status; OM_uint32 gss_major_status, gss_minor_status, gss_status;
OM_uint32 gss_ret_flags; OM_uint32 gss_ret_flags;
int gss_conf_state, gss_enc; 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 */ unsigned char socksreq[4]; /* room for gssapi exchange header only */
char *serviceptr = data->set.str[STRING_SOCKS5_GSSAPI_SERVICE]; char *serviceptr = data->set.str[STRING_SOCKS5_GSSAPI_SERVICE];
/* get timeout */
timeout = Curl_timeleft(data, NULL, TRUE);
/* GSSAPI request looks like /* GSSAPI request looks like
* +----+------+-----+----------------+ * +----+------+-----+----------------+
* |VER | MTYP | LEN | TOKEN | * |VER | MTYP | LEN | TOKEN |
@ -245,8 +241,7 @@ CURLcode Curl_SOCKS5_gssapi_negotiate(int sockindex,
* +----+------+-----+----------------+ * +----+------+-----+----------------+
*/ */
result=Curl_blockread_all(conn, sock, (char *)socksreq, 4, result=Curl_blockread_all(conn, sock, (char *)socksreq, 4, &actualread);
&actualread, timeout);
if(result != CURLE_OK || actualread != 4) { if(result != CURLE_OK || actualread != 4) {
failf(data, "Failed to receive GSSAPI authentication response."); failf(data, "Failed to receive GSSAPI authentication response.");
gss_release_name(&gss_status, &server); 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, result=Curl_blockread_all(conn, sock, (char *)gss_recv_token.value,
gss_recv_token.length, gss_recv_token.length, &actualread);
&actualread, timeout);
if(result != CURLE_OK || actualread != us_length) { if(result != CURLE_OK || actualread != us_length) {
failf(data, "Failed to receive GSSAPI authentication token."); 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); gss_release_buffer(&gss_status, &gss_w_token);
} }
result=Curl_blockread_all(conn, sock, (char *)socksreq, 4, result=Curl_blockread_all(conn, sock, (char *)socksreq, 4, &actualread);
&actualread, timeout);
if(result != CURLE_OK || actualread != 4) { if(result != CURLE_OK || actualread != 4) {
failf(data, "Failed to receive GSSAPI encryption response."); failf(data, "Failed to receive GSSAPI encryption response.");
gss_delete_sec_context(&gss_status, &gss_context, NULL); 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; return CURLE_OUT_OF_MEMORY;
} }
result=Curl_blockread_all(conn, sock, (char *)gss_recv_token.value, result=Curl_blockread_all(conn, sock, (char *)gss_recv_token.value,
gss_recv_token.length, gss_recv_token.length, &actualread);
&actualread, timeout);
if(result != CURLE_OK || actualread != us_length) { if(result != CURLE_OK || actualread != us_length) {
failf(data, "Failed to receive GSSAPI encryptrion type."); failf(data, "Failed to receive GSSAPI encryptrion type.");

View File

@ -160,7 +160,6 @@ CURLcode Curl_SOCKS5_gssapi_negotiate(int sockindex,
ssize_t actualread; ssize_t actualread;
ssize_t written; ssize_t written;
int result; int result;
long timeout;
/* Needs GSSAPI authentication */ /* Needs GSSAPI authentication */
SECURITY_STATUS sspi_major_status, sspi_minor_status=0; SECURITY_STATUS sspi_major_status, sspi_minor_status=0;
unsigned long sspi_ret_flags=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 */ unsigned char socksreq[4]; /* room for gssapi exchange header only */
char *service = data->set.str[STRING_SOCKS5_GSSAPI_SERVICE]; char *service = data->set.str[STRING_SOCKS5_GSSAPI_SERVICE];
/* get timeout */
timeout = Curl_timeleft(data, NULL, TRUE);
/* GSSAPI request looks like /* GSSAPI request looks like
* +----+------+-----+----------------+ * +----+------+-----+----------------+
* |VER | MTYP | LEN | TOKEN | * |VER | MTYP | LEN | TOKEN |
@ -337,8 +333,7 @@ CURLcode Curl_SOCKS5_gssapi_negotiate(int sockindex,
* +----+------+-----+----------------+ * +----+------+-----+----------------+
*/ */
result=Curl_blockread_all(conn, sock, (char *)socksreq, 4, result=Curl_blockread_all(conn, sock, (char *)socksreq, 4, &actualread);
&actualread, timeout);
if(result != CURLE_OK || actualread != 4) { if(result != CURLE_OK || actualread != 4) {
failf(data, "Failed to receive SSPI authentication response."); failf(data, "Failed to receive SSPI authentication response.");
free(service_name); free(service_name);
@ -383,8 +378,7 @@ CURLcode Curl_SOCKS5_gssapi_negotiate(int sockindex,
return CURLE_OUT_OF_MEMORY; return CURLE_OUT_OF_MEMORY;
} }
result = Curl_blockread_all(conn, sock, (char *)sspi_recv_token.pvBuffer, result = Curl_blockread_all(conn, sock, (char *)sspi_recv_token.pvBuffer,
sspi_recv_token.cbBuffer, sspi_recv_token.cbBuffer, &actualread);
&actualread, timeout);
if(result != CURLE_OK || actualread != us_length) { if(result != CURLE_OK || actualread != us_length) {
failf(data, "Failed to receive SSPI authentication token."); 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); s_pSecFn->FreeContextBuffer(sspi_send_token.pvBuffer);
} }
result=Curl_blockread_all(conn, sock, (char *)socksreq, 4, result=Curl_blockread_all(conn, sock, (char *)socksreq, 4, &actualread);
&actualread, timeout);
if(result != CURLE_OK || actualread != 4) { if(result != CURLE_OK || actualread != 4) {
failf(data, "Failed to receive SSPI encryption response."); failf(data, "Failed to receive SSPI encryption response.");
s_pSecFn->DeleteSecurityContext(&sspi_context); 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, result=Curl_blockread_all(conn, sock, (char *)sspi_w_token[0].pvBuffer,
sspi_w_token[0].cbBuffer, sspi_w_token[0].cbBuffer, &actualread);
&actualread, timeout);
if(result != CURLE_OK || actualread != us_length) { if(result != CURLE_OK || actualread != us_length) {
failf(data, "Failed to receive SSPI encryption type."); failf(data, "Failed to receive SSPI encryption type.");