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