connect: Fixed "Whut?" no server connection failures
[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     if(result == 0) { /* no connection yet */
746       if(curlx_tvdiff(now, conn->connecttime) >= conn->timeoutms_per_addr) {
747         infof(data, "After %ldms connect time, move on!\n",
748               conn->timeoutms_per_addr);
749         error = ETIMEDOUT;
750       }
751     }
752     else if(result == CURL_CSELECT_OUT) {
753       if(verifyconnect(conn->tempsock[i], &error)) {
754         /* we are connected with TCP, awesome! */
755         int other = i ^ 1;
756
757         /* use this socket from now on */
758         conn->sock[sockindex] = conn->tempsock[i];
759         conn->ip_addr = conn->tempaddr[i];
760
761         /* close the other socket, if open */
762         if(conn->tempsock[other] != CURL_SOCKET_BAD) {
763           if(conn->fclosesocket)
764             conn->fclosesocket(conn->closesocket_client,
765                                conn->tempsock[other]);
766           else
767             sclose(conn->tempsock[other]);
768         }
769
770         /* see if we need to do any proxy magic first once we connected */
771         code = Curl_connected_proxy(conn, sockindex);
772         if(code)
773           return code;
774
775         conn->bits.tcpconnect[sockindex] = TRUE;
776
777         *connected = TRUE;
778         if(sockindex == FIRSTSOCKET)
779           Curl_pgrsTime(data, TIMER_CONNECT); /* connect done */
780         Curl_updateconninfo(conn, conn->sock[sockindex]);
781         Curl_verboseconnect(conn);
782
783         return CURLE_OK;
784       }
785       else
786         infof(data, "Connection failed\n");
787     }
788     else if((result & CURL_CSELECT_ERR) == CURL_CSELECT_ERR)
789       (void)verifyconnect(conn->tempsock[i], &error);
790
791     /*
792      * The connection failed here, we should attempt to connect to the "next
793      * address" for the given host. But first remember the latest error.
794      */
795     if(error) {
796       char ipaddress[MAX_IPADR_LEN];
797       data->state.os_errno = error;
798       SET_SOCKERRNO(error);
799       Curl_printable_address(conn->tempaddr[i], ipaddress, MAX_IPADR_LEN);
800       infof(data, "connect to %s port %ld: %s\n",
801             ipaddress, conn->port, Curl_strerror(conn, error));
802
803       conn->timeoutms_per_addr = conn->tempaddr[i]->ai_next == NULL ?
804                                  allow : allow / 2;
805
806       code = trynextip(conn, sockindex, i, connected);
807     }
808   }
809
810   if(code) {
811     /* no more addresses to try */
812     failf(data, "Failed to connect to %s port %ld: %s",
813           conn->host.name, conn->port, Curl_strerror(conn, error));
814   }
815
816   return code;
817 }
818
819 static void tcpnodelay(struct connectdata *conn,
820                        curl_socket_t sockfd)
821 {
822 #ifdef TCP_NODELAY
823   struct SessionHandle *data= conn->data;
824   curl_socklen_t onoff = (curl_socklen_t) data->set.tcp_nodelay;
825   int level = IPPROTO_TCP;
826
827 #if 0
828   /* The use of getprotobyname() is disabled since it isn't thread-safe on
829      numerous systems. On these getprotobyname_r() should be used instead, but
830      that exists in at least one 4 arg version and one 5 arg version, and
831      since the proto number rarely changes anyway we now just use the hard
832      coded number. The "proper" fix would need a configure check for the
833      correct function much in the same style the gethostbyname_r versions are
834      detected. */
835   struct protoent *pe = getprotobyname("tcp");
836   if(pe)
837     level = pe->p_proto;
838 #endif
839
840   if(setsockopt(sockfd, level, TCP_NODELAY, (void *)&onoff,
841                 sizeof(onoff)) < 0)
842     infof(data, "Could not set TCP_NODELAY: %s\n",
843           Curl_strerror(conn, SOCKERRNO));
844   else
845     infof(data,"TCP_NODELAY set\n");
846 #else
847   (void)conn;
848   (void)sockfd;
849 #endif
850 }
851
852 #ifdef SO_NOSIGPIPE
853 /* The preferred method on Mac OS X (10.2 and later) to prevent SIGPIPEs when
854    sending data to a dead peer (instead of relying on the 4th argument to send
855    being MSG_NOSIGNAL). Possibly also existing and in use on other BSD
856    systems? */
857 static void nosigpipe(struct connectdata *conn,
858                       curl_socket_t sockfd)
859 {
860   struct SessionHandle *data= conn->data;
861   int onoff = 1;
862   if(setsockopt(sockfd, SOL_SOCKET, SO_NOSIGPIPE, (void *)&onoff,
863                 sizeof(onoff)) < 0)
864     infof(data, "Could not set SO_NOSIGPIPE: %s\n",
865           Curl_strerror(conn, SOCKERRNO));
866 }
867 #else
868 #define nosigpipe(x,y) Curl_nop_stmt
869 #endif
870
871 #ifdef USE_WINSOCK
872 /* When you run a program that uses the Windows Sockets API, you may
873    experience slow performance when you copy data to a TCP server.
874
875    http://support.microsoft.com/kb/823764
876
877    Work-around: Make the Socket Send Buffer Size Larger Than the Program Send
878    Buffer Size
879
880    The problem described in this knowledge-base is applied only to pre-Vista
881    Windows.  Following function trying to detect OS version and skips
882    SO_SNDBUF adjustment for Windows Vista and above.
883 */
884 #define DETECT_OS_NONE 0
885 #define DETECT_OS_PREVISTA 1
886 #define DETECT_OS_VISTA_OR_LATER 2
887
888 void Curl_sndbufset(curl_socket_t sockfd)
889 {
890   int val = CURL_MAX_WRITE_SIZE + 32;
891   int curval = 0;
892   int curlen = sizeof(curval);
893
894   OSVERSIONINFO osver;
895   static int detectOsState = DETECT_OS_NONE;
896
897   if(detectOsState == DETECT_OS_NONE) {
898     memset(&osver, 0, sizeof(osver));
899     osver.dwOSVersionInfoSize = sizeof(osver);
900     detectOsState = DETECT_OS_PREVISTA;
901     if(GetVersionEx(&osver)) {
902       if(osver.dwMajorVersion >= 6)
903         detectOsState = DETECT_OS_VISTA_OR_LATER;
904     }
905   }
906   if(detectOsState == DETECT_OS_VISTA_OR_LATER)
907     return;
908
909   if(getsockopt(sockfd, SOL_SOCKET, SO_SNDBUF, (char *)&curval, &curlen) == 0)
910     if(curval > val)
911       return;
912
913   setsockopt(sockfd, SOL_SOCKET, SO_SNDBUF, (const char *)&val, sizeof(val));
914 }
915 #endif
916
917
918 /*
919  * singleipconnect()
920  *
921  * Note that even on connect fail it returns CURLE_OK, but with 'sock' set to
922  * CURL_SOCKET_BAD. Other errors will however return proper errors.
923  *
924  * singleipconnect() connects to the given IP only, and it may return without
925  * having connected.
926  */
927 static CURLcode
928 singleipconnect(struct connectdata *conn,
929                 const Curl_addrinfo *ai,
930                 curl_socket_t *sockp,
931                 bool *connected)
932 {
933   struct Curl_sockaddr_ex addr;
934   int rc;
935   int error = 0;
936   bool isconnected = FALSE;
937   struct SessionHandle *data = conn->data;
938   curl_socket_t sockfd;
939   CURLcode res = CURLE_OK;
940   char ipaddress[MAX_IPADR_LEN];
941   long port;
942
943   *sockp = CURL_SOCKET_BAD;
944   *connected = FALSE; /* default is not connected */
945
946   res = Curl_socket(conn, ai, &addr, &sockfd);
947   if(res)
948     /* Failed to create the socket, but still return OK since we signal the
949        lack of socket as well. This allows the parent function to keep looping
950        over alternative addresses/socket families etc. */
951     return CURLE_OK;
952
953   /* store remote address and port used in this connection attempt */
954   if(!getaddressinfo((struct sockaddr*)&addr.sa_addr,
955                      ipaddress, &port)) {
956     /* malformed address or bug in inet_ntop, try next address */
957     error = ERRNO;
958     failf(data, "sa_addr inet_ntop() failed with errno %d: %s",
959           error, Curl_strerror(conn, error));
960     Curl_closesocket(conn, sockfd);
961     return CURLE_OK;
962   }
963   infof(data, "  Trying %s...\n", ipaddress);
964
965   if(data->set.tcp_nodelay)
966     tcpnodelay(conn, sockfd);
967
968   nosigpipe(conn, sockfd);
969
970   Curl_sndbufset(sockfd);
971
972   if(data->set.tcp_keepalive)
973     tcpkeepalive(data, sockfd);
974
975   if(data->set.fsockopt) {
976     /* activate callback for setting socket options */
977     error = data->set.fsockopt(data->set.sockopt_client,
978                                sockfd,
979                                CURLSOCKTYPE_IPCXN);
980
981     if(error == CURL_SOCKOPT_ALREADY_CONNECTED)
982       isconnected = TRUE;
983     else if(error) {
984       Curl_closesocket(conn, sockfd); /* close the socket and bail out */
985       return CURLE_ABORTED_BY_CALLBACK;
986     }
987   }
988
989   /* possibly bind the local end to an IP, interface or port */
990   res = bindlocal(conn, sockfd, addr.family);
991   if(res) {
992     Curl_closesocket(conn, sockfd); /* close socket and bail out */
993     if(res == CURLE_UNSUPPORTED_PROTOCOL) {
994       /* The address family is not supported on this interface.
995          We can continue trying addresses */
996       return CURLE_OK;
997     }
998     return res;
999   }
1000
1001   /* set socket non-blocking */
1002   curlx_nonblock(sockfd, TRUE);
1003
1004   conn->connecttime = Curl_tvnow();
1005   if(conn->num_addr > 1)
1006     Curl_expire(data, conn->timeoutms_per_addr);
1007
1008   /* Connect TCP sockets, bind UDP */
1009   if(!isconnected && (conn->socktype == SOCK_STREAM)) {
1010     rc = connect(sockfd, &addr.sa_addr, addr.addrlen);
1011     if(-1 == rc)
1012       error = SOCKERRNO;
1013   }
1014   else {
1015     *sockp = sockfd;
1016     return CURLE_OK;
1017   }
1018
1019 #ifdef ENABLE_IPV6
1020   conn->bits.ipv6 = (addr.family == AF_INET6)?TRUE:FALSE;
1021 #endif
1022
1023   if(-1 == rc) {
1024     switch (error) {
1025     case EINPROGRESS:
1026     case EWOULDBLOCK:
1027 #if defined(EAGAIN)
1028 #if (EAGAIN) != (EWOULDBLOCK)
1029       /* On some platforms EAGAIN and EWOULDBLOCK are the
1030        * same value, and on others they are different, hence
1031        * the odd #if
1032        */
1033     case EAGAIN:
1034 #endif
1035 #endif
1036       *sockp = sockfd;
1037       return CURLE_OK;
1038
1039     default:
1040       /* unknown error, fallthrough and try another address! */
1041       failf(data, "Failed to connect to %s: %s",
1042             conn->ip_addr_str, Curl_strerror(conn,error));
1043       data->state.os_errno = error;
1044
1045       /* connect failed */
1046       Curl_closesocket(conn, sockfd);
1047
1048       break;
1049     }
1050   }
1051   else
1052     *sockp = sockfd;
1053
1054   return CURLE_OK;
1055 }
1056
1057 /*
1058  * TCP connect to the given host with timeout, proxy or remote doesn't matter.
1059  * There might be more than one IP address to try out. Fill in the passed
1060  * pointer with the connected socket.
1061  */
1062
1063 CURLcode Curl_connecthost(struct connectdata *conn,  /* context */
1064                           const struct Curl_dns_entry *remotehost,
1065                           bool *connected)           /* really connected? */
1066 {
1067   struct SessionHandle *data = conn->data;
1068   struct timeval after;
1069   struct timeval before = Curl_tvnow();
1070   int i;
1071
1072   /*************************************************************
1073    * Figure out what maximum time we have left
1074    *************************************************************/
1075   long timeout_ms;
1076
1077   *connected = FALSE; /* default to not connected */
1078
1079   /* get the timeout left */
1080   timeout_ms = Curl_timeleft(data, &before, TRUE);
1081
1082   if(timeout_ms < 0) {
1083     /* a precaution, no need to continue if time already is up */
1084     failf(data, "Connection time-out");
1085     return CURLE_OPERATION_TIMEDOUT;
1086   }
1087
1088   conn->num_addr = Curl_num_addresses(remotehost->addr);
1089   conn->tempaddr[0] = remotehost->addr;
1090   conn->tempaddr[1] = remotehost->addr;
1091
1092   /* Below is the loop that attempts to connect to all IP-addresses we
1093    * know for the given host.
1094    * One by one, for each protocol, until one IP succeeds.
1095    */
1096
1097   for(i=0; i<2; i++) {
1098     curl_socket_t sockfd = CURL_SOCKET_BAD;
1099     Curl_addrinfo *ai = conn->tempaddr[i];
1100     int family = i ? AF_INET6 : AF_INET;
1101
1102     /* find first address for this address family, if any */
1103     while(ai && ai->ai_family != family)
1104       ai = ai->ai_next;
1105
1106     /*
1107      * Connecting with a Curl_addrinfo chain
1108      */
1109     while(ai) {
1110       CURLcode res;
1111
1112       /* Max time for the next connection attempt */
1113       conn->timeoutms_per_addr = ai->ai_next == NULL ?
1114                                  timeout_ms : timeout_ms / 2;
1115
1116       /* start connecting to the IP curr_addr points to */
1117       res = singleipconnect(conn, ai, &sockfd, connected);
1118       if(res)
1119         return res;
1120
1121       if(sockfd != CURL_SOCKET_BAD)
1122         break;
1123
1124       /* get a new timeout for next attempt */
1125       after = Curl_tvnow();
1126       timeout_ms -= Curl_tvdiff(after, before);
1127       if(timeout_ms < 0) {
1128         failf(data, "connect() timed out!");
1129         return CURLE_OPERATION_TIMEDOUT;
1130       }
1131       before = after;
1132
1133       /* next addresses */
1134       do {
1135         ai = ai->ai_next;
1136       } while(ai && ai->ai_family != family);
1137     }  /* end of connect-to-each-address loop */
1138
1139     conn->tempsock[i] = sockfd;
1140     conn->tempaddr[i] = ai;
1141   }
1142
1143   if((conn->tempsock[0] == CURL_SOCKET_BAD) &&
1144      (conn->tempsock[1] == CURL_SOCKET_BAD)) {
1145     /* no good connect was made */
1146     failf(data, "couldn't connect to %s at %s:%ld",
1147           conn->bits.proxy?"proxy":"host",
1148           conn->bits.proxy?conn->proxy.name:conn->host.name, conn->port);
1149     return CURLE_COULDNT_CONNECT;
1150   }
1151
1152   /* leave the socket in non-blocking mode */
1153
1154   data->info.numconnects++; /* to track the number of connections made */
1155
1156   return CURLE_OK;
1157 }
1158
1159 struct connfind {
1160   struct connectdata *tofind;
1161   bool found;
1162 };
1163
1164 static int conn_is_conn(struct connectdata *conn, void *param)
1165 {
1166   struct connfind *f = (struct connfind *)param;
1167   if(conn == f->tofind) {
1168     f->found = TRUE;
1169     return 1;
1170   }
1171   return 0;
1172 }
1173
1174 /*
1175  * Used to extract socket and connectdata struct for the most recent
1176  * transfer on the given SessionHandle.
1177  *
1178  * The returned socket will be CURL_SOCKET_BAD in case of failure!
1179  */
1180 curl_socket_t Curl_getconnectinfo(struct SessionHandle *data,
1181                                   struct connectdata **connp)
1182 {
1183   curl_socket_t sockfd;
1184
1185   DEBUGASSERT(data);
1186
1187   /* this only works for an easy handle that has been used for
1188      curl_easy_perform()! */
1189   if(data->state.lastconnect && data->multi_easy) {
1190     struct connectdata *c = data->state.lastconnect;
1191     struct connfind find;
1192     find.tofind = data->state.lastconnect;
1193     find.found = FALSE;
1194
1195     Curl_conncache_foreach(data->multi_easy->conn_cache, &find, conn_is_conn);
1196
1197     if(!find.found) {
1198       data->state.lastconnect = NULL;
1199       return CURL_SOCKET_BAD;
1200     }
1201
1202     if(connp)
1203       /* only store this if the caller cares for it */
1204       *connp = c;
1205     sockfd = c->sock[FIRSTSOCKET];
1206     /* we have a socket connected, let's determine if the server shut down */
1207     /* determine if ssl */
1208     if(c->ssl[FIRSTSOCKET].use) {
1209       /* use the SSL context */
1210       if(!Curl_ssl_check_cxn(c))
1211         return CURL_SOCKET_BAD;   /* FIN received */
1212     }
1213 /* Minix 3.1 doesn't support any flags on recv; just assume socket is OK */
1214 #ifdef MSG_PEEK
1215     else {
1216       /* use the socket */
1217       char buf;
1218       if(recv((RECV_TYPE_ARG1)c->sock[FIRSTSOCKET], (RECV_TYPE_ARG2)&buf,
1219               (RECV_TYPE_ARG3)1, (RECV_TYPE_ARG4)MSG_PEEK) == 0) {
1220         return CURL_SOCKET_BAD;   /* FIN received */
1221       }
1222     }
1223 #endif
1224   }
1225   else
1226     return CURL_SOCKET_BAD;
1227
1228   return sockfd;
1229 }
1230
1231 /*
1232  * Close a socket.
1233  *
1234  * 'conn' can be NULL, beware!
1235  */
1236 int Curl_closesocket(struct connectdata *conn,
1237                       curl_socket_t sock)
1238 {
1239   if(conn && conn->fclosesocket) {
1240     if((sock == conn->sock[SECONDARYSOCKET]) &&
1241        conn->sock_accepted[SECONDARYSOCKET])
1242       /* if this socket matches the second socket, and that was created with
1243          accept, then we MUST NOT call the callback but clear the accepted
1244          status */
1245       conn->sock_accepted[SECONDARYSOCKET] = FALSE;
1246     else
1247       return conn->fclosesocket(conn->closesocket_client, sock);
1248   }
1249   sclose(sock);
1250
1251   if(conn)
1252     /* tell the multi-socket code about this */
1253     Curl_multi_closed(conn, sock);
1254
1255   return 0;
1256 }
1257
1258 /*
1259  * Create a socket based on info from 'conn' and 'ai'.
1260  *
1261  * 'addr' should be a pointer to the correct struct to get data back, or NULL.
1262  * 'sockfd' must be a pointer to a socket descriptor.
1263  *
1264  * If the open socket callback is set, used that!
1265  *
1266  */
1267 CURLcode Curl_socket(struct connectdata *conn,
1268                      const Curl_addrinfo *ai,
1269                      struct Curl_sockaddr_ex *addr,
1270                      curl_socket_t *sockfd)
1271 {
1272   struct SessionHandle *data = conn->data;
1273   struct Curl_sockaddr_ex dummy;
1274
1275   if(!addr)
1276     /* if the caller doesn't want info back, use a local temp copy */
1277     addr = &dummy;
1278
1279   /*
1280    * The Curl_sockaddr_ex structure is basically libcurl's external API
1281    * curl_sockaddr structure with enough space available to directly hold
1282    * any protocol-specific address structures. The variable declared here
1283    * will be used to pass / receive data to/from the fopensocket callback
1284    * if this has been set, before that, it is initialized from parameters.
1285    */
1286
1287   addr->family = ai->ai_family;
1288   addr->socktype = conn->socktype;
1289   addr->protocol = conn->socktype==SOCK_DGRAM?IPPROTO_UDP:ai->ai_protocol;
1290   addr->addrlen = ai->ai_addrlen;
1291
1292   if(addr->addrlen > sizeof(struct Curl_sockaddr_storage))
1293      addr->addrlen = sizeof(struct Curl_sockaddr_storage);
1294   memcpy(&addr->sa_addr, ai->ai_addr, addr->addrlen);
1295
1296   if(data->set.fopensocket)
1297    /*
1298     * If the opensocket callback is set, all the destination address
1299     * information is passed to the callback. Depending on this information the
1300     * callback may opt to abort the connection, this is indicated returning
1301     * CURL_SOCKET_BAD; otherwise it will return a not-connected socket. When
1302     * the callback returns a valid socket the destination address information
1303     * might have been changed and this 'new' address will actually be used
1304     * here to connect.
1305     */
1306     *sockfd = data->set.fopensocket(data->set.opensocket_client,
1307                                     CURLSOCKTYPE_IPCXN,
1308                                     (struct curl_sockaddr *)addr);
1309   else
1310     /* opensocket callback not set, so simply create the socket now */
1311     *sockfd = socket(addr->family, addr->socktype, addr->protocol);
1312
1313   if(*sockfd == CURL_SOCKET_BAD)
1314     /* no socket, no connection */
1315     return CURLE_COULDNT_CONNECT;
1316
1317 #if defined(ENABLE_IPV6) && defined(HAVE_SOCKADDR_IN6_SIN6_SCOPE_ID)
1318   if(conn->scope && (addr->family == AF_INET6)) {
1319     struct sockaddr_in6 * const sa6 = (void *)&addr->sa_addr;
1320     sa6->sin6_scope_id = conn->scope;
1321   }
1322 #endif
1323
1324   return CURLE_OK;
1325
1326 }