b5082d896c930c8eea0e519d413ed44081e49435
[platform/upstream/curl.git] / lib / connect.c
1 /***************************************************************************
2  *                                  _   _ ____  _
3  *  Project                     ___| | | |  _ \| |
4  *                             / __| | | | |_) | |
5  *                            | (__| |_| |  _ <| |___
6  *                             \___|\___/|_| \_\_____|
7  *
8  * Copyright (C) 1998 - 2012, 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   conn->timeoutms_per_addr = conn->ip_addr->ai_next == NULL ?
736                              allow : allow / 2;
737   code = trynextip(conn, sockindex, connected);
738
739   if(code) {
740     error = SOCKERRNO;
741     data->state.os_errno = error;
742     failf(data, "Failed connect to %s:%ld; %s",
743           conn->host.name, conn->port, Curl_strerror(conn, error));
744   }
745
746   return code;
747 }
748
749 static void tcpnodelay(struct connectdata *conn,
750                        curl_socket_t sockfd)
751 {
752 #ifdef TCP_NODELAY
753   struct SessionHandle *data= conn->data;
754   curl_socklen_t onoff = (curl_socklen_t) data->set.tcp_nodelay;
755   int level = IPPROTO_TCP;
756
757 #if 0
758   /* The use of getprotobyname() is disabled since it isn't thread-safe on
759      numerous systems. On these getprotobyname_r() should be used instead, but
760      that exists in at least one 4 arg version and one 5 arg version, and
761      since the proto number rarely changes anyway we now just use the hard
762      coded number. The "proper" fix would need a configure check for the
763      correct function much in the same style the gethostbyname_r versions are
764      detected. */
765   struct protoent *pe = getprotobyname("tcp");
766   if(pe)
767     level = pe->p_proto;
768 #endif
769
770   if(setsockopt(sockfd, level, TCP_NODELAY, (void *)&onoff,
771                 sizeof(onoff)) < 0)
772     infof(data, "Could not set TCP_NODELAY: %s\n",
773           Curl_strerror(conn, SOCKERRNO));
774   else
775     infof(data,"TCP_NODELAY set\n");
776 #else
777   (void)conn;
778   (void)sockfd;
779 #endif
780 }
781
782 #ifdef SO_NOSIGPIPE
783 /* The preferred method on Mac OS X (10.2 and later) to prevent SIGPIPEs when
784    sending data to a dead peer (instead of relying on the 4th argument to send
785    being MSG_NOSIGNAL). Possibly also existing and in use on other BSD
786    systems? */
787 static void nosigpipe(struct connectdata *conn,
788                       curl_socket_t sockfd)
789 {
790   struct SessionHandle *data= conn->data;
791   int onoff = 1;
792   if(setsockopt(sockfd, SOL_SOCKET, SO_NOSIGPIPE, (void *)&onoff,
793                 sizeof(onoff)) < 0)
794     infof(data, "Could not set SO_NOSIGPIPE: %s\n",
795           Curl_strerror(conn, SOCKERRNO));
796 }
797 #else
798 #define nosigpipe(x,y) Curl_nop_stmt
799 #endif
800
801 #ifdef USE_WINSOCK
802 /* When you run a program that uses the Windows Sockets API, you may
803    experience slow performance when you copy data to a TCP server.
804
805    http://support.microsoft.com/kb/823764
806
807    Work-around: Make the Socket Send Buffer Size Larger Than the Program Send
808    Buffer Size
809
810 */
811 void Curl_sndbufset(curl_socket_t sockfd)
812 {
813   int val = CURL_MAX_WRITE_SIZE + 32;
814   int curval = 0;
815   int curlen = sizeof(curval);
816
817   if(getsockopt(sockfd, SOL_SOCKET, SO_SNDBUF, (char *)&curval, &curlen) == 0)
818     if(curval > val)
819       return;
820
821   setsockopt(sockfd, SOL_SOCKET, SO_SNDBUF, (const char *)&val, sizeof(val));
822 }
823 #endif
824
825
826 /*
827  * singleipconnect()
828  *
829  * Note that even on connect fail it returns CURLE_OK, but with 'sock' set to
830  * CURL_SOCKET_BAD. Other errors will however return proper errors.
831  *
832  * singleipconnect() connects to the given IP only, and it may return without
833  * having connected if used from the multi interface.
834  */
835 static CURLcode
836 singleipconnect(struct connectdata *conn,
837                 const Curl_addrinfo *ai,
838                 long timeout_ms,
839                 curl_socket_t *sockp,
840                 bool *connected)
841 {
842   struct Curl_sockaddr_ex addr;
843   int rc;
844   int error = 0;
845   bool isconnected = FALSE;
846   struct SessionHandle *data = conn->data;
847   curl_socket_t sockfd;
848   CURLcode res = CURLE_OK;
849
850   *sockp = CURL_SOCKET_BAD;
851   *connected = FALSE; /* default is not connected */
852
853   res = Curl_socket(conn, ai, &addr, &sockfd);
854   if(res)
855     return res;
856
857   /* store remote address and port used in this connection attempt */
858   if(!getaddressinfo((struct sockaddr*)&addr.sa_addr,
859                      conn->primary_ip, &conn->primary_port)) {
860     /* malformed address or bug in inet_ntop, try next address */
861     error = ERRNO;
862     failf(data, "sa_addr inet_ntop() failed with errno %d: %s",
863           error, Curl_strerror(conn, error));
864     Curl_closesocket(conn, sockfd);
865     return CURLE_OK;
866   }
867   memcpy(conn->ip_addr_str, conn->primary_ip, MAX_IPADR_LEN);
868   infof(data, "  Trying %s...\n", conn->ip_addr_str);
869
870   Curl_persistconninfo(conn);
871
872   if(data->set.tcp_nodelay)
873     tcpnodelay(conn, sockfd);
874
875   nosigpipe(conn, sockfd);
876
877   Curl_sndbufset(sockfd);
878
879   if(data->set.fsockopt) {
880     /* activate callback for setting socket options */
881     error = data->set.fsockopt(data->set.sockopt_client,
882                                sockfd,
883                                CURLSOCKTYPE_IPCXN);
884
885     if(error == CURL_SOCKOPT_ALREADY_CONNECTED)
886       isconnected = TRUE;
887     else if(error) {
888       Curl_closesocket(conn, sockfd); /* close the socket and bail out */
889       return CURLE_ABORTED_BY_CALLBACK;
890     }
891   }
892
893   /* possibly bind the local end to an IP, interface or port */
894   res = bindlocal(conn, sockfd, addr.family);
895   if(res) {
896     Curl_closesocket(conn, sockfd); /* close socket and bail out */
897     return res;
898   }
899
900   /* set socket non-blocking */
901   curlx_nonblock(sockfd, TRUE);
902
903   /* Connect TCP sockets, bind UDP */
904   if(!isconnected && (conn->socktype == SOCK_STREAM)) {
905     rc = connect(sockfd, &addr.sa_addr, addr.addrlen);
906     if(-1 == rc)
907       error = SOCKERRNO;
908     conn->connecttime = Curl_tvnow();
909     if(conn->num_addr > 1)
910       Curl_expire(data, conn->timeoutms_per_addr);
911   }
912   else
913     rc = 0;
914
915   if(-1 == rc) {
916     switch (error) {
917     case EINPROGRESS:
918     case EWOULDBLOCK:
919 #if defined(EAGAIN)
920 #if (EAGAIN) != (EWOULDBLOCK)
921       /* On some platforms EAGAIN and EWOULDBLOCK are the
922        * same value, and on others they are different, hence
923        * the odd #if
924        */
925     case EAGAIN:
926 #endif
927 #endif
928       rc = waitconnect(conn, sockfd, timeout_ms);
929       if(WAITCONN_ABORTED == rc) {
930         Curl_closesocket(conn, sockfd);
931         return CURLE_ABORTED_BY_CALLBACK;
932       }
933       break;
934     default:
935       /* unknown error, fallthrough and try another address! */
936       failf(data, "Failed to connect to %s: %s",
937             conn->ip_addr_str, Curl_strerror(conn,error));
938       data->state.os_errno = error;
939       break;
940     }
941   }
942
943   /* The 'WAITCONN_TIMEOUT == rc' comes from the waitconnect(), and not from
944      connect(). We can be sure of this since connect() cannot return 1. */
945   if((WAITCONN_TIMEOUT == rc) &&
946      (data->state.used_interface == Curl_if_multi)) {
947     /* Timeout when running the multi interface */
948     *sockp = sockfd;
949     return CURLE_OK;
950   }
951
952   if(!isconnected)
953     isconnected = verifyconnect(sockfd, &error);
954
955   if(!rc && isconnected) {
956     /* we are connected, awesome! */
957     *connected = TRUE; /* this is a true connect */
958     infof(data, "connected\n");
959 #ifdef ENABLE_IPV6
960     conn->bits.ipv6 = (addr.family == AF_INET6)?TRUE:FALSE;
961 #endif
962
963     Curl_updateconninfo(conn, sockfd);
964     *sockp = sockfd;
965     return CURLE_OK;
966   }
967   else if(WAITCONN_TIMEOUT == rc)
968     infof(data, "Timeout\n");
969   else {
970     data->state.os_errno = error;
971     infof(data, "%s\n", Curl_strerror(conn, error));
972   }
973
974   /* connect failed or timed out */
975   Curl_closesocket(conn, sockfd);
976
977   return CURLE_OK;
978 }
979
980 /*
981  * TCP connect to the given host with timeout, proxy or remote doesn't matter.
982  * There might be more than one IP address to try out. Fill in the passed
983  * pointer with the connected socket.
984  */
985
986 CURLcode Curl_connecthost(struct connectdata *conn,  /* context */
987                           const struct Curl_dns_entry *remotehost,
988                           curl_socket_t *sockconn,   /* the connected socket */
989                           Curl_addrinfo **addr,      /* the one we used */
990                           bool *connected)           /* really connected? */
991 {
992   struct SessionHandle *data = conn->data;
993   curl_socket_t sockfd = CURL_SOCKET_BAD;
994   Curl_addrinfo *ai;
995   Curl_addrinfo *curr_addr;
996
997   struct timeval after;
998   struct timeval before = Curl_tvnow();
999
1000   /*************************************************************
1001    * Figure out what maximum time we have left
1002    *************************************************************/
1003   long timeout_ms;
1004
1005   DEBUGASSERT(sockconn);
1006   *connected = FALSE; /* default to not connected */
1007
1008   /* get the timeout left */
1009   timeout_ms = Curl_timeleft(data, &before, TRUE);
1010
1011   if(timeout_ms < 0) {
1012     /* a precaution, no need to continue if time already is up */
1013     failf(data, "Connection time-out");
1014     return CURLE_OPERATION_TIMEDOUT;
1015   }
1016
1017   conn->num_addr = Curl_num_addresses(remotehost->addr);
1018
1019   ai = remotehost->addr;
1020
1021   /* Below is the loop that attempts to connect to all IP-addresses we
1022    * know for the given host. One by one until one IP succeeds.
1023    */
1024
1025   /*
1026    * Connecting with a Curl_addrinfo chain
1027    */
1028   for(curr_addr = ai; curr_addr; curr_addr = curr_addr->ai_next) {
1029     CURLcode res;
1030
1031     /* Max time for the next address */
1032     conn->timeoutms_per_addr = curr_addr->ai_next == NULL ?
1033                                timeout_ms : timeout_ms / 2;
1034
1035     /* start connecting to the IP curr_addr points to */
1036     res = singleipconnect(conn, curr_addr,
1037                           /* don't hang when doing multi */
1038                           (data->state.used_interface == Curl_if_multi)?0:
1039                           conn->timeoutms_per_addr, &sockfd, connected);
1040     if(res)
1041       return res;
1042
1043     if(sockfd != CURL_SOCKET_BAD)
1044       break;
1045
1046     /* get a new timeout for next attempt */
1047     after = Curl_tvnow();
1048     timeout_ms -= Curl_tvdiff(after, before);
1049     if(timeout_ms < 0) {
1050       failf(data, "connect() timed out!");
1051       return CURLE_OPERATION_TIMEDOUT;
1052     }
1053     before = after;
1054   }  /* end of connect-to-each-address loop */
1055
1056   *sockconn = sockfd;    /* the socket descriptor we've connected */
1057
1058   if(sockfd == CURL_SOCKET_BAD) {
1059     /* no good connect was made */
1060     failf(data, "couldn't connect to host");
1061     return CURLE_COULDNT_CONNECT;
1062   }
1063
1064   /* leave the socket in non-blocking mode */
1065
1066   /* store the address we use */
1067   if(addr)
1068     *addr = curr_addr;
1069
1070   data->info.numconnects++; /* to track the number of connections made */
1071
1072   return CURLE_OK;
1073 }
1074
1075 /*
1076  * Used to extract socket and connectdata struct for the most recent
1077  * transfer on the given SessionHandle.
1078  *
1079  * The returned socket will be CURL_SOCKET_BAD in case of failure!
1080  */
1081 curl_socket_t Curl_getconnectinfo(struct SessionHandle *data,
1082                                   struct connectdata **connp)
1083 {
1084   curl_socket_t sockfd;
1085
1086   DEBUGASSERT(data);
1087
1088   if((data->state.lastconnect != -1) &&
1089      (data->state.connc->connects[data->state.lastconnect] != NULL)) {
1090     struct connectdata *c =
1091       data->state.connc->connects[data->state.lastconnect];
1092     if(connp)
1093       /* only store this if the caller cares for it */
1094       *connp = c;
1095     sockfd = c->sock[FIRSTSOCKET];
1096     /* we have a socket connected, let's determine if the server shut down */
1097     /* determine if ssl */
1098     if(c->ssl[FIRSTSOCKET].use) {
1099       /* use the SSL context */
1100       if(!Curl_ssl_check_cxn(c))
1101         return CURL_SOCKET_BAD;   /* FIN received */
1102     }
1103 /* Minix 3.1 doesn't support any flags on recv; just assume socket is OK */
1104 #ifdef MSG_PEEK
1105     else {
1106       /* use the socket */
1107       char buf;
1108       if(recv((RECV_TYPE_ARG1)c->sock[FIRSTSOCKET], (RECV_TYPE_ARG2)&buf,
1109               (RECV_TYPE_ARG3)1, (RECV_TYPE_ARG4)MSG_PEEK) == 0) {
1110         return CURL_SOCKET_BAD;   /* FIN received */
1111       }
1112     }
1113 #endif
1114   }
1115   else
1116     return CURL_SOCKET_BAD;
1117
1118   return sockfd;
1119 }
1120
1121 /*
1122  * Close a socket.
1123  *
1124  * 'conn' can be NULL, beware!
1125  */
1126 int Curl_closesocket(struct connectdata *conn,
1127                      curl_socket_t sock)
1128 {
1129   if(conn && conn->fclosesocket) {
1130     if((sock == conn->sock[SECONDARYSOCKET]) &&
1131        conn->sock_accepted[SECONDARYSOCKET])
1132       /* if this socket matches the second socket, and that was created with
1133          accept, then we MUST NOT call the callback but clear the accepted
1134          status */
1135       conn->sock_accepted[SECONDARYSOCKET] = FALSE;
1136     else
1137       return conn->fclosesocket(conn->closesocket_client, sock);
1138   }
1139   return sclose(sock);
1140 }
1141
1142 /*
1143  * Create a socket based on info from 'conn' and 'ai'.
1144  *
1145  * 'addr' should be a pointer to the correct struct to get data back, or NULL.
1146  * 'sockfd' must be a pointer to a socket descriptor.
1147  *
1148  * If the open socket callback is set, used that!
1149  *
1150  */
1151 CURLcode Curl_socket(struct connectdata *conn,
1152                      const Curl_addrinfo *ai,
1153                      struct Curl_sockaddr_ex *addr,
1154                      curl_socket_t *sockfd)
1155 {
1156   struct SessionHandle *data = conn->data;
1157   struct Curl_sockaddr_ex dummy;
1158
1159   if(!addr)
1160     /* if the caller doesn't want info back, use a local temp copy */
1161     addr = &dummy;
1162
1163   /*
1164    * The Curl_sockaddr_ex structure is basically libcurl's external API
1165    * curl_sockaddr structure with enough space available to directly hold
1166    * any protocol-specific address structures. The variable declared here
1167    * will be used to pass / receive data to/from the fopensocket callback
1168    * if this has been set, before that, it is initialized from parameters.
1169    */
1170
1171   addr->family = ai->ai_family;
1172   addr->socktype = conn->socktype;
1173   addr->protocol = conn->socktype==SOCK_DGRAM?IPPROTO_UDP:ai->ai_protocol;
1174   addr->addrlen = ai->ai_addrlen;
1175
1176   if(addr->addrlen > sizeof(struct Curl_sockaddr_storage))
1177      addr->addrlen = sizeof(struct Curl_sockaddr_storage);
1178   memcpy(&addr->sa_addr, ai->ai_addr, addr->addrlen);
1179
1180   if(data->set.fopensocket)
1181    /*
1182     * If the opensocket callback is set, all the destination address
1183     * information is passed to the callback. Depending on this information the
1184     * callback may opt to abort the connection, this is indicated returning
1185     * CURL_SOCKET_BAD; otherwise it will return a not-connected socket. When
1186     * the callback returns a valid socket the destination address information
1187     * might have been changed and this 'new' address will actually be used
1188     * here to connect.
1189     */
1190     *sockfd = data->set.fopensocket(data->set.opensocket_client,
1191                                     CURLSOCKTYPE_IPCXN,
1192                                     (struct curl_sockaddr *)addr);
1193   else
1194     /* opensocket callback not set, so simply create the socket now */
1195     *sockfd = socket(addr->family, addr->socktype, addr->protocol);
1196
1197   if(*sockfd == CURL_SOCKET_BAD)
1198     /* no socket, no connection */
1199     return CURLE_FAILED_INIT;
1200
1201 #if defined(ENABLE_IPV6) && defined(HAVE_SOCKADDR_IN6_SIN6_SCOPE_ID)
1202   if(conn->scope && (addr->family == AF_INET6)) {
1203     struct sockaddr_in6 * const sa6 = (void *)&addr->sa_addr;
1204     sa6->sin6_scope_id = conn->scope;
1205   }
1206 #endif
1207
1208   return CURLE_OK;
1209
1210 }