summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDaniel Stenberg <daniel@haxx.se>2002-01-07 18:38:01 +0000
committerDaniel Stenberg <daniel@haxx.se>2002-01-07 18:38:01 +0000
commitd3299beec734be02a781c393a994d525e3eaaac1 (patch)
tree775320b144a733daa4e9fec1aad1892e792e83bd
parentf9192db35865373e91320e09d9ad4a8013c0a8b5 (diff)
downloadgnurl-d3299beec734be02a781c393a994d525e3eaaac1.tar.gz
gnurl-d3299beec734be02a781c393a994d525e3eaaac1.tar.bz2
gnurl-d3299beec734be02a781c393a994d525e3eaaac1.zip
Modified to use non-blocking sockets all the time.
-rw-r--r--lib/connect.c8
-rw-r--r--lib/ssluse.c74
2 files changed, 75 insertions, 7 deletions
diff --git a/lib/connect.c b/lib/connect.c
index d7add1067..61e45689e 100644
--- a/lib/connect.c
+++ b/lib/connect.c
@@ -448,8 +448,7 @@ CURLcode Curl_connecthost(struct connectdata *conn, /* context */
return CURLE_COULDNT_CONNECT;
}
- /* now disable the non-blocking mode again */
- Curl_nonblock(sockfd, FALSE);
+ /* leave the socket in non-blocking mode */
if(addr)
*addr = ai; /* the address we ended up connected to */
@@ -554,9 +553,8 @@ CURLcode Curl_connecthost(struct connectdata *conn, /* context */
failf(data, "Couldn't connect to host");
return CURLE_COULDNT_CONNECT;
}
-
- /* now disable the non-blocking mode again */
- Curl_nonblock(sockfd, FALSE);
+
+ /* leave the socket in non-blocking mode */
if(addr)
/* this is the address we've connected to */
diff --git a/lib/ssluse.c b/lib/ssluse.c
index 55b0a2e09..3c4728ab6 100644
--- a/lib/ssluse.c
+++ b/lib/ssluse.c
@@ -736,8 +736,78 @@ Curl_SSLConnect(struct connectdata *conn)
}
/* pass the raw socket into the SSL layers */
- SSL_set_fd (conn->ssl.handle, conn->firstsocket);
- err = SSL_connect (conn->ssl.handle);
+ SSL_set_fd(conn->ssl.handle, conn->firstsocket);
+
+ do {
+ int what;
+ fd_set writefd;
+ fd_set readfd;
+ struct timeval interval;
+ long timeout_ms;
+
+ err = SSL_connect(conn->ssl.handle);
+
+ what = SSL_get_error(conn->ssl.handle, err);
+
+ FD_ZERO(&writefd);
+ FD_ZERO(&readfd);
+
+ if(SSL_ERROR_WANT_READ == what)
+ FD_SET(conn->firstsocket, &readfd);
+ else if(SSL_ERROR_WANT_WRITE == what)
+ FD_SET(conn->firstsocket, &writefd);
+ else
+ break; /* untreated error */
+
+ /* Find out if any timeout is set. If not, use 300 seconds.
+ Otherwise, figure out the most strict timeout of the two possible one
+ and then how much time that has elapsed to know how much time we
+ allow for the connect call */
+ if(data->set.timeout || data->set.connecttimeout) {
+ double has_passed;
+
+ /* Evaluate in milliseconds how much time that has passed */
+ has_passed = Curl_tvdiff(Curl_tvnow(), data->progress.start);
+
+#ifndef min
+#define min(a, b) ((a) < (b) ? (a) : (b))
+#endif
+
+ /* get the most strict timeout of the ones converted to milliseconds */
+ if(data->set.timeout &&
+ (data->set.timeout>data->set.connecttimeout))
+ timeout_ms = data->set.timeout*1000;
+ else
+ timeout_ms = data->set.connecttimeout*1000;
+
+ /* subtract the passed time */
+ timeout_ms -= (long)has_passed;
+
+ if(timeout_ms < 0)
+ /* a precaution, no need to continue if time already is up */
+ return CURLE_OPERATION_TIMEOUTED;
+ }
+ else
+ /* no particular time-out has been set */
+ timeout_ms=300000; /* milliseconds, default to five minutes */
+
+ interval.tv_sec = timeout_ms/1000;
+ timeout_ms -= interval.tv_sec*1000;
+
+ interval.tv_usec = timeout_ms*1000;
+
+ what = select(conn->firstsocket+1, &readfd, &writefd, NULL, &interval);
+ if(what > 0)
+ /* reabable or writable, go loop yourself */
+ continue;
+ else if(0 == what) {
+ /* timeout */
+ failf(data, "SSL connection timeout");
+ return CURLE_OPERATION_TIMEOUTED;
+ }
+ else
+ break; /* get out of loop */
+ } while(1);
/* 1 is fine
0 is "not successful but was shut down controlled"