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