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
	 Daniel Stenberg
					Daniel Stenberg