Skip to content
Snippets Groups Projects
Commit 72dbe9da authored by Daniel Stenberg's avatar Daniel Stenberg
Browse files

praise Bjorn Reese for mastering these dusty corners of socket hacking, now

we check for the error state before believing we are connected in IPv6
cases
parent dd028817
No related branches found
No related tags found
No related merge requests found
......@@ -72,6 +72,16 @@
#include "memdebug.h"
#endif
static
int geterrno(void)
{
#ifdef WIN32
return (int)GetLastError();
#else
return errno;
#endif
}
/*************************************************************************
* Curl_nonblock
*
......@@ -300,6 +310,19 @@ static CURLcode bindlocal(struct connectdata *conn,
}
#endif /* end of ipv4-specific section */
static
int socketerror(int sockfd)
{
int err = 0;
socklen_t errSize = sizeof(err);
if( -1 == getsockopt(sockfd, SOL_SOCKET, SO_ERROR,
(void *)&err, &errSize))
err = geterrno();
return err;
}
/*
* 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
......@@ -355,6 +378,7 @@ CURLcode Curl_connecthost(struct connectdata *conn, /* context */
*/
{
struct addrinfo *ai;
port =0; /* prevent compiler warning */
for (ai = remotehost; ai; ai = ai->ai_next, aliasindex++) {
sockfd = socket(ai->ai_family, ai->ai_socktype, ai->ai_protocol);
......@@ -367,12 +391,8 @@ CURLcode Curl_connecthost(struct connectdata *conn, /* context */
rc = connect(sockfd, ai->ai_addr, ai->ai_addrlen);
if(-1 == rc) {
int error;
#ifdef WIN32
error = (int)GetLastError();
#else
error = errno;
#endif
int error=geterrno();
switch (error) {
case EINPROGRESS:
case EWOULDBLOCK:
......@@ -391,29 +411,35 @@ CURLcode Curl_connecthost(struct connectdata *conn, /* context */
case ECONNREFUSED: /* no one listening */
default:
/* unknown error, fallthrough and try another address! */
failf(data, "Failed to connect to IP number %d", aliasindex+1);
failf(data, "Failed to connect");
break;
}
}
if(0 == rc)
/* direct connect, awesome! */
break;
if(0 == rc) {
/* we might be connected, if the socket says it is OK! Ask it! */
int err;
else {
/* connect failed or timed out */
sclose(sockfd);
sockfd = -1;
/* get a new timeout for next attempt */
after = Curl_tvnow();
timeout_ms -= (long)(Curl_tvdiff(after, before)*1000);
if(timeout_ms < 0) {
failf(data, "connect() timed out!");
return CURLE_OPERATION_TIMEOUTED;
}
before = after;
continue;
err = socketerror(sockfd);
if ((0 == err) || (EISCONN == err)) {
/* we are connected, awesome! */
break;
}
/* we are _not_ connected, it was a false alert, continue please */
}
/* connect failed or timed out */
sclose(sockfd);
sockfd = -1;
/* get a new timeout for next attempt */
after = Curl_tvnow();
timeout_ms -= (long)(Curl_tvdiff(after, before)*1000);
if(timeout_ms < 0) {
failf(data, "connect() timed out!");
return CURLE_OPERATION_TIMEOUTED;
}
before = after;
continue;
}
if (sockfd < 0) {
failf(data, "connect() failed");
......@@ -466,12 +492,8 @@ CURLcode Curl_connecthost(struct connectdata *conn, /* context */
sizeof(serv_addr));
if(-1 == rc) {
int error;
#ifdef WIN32
error = (int)GetLastError();
#else
error = errno;
#endif
int error=geterrno();
switch (error) {
case EINPROGRESS:
case EWOULDBLOCK:
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment