Add "Happy Eyeballs" for IPv4/IPv6.
[platform/upstream/curl.git] / lib / connect.c
1 /***************************************************************************
2  *                                  _   _ ____  _
3  *  Project                     ___| | | |  _ \| |
4  *                             / __| | | | |_) | |
5  *                            | (__| |_| |  _ <| |___
6  *                             \___|\___/|_| \_\_____|
7  *
8  * Copyright (C) 1998 - 2013, Daniel Stenberg, <daniel@haxx.se>, et al.
9  *
10  * This software is licensed as described in the file COPYING, which
11  * you should have received as part of this distribution. The terms
12  * are also available at http://curl.haxx.se/docs/copyright.html.
13  *
14  * You may opt to use, copy, modify, merge, publish, distribute and/or sell
15  * copies of the Software, and permit persons to whom the Software is
16  * furnished to do so, under the terms of the COPYING file.
17  *
18  * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
19  * KIND, either express or implied.
20  *
21  ***************************************************************************/
22
23 #include "curl_setup.h"
24
25 #ifdef HAVE_NETINET_IN_H
26 #include <netinet/in.h> /* <netinet/tcp.h> may need it */
27 #endif
28 #ifdef HAVE_SYS_UN_H
29 #include <sys/un.h> /* for sockaddr_un */
30 #endif
31 #ifdef HAVE_NETINET_TCP_H
32 #include <netinet/tcp.h> /* for TCP_NODELAY */
33 #endif
34 #ifdef HAVE_SYS_IOCTL_H
35 #include <sys/ioctl.h>
36 #endif
37 #ifdef HAVE_NETDB_H
38 #include <netdb.h>
39 #endif
40 #ifdef HAVE_FCNTL_H
41 #include <fcntl.h>
42 #endif
43 #ifdef HAVE_ARPA_INET_H
44 #include <arpa/inet.h>
45 #endif
46
47 #if (defined(HAVE_IOCTL_FIONBIO) && defined(NETWARE))
48 #include <sys/filio.h>
49 #endif
50 #ifdef NETWARE
51 #undef in_addr_t
52 #define in_addr_t unsigned long
53 #endif
54 #ifdef __VMS
55 #include <in.h>
56 #include <inet.h>
57 #endif
58
59 #define _MPRINTF_REPLACE /* use our functions only */
60 #include <curl/mprintf.h>
61
62 #include "urldata.h"
63 #include "sendf.h"
64 #include "if2ip.h"
65 #include "strerror.h"
66 #include "connect.h"
67 #include "curl_memory.h"
68 #include "select.h"
69 #include "url.h" /* for Curl_safefree() */
70 #include "multiif.h"
71 #include "sockaddr.h" /* required for Curl_sockaddr_storage */
72 #include "inet_ntop.h"
73 #include "inet_pton.h"
74 #include "sslgen.h" /* for Curl_ssl_check_cxn() */
75 #include "progress.h"
76 #include "warnless.h"
77 #include "conncache.h"
78 #include "multihandle.h"
79
80 /* The last #include file should be: */
81 #include "memdebug.h"
82
83 #ifdef __SYMBIAN32__
84 /* This isn't actually supported under Symbian OS */
85 #undef SO_NOSIGPIPE
86 #endif
87
88 static bool verifyconnect(curl_socket_t sockfd, int *error);
89
90 #if defined(__DragonFly__) || defined(HAVE_WINSOCK_H)
91 /* DragonFlyBSD and Windows use millisecond units */
92 #define KEEPALIVE_FACTOR(x) (x *= 1000)
93 #else
94 #define KEEPALIVE_FACTOR(x)
95 #endif
96
97 #if defined(HAVE_WINSOCK_H) && !defined(SIO_KEEPALIVE_VALS)
98 #define SIO_KEEPALIVE_VALS    _WSAIOW(IOC_VENDOR,4)
99
100 struct tcp_keepalive {
101   u_long onoff;
102   u_long keepalivetime;
103   u_long keepaliveinterval;
104 };
105 #endif
106
107 static void
108 tcpkeepalive(struct SessionHandle *data,
109              curl_socket_t sockfd)
110 {
111   int optval = data->set.tcp_keepalive?1:0;
112
113   /* only set IDLE and INTVL if setting KEEPALIVE is successful */
114   if(setsockopt(sockfd, SOL_SOCKET, SO_KEEPALIVE,
115         (void *)&optval, sizeof(optval)) < 0) {
116     infof(data, "Failed to set SO_KEEPALIVE on fd %d\n", sockfd);
117   }
118   else {
119 #if defined(SIO_KEEPALIVE_VALS)
120     struct tcp_keepalive vals;
121     DWORD dummy;
122     vals.onoff = 1;
123     optval = curlx_sltosi(data->set.tcp_keepidle);
124     KEEPALIVE_FACTOR(optval);
125     vals.keepalivetime = optval;
126     optval = curlx_sltosi(data->set.tcp_keepintvl);
127     KEEPALIVE_FACTOR(optval);
128     vals.keepaliveinterval = optval;
129     if(WSAIoctl(sockfd, SIO_KEEPALIVE_VALS, (LPVOID) &vals, sizeof(vals),
130                 NULL, 0, &dummy, NULL, NULL) != 0) {
131       infof(data, "Failed to set SIO_KEEPALIVE_VALS on fd %d: %d\n",
132             (int)sockfd, WSAGetLastError());
133     }
134 #else
135 #ifdef TCP_KEEPIDLE
136     optval = curlx_sltosi(data->set.tcp_keepidle);
137     KEEPALIVE_FACTOR(optval);
138     if(setsockopt(sockfd, IPPROTO_TCP, TCP_KEEPIDLE,
139           (void *)&optval, sizeof(optval)) < 0) {
140       infof(data, "Failed to set TCP_KEEPIDLE on fd %d\n", sockfd);
141     }
142 #endif
143 #ifdef TCP_KEEPINTVL
144     optval = curlx_sltosi(data->set.tcp_keepintvl);
145     KEEPALIVE_FACTOR(optval);
146     if(setsockopt(sockfd, IPPROTO_TCP, TCP_KEEPINTVL,
147           (void *)&optval, sizeof(optval)) < 0) {
148       infof(data, "Failed to set TCP_KEEPINTVL on fd %d\n", sockfd);
149     }
150 #endif
151 #ifdef TCP_KEEPALIVE
152     /* Mac OS X style */
153     optval = curlx_sltosi(data->set.tcp_keepidle);
154     KEEPALIVE_FACTOR(optval);
155     if(setsockopt(sockfd, IPPROTO_TCP, TCP_KEEPALIVE,
156           (void *)&optval, sizeof(optval)) < 0) {
157       infof(data, "Failed to set TCP_KEEPALIVE on fd %d\n", sockfd);
158     }
159 #endif
160 #endif
161   }
162 }
163
164 static CURLcode
165 singleipconnect(struct connectdata *conn,
166                 const Curl_addrinfo *ai, /* start connecting to this */
167                 curl_socket_t *sock,
168                 bool *connected);
169
170 /*
171  * Curl_timeleft() returns the amount of milliseconds left allowed for the
172  * transfer/connection. If the value is negative, the timeout time has already
173  * elapsed.
174  *
175  * The start time is stored in progress.t_startsingle - as set with
176  * Curl_pgrsTime(..., TIMER_STARTSINGLE);
177  *
178  * If 'nowp' is non-NULL, it points to the current time.
179  * 'duringconnect' is FALSE if not during a connect, as then of course the
180  * connect timeout is not taken into account!
181  *
182  * @unittest: 1303
183  */
184 long Curl_timeleft(struct SessionHandle *data,
185                    struct timeval *nowp,
186                    bool duringconnect)
187 {
188   int timeout_set = 0;
189   long timeout_ms = duringconnect?DEFAULT_CONNECT_TIMEOUT:0;
190   struct timeval now;
191
192   /* if a timeout is set, use the most restrictive one */
193
194   if(data->set.timeout > 0)
195     timeout_set |= 1;
196   if(duringconnect && (data->set.connecttimeout > 0))
197     timeout_set |= 2;
198
199   switch (timeout_set) {
200   case 1:
201     timeout_ms = data->set.timeout;
202     break;
203   case 2:
204     timeout_ms = data->set.connecttimeout;
205     break;
206   case 3:
207     if(data->set.timeout < data->set.connecttimeout)
208       timeout_ms = data->set.timeout;
209     else
210       timeout_ms = data->set.connecttimeout;
211     break;
212   default:
213     /* use the default */
214     if(!duringconnect)
215       /* if we're not during connect, there's no default timeout so if we're
216          at zero we better just return zero and not make it a negative number
217          by the math below */
218       return 0;
219     break;
220   }
221
222   if(!nowp) {
223     now = Curl_tvnow();
224     nowp = &now;
225   }
226
227   /* subtract elapsed time */
228   timeout_ms -= Curl_tvdiff(*nowp, data->progress.t_startsingle);
229   if(!timeout_ms)
230     /* avoid returning 0 as that means no timeout! */
231     return -1;
232
233   return timeout_ms;
234 }
235
236 static CURLcode bindlocal(struct connectdata *conn,
237                           curl_socket_t sockfd, int af)
238 {
239   struct SessionHandle *data = conn->data;
240
241   struct Curl_sockaddr_storage sa;
242   struct sockaddr *sock = (struct sockaddr *)&sa;  /* bind to this address */
243   curl_socklen_t sizeof_sa = 0; /* size of the data sock points to */
244   struct sockaddr_in *si4 = (struct sockaddr_in *)&sa;
245 #ifdef ENABLE_IPV6
246   struct sockaddr_in6 *si6 = (struct sockaddr_in6 *)&sa;
247 #endif
248
249   struct Curl_dns_entry *h=NULL;
250   unsigned short port = data->set.localport; /* use this port number, 0 for
251                                                 "random" */
252   /* how many port numbers to try to bind to, increasing one at a time */
253   int portnum = data->set.localportrange;
254   const char *dev = data->set.str[STRING_DEVICE];
255   int error;
256   char myhost[256] = "";
257   int done = 0; /* -1 for error, 1 for address found */
258   bool is_interface = FALSE;
259   bool is_host = FALSE;
260   static const char *if_prefix = "if!";
261   static const char *host_prefix = "host!";
262
263   /*************************************************************
264    * Select device to bind socket to
265    *************************************************************/
266   if(!dev && !port)
267     /* no local kind of binding was requested */
268     return CURLE_OK;
269
270   memset(&sa, 0, sizeof(struct Curl_sockaddr_storage));
271
272   if(dev && (strlen(dev)<255) ) {
273     if(strncmp(if_prefix, dev, strlen(if_prefix)) == 0) {
274       dev += strlen(if_prefix);
275       is_interface = TRUE;
276     }
277     else if(strncmp(host_prefix, dev, strlen(host_prefix)) == 0) {
278       dev += strlen(host_prefix);
279       is_host = TRUE;
280     }
281
282     /* interface */
283     if(!is_host) {
284       switch(Curl_if2ip(af, conn->scope, dev, myhost, sizeof(myhost))) {
285         case IF2IP_NOT_FOUND:
286           if(is_interface) {
287             /* Do not fall back to treating it as a host name */
288             failf(data, "Couldn't bind to interface '%s'", dev);
289             return CURLE_INTERFACE_FAILED;
290           }
291           break;
292         case IF2IP_AF_NOT_SUPPORTED:
293           /* Signal the caller to try another address family if available */
294           return CURLE_UNSUPPORTED_PROTOCOL;
295         case IF2IP_FOUND:
296           is_interface = TRUE;
297           /*
298            * We now have the numerical IP address in the 'myhost' buffer
299            */
300           infof(data, "Local Interface %s is ip %s using address family %i\n",
301                 dev, myhost, af);
302           done = 1;
303
304 #ifdef SO_BINDTODEVICE
305           /* I am not sure any other OSs than Linux that provide this feature,
306            * and at the least I cannot test. --Ben
307            *
308            * This feature allows one to tightly bind the local socket to a
309            * particular interface.  This will force even requests to other
310            * local interfaces to go out the external interface.
311            *
312            *
313            * Only bind to the interface when specified as interface, not just
314            * as a hostname or ip address.
315            */
316           if(setsockopt(sockfd, SOL_SOCKET, SO_BINDTODEVICE,
317                         dev, (curl_socklen_t)strlen(dev)+1) != 0) {
318             error = SOCKERRNO;
319             infof(data, "SO_BINDTODEVICE %s failed with errno %d: %s;"
320                   " will do regular bind\n",
321                   dev, error, Curl_strerror(conn, error));
322             /* This is typically "errno 1, error: Operation not permitted" if
323                you're not running as root or another suitable privileged
324                user */
325           }
326 #endif
327           break;
328       }
329     }
330     if(!is_interface) {
331       /*
332        * This was not an interface, resolve the name as a host name
333        * or IP number
334        *
335        * Temporarily force name resolution to use only the address type
336        * of the connection. The resolve functions should really be changed
337        * to take a type parameter instead.
338        */
339       long ipver = conn->ip_version;
340       int rc;
341
342       if(af == AF_INET)
343         conn->ip_version = CURL_IPRESOLVE_V4;
344 #ifdef ENABLE_IPV6
345       else if(af == AF_INET6)
346         conn->ip_version = CURL_IPRESOLVE_V6;
347 #endif
348
349       rc = Curl_resolv(conn, dev, 0, &h);
350       if(rc == CURLRESOLV_PENDING)
351         (void)Curl_resolver_wait_resolv(conn, &h);
352       conn->ip_version = ipver;
353
354       if(h) {
355         /* convert the resolved address, sizeof myhost >= INET_ADDRSTRLEN */
356         Curl_printable_address(h->addr, myhost, sizeof(myhost));
357         infof(data, "Name '%s' family %i resolved to '%s' family %i\n",
358               dev, af, myhost, h->addr->ai_family);
359         Curl_resolv_unlock(data, h);
360         done = 1;
361       }
362       else {
363         /*
364          * provided dev was no interface (or interfaces are not supported
365          * e.g. solaris) no ip address and no domain we fail here
366          */
367         done = -1;
368       }
369     }
370
371     if(done > 0) {
372 #ifdef ENABLE_IPV6
373       /* ipv6 address */
374       if(af == AF_INET6) {
375 #ifdef HAVE_SOCKADDR_IN6_SIN6_SCOPE_ID
376         char *scope_ptr = strchr(myhost, '%');
377         if(scope_ptr)
378           *(scope_ptr++) = 0;
379 #endif
380         if(Curl_inet_pton(AF_INET6, myhost, &si6->sin6_addr) > 0) {
381           si6->sin6_family = AF_INET6;
382           si6->sin6_port = htons(port);
383 #ifdef HAVE_SOCKADDR_IN6_SIN6_SCOPE_ID
384           if(scope_ptr)
385             /* The "myhost" string either comes from Curl_if2ip or from
386                Curl_printable_address. The latter returns only numeric scope
387                IDs and the former returns none at all.  So the scope ID, if
388                present, is known to be numeric */
389             si6->sin6_scope_id = atoi(scope_ptr);
390 #endif
391         }
392         sizeof_sa = sizeof(struct sockaddr_in6);
393       }
394       else
395 #endif
396       /* ipv4 address */
397       if((af == AF_INET) &&
398          (Curl_inet_pton(AF_INET, myhost, &si4->sin_addr) > 0)) {
399         si4->sin_family = AF_INET;
400         si4->sin_port = htons(port);
401         sizeof_sa = sizeof(struct sockaddr_in);
402       }
403     }
404
405     if(done < 1) {
406       failf(data, "Couldn't bind to '%s'", dev);
407       return CURLE_INTERFACE_FAILED;
408     }
409   }
410   else {
411     /* no device was given, prepare sa to match af's needs */
412 #ifdef ENABLE_IPV6
413     if(af == AF_INET6) {
414       si6->sin6_family = AF_INET6;
415       si6->sin6_port = htons(port);
416       sizeof_sa = sizeof(struct sockaddr_in6);
417     }
418     else
419 #endif
420     if(af == AF_INET) {
421       si4->sin_family = AF_INET;
422       si4->sin_port = htons(port);
423       sizeof_sa = sizeof(struct sockaddr_in);
424     }
425   }
426
427   for(;;) {
428     if(bind(sockfd, sock, sizeof_sa) >= 0) {
429       /* we succeeded to bind */
430       struct Curl_sockaddr_storage add;
431       curl_socklen_t size = sizeof(add);
432       memset(&add, 0, sizeof(struct Curl_sockaddr_storage));
433       if(getsockname(sockfd, (struct sockaddr *) &add, &size) < 0) {
434         data->state.os_errno = error = SOCKERRNO;
435         failf(data, "getsockname() failed with errno %d: %s",
436               error, Curl_strerror(conn, error));
437         return CURLE_INTERFACE_FAILED;
438       }
439       infof(data, "Local port: %hu\n", port);
440       conn->bits.bound = TRUE;
441       return CURLE_OK;
442     }
443
444     if(--portnum > 0) {
445       infof(data, "Bind to local port %hu failed, trying next\n", port);
446       port++; /* try next port */
447       /* We re-use/clobber the port variable here below */
448       if(sock->sa_family == AF_INET)
449         si4->sin_port = ntohs(port);
450 #ifdef ENABLE_IPV6
451       else
452         si6->sin6_port = ntohs(port);
453 #endif
454     }
455     else
456       break;
457   }
458
459   data->state.os_errno = error = SOCKERRNO;
460   failf(data, "bind failed with errno %d: %s",
461         error, Curl_strerror(conn, error));
462
463   return CURLE_INTERFACE_FAILED;
464 }
465
466 /*
467  * verifyconnect() returns TRUE if the connect really has happened.
468  */
469 static bool verifyconnect(curl_socket_t sockfd, int *error)
470 {
471   bool rc = TRUE;
472 #ifdef SO_ERROR
473   int err = 0;
474   curl_socklen_t errSize = sizeof(err);
475
476 #ifdef WIN32
477   /*
478    * In October 2003 we effectively nullified this function on Windows due to
479    * problems with it using all CPU in multi-threaded cases.
480    *
481    * In May 2004, we bring it back to offer more info back on connect failures.
482    * Gisle Vanem could reproduce the former problems with this function, but
483    * could avoid them by adding this SleepEx() call below:
484    *
485    *    "I don't have Rational Quantify, but the hint from his post was
486    *    ntdll::NtRemoveIoCompletion(). So I'd assume the SleepEx (or maybe
487    *    just Sleep(0) would be enough?) would release whatever
488    *    mutex/critical-section the ntdll call is waiting on.
489    *
490    *    Someone got to verify this on Win-NT 4.0, 2000."
491    */
492
493 #ifdef _WIN32_WCE
494   Sleep(0);
495 #else
496   SleepEx(0, FALSE);
497 #endif
498
499 #endif
500
501   if(0 != getsockopt(sockfd, SOL_SOCKET, SO_ERROR, (void *)&err, &errSize))
502     err = SOCKERRNO;
503 #ifdef _WIN32_WCE
504   /* Old WinCE versions don't support SO_ERROR */
505   if(WSAENOPROTOOPT == err) {
506     SET_SOCKERRNO(0);
507     err = 0;
508   }
509 #endif
510 #ifdef __minix
511   /* Minix 3.1.x doesn't support getsockopt on UDP sockets */
512   if(EBADIOCTL == err) {
513     SET_SOCKERRNO(0);
514     err = 0;
515   }
516 #endif
517   if((0 == err) || (EISCONN == err))
518     /* we are connected, awesome! */
519     rc = TRUE;
520   else
521     /* This wasn't a successful connect */
522     rc = FALSE;
523   if(error)
524     *error = err;
525 #else
526   (void)sockfd;
527   if(error)
528     *error = SOCKERRNO;
529 #endif
530   return rc;
531 }
532
533 /* Used within the multi interface. Try next IP address, return TRUE if no
534    more address exists or error */
535 static CURLcode trynextip(struct connectdata *conn,
536                           int sockindex,
537                           int tempindex,
538                           bool *connected)
539 {
540   curl_socket_t sockfd;
541   Curl_addrinfo *ai;
542   int family = tempindex ? AF_INET6 : AF_INET;
543
544   /* First clean up after the failed socket.
545      Don't close it yet to ensure that the next IP's socket gets a different
546      file descriptor, which can prevent bugs when the curl_multi_socket_action
547      interface is used with certain select() replacements such as kqueue. */
548   curl_socket_t fd_to_close = conn->tempsock[tempindex];
549   conn->tempsock[tempindex] = CURL_SOCKET_BAD;
550   *connected = FALSE;
551
552   if(sockindex != FIRSTSOCKET) {
553     Curl_closesocket(conn, fd_to_close);
554     return CURLE_COULDNT_CONNECT; /* no next */
555   }
556
557   /* try the next address with same family */
558   ai = conn->tempaddr[tempindex]->ai_next;
559   while(ai && ai->ai_family != family)
560     ai = ai->ai_next;
561
562   while(ai && ai->ai_family == family) {
563     CURLcode res = singleipconnect(conn, ai, &sockfd, connected);
564     if(res)
565       return res;
566     if(sockfd != CURL_SOCKET_BAD) {
567       /* store the new socket descriptor */
568       conn->tempsock[tempindex] = sockfd;
569       conn->tempaddr[tempindex] = ai;
570       Curl_closesocket(conn, fd_to_close);
571       return CURLE_OK;
572     }
573
574     do {
575       ai = ai->ai_next;
576     } while(ai && ai->ai_family == family);
577   }
578   Curl_closesocket(conn, fd_to_close);
579   return CURLE_COULDNT_CONNECT;
580 }
581
582 /* Copies connection info into the session handle to make it available
583    when the session handle is no longer associated with a connection. */
584 void Curl_persistconninfo(struct connectdata *conn)
585 {
586   memcpy(conn->data->info.conn_primary_ip, conn->primary_ip, MAX_IPADR_LEN);
587   memcpy(conn->data->info.conn_local_ip, conn->local_ip, MAX_IPADR_LEN);
588   conn->data->info.conn_primary_port = conn->primary_port;
589   conn->data->info.conn_local_port = conn->local_port;
590 }
591
592 /* retrieves ip address and port from a sockaddr structure */
593 static bool getaddressinfo(struct sockaddr* sa, char* addr,
594                            long* port)
595 {
596   unsigned short us_port;
597   struct sockaddr_in* si = NULL;
598 #ifdef ENABLE_IPV6
599   struct sockaddr_in6* si6 = NULL;
600 #endif
601 #if defined(HAVE_SYS_UN_H) && defined(AF_UNIX)
602   struct sockaddr_un* su = NULL;
603 #endif
604
605   switch (sa->sa_family) {
606     case AF_INET:
607       si = (struct sockaddr_in*) sa;
608       if(Curl_inet_ntop(sa->sa_family, &si->sin_addr,
609                         addr, MAX_IPADR_LEN)) {
610         us_port = ntohs(si->sin_port);
611         *port = us_port;
612         return TRUE;
613       }
614       break;
615 #ifdef ENABLE_IPV6
616     case AF_INET6:
617       si6 = (struct sockaddr_in6*)sa;
618       if(Curl_inet_ntop(sa->sa_family, &si6->sin6_addr,
619                         addr, MAX_IPADR_LEN)) {
620         us_port = ntohs(si6->sin6_port);
621         *port = us_port;
622         return TRUE;
623       }
624       break;
625 #endif
626 #if defined(HAVE_SYS_UN_H) && defined(AF_UNIX)
627     case AF_UNIX:
628       su = (struct sockaddr_un*)sa;
629       snprintf(addr, MAX_IPADR_LEN, "%s", su->sun_path);
630       *port = 0;
631       return TRUE;
632 #endif
633     default:
634       break;
635   }
636
637   addr[0] = '\0';
638   *port = 0;
639
640   return FALSE;
641 }
642
643 /* retrieves the start/end point information of a socket of an established
644    connection */
645 void Curl_updateconninfo(struct connectdata *conn, curl_socket_t sockfd)
646 {
647   int error;
648   curl_socklen_t len;
649   struct Curl_sockaddr_storage ssrem;
650   struct Curl_sockaddr_storage ssloc;
651   struct SessionHandle *data = conn->data;
652
653   if(!conn->bits.reuse) {
654
655     len = sizeof(struct Curl_sockaddr_storage);
656     if(getpeername(sockfd, (struct sockaddr*) &ssrem, &len)) {
657       error = SOCKERRNO;
658       failf(data, "getpeername() failed with errno %d: %s",
659             error, Curl_strerror(conn, error));
660       return;
661     }
662
663     len = sizeof(struct Curl_sockaddr_storage);
664     if(getsockname(sockfd, (struct sockaddr*) &ssloc, &len)) {
665       error = SOCKERRNO;
666       failf(data, "getsockname() failed with errno %d: %s",
667             error, Curl_strerror(conn, error));
668       return;
669     }
670
671     if(!getaddressinfo((struct sockaddr*)&ssrem,
672                         conn->primary_ip, &conn->primary_port)) {
673       error = ERRNO;
674       failf(data, "ssrem inet_ntop() failed with errno %d: %s",
675             error, Curl_strerror(conn, error));
676       return;
677     }
678     memcpy(conn->ip_addr_str, conn->primary_ip, MAX_IPADR_LEN);
679
680     if(!getaddressinfo((struct sockaddr*)&ssloc,
681                        conn->local_ip, &conn->local_port)) {
682       error = ERRNO;
683       failf(data, "ssloc inet_ntop() failed with errno %d: %s",
684             error, Curl_strerror(conn, error));
685       return;
686     }
687
688   }
689
690   /* persist connection info in session handle */
691   Curl_persistconninfo(conn);
692 }
693
694 /*
695  * Curl_is_connected() checks if the socket has connected.
696  */
697
698 CURLcode Curl_is_connected(struct connectdata *conn,
699                            int sockindex,
700                            bool *connected)
701 {
702   struct SessionHandle *data = conn->data;
703   CURLcode code = CURLE_OK;
704   long allow = DEFAULT_CONNECT_TIMEOUT;
705   int error = 0;
706   struct timeval now;
707   int result;
708   int i;
709
710   DEBUGASSERT(sockindex >= FIRSTSOCKET && sockindex <= SECONDARYSOCKET);
711
712   *connected = FALSE; /* a very negative world view is best */
713
714   if(conn->bits.tcpconnect[sockindex]) {
715     /* we are connected already! */
716     *connected = TRUE;
717     return CURLE_OK;
718   }
719
720   now = Curl_tvnow();
721
722   /* figure out how long time we have left to connect */
723   allow = Curl_timeleft(data, &now, TRUE);
724
725   if(allow < 0) {
726     /* time-out, bail out, go home */
727     failf(data, "Connection time-out");
728     return CURLE_OPERATION_TIMEDOUT;
729   }
730
731   for(i=0; i<2; i++) {
732     if(conn->tempsock[i] == CURL_SOCKET_BAD)
733       continue;
734
735 #ifdef mpeix
736     /* Call this function once now, and ignore the results. We do this to
737        "clear" the error state on the socket so that we can later read it
738        reliably. This is reported necessary on the MPE/iX operating system. */
739     (void)verifyconnect(conn->tempsock[i], NULL);
740 #endif
741
742     /* check socket for connect */
743     result = Curl_socket_ready(CURL_SOCKET_BAD, conn->tempsock[i], 0);
744
745     switch(result) {
746     case 0: /* no connection yet */
747       if(curlx_tvdiff(now, conn->connecttime) >= conn->timeoutms_per_addr) {
748         infof(data, "After %ldms connect time, move on!\n",
749               conn->timeoutms_per_addr);
750         break;
751       }
752       return CURLE_OK;
753
754     case CURL_CSELECT_OUT:
755       if(verifyconnect(conn->tempsock[i], &error)) {
756         /* we are connected with TCP, awesome! */
757         int other = i ^ 1;
758
759         /* use this socket from now on */
760         conn->sock[sockindex] = conn->tempsock[i];
761         conn->ip_addr = conn->tempaddr[i];
762
763         /* close the other socket, if open */
764         if(conn->tempsock[other] != CURL_SOCKET_BAD) {
765           if(conn->fclosesocket)
766             conn->fclosesocket(conn->closesocket_client,
767                                conn->tempsock[other]);
768           else
769             sclose(conn->tempsock[other]);
770         }
771
772         /* see if we need to do any proxy magic first once we connected */
773         code = Curl_connected_proxy(conn, sockindex);
774         if(code)
775           return code;
776
777         conn->bits.tcpconnect[sockindex] = TRUE;
778
779         *connected = TRUE;
780         if(sockindex == FIRSTSOCKET)
781           Curl_pgrsTime(data, TIMER_CONNECT); /* connect done */
782         Curl_updateconninfo(conn, conn->sock[sockindex]);
783         Curl_verboseconnect(conn);
784
785         return CURLE_OK;
786       }
787       else
788         infof(data, "Connection failed\n");
789       break;
790
791     case CURL_CSELECT_ERR|CURL_CSELECT_OUT:
792       (void)verifyconnect(conn->tempsock[i], &error);
793       break;
794
795     default:
796       infof(data, "Whut?\n");
797       return CURLE_OK;
798     }
799
800     /*
801      * The connection failed here, we should attempt to connect to the "next
802      * address" for the given host. But first remember the latest error.
803      */
804     if(error) {
805       data->state.os_errno = error;
806       SET_SOCKERRNO(error);
807     }
808
809     conn->timeoutms_per_addr = conn->tempaddr[i]->ai_next == NULL ?
810                                allow : allow / 2;
811     code = trynextip(conn, sockindex, i, connected);
812
813     if(code) {
814       error = SOCKERRNO;
815       data->state.os_errno = error;
816       failf(data, "Failed connect to %s:%ld; %s",
817             conn->host.name, conn->port, Curl_strerror(conn, error));
818     }
819   }
820
821   return code;
822 }
823
824 static void tcpnodelay(struct connectdata *conn,
825                        curl_socket_t sockfd)
826 {
827 #ifdef TCP_NODELAY
828   struct SessionHandle *data= conn->data;
829   curl_socklen_t onoff = (curl_socklen_t) data->set.tcp_nodelay;
830   int level = IPPROTO_TCP;
831
832 #if 0
833   /* The use of getprotobyname() is disabled since it isn't thread-safe on
834      numerous systems. On these getprotobyname_r() should be used instead, but
835      that exists in at least one 4 arg version and one 5 arg version, and
836      since the proto number rarely changes anyway we now just use the hard
837      coded number. The "proper" fix would need a configure check for the
838      correct function much in the same style the gethostbyname_r versions are
839      detected. */
840   struct protoent *pe = getprotobyname("tcp");
841   if(pe)
842     level = pe->p_proto;
843 #endif
844
845   if(setsockopt(sockfd, level, TCP_NODELAY, (void *)&onoff,
846                 sizeof(onoff)) < 0)
847     infof(data, "Could not set TCP_NODELAY: %s\n",
848           Curl_strerror(conn, SOCKERRNO));
849   else
850     infof(data,"TCP_NODELAY set\n");
851 #else
852   (void)conn;
853   (void)sockfd;
854 #endif
855 }
856
857 #ifdef SO_NOSIGPIPE
858 /* The preferred method on Mac OS X (10.2 and later) to prevent SIGPIPEs when
859    sending data to a dead peer (instead of relying on the 4th argument to send
860    being MSG_NOSIGNAL). Possibly also existing and in use on other BSD
861    systems? */
862 static void nosigpipe(struct connectdata *conn,
863                       curl_socket_t sockfd)
864 {
865   struct SessionHandle *data= conn->data;
866   int onoff = 1;
867   if(setsockopt(sockfd, SOL_SOCKET, SO_NOSIGPIPE, (void *)&onoff,
868                 sizeof(onoff)) < 0)
869     infof(data, "Could not set SO_NOSIGPIPE: %s\n",
870           Curl_strerror(conn, SOCKERRNO));
871 }
872 #else
873 #define nosigpipe(x,y) Curl_nop_stmt
874 #endif
875
876 #ifdef USE_WINSOCK
877 /* When you run a program that uses the Windows Sockets API, you may
878    experience slow performance when you copy data to a TCP server.
879
880    http://support.microsoft.com/kb/823764
881
882    Work-around: Make the Socket Send Buffer Size Larger Than the Program Send
883    Buffer Size
884
885    The problem described in this knowledge-base is applied only to pre-Vista
886    Windows.  Following function trying to detect OS version and skips
887    SO_SNDBUF adjustment for Windows Vista and above.
888 */
889 #define DETECT_OS_NONE 0
890 #define DETECT_OS_PREVISTA 1
891 #define DETECT_OS_VISTA_OR_LATER 2
892
893 void Curl_sndbufset(curl_socket_t sockfd)
894 {
895   int val = CURL_MAX_WRITE_SIZE + 32;
896   int curval = 0;
897   int curlen = sizeof(curval);
898
899   OSVERSIONINFO osver;
900   static int detectOsState = DETECT_OS_NONE;
901
902   if(detectOsState == DETECT_OS_NONE) {
903     memset(&osver, 0, sizeof(osver));
904     osver.dwOSVersionInfoSize = sizeof(osver);
905     detectOsState = DETECT_OS_PREVISTA;
906     if(GetVersionEx(&osver)) {
907       if(osver.dwMajorVersion >= 6)
908         detectOsState = DETECT_OS_VISTA_OR_LATER;
909     }
910   }
911   if(detectOsState == DETECT_OS_VISTA_OR_LATER)
912     return;
913
914   if(getsockopt(sockfd, SOL_SOCKET, SO_SNDBUF, (char *)&curval, &curlen) == 0)
915     if(curval > val)
916       return;
917
918   setsockopt(sockfd, SOL_SOCKET, SO_SNDBUF, (const char *)&val, sizeof(val));
919 }
920 #endif
921
922
923 /*
924  * singleipconnect()
925  *
926  * Note that even on connect fail it returns CURLE_OK, but with 'sock' set to
927  * CURL_SOCKET_BAD. Other errors will however return proper errors.
928  *
929  * singleipconnect() connects to the given IP only, and it may return without
930  * having connected.
931  */
932 static CURLcode
933 singleipconnect(struct connectdata *conn,
934                 const Curl_addrinfo *ai,
935                 curl_socket_t *sockp,
936                 bool *connected)
937 {
938   struct Curl_sockaddr_ex addr;
939   int rc;
940   int error = 0;
941   bool isconnected = FALSE;
942   struct SessionHandle *data = conn->data;
943   curl_socket_t sockfd;
944   CURLcode res = CURLE_OK;
945   char ipaddress[MAX_IPADR_LEN];
946   long port;
947
948   *sockp = CURL_SOCKET_BAD;
949   *connected = FALSE; /* default is not connected */
950
951   res = Curl_socket(conn, ai, &addr, &sockfd);
952   if(res)
953     /* Failed to create the socket, but still return OK since we signal the
954        lack of socket as well. This allows the parent function to keep looping
955        over alternative addresses/socket families etc. */
956     return CURLE_OK;
957
958   /* store remote address and port used in this connection attempt */
959   if(!getaddressinfo((struct sockaddr*)&addr.sa_addr,
960                      ipaddress, &port)) {
961     /* malformed address or bug in inet_ntop, try next address */
962     error = ERRNO;
963     failf(data, "sa_addr inet_ntop() failed with errno %d: %s",
964           error, Curl_strerror(conn, error));
965     Curl_closesocket(conn, sockfd);
966     return CURLE_OK;
967   }
968   infof(data, "  Trying %s...\n", ipaddress);
969
970   if(data->set.tcp_nodelay)
971     tcpnodelay(conn, sockfd);
972
973   nosigpipe(conn, sockfd);
974
975   Curl_sndbufset(sockfd);
976
977   if(data->set.tcp_keepalive)
978     tcpkeepalive(data, sockfd);
979
980   if(data->set.fsockopt) {
981     /* activate callback for setting socket options */
982     error = data->set.fsockopt(data->set.sockopt_client,
983                                sockfd,
984                                CURLSOCKTYPE_IPCXN);
985
986     if(error == CURL_SOCKOPT_ALREADY_CONNECTED)
987       isconnected = TRUE;
988     else if(error) {
989       Curl_closesocket(conn, sockfd); /* close the socket and bail out */
990       return CURLE_ABORTED_BY_CALLBACK;
991     }
992   }
993
994   /* possibly bind the local end to an IP, interface or port */
995   res = bindlocal(conn, sockfd, addr.family);
996   if(res) {
997     Curl_closesocket(conn, sockfd); /* close socket and bail out */
998     if(res == CURLE_UNSUPPORTED_PROTOCOL) {
999       /* The address family is not supported on this interface.
1000          We can continue trying addresses */
1001       return CURLE_OK;
1002     }
1003     return res;
1004   }
1005
1006   /* set socket non-blocking */
1007   curlx_nonblock(sockfd, TRUE);
1008
1009   conn->connecttime = Curl_tvnow();
1010   if(conn->num_addr > 1)
1011     Curl_expire(data, conn->timeoutms_per_addr);
1012
1013   /* Connect TCP sockets, bind UDP */
1014   if(!isconnected && (conn->socktype == SOCK_STREAM)) {
1015     rc = connect(sockfd, &addr.sa_addr, addr.addrlen);
1016     if(-1 == rc)
1017       error = SOCKERRNO;
1018   }
1019   else {
1020     *sockp = sockfd;
1021     return CURLE_OK;
1022   }
1023
1024 #ifdef ENABLE_IPV6
1025   conn->bits.ipv6 = (addr.family == AF_INET6)?TRUE:FALSE;
1026 #endif
1027
1028   if(-1 == rc) {
1029     switch (error) {
1030     case EINPROGRESS:
1031     case EWOULDBLOCK:
1032 #if defined(EAGAIN)
1033 #if (EAGAIN) != (EWOULDBLOCK)
1034       /* On some platforms EAGAIN and EWOULDBLOCK are the
1035        * same value, and on others they are different, hence
1036        * the odd #if
1037        */
1038     case EAGAIN:
1039 #endif
1040 #endif
1041       *sockp = sockfd;
1042       return CURLE_OK;
1043
1044     default:
1045       /* unknown error, fallthrough and try another address! */
1046       failf(data, "Failed to connect to %s: %s",
1047             conn->ip_addr_str, Curl_strerror(conn,error));
1048       data->state.os_errno = error;
1049
1050       /* connect failed */
1051       Curl_closesocket(conn, sockfd);
1052
1053       break;
1054     }
1055   }
1056   else
1057     *sockp = sockfd;
1058
1059   return CURLE_OK;
1060 }
1061
1062 /*
1063  * TCP connect to the given host with timeout, proxy or remote doesn't matter.
1064  * There might be more than one IP address to try out. Fill in the passed
1065  * pointer with the connected socket.
1066  */
1067
1068 CURLcode Curl_connecthost(struct connectdata *conn,  /* context */
1069                           const struct Curl_dns_entry *remotehost,
1070                           bool *connected)           /* really connected? */
1071 {
1072   struct SessionHandle *data = conn->data;
1073   struct timeval after;
1074   struct timeval before = Curl_tvnow();
1075   int i;
1076
1077   /*************************************************************
1078    * Figure out what maximum time we have left
1079    *************************************************************/
1080   long timeout_ms;
1081
1082   *connected = FALSE; /* default to not connected */
1083
1084   /* get the timeout left */
1085   timeout_ms = Curl_timeleft(data, &before, TRUE);
1086
1087   if(timeout_ms < 0) {
1088     /* a precaution, no need to continue if time already is up */
1089     failf(data, "Connection time-out");
1090     return CURLE_OPERATION_TIMEDOUT;
1091   }
1092
1093   conn->num_addr = Curl_num_addresses(remotehost->addr);
1094   conn->tempaddr[0] = remotehost->addr;
1095   conn->tempaddr[1] = remotehost->addr;
1096
1097   /* Below is the loop that attempts to connect to all IP-addresses we
1098    * know for the given host.
1099    * One by one, for each protocol, until one IP succeeds.
1100    */
1101
1102   for(i=0; i<2; i++) {
1103     curl_socket_t sockfd = CURL_SOCKET_BAD;
1104     Curl_addrinfo *ai = conn->tempaddr[i];
1105     int family = i ? AF_INET6 : AF_INET;
1106
1107     /* find first address for this address family, if any */
1108     while(ai && ai->ai_family != family)
1109       ai = ai->ai_next;
1110
1111     /*
1112      * Connecting with a Curl_addrinfo chain
1113      */
1114     while(ai) {
1115       CURLcode res;
1116
1117       /* Max time for the next connection attempt */
1118       conn->timeoutms_per_addr = ai->ai_next == NULL ?
1119                                  timeout_ms : timeout_ms / 2;
1120
1121       /* start connecting to the IP curr_addr points to */
1122       res = singleipconnect(conn, ai, &sockfd, connected);
1123       if(res)
1124         return res;
1125
1126       if(sockfd != CURL_SOCKET_BAD)
1127         break;
1128
1129       /* get a new timeout for next attempt */
1130       after = Curl_tvnow();
1131       timeout_ms -= Curl_tvdiff(after, before);
1132       if(timeout_ms < 0) {
1133         failf(data, "connect() timed out!");
1134         return CURLE_OPERATION_TIMEDOUT;
1135       }
1136       before = after;
1137
1138       /* next addresses */
1139       do {
1140         ai = ai->ai_next;
1141       } while(ai && ai->ai_family != family);
1142     }  /* end of connect-to-each-address loop */
1143
1144     conn->tempsock[i] = sockfd;
1145     conn->tempaddr[i] = ai;
1146   }
1147
1148   if((conn->tempsock[0] == CURL_SOCKET_BAD) &&
1149      (conn->tempsock[1] == CURL_SOCKET_BAD)) {
1150     /* no good connect was made */
1151     failf(data, "couldn't connect to %s at %s:%ld",
1152           conn->bits.proxy?"proxy":"host",
1153           conn->bits.proxy?conn->proxy.name:conn->host.name, conn->port);
1154     return CURLE_COULDNT_CONNECT;
1155   }
1156
1157   /* leave the socket in non-blocking mode */
1158
1159   data->info.numconnects++; /* to track the number of connections made */
1160
1161   return CURLE_OK;
1162 }
1163
1164 struct connfind {
1165   struct connectdata *tofind;
1166   bool found;
1167 };
1168
1169 static int conn_is_conn(struct connectdata *conn, void *param)
1170 {
1171   struct connfind *f = (struct connfind *)param;
1172   if(conn == f->tofind) {
1173     f->found = TRUE;
1174     return 1;
1175   }
1176   return 0;
1177 }
1178
1179 /*
1180  * Used to extract socket and connectdata struct for the most recent
1181  * transfer on the given SessionHandle.
1182  *
1183  * The returned socket will be CURL_SOCKET_BAD in case of failure!
1184  */
1185 curl_socket_t Curl_getconnectinfo(struct SessionHandle *data,
1186                                   struct connectdata **connp)
1187 {
1188   curl_socket_t sockfd;
1189
1190   DEBUGASSERT(data);
1191
1192   /* this only works for an easy handle that has been used for
1193      curl_easy_perform()! */
1194   if(data->state.lastconnect && data->multi_easy) {
1195     struct connectdata *c = data->state.lastconnect;
1196     struct connfind find;
1197     find.tofind = data->state.lastconnect;
1198     find.found = FALSE;
1199
1200     Curl_conncache_foreach(data->multi_easy->conn_cache, &find, conn_is_conn);
1201
1202     if(!find.found) {
1203       data->state.lastconnect = NULL;
1204       return CURL_SOCKET_BAD;
1205     }
1206
1207     if(connp)
1208       /* only store this if the caller cares for it */
1209       *connp = c;
1210     sockfd = c->sock[FIRSTSOCKET];
1211     /* we have a socket connected, let's determine if the server shut down */
1212     /* determine if ssl */
1213     if(c->ssl[FIRSTSOCKET].use) {
1214       /* use the SSL context */
1215       if(!Curl_ssl_check_cxn(c))
1216         return CURL_SOCKET_BAD;   /* FIN received */
1217     }
1218 /* Minix 3.1 doesn't support any flags on recv; just assume socket is OK */
1219 #ifdef MSG_PEEK
1220     else {
1221       /* use the socket */
1222       char buf;
1223       if(recv((RECV_TYPE_ARG1)c->sock[FIRSTSOCKET], (RECV_TYPE_ARG2)&buf,
1224               (RECV_TYPE_ARG3)1, (RECV_TYPE_ARG4)MSG_PEEK) == 0) {
1225         return CURL_SOCKET_BAD;   /* FIN received */
1226       }
1227     }
1228 #endif
1229   }
1230   else
1231     return CURL_SOCKET_BAD;
1232
1233   return sockfd;
1234 }
1235
1236 /*
1237  * Close a socket.
1238  *
1239  * 'conn' can be NULL, beware!
1240  */
1241 int Curl_closesocket(struct connectdata *conn,
1242                       curl_socket_t sock)
1243 {
1244   if(conn && conn->fclosesocket) {
1245     if((sock == conn->sock[SECONDARYSOCKET]) &&
1246        conn->sock_accepted[SECONDARYSOCKET])
1247       /* if this socket matches the second socket, and that was created with
1248          accept, then we MUST NOT call the callback but clear the accepted
1249          status */
1250       conn->sock_accepted[SECONDARYSOCKET] = FALSE;
1251     else
1252       return conn->fclosesocket(conn->closesocket_client, sock);
1253   }
1254   sclose(sock);
1255
1256   if(conn)
1257     /* tell the multi-socket code about this */
1258     Curl_multi_closed(conn, sock);
1259
1260   return 0;
1261 }
1262
1263 /*
1264  * Create a socket based on info from 'conn' and 'ai'.
1265  *
1266  * 'addr' should be a pointer to the correct struct to get data back, or NULL.
1267  * 'sockfd' must be a pointer to a socket descriptor.
1268  *
1269  * If the open socket callback is set, used that!
1270  *
1271  */
1272 CURLcode Curl_socket(struct connectdata *conn,
1273                      const Curl_addrinfo *ai,
1274                      struct Curl_sockaddr_ex *addr,
1275                      curl_socket_t *sockfd)
1276 {
1277   struct SessionHandle *data = conn->data;
1278   struct Curl_sockaddr_ex dummy;
1279
1280   if(!addr)
1281     /* if the caller doesn't want info back, use a local temp copy */
1282     addr = &dummy;
1283
1284   /*
1285    * The Curl_sockaddr_ex structure is basically libcurl's external API
1286    * curl_sockaddr structure with enough space available to directly hold
1287    * any protocol-specific address structures. The variable declared here
1288    * will be used to pass / receive data to/from the fopensocket callback
1289    * if this has been set, before that, it is initialized from parameters.
1290    */
1291
1292   addr->family = ai->ai_family;
1293   addr->socktype = conn->socktype;
1294   addr->protocol = conn->socktype==SOCK_DGRAM?IPPROTO_UDP:ai->ai_protocol;
1295   addr->addrlen = ai->ai_addrlen;
1296
1297   if(addr->addrlen > sizeof(struct Curl_sockaddr_storage))
1298      addr->addrlen = sizeof(struct Curl_sockaddr_storage);
1299   memcpy(&addr->sa_addr, ai->ai_addr, addr->addrlen);
1300
1301   if(data->set.fopensocket)
1302    /*
1303     * If the opensocket callback is set, all the destination address
1304     * information is passed to the callback. Depending on this information the
1305     * callback may opt to abort the connection, this is indicated returning
1306     * CURL_SOCKET_BAD; otherwise it will return a not-connected socket. When
1307     * the callback returns a valid socket the destination address information
1308     * might have been changed and this 'new' address will actually be used
1309     * here to connect.
1310     */
1311     *sockfd = data->set.fopensocket(data->set.opensocket_client,
1312                                     CURLSOCKTYPE_IPCXN,
1313                                     (struct curl_sockaddr *)addr);
1314   else
1315     /* opensocket callback not set, so simply create the socket now */
1316     *sockfd = socket(addr->family, addr->socktype, addr->protocol);
1317
1318   if(*sockfd == CURL_SOCKET_BAD)
1319     /* no socket, no connection */
1320     return CURLE_COULDNT_CONNECT;
1321
1322 #if defined(ENABLE_IPV6) && defined(HAVE_SOCKADDR_IN6_SIN6_SCOPE_ID)
1323   if(conn->scope && (addr->family == AF_INET6)) {
1324     struct sockaddr_in6 * const sa6 = (void *)&addr->sa_addr;
1325     sa6->sin6_scope_id = conn->scope;
1326   }
1327 #endif
1328
1329   return CURLE_OK;
1330
1331 }