IPv6 adjustments, connect()ing to bad ports still don't work properly for
IPv6
This commit is contained in:
@@ -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
|
||||||
|
|||||||
@@ -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)) {
|
||||||
|
|||||||
Reference in New Issue
Block a user