aboutsummaryrefslogtreecommitdiff
path: root/lib/connect.c
diff options
context:
space:
mode:
Diffstat (limited to 'lib/connect.c')
-rw-r--r--lib/connect.c91
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);