Loading lib/connect.c +49 −91 Original line number Diff line number Diff line Loading @@ -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); Loading Loading @@ -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 Loading @@ -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; return CHKCONN_SELECT_ERROR; continue; } if(rc & CURL_CSELECT_ERR) else if(rc & CURL_CSELECT_ERR) /* error condition caught */ return WAITCONN_FDSET_ERROR; return CHKCONN_FDSET_ERROR; break; } return WAITCONN_CONNECTED; else if(rc) return CHKCONN_CONNECTED; return CHKCONN_IDLE; } static CURLcode bindlocal(struct connectdata *conn, Loading Loading @@ -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) { Loading Loading @@ -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); Loading @@ -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); Loading @@ -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! */ Loading @@ -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 */ Loading @@ -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)); } Loading Loading @@ -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) { Loading Loading @@ -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) { Loading @@ -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); 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 /* connect failed */ Curl_closesocket(conn, sockfd); Curl_updateconninfo(conn, sockfd); *sockp = sockfd; return CURLE_OK; break; } else if(WAITCONN_TIMEOUT == rc) infof(data, "Timeout\n"); else { data->state.os_errno = error; infof(data, "%s\n", Curl_strerror(conn, error)); } /* connect failed or timed out */ Curl_closesocket(conn, sockfd); return CURLE_OK; } Loading Loading @@ -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; Loading Loading
lib/connect.c +49 −91 Original line number Diff line number Diff line Loading @@ -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); Loading Loading @@ -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 Loading @@ -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; return CHKCONN_SELECT_ERROR; continue; } if(rc & CURL_CSELECT_ERR) else if(rc & CURL_CSELECT_ERR) /* error condition caught */ return WAITCONN_FDSET_ERROR; return CHKCONN_FDSET_ERROR; break; } return WAITCONN_CONNECTED; else if(rc) return CHKCONN_CONNECTED; return CHKCONN_IDLE; } static CURLcode bindlocal(struct connectdata *conn, Loading Loading @@ -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) { Loading Loading @@ -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); Loading @@ -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); Loading @@ -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! */ Loading @@ -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 */ Loading @@ -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)); } Loading Loading @@ -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) { Loading Loading @@ -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) { Loading @@ -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); 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 /* connect failed */ Curl_closesocket(conn, sockfd); Curl_updateconninfo(conn, sockfd); *sockp = sockfd; return CURLE_OK; break; } else if(WAITCONN_TIMEOUT == rc) infof(data, "Timeout\n"); else { data->state.os_errno = error; infof(data, "%s\n", Curl_strerror(conn, error)); } /* connect failed or timed out */ Curl_closesocket(conn, sockfd); return CURLE_OK; } Loading Loading @@ -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; Loading