aboutsummaryrefslogtreecommitdiff
path: root/lib/connect.c
diff options
context:
space:
mode:
authorDaniel Stenberg <daniel@haxx.se>2013-02-01 00:17:07 +0100
committerDaniel Stenberg <daniel@haxx.se>2013-02-01 08:16:08 +0100
commit56b7c87c74d293ac37f42f5551be115710cb7eaf (patch)
treedeb786281ebe26488018d0697d318bf7c5604c24 /lib/connect.c
parent32e8467a66778d3ffea64ff346d86bf4d9fd3db7 (diff)
singleipconnect: simplify and clean up
Remove timeout argument that's never used. Make the actual connection get detected on a single spot to reduce code duplication. Store the IPv6 state already when the connection is attempted.
Diffstat (limited to 'lib/connect.c')
-rw-r--r--lib/connect.c140
1 files changed, 49 insertions, 91 deletions
diff --git a/lib/connect.c b/lib/connect.c
index c411a0eb5..28c44559d 100644
--- a/lib/connect.c
+++ b/lib/connect.c
@@ -128,7 +128,6 @@ tcpkeepalive(struct SessionHandle *data,
static CURLcode
singleipconnect(struct connectdata *conn,
const Curl_addrinfo *ai, /* start connecting to this */
- long timeout_ms,
curl_socket_t *sock,
bool *connected);
@@ -199,20 +198,19 @@ long Curl_timeleft(struct SessionHandle *data,
}
/*
- * waitconnect() waits for a TCP connect on the given socket for the specified
- * number if milliseconds. It returns:
+ * checkconnect() checks for a TCP connect on the given socket.
+ * It returns:
*/
-#define WAITCONN_CONNECTED 0
-#define WAITCONN_SELECT_ERROR -1
-#define WAITCONN_TIMEOUT 1
-#define WAITCONN_FDSET_ERROR 2
-#define WAITCONN_ABORTED 3
+enum chkconn_t {
+ CHKCONN_SELECT_ERROR = -1,
+ CHKCONN_CONNECTED = 0,
+ CHKCONN_IDLE = 1,
+ CHKCONN_FDSET_ERROR = 2
+};
-static
-int waitconnect(struct connectdata *conn,
- curl_socket_t sockfd, /* socket */
- long timeout_msec)
+static enum chkconn_t
+checkconnect(curl_socket_t sockfd)
{
int rc;
#ifdef mpeix
@@ -222,34 +220,20 @@ int waitconnect(struct connectdata *conn,
(void)verifyconnect(sockfd, NULL);
#endif
- for(;;) {
-
- /* now select() until we get connect or timeout */
- rc = Curl_socket_ready(CURL_SOCKET_BAD, sockfd, timeout_msec>1000?
- 1000:timeout_msec);
- if(Curl_pgrsUpdate(conn))
- return WAITCONN_ABORTED;
+ rc = Curl_socket_ready(CURL_SOCKET_BAD, sockfd, 0);
- if(-1 == rc)
- /* error, no connect here, try next */
- return WAITCONN_SELECT_ERROR;
-
- else if(0 == rc) {
- /* timeout */
- timeout_msec -= 1000;
- if(timeout_msec <= 0)
- return WAITCONN_TIMEOUT;
+ if(-1 == rc)
+ /* error, no connect here, try next */
+ return CHKCONN_SELECT_ERROR;
- continue;
- }
+ else if(rc & CURL_CSELECT_ERR)
+ /* error condition caught */
+ return CHKCONN_FDSET_ERROR;
- if(rc & CURL_CSELECT_ERR)
- /* error condition caught */
- return WAITCONN_FDSET_ERROR;
+ else if(rc)
+ return CHKCONN_CONNECTED;
- break;
- }
- return WAITCONN_CONNECTED;
+ return CHKCONN_IDLE;
}
static CURLcode bindlocal(struct connectdata *conn,
@@ -548,7 +532,7 @@ static CURLcode trynextip(struct connectdata *conn,
ai = conn->ip_addr->ai_next;
while(ai) {
- CURLcode res = singleipconnect(conn, ai, 0L, &sockfd, connected);
+ CURLcode res = singleipconnect(conn, ai, &sockfd, connected);
if(res)
return res;
if(sockfd != CURL_SOCKET_BAD) {
@@ -676,21 +660,20 @@ void Curl_updateconninfo(struct connectdata *conn, curl_socket_t sockfd)
}
/*
- * Curl_is_connected() is used from the multi interface to check if the
- * firstsocket has connected.
+ * Curl_is_connected() checks if the socket has connected.
*/
CURLcode Curl_is_connected(struct connectdata *conn,
int sockindex,
bool *connected)
{
- int rc;
struct SessionHandle *data = conn->data;
CURLcode code = CURLE_OK;
curl_socket_t sockfd = conn->sock[sockindex];
long allow = DEFAULT_CONNECT_TIMEOUT;
int error = 0;
struct timeval now;
+ enum chkconn_t chk;
DEBUGASSERT(sockindex >= FIRSTSOCKET && sockindex <= SECONDARYSOCKET);
@@ -713,9 +696,9 @@ CURLcode Curl_is_connected(struct connectdata *conn,
return CURLE_OPERATION_TIMEDOUT;
}
- /* check for connect without timeout as we want to return immediately */
- rc = waitconnect(conn, sockfd, 0);
- if(WAITCONN_TIMEOUT == rc) {
+ /* check socket for connect */
+ chk = checkconnect(sockfd);
+ if(CHKCONN_IDLE == chk) {
if(curlx_tvdiff(now, conn->connecttime) >= conn->timeoutms_per_addr) {
infof(data, "After %ldms connect time, move on!\n",
conn->timeoutms_per_addr);
@@ -726,7 +709,7 @@ CURLcode Curl_is_connected(struct connectdata *conn,
return code;
}
- if(WAITCONN_CONNECTED == rc) {
+ if(CHKCONN_CONNECTED == chk) {
if(verifyconnect(sockfd, &error)) {
/* we are connected with TCP, awesome! */
@@ -736,6 +719,7 @@ CURLcode Curl_is_connected(struct connectdata *conn,
return code;
conn->bits.tcpconnect[sockindex] = TRUE;
+
*connected = TRUE;
if(sockindex == FIRSTSOCKET)
Curl_pgrsTime(data, TIMER_CONNECT); /* connect done */
@@ -748,7 +732,7 @@ CURLcode Curl_is_connected(struct connectdata *conn,
}
else {
/* nope, not connected */
- if(WAITCONN_FDSET_ERROR == rc) {
+ if(CHKCONN_FDSET_ERROR == chk) {
(void)verifyconnect(sockfd, &error);
infof(data, "%s\n",Curl_strerror(conn, error));
}
@@ -864,12 +848,11 @@ void Curl_sndbufset(curl_socket_t sockfd)
* CURL_SOCKET_BAD. Other errors will however return proper errors.
*
* singleipconnect() connects to the given IP only, and it may return without
- * having connected if used from the multi interface.
+ * having connected.
*/
static CURLcode
singleipconnect(struct connectdata *conn,
const Curl_addrinfo *ai,
- long timeout_ms,
curl_socket_t *sockp,
bool *connected)
{
@@ -940,17 +923,25 @@ singleipconnect(struct connectdata *conn,
/* set socket non-blocking */
curlx_nonblock(sockfd, TRUE);
+ conn->connecttime = Curl_tvnow();
+ if(conn->num_addr > 1)
+ Curl_expire(data, conn->timeoutms_per_addr);
+
/* Connect TCP sockets, bind UDP */
if(!isconnected && (conn->socktype == SOCK_STREAM)) {
rc = connect(sockfd, &addr.sa_addr, addr.addrlen);
if(-1 == rc)
error = SOCKERRNO;
- conn->connecttime = Curl_tvnow();
- if(conn->num_addr > 1)
- Curl_expire(data, conn->timeoutms_per_addr);
}
- else
+ else {
rc = 0;
+ *sockp = sockfd;
+ return CURLE_OK;
+ }
+
+#ifdef ENABLE_IPV6
+ conn->bits.ipv6 = (addr.family == AF_INET6)?TRUE:FALSE;
+#endif
if(-1 == rc) {
switch (error) {
@@ -965,54 +956,22 @@ singleipconnect(struct connectdata *conn,
case EAGAIN:
#endif
#endif
- rc = waitconnect(conn, sockfd, timeout_ms);
- if(WAITCONN_ABORTED == rc) {
- Curl_closesocket(conn, sockfd);
- return CURLE_ABORTED_BY_CALLBACK;
- }
- break;
+ *sockp = sockfd;
+ return CURLE_OK;
+
default:
/* unknown error, fallthrough and try another address! */
failf(data, "Failed to connect to %s: %s",
conn->ip_addr_str, Curl_strerror(conn,error));
data->state.os_errno = error;
- break;
- }
- }
- /* The 'WAITCONN_TIMEOUT == rc' comes from the waitconnect(), and not from
- connect(). We can be sure of this since connect() cannot return 1. */
- if(WAITCONN_TIMEOUT == rc) {
- /* Timeout when running the multi interface */
- *sockp = sockfd;
- return CURLE_OK;
- }
-
- if(!isconnected)
- isconnected = verifyconnect(sockfd, &error);
+ /* connect failed */
+ Curl_closesocket(conn, sockfd);
- if(!rc && isconnected) {
- /* we are connected, awesome! */
- *connected = TRUE; /* this is a true connect */
- infof(data, "connected\n");
-#ifdef ENABLE_IPV6
- conn->bits.ipv6 = (addr.family == AF_INET6)?TRUE:FALSE;
-#endif
-
- Curl_updateconninfo(conn, sockfd);
- *sockp = sockfd;
- return CURLE_OK;
- }
- else if(WAITCONN_TIMEOUT == rc)
- infof(data, "Timeout\n");
- else {
- data->state.os_errno = error;
- infof(data, "%s\n", Curl_strerror(conn, error));
+ break;
+ }
}
- /* connect failed or timed out */
- Curl_closesocket(conn, sockfd);
-
return CURLE_OK;
}
@@ -1073,7 +1032,6 @@ CURLcode Curl_connecthost(struct connectdata *conn, /* context */
/* start connecting to the IP curr_addr points to */
res = singleipconnect(conn, curr_addr,
- 0, /* don't hang when doing multi */
&sockfd, connected);
if(res)
return res;