IPv6 adjustments, connect()ing to bad ports still don't work properly for

IPv6
This commit is contained in:
Daniel Stenberg
2001-10-02 11:26:53 +00:00
parent 51ca5fcbe0
commit ced8955325
2 changed files with 78 additions and 41 deletions

View File

@@ -132,6 +132,7 @@ int waitconnect(int sockfd, /* socket */
int timeout_msec) int timeout_msec)
{ {
fd_set fd; fd_set fd;
fd_set errfd;
struct timeval interval; struct timeval interval;
int rc; int rc;
@@ -139,12 +140,15 @@ int waitconnect(int sockfd, /* socket */
FD_ZERO(&fd); FD_ZERO(&fd);
FD_SET(sockfd, &fd); FD_SET(sockfd, &fd);
FD_ZERO(&errfd);
FD_SET(sockfd, &errfd);
interval.tv_sec = timeout_msec/1000; interval.tv_sec = timeout_msec/1000;
timeout_msec -= interval.tv_sec*1000; timeout_msec -= interval.tv_sec*1000;
interval.tv_usec = timeout_msec*1000; interval.tv_usec = timeout_msec*1000;
rc = select(sockfd+1, NULL, &fd, NULL, &interval); rc = select(sockfd+1, NULL, &fd, &errfd, &interval);
if(-1 == rc) if(-1 == rc)
/* error, no connect here, try next */ /* error, no connect here, try next */
return -1; return -1;
@@ -153,10 +157,16 @@ int waitconnect(int sockfd, /* socket */
/* timeout, no connect today */ /* timeout, no connect today */
return 1; return 1;
if(FD_ISSET(sockfd, &errfd)) {
/* error condition caught */
return 2;
}
/* we have a connect! */ /* we have a connect! */
return 0; return 0;
} }
#ifndef ENABLE_IPV6
static CURLcode bindlocal(struct connectdata *conn, static CURLcode bindlocal(struct connectdata *conn,
int sockfd) int sockfd)
{ {
@@ -171,7 +181,6 @@ static CURLcode bindlocal(struct connectdata *conn,
#define INADDR_NONE (unsigned long) ~0 #define INADDR_NONE (unsigned long) ~0
#endif #endif
#ifndef ENABLE_IPV6
struct SessionHandle *data = conn->data; struct SessionHandle *data = conn->data;
/************************************************************* /*************************************************************
@@ -286,10 +295,10 @@ static CURLcode bindlocal(struct connectdata *conn,
} /* end of device selection support */ } /* end of device selection support */
#endif /* end of HAVE_INET_NTOA */ #endif /* end of HAVE_INET_NTOA */
#endif /* end of not WIN32 */ #endif /* end of not WIN32 */
#endif /*ENABLE_IPV6*/
return CURLE_HTTP_PORT_FAILED; return CURLE_HTTP_PORT_FAILED;
} }
#endif /* end of ipv4-specific section */
/* /*
* TCP connect to the given host with timeout, proxy or remote doesn't matter. * TCP connect to the given host with timeout, proxy or remote doesn't matter.
@@ -341,11 +350,11 @@ CURLcode Curl_connecthost(struct connectdata *conn, /* context */
} }
#ifdef ENABLE_IPV6 #ifdef ENABLE_IPV6
struct addrinfo *ai;
/* /*
* Connecting with IPv6 support is so much easier and cleanly done * Connecting with IPv6 support is so much easier and cleanly done
*/ */
port =0; /* we already have port in the 'remotehost' struct */ {
struct addrinfo *ai;
for (ai = remotehost; ai; ai = ai->ai_next, aliasindex++) { for (ai = remotehost; ai; ai = ai->ai_next, aliasindex++) {
sockfd = socket(ai->ai_family, ai->ai_socktype, ai->ai_protocol); sockfd = socket(ai->ai_family, ai->ai_socktype, ai->ai_protocol);
@@ -357,13 +366,40 @@ CURLcode Curl_connecthost(struct connectdata *conn, /* context */
rc = connect(sockfd, ai->ai_addr, ai->ai_addrlen); rc = connect(sockfd, ai->ai_addr, ai->ai_addrlen);
if(-1 == rc) {
int error;
#ifdef WIN32
error = (int)GetLastError();
#else
error = errno;
#endif
switch (error) {
case EINPROGRESS:
case EWOULDBLOCK:
#if defined(EAGAIN) && EAGAIN != EWOULDBLOCK
/* On some platforms EAGAIN and EWOULDBLOCK are the
* same value, and on others they are different, hence
* the odd #if
*/
case EAGAIN:
#endif
case EINTR:
/* asynchronous connect, wait for connect or timeout */
rc = waitconnect(sockfd, timeout_ms);
break;
case ECONNREFUSED: /* no one listening */
default:
/* unknown error, fallthrough and try another address! */
failf(data, "Failed to connect to IP number %d", aliasindex+1);
break;
}
}
if(0 == rc) if(0 == rc)
/* direct connect, awesome! */ /* direct connect, awesome! */
break; break;
/* asynchronous connect, wait for connect or timeout */ else {
rc = waitconnect(sockfd, timeout_ms);
if(0 != rc) {
/* connect failed or timed out */ /* connect failed or timed out */
sclose(sockfd); sclose(sockfd);
sockfd = -1; sockfd = -1;
@@ -371,24 +407,25 @@ CURLcode Curl_connecthost(struct connectdata *conn, /* context */
/* get a new timeout for next attempt */ /* get a new timeout for next attempt */
after = Curl_tvnow(); after = Curl_tvnow();
timeout_ms -= (long)(Curl_tvdiff(after, before)*1000); timeout_ms -= (long)(Curl_tvdiff(after, before)*1000);
if(timeout_ms < 0) if(timeout_ms < 0) {
break; failf(data, "connect() timed out!");
return CURLE_OPERATION_TIMEOUTED;
}
before = after; before = after;
continue; continue;
} }
}
if (sockfd < 0) {
failf(data, "connect() failed");
return CURLE_COULDNT_CONNECT;
}
/* now disable the non-blocking mode again */ /* now disable the non-blocking mode again */
nonblock(sockfd, FALSE); nonblock(sockfd, FALSE);
break;
}
if (sockfd < 0) {
failf(data, strerror(errno));
return CURLE_COULDNT_CONNECT;
}
if(addr) if(addr)
*addr = ai; /* the address we ended up connected to */ *addr = ai; /* the address we ended up connected to */
}
#else #else
/* /*
* Connecting with IPv4-only support * Connecting with IPv4-only support

View File

@@ -2040,7 +2040,7 @@ static CURLcode CreateConnection(struct SessionHandle *data,
#else #else
const int niflags = NI_NUMERICHOST; const int niflags = NI_NUMERICHOST;
#endif #endif
struct addrinfo *ai = conn->ai; struct addrinfo *ai = conn->serv_addr;
if (getnameinfo(ai->ai_addr, ai->ai_addrlen, hbuf, sizeof(hbuf), NULL, 0, if (getnameinfo(ai->ai_addr, ai->ai_addrlen, hbuf, sizeof(hbuf), NULL, 0,
niflags)) { niflags)) {