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