diff options
Diffstat (limited to 'lib/connect.c')
-rw-r--r-- | lib/connect.c | 91 |
1 files changed, 88 insertions, 3 deletions
diff --git a/lib/connect.c b/lib/connect.c index ba00b73e9..545062c66 100644 --- a/lib/connect.c +++ b/lib/connect.c @@ -338,6 +338,70 @@ int socketerror(int sockfd) } /* + * Curl_is_connected() is used from the multi interface to check if the + * firstsocket has connected. + */ + +CURLcode Curl_is_connected(struct connectdata *conn, + int sockfd, + bool *connected) +{ + int rc; + struct SessionHandle *data = conn->data; + + *connected = FALSE; /* a very negative world view is best */ + + if(data->set.timeout || data->set.connecttimeout) { + /* there is a timeout set */ + + /* Evaluate in milliseconds how much time that has passed */ + long has_passed = Curl_tvdiff(Curl_tvnow(), data->progress.start); + + /* subtract the most strict timeout of the ones */ + if(data->set.timeout && data->set.connecttimeout) { + if (data->set.timeout < data->set.connecttimeout) + has_passed -= data->set.timeout*1000; + else + has_passed -= data->set.connecttimeout*1000; + } + else if(data->set.timeout) + has_passed -= data->set.timeout*1000; + else + has_passed -= data->set.connecttimeout*1000; + + if(has_passed > 0 ) { + /* time-out, bail out, go home */ + failf(data, "Connection time-out"); + return CURLE_OPERATION_TIMEOUTED; + } + } + + /* check for connect without timeout as we want to return immediately */ + rc = waitconnect(sockfd, 0); + + if(0 == rc) { + int err = socketerror(sockfd); + if ((0 == err) || (EISCONN == err)) { + /* we are connected, awesome! */ + *connected = TRUE; + return CURLE_OK; + } + /* nope, not connected for real */ + } + + /* + * If the connection phase is "done" here, we should attempt to connect + * to the "next address" in the Curl_hostaddr structure that we resolved + * before. But we don't have that struct around anymore and we can't just + * keep a pointer since the cache might in fact have gotten pruned by the + * time we want to read this... Alas, we don't do this yet. + */ + + return CURLE_OK; +} + + +/* * TCP connect to the given host with timeout, proxy or remote doesn't matter. * There might be more than one IP address to try out. Fill in the passed * pointer with the connected socket. @@ -347,7 +411,8 @@ CURLcode Curl_connecthost(struct connectdata *conn, /* context */ Curl_addrinfo *remotehost, /* use one in here */ int port, /* connect to this */ int *sockconn, /* the connected socket */ - Curl_ipconnect **addr) /* the one we used */ + Curl_ipconnect **addr, /* the one we used */ + bool *connected) /* really connected? */ { struct SessionHandle *data = conn->data; int rc; @@ -437,8 +502,11 @@ CURLcode Curl_connecthost(struct connectdata *conn, /* context */ case EAGAIN: #endif case EINTR: - /* asynchronous connect, wait for connect or timeout */ + if(data->state.used_interface == Curl_if_multi) + /* don't hang when doing multi */ + timeout_ms = 0; + rc = waitconnect(sockfd, timeout_ms); break; case ECONNREFUSED: /* no one listening */ @@ -448,6 +516,7 @@ CURLcode Curl_connecthost(struct connectdata *conn, /* context */ break; } } + if(0 == rc) { /* we might be connected, if the socket says it is OK! Ask it! */ int err; @@ -455,11 +524,17 @@ CURLcode Curl_connecthost(struct connectdata *conn, /* context */ err = socketerror(sockfd); if ((0 == err) || (EISCONN == err)) { /* we are connected, awesome! */ + *connected = TRUE; /* this is truly a connect */ break; } failf(data, "socket error: %d", err); /* we are _not_ connected, it was a false alert, continue please */ } + else if(data->state.used_interface == Curl_if_multi) { + /* When running the multi interface, we bail out here */ + rc = 0; + break; + } /* connect failed or timed out */ sclose(sockfd); @@ -542,8 +617,11 @@ CURLcode Curl_connecthost(struct connectdata *conn, /* context */ */ case EAGAIN: #endif - /* asynchronous connect, wait for connect or timeout */ + if(data->state.used_interface == Curl_if_multi) + /* don't hang when doing multi */ + timeout_ms = 0; + rc = waitconnect(sockfd, timeout_ms); break; default: @@ -558,6 +636,7 @@ CURLcode Curl_connecthost(struct connectdata *conn, /* context */ int err = socketerror(sockfd); if ((0 == err) || (EISCONN == err)) { /* we are connected, awesome! */ + *connected = TRUE; /* this is a true connect */ break; } /* nope, not connected for real */ @@ -565,6 +644,12 @@ CURLcode Curl_connecthost(struct connectdata *conn, /* context */ } if(0 != rc) { + if(data->state.used_interface == Curl_if_multi) { + /* When running the multi interface, we bail out here */ + rc = 0; + break; + } + /* get a new timeout for next attempt */ after = Curl_tvnow(); timeout_ms -= Curl_tvdiff(after, before); |