bd5f2ed53672d6ecfcaaf352f3ceea587437e823
[platform/upstream/curl.git] / lib / url.c
1 /***************************************************************************
2  *                                  _   _ ____  _
3  *  Project                     ___| | | |  _ \| |
4  *                             / __| | | | |_) | |
5  *                            | (__| |_| |  _ <| |___
6  *                             \___|\___/|_| \_\_____|
7  *
8  * Copyright (C) 1998 - 2005, 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  * $Id$
22  ***************************************************************************/
23
24 /* -- WIN32 approved -- */
25
26 #include "setup.h"
27
28 #include <stdio.h>
29 #include <string.h>
30 #include <stdarg.h>
31 #include <stdlib.h>
32 #include <ctype.h>
33 #ifdef HAVE_SYS_TYPES_H
34 #include <sys/types.h>
35 #endif
36 #ifdef HAVE_SYS_STAT_H
37 #include <sys/stat.h>
38 #endif
39 #include <errno.h>
40
41 #if defined(WIN32) && !defined(__GNUC__) || defined(__MINGW32__)
42 #include <time.h>
43 #include <io.h>
44 #else
45 #ifdef HAVE_SYS_SOCKET_H
46 #include <sys/socket.h>
47 #endif
48 #include <netinet/in.h>
49 #include <sys/time.h>
50 #ifdef HAVE_UNISTD_H
51 #include <unistd.h>
52 #endif
53 #include <netdb.h>
54 #ifdef HAVE_ARPA_INET_H
55 #include <arpa/inet.h>
56 #endif
57 #ifdef HAVE_NET_IF_H
58 #include <net/if.h>
59 #endif
60 #include <sys/ioctl.h>
61 #include <signal.h>
62
63 #ifdef HAVE_SYS_PARAM_H
64 #include <sys/param.h>
65 #endif
66
67 #ifdef VMS
68 #include <in.h>
69 #include <inet.h>
70 #endif
71
72 #ifdef HAVE_SETJMP_H
73 #include <setjmp.h>
74 #endif
75
76 #ifndef HAVE_SOCKET
77 #error "We can't compile without socket() support!"
78 #endif
79
80
81 #endif
82
83 #ifdef USE_LIBIDN
84 #include <idna.h>
85 #include <tld.h>
86 #include <stringprep.h>
87 #ifdef HAVE_IDN_FREE_H
88 #include <idn-free.h>
89 #else
90 void idn_free (void *ptr); /* prototype from idn-free.h, not provided by
91                               libidn 0.4.5's make install! */
92 #endif
93 #ifndef HAVE_IDN_FREE
94 /* if idn_free() was not found in this version of libidn, use plain free()
95    instead */
96 #define idn_free(x) (free)(x)
97 #endif
98 #endif
99
100 #include "urldata.h"
101 #include "netrc.h"
102
103 #include "formdata.h"
104 #include "base64.h"
105 #include "ssluse.h"
106 #include "hostip.h"
107 #include "if2ip.h"
108 #include "transfer.h"
109 #include "sendf.h"
110 #include "progress.h"
111 #include "cookie.h"
112 #include "strequal.h"
113 #include "strerror.h"
114 #include "escape.h"
115 #include "strtok.h"
116 #include "share.h"
117 #include "content_encoding.h"
118 #include "http_digest.h"
119 #include "http_negotiate.h"
120 #include "select.h"
121 #include "multiif.h"
122
123 /* And now for the protocols */
124 #include "ftp.h"
125 #include "dict.h"
126 #include "telnet.h"
127 #include "http.h"
128 #include "file.h"
129 #include "ldap.h"
130 #include "url.h"
131 #include "connect.h"
132 #include "inet_ntop.h"
133 #include "http_ntlm.h"
134 #include <ca-bundle.h>
135
136 #if defined(HAVE_INET_NTOA_R) && !defined(HAVE_INET_NTOA_R_DECL)
137 #include "inet_ntoa_r.h"
138 #endif
139
140 #define _MPRINTF_REPLACE /* use our functions only */
141 #include <curl/mprintf.h>
142
143 #ifdef HAVE_KRB4
144 #include "krb4.h"
145 #endif
146 #include "memory.h"
147
148 /* The last #include file should be: */
149 #include "memdebug.h"
150
151 /* Local static prototypes */
152 static long ConnectionKillOne(struct SessionHandle *data);
153 static bool ConnectionExists(struct SessionHandle *data,
154                              struct connectdata *needle,
155                              struct connectdata **usethis);
156 static long ConnectionStore(struct SessionHandle *data,
157                             struct connectdata *conn);
158 static bool safe_strequal(char* str1, char* str2);
159
160 #ifndef USE_ARES
161 /* not for Win32, unless it is cygwin
162    not for ares builds */
163 #if !defined(WIN32) || defined(__CYGWIN32__)
164
165 #ifndef RETSIGTYPE
166 #define RETSIGTYPE void
167 #endif
168 #ifdef HAVE_SIGSETJMP
169 extern sigjmp_buf curl_jmpenv;
170 #endif
171 static
172 RETSIGTYPE alarmfunc(int sig)
173 {
174   /* this is for "-ansi -Wall -pedantic" to stop complaining!   (rabe) */
175   (void)sig;
176 #ifdef HAVE_SIGSETJMP
177   siglongjmp(curl_jmpenv, 1);
178 #endif
179   return;
180 }
181 #endif
182 #endif /* USE_ARES */
183
184 void Curl_safefree(void *ptr)
185 {
186   if(ptr)
187     free(ptr);
188 }
189
190 /*
191  * This is the internal function curl_easy_cleanup() calls. This should
192  * cleanup and free all resources associated with this sessionhandle.
193  *
194  * NOTE: if we ever add something that attempts to write to a socket or
195  * similar here, we must ignore SIGPIPE first. It is currently only done
196  * when curl_easy_perform() is invoked.
197  */
198
199 CURLcode Curl_close(struct SessionHandle *data)
200 {
201   if(data->multi) {
202     /* this handle is still part of a multi handle, take care of this first */
203     Curl_multi_rmeasy(data->multi, data);
204   }
205   /* Loop through all open connections and kill them one by one */
206   while(-1 != ConnectionKillOne(data))
207     ; /* empty loop */
208
209   if ( ! (data->share && data->share->hostcache) ) {
210     if ( !Curl_global_host_cache_use(data)) {
211       Curl_hash_destroy(data->hostcache);
212     }
213   }
214
215 #ifdef USE_SSLEAY
216   /* Close down all open SSL info and sessions */
217   Curl_SSL_Close_All(data);
218 #endif
219
220   Curl_safefree(data->state.first_host);
221   Curl_safefree(data->state.scratch);
222
223   if(data->change.proxy_alloc)
224     free(data->change.proxy);
225
226   if(data->change.referer_alloc)
227     free(data->change.referer);
228
229   if(data->change.url_alloc)
230     free(data->change.url);
231
232   Curl_safefree(data->state.headerbuff);
233
234 #if !defined(CURL_DISABLE_HTTP) && !defined(CURL_DISABLE_COOKIES)
235   if(data->change.cookielist) /* clean up list if any */
236     curl_slist_free_all(data->change.cookielist);
237
238   Curl_share_lock(data, CURL_LOCK_DATA_COOKIE, CURL_LOCK_ACCESS_SINGLE);
239   if(data->set.cookiejar) {
240     /* we have a "destination" for all the cookies to get dumped to */
241     if(Curl_cookie_output(data->cookies, data->set.cookiejar))
242       infof(data, "WARNING: failed to save cookies in %s\n",
243             data->set.cookiejar);
244   }
245
246   if( !data->share || (data->cookies != data->share->cookies) ) {
247     Curl_cookie_cleanup(data->cookies);
248   }
249   Curl_share_unlock(data, CURL_LOCK_DATA_COOKIE);
250 #endif
251
252 #if !defined(CURL_DISABLE_HTTP) && !defined(CURL_DISABLE_CRYPTO_AUTH)
253   Curl_digest_cleanup(data);
254 #endif
255
256   /* free the connection cache */
257   free(data->state.connects);
258
259   Curl_safefree(data->info.contenttype);
260
261 #ifdef USE_ARES
262   /* this destroys the channel and we cannot use it anymore after this */
263   ares_destroy(data->state.areschannel);
264 #endif
265
266   /* No longer a dirty share, if it exists */
267   if (data->share)
268     data->share->dirty--;
269
270   free(data);
271   return CURLE_OK;
272 }
273
274 /**
275  * Curl_open()
276  *
277  * @param curl is a pointer to a sessionhandle pointer that gets set by this
278  * function.
279  * @return CURLcode
280  */
281
282 CURLcode Curl_open(struct SessionHandle **curl)
283 {
284   CURLcode res = CURLE_OK;
285   struct SessionHandle *data;
286   /* Very simple start-up: alloc the struct, init it with zeroes and return */
287   data = (struct SessionHandle *)calloc(1, sizeof(struct SessionHandle));
288   if(!data)
289     /* this is a very serious error */
290     return CURLE_OUT_OF_MEMORY;
291
292 #ifdef USE_ARES
293   if(ARES_SUCCESS != ares_init(&data->state.areschannel)) {
294     free(data);
295     return CURLE_FAILED_INIT;
296   }
297   /* make sure that all other returns from this function should destroy the
298      ares channel before returning error! */
299 #endif
300
301   /* We do some initial setup here, all those fields that can't be just 0 */
302
303   data->state.headerbuff=(char*)malloc(HEADERSIZE);
304   if(!data->state.headerbuff)
305     res = CURLE_OUT_OF_MEMORY;
306   else {
307     data->state.headersize=HEADERSIZE;
308
309     data->set.out = stdout; /* default output to stdout */
310     data->set.in  = stdin;  /* default input from stdin */
311     data->set.err  = stderr;  /* default stderr to stderr */
312
313     /* use fwrite as default function to store output */
314     data->set.fwrite = (curl_write_callback)fwrite;
315
316     /* use fread as default function to read input */
317     data->set.fread = (curl_read_callback)fread;
318
319     data->set.infilesize = -1; /* we don't know any size */
320     data->set.postfieldsize = -1;
321
322     data->state.current_speed = -1; /* init to negative == impossible */
323
324     data->set.httpreq = HTTPREQ_GET; /* Default HTTP request */
325     data->set.ftp_use_epsv = TRUE;   /* FTP defaults to EPSV operations */
326     data->set.ftp_use_eprt = TRUE;   /* FTP defaults to EPRT operations */
327     data->set.ftp_use_lprt = TRUE;   /* FTP defaults to EPRT operations */
328
329     data->set.dns_cache_timeout = 60; /* Timeout every 60 seconds by default */
330
331     /* make libcurl quiet by default: */
332     data->set.hide_progress = TRUE;  /* CURLOPT_NOPROGRESS changes these */
333     data->progress.flags |= PGRS_HIDE;
334
335     /* Set the default size of the SSL session ID cache */
336     data->set.ssl.numsessions = 5;
337
338     data->set.proxyport = 1080;
339     data->set.proxytype = CURLPROXY_HTTP; /* defaults to HTTP proxy */
340     data->set.httpauth = CURLAUTH_BASIC;  /* defaults to basic */
341     data->set.proxyauth = CURLAUTH_BASIC; /* defaults to basic */
342
343     /* create an array with connection data struct pointers */
344     data->state.numconnects = 5; /* hard-coded right now */
345     data->state.connects = (struct connectdata **)
346       malloc(sizeof(struct connectdata *) * data->state.numconnects);
347
348     if(!data->state.connects)
349       res = CURLE_OUT_OF_MEMORY;
350     else
351       memset(data->state.connects, 0,
352              sizeof(struct connectdata *)*data->state.numconnects);
353
354     /*
355      * libcurl 7.10 introduced SSL verification *by default*! This needs to be
356      * switched off unless wanted.
357      */
358     data->set.ssl.verifypeer = TRUE;
359     data->set.ssl.verifyhost = 2;
360 #ifdef CURL_CA_BUNDLE
361     /* This is our prefered CA cert bundle since install time */
362     data->set.ssl.CAfile = (char *)CURL_CA_BUNDLE;
363 #endif
364   }
365
366   if(res) {
367 #ifdef USE_ARES
368     ares_destroy(data->state.areschannel);
369 #endif
370     if(data->state.headerbuff)
371       free(data->state.headerbuff);
372     free(data);
373     data = NULL;
374   }
375
376   *curl = data;
377   return CURLE_OK;
378 }
379
380 CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, ...)
381 {
382   va_list param;
383   char *argptr;
384   CURLcode result = CURLE_OK;
385
386   va_start(param, option);
387
388   switch(option) {
389   case CURLOPT_DNS_CACHE_TIMEOUT:
390     data->set.dns_cache_timeout = va_arg(param, int);
391     break;
392   case CURLOPT_DNS_USE_GLOBAL_CACHE:
393     {
394       int use_cache = va_arg(param, int);
395       if (use_cache) {
396         Curl_global_host_cache_init();
397       }
398
399       data->set.global_dns_cache = use_cache;
400     }
401     break;
402   case CURLOPT_SSL_CIPHER_LIST:
403     /* set a list of cipher we want to use in the SSL connection */
404     data->set.ssl.cipher_list = va_arg(param, char *);
405     break;
406
407   case CURLOPT_RANDOM_FILE:
408     /*
409      * This is the path name to a file that contains random data to seed
410      * the random SSL stuff with. The file is only used for reading.
411      */
412     data->set.ssl.random_file = va_arg(param, char *);
413     break;
414   case CURLOPT_EGDSOCKET:
415     /*
416      * The Entropy Gathering Daemon socket pathname
417      */
418     data->set.ssl.egdsocket = va_arg(param, char *);
419     break;
420   case CURLOPT_MAXCONNECTS:
421     /*
422      * Set the absolute number of maximum simultaneous alive connection that
423      * libcurl is allowed to have.
424      */
425     {
426       long newconnects= va_arg(param, long);
427       struct connectdata **newptr;
428       long i;
429
430       if(newconnects < data->state.numconnects) {
431         /* Since this number is *decreased* from the existing number, we must
432            close the possibly open connections that live on the indexes that
433            are being removed! */
434         for(i=newconnects; i< data->state.numconnects; i++)
435           Curl_disconnect(data->state.connects[i]);
436       }
437       if(newconnects) {
438         newptr= (struct connectdata **)
439           realloc(data->state.connects,
440                   sizeof(struct connectdata *) * newconnects);
441         if(!newptr)
442           /* we closed a few connections in vain, but so what? */
443           return CURLE_OUT_OF_MEMORY;
444
445         /* nullify the newly added pointers */
446         for(i=data->state.numconnects; i<newconnects; i++) {
447           newptr[i] = NULL;
448         }
449
450         data->state.connects = newptr;
451         data->state.numconnects = newconnects;
452       }
453       else {
454         /* zero makes NO cache at all */
455         if(data->state.connects)
456           free(data->state.connects);
457         data->state.connects=NULL;
458         data->state.numconnects=0;
459       }
460     }
461     break;
462   case CURLOPT_FORBID_REUSE:
463     /*
464      * When this transfer is done, it must not be left to be reused by a
465      * subsequent transfer but shall be closed immediately.
466      */
467     data->set.reuse_forbid = va_arg(param, long)?TRUE:FALSE;
468     break;
469   case CURLOPT_FRESH_CONNECT:
470     /*
471      * This transfer shall not use a previously cached connection but
472      * should be made with a fresh new connect!
473      */
474     data->set.reuse_fresh = va_arg(param, long)?TRUE:FALSE;
475     break;
476   case CURLOPT_VERBOSE:
477     /*
478      * Verbose means infof() calls that give a lot of information about
479      * the connection and transfer procedures as well as internal choices.
480      */
481     data->set.verbose = va_arg(param, long)?TRUE:FALSE;
482     break;
483   case CURLOPT_HEADER:
484     /*
485      * Set to include the header in the general data output stream.
486      */
487     data->set.include_header = va_arg(param, long)?TRUE:FALSE;
488     break;
489   case CURLOPT_NOPROGRESS:
490     /*
491      * Shut off the internal supported progress meter
492      */
493     data->set.hide_progress = va_arg(param, long)?TRUE:FALSE;
494     if(data->set.hide_progress)
495       data->progress.flags |= PGRS_HIDE;
496     else
497       data->progress.flags &= ~PGRS_HIDE;
498     break;
499   case CURLOPT_NOBODY:
500     /*
501      * Do not include the body part in the output data stream.
502      */
503     data->set.opt_no_body = va_arg(param, long)?TRUE:FALSE;
504     if(data->set.opt_no_body)
505       /* in HTTP lingo, this means using the HEAD request */
506       data->set.httpreq = HTTPREQ_HEAD;
507     break;
508   case CURLOPT_FAILONERROR:
509     /*
510      * Don't output the >=300 error code HTML-page, but instead only
511      * return error.
512      */
513     data->set.http_fail_on_error = va_arg(param, long)?TRUE:FALSE;
514     break;
515   case CURLOPT_UPLOAD:
516   case CURLOPT_PUT:
517     /*
518      * We want to sent data to the remote host. If this is HTTP, that equals
519      * using the PUT request.
520      */
521     data->set.upload = va_arg(param, long)?TRUE:FALSE;
522     if(data->set.upload)
523       /* If this is HTTP, PUT is what's needed to "upload" */
524       data->set.httpreq = HTTPREQ_PUT;
525     break;
526   case CURLOPT_FILETIME:
527     /*
528      * Try to get the file time of the remote document. The time will
529      * later (possibly) become available using curl_easy_getinfo().
530      */
531     data->set.get_filetime = va_arg(param, long)?TRUE:FALSE;
532     break;
533   case CURLOPT_FTP_CREATE_MISSING_DIRS:
534     /*
535      * An FTP option that modifies an upload to create missing directories on
536      * the server.
537      */
538     data->set.ftp_create_missing_dirs = va_arg( param , long )?TRUE:FALSE;
539     break;
540   case CURLOPT_FTP_RESPONSE_TIMEOUT:
541     /*
542      * An FTP option that specifies how quickly an FTP response must be
543      * obtained before it is considered failure.
544      */
545     data->set.ftp_response_timeout = va_arg( param , long );
546     break;
547   case CURLOPT_FTPLISTONLY:
548     /*
549      * An FTP option that changes the command to one that asks for a list
550      * only, no file info details.
551      */
552     data->set.ftp_list_only = va_arg(param, long)?TRUE:FALSE;
553     break;
554   case CURLOPT_FTPAPPEND:
555     /*
556      * We want to upload and append to an existing (FTP) file.
557      */
558     data->set.ftp_append = va_arg(param, long)?TRUE:FALSE;
559     break;
560   case CURLOPT_NETRC:
561     /*
562      * Parse the $HOME/.netrc file
563      */
564     data->set.use_netrc = (enum CURL_NETRC_OPTION)va_arg(param, long);
565     break;
566   case CURLOPT_NETRC_FILE:
567     /*
568      * Use this file instead of the $HOME/.netrc file
569      */
570     data->set.netrc_file = va_arg(param, char *);
571     break;
572   case CURLOPT_TRANSFERTEXT:
573     /*
574      * This option was previously named 'FTPASCII'. Renamed to work with
575      * more protocols than merely FTP.
576      *
577      * Transfer using ASCII (instead of BINARY).
578      */
579     data->set.ftp_ascii = va_arg(param, long)?TRUE:FALSE;
580     break;
581   case CURLOPT_TIMECONDITION:
582     /*
583      * Set HTTP time condition. This must be one of the defines in the
584      * curl/curl.h header file.
585      */
586     data->set.timecondition = (curl_TimeCond)va_arg(param, long);
587     break;
588   case CURLOPT_TIMEVALUE:
589     /*
590      * This is the value to compare with the remote document with the
591      * method set with CURLOPT_TIMECONDITION
592      */
593     data->set.timevalue = (time_t)va_arg(param, long);
594     break;
595   case CURLOPT_SSLVERSION:
596     /*
597      * Set explicit SSL version to try to connect with, as some SSL
598      * implementations are lame.
599      */
600     data->set.ssl.version = va_arg(param, long);
601     break;
602
603 #ifndef CURL_DISABLE_HTTP
604   case CURLOPT_AUTOREFERER:
605     /*
606      * Switch on automatic referer that gets set if curl follows locations.
607      */
608     data->set.http_auto_referer = va_arg(param, long)?1:0;
609     break;
610
611   case CURLOPT_ENCODING:
612     /*
613      * String to use at the value of Accept-Encoding header.
614      *
615      * If the encoding is set to "" we use an Accept-Encoding header that
616      * encompasses all the encodings we support.
617      * If the encoding is set to NULL we don't send an Accept-Encoding header
618      * and ignore an received Content-Encoding header.
619      *
620      */
621     data->set.encoding = va_arg(param, char *);
622     if(data->set.encoding && !*data->set.encoding)
623       data->set.encoding = (char*)ALL_CONTENT_ENCODINGS;
624     break;
625
626   case CURLOPT_FOLLOWLOCATION:
627     /*
628      * Follow Location: header hints on a HTTP-server.
629      */
630     data->set.http_follow_location = va_arg(param, long)?TRUE:FALSE;
631     break;
632
633   case CURLOPT_UNRESTRICTED_AUTH:
634     /*
635      * Send authentication (user+password) when following locations, even when
636      * hostname changed.
637      */
638     data->set.http_disable_hostname_check_before_authentication =
639       va_arg(param, long)?TRUE:FALSE;
640     break;
641
642   case CURLOPT_MAXREDIRS:
643     /*
644      * The maximum amount of hops you allow curl to follow Location:
645      * headers. This should mostly be used to detect never-ending loops.
646      */
647     data->set.maxredirs = va_arg(param, long);
648     break;
649
650   case CURLOPT_POST:
651     /* Does this option serve a purpose anymore? Yes it does, when
652        CURLOPT_POSTFIELDS isn't used and the POST data is read off the
653        callback! */
654     if(va_arg(param, long))
655       data->set.httpreq = HTTPREQ_POST;
656     else
657       data->set.httpreq = HTTPREQ_GET;
658     break;
659
660   case CURLOPT_POSTFIELDS:
661     /*
662      * A string with POST data. Makes curl HTTP POST. Even if it is NULL.
663      */
664     data->set.postfields = va_arg(param, char *);
665     data->set.httpreq = HTTPREQ_POST;
666     break;
667
668   case CURLOPT_POSTFIELDSIZE:
669     /*
670      * The size of the POSTFIELD data to prevent libcurl to do strlen() to
671      * figure it out. Enables binary posts.
672      */
673     data->set.postfieldsize = va_arg(param, long);
674     break;
675
676   case CURLOPT_POSTFIELDSIZE_LARGE:
677     /*
678      * The size of the POSTFIELD data to prevent libcurl to do strlen() to
679      * figure it out. Enables binary posts.
680      */
681     data->set.postfieldsize = va_arg(param, curl_off_t);
682     break;
683
684   case CURLOPT_HTTPPOST:
685     /*
686      * Set to make us do HTTP POST
687      */
688     data->set.httppost = va_arg(param, struct curl_httppost *);
689     data->set.httpreq = HTTPREQ_POST_FORM;
690     break;
691
692   case CURLOPT_REFERER:
693     /*
694      * String to set in the HTTP Referer: field.
695      */
696     if(data->change.referer_alloc) {
697       free(data->change.referer);
698       data->change.referer_alloc = FALSE;
699     }
700     data->set.set_referer = va_arg(param, char *);
701     data->change.referer = data->set.set_referer;
702     break;
703
704   case CURLOPT_USERAGENT:
705     /*
706      * String to use in the HTTP User-Agent field
707      */
708     data->set.useragent = va_arg(param, char *);
709     break;
710
711   case CURLOPT_HTTPHEADER:
712     /*
713      * Set a list with HTTP headers to use (or replace internals with)
714      */
715     data->set.headers = va_arg(param, struct curl_slist *);
716     break;
717
718   case CURLOPT_HTTP200ALIASES:
719     /*
720      * Set a list of aliases for HTTP 200 in response header
721      */
722     data->set.http200aliases = va_arg(param, struct curl_slist *);
723     break;
724
725 #if !defined(CURL_DISABLE_COOKIES)
726   case CURLOPT_COOKIE:
727     /*
728      * Cookie string to send to the remote server in the request.
729      */
730     data->set.cookie = va_arg(param, char *);
731     break;
732
733   case CURLOPT_COOKIEFILE:
734     /*
735      * Set cookie file to read and parse. Can be used multiple times.
736      */
737     argptr = (char *)va_arg(param, void *);
738     if(argptr) {
739       struct curl_slist *cl;
740       /* append the cookie file name to the list of file names, and deal with
741          them later */
742       cl = curl_slist_append(data->change.cookielist, argptr);
743
744       if(!cl)
745         return CURLE_OUT_OF_MEMORY;
746
747       data->change.cookielist = cl;
748     }
749     break;
750
751   case CURLOPT_COOKIEJAR:
752     /*
753      * Set cookie file name to dump all cookies to when we're done.
754      */
755     data->set.cookiejar = (char *)va_arg(param, void *);
756
757     /*
758      * Activate the cookie parser. This may or may not already
759      * have been made.
760      */
761     data->cookies = Curl_cookie_init(data, NULL, data->cookies,
762                                      data->set.cookiesession);
763     break;
764
765   case CURLOPT_COOKIESESSION:
766     /*
767      * Set this option to TRUE to start a new "cookie session". It will
768      * prevent the forthcoming read-cookies-from-file actions to accept
769      * cookies that are marked as being session cookies, as they belong to a
770      * previous session.
771      *
772      * In the original Netscape cookie spec, "session cookies" are cookies
773      * with no expire date set. RFC2109 describes the same action if no
774      * 'Max-Age' is set and RFC2965 includes the RFC2109 description and adds
775      * a 'Discard' action that can enforce the discard even for cookies that
776      * have a Max-Age.
777      *
778      * We run mostly with the original cookie spec, as hardly anyone implements
779      * anything else.
780      */
781     data->set.cookiesession = (bool)va_arg(param, long);
782     break;
783 #endif /* CURL_DISABLE_COOKIES */
784
785   case CURLOPT_HTTPGET:
786     /*
787      * Set to force us do HTTP GET
788      */
789     if(va_arg(param, long)) {
790       data->set.httpreq = HTTPREQ_GET;
791       data->set.upload = FALSE; /* switch off upload */
792     }
793     break;
794
795   case CURLOPT_HTTP_VERSION:
796     /*
797      * This sets a requested HTTP version to be used. The value is one of
798      * the listed enums in curl/curl.h.
799      */
800     data->set.httpversion = va_arg(param, long);
801     break;
802
803   case CURLOPT_HTTPPROXYTUNNEL:
804     /*
805      * Tunnel operations through the proxy instead of normal proxy use
806      */
807     data->set.tunnel_thru_httpproxy = va_arg(param, long)?TRUE:FALSE;
808     break;
809
810   case CURLOPT_CUSTOMREQUEST:
811     /*
812      * Set a custom string to use as request
813      */
814     data->set.customrequest = va_arg(param, char *);
815
816     /* we don't set
817        data->set.httpreq = HTTPREQ_CUSTOM;
818        here, we continue as if we were using the already set type
819        and this just changes the actual request keyword */
820     break;
821
822   case CURLOPT_PROXYPORT:
823     /*
824      * Explicitly set HTTP proxy port number.
825      */
826     data->set.proxyport = va_arg(param, long);
827     break;
828
829   case CURLOPT_HTTPAUTH:
830     /*
831      * Set HTTP Authentication type BITMASK.
832      */
833   {
834     long auth = va_arg(param, long);
835     /* switch off bits we can't support */
836 #if ! defined(USE_SSLEAY) && !defined(USE_WINDOWS_SSPI)
837     auth &= ~CURLAUTH_NTLM; /* no NTLM without SSL */
838 #endif
839 #ifndef HAVE_GSSAPI
840     auth &= ~CURLAUTH_GSSNEGOTIATE; /* no GSS-Negotiate without GSSAPI */
841 #endif
842     if(!auth)
843       return CURLE_FAILED_INIT; /* no supported types left! */
844
845     data->set.httpauth = auth;
846   }
847   break;
848
849   case CURLOPT_PROXYAUTH:
850     /*
851      * Set HTTP Authentication type BITMASK.
852      */
853   {
854     long auth = va_arg(param, long);
855     /* switch off bits we can't support */
856 #ifndef USE_SSLEAY
857     auth &= ~CURLAUTH_NTLM; /* no NTLM without SSL */
858 #endif
859 #ifndef HAVE_GSSAPI
860     auth &= ~CURLAUTH_GSSNEGOTIATE; /* no GSS-Negotiate without GSSAPI */
861 #endif
862     if(!auth)
863       return CURLE_FAILED_INIT; /* no supported types left! */
864
865     data->set.proxyauth = auth;
866   }
867   break;
868 #endif   /* CURL_DISABLE_HTTP */
869
870   case CURLOPT_PROXY:
871     /*
872      * Set proxy server:port to use as HTTP proxy.
873      *
874      * If the proxy is set to "" we explicitly say that we don't want to use a
875      * proxy (even though there might be environment variables saying so).
876      *
877      * Setting it to NULL, means no proxy but allows the environment variables
878      * to decide for us.
879      */
880     if(data->change.proxy_alloc) {
881       /*
882        * The already set string is allocated, free that first
883        */
884       data->change.proxy_alloc=FALSE;;
885       free(data->change.proxy);
886     }
887     data->set.set_proxy = va_arg(param, char *);
888     data->change.proxy = data->set.set_proxy;
889     break;
890
891   case CURLOPT_WRITEHEADER:
892     /*
893      * Custom pointer to pass the header write callback function
894      */
895     data->set.writeheader = (void *)va_arg(param, void *);
896     break;
897   case CURLOPT_ERRORBUFFER:
898     /*
899      * Error buffer provided by the caller to get the human readable
900      * error string in.
901      */
902     data->set.errorbuffer = va_arg(param, char *);
903     break;
904   case CURLOPT_FILE:
905     /*
906      * FILE pointer to write to or include in the data write callback
907      */
908     data->set.out = va_arg(param, FILE *);
909     break;
910   case CURLOPT_FTPPORT:
911     /*
912      * Use FTP PORT, this also specifies which IP address to use
913      */
914     data->set.ftpport = va_arg(param, char *);
915     data->set.ftp_use_port = data->set.ftpport?1:0;
916     break;
917
918   case CURLOPT_FTP_USE_EPRT:
919     data->set.ftp_use_eprt = va_arg(param, long)?TRUE:FALSE;
920     data->set.ftp_use_lprt = data->set.ftp_use_eprt;
921     break;
922
923   case CURLOPT_FTP_USE_EPSV:
924     data->set.ftp_use_epsv = va_arg(param, long)?TRUE:FALSE;
925     break;
926
927   case CURLOPT_INFILE:
928     /*
929      * FILE pointer to read the file to be uploaded from. Or possibly
930      * used as argument to the read callback.
931      */
932     data->set.in = va_arg(param, FILE *);
933     break;
934   case CURLOPT_INFILESIZE:
935     /*
936      * If known, this should inform curl about the file size of the
937      * to-be-uploaded file.
938      */
939     data->set.infilesize = va_arg(param, long);
940     break;
941   case CURLOPT_INFILESIZE_LARGE:
942     /*
943      * If known, this should inform curl about the file size of the
944      * to-be-uploaded file.
945      */
946     data->set.infilesize = va_arg(param, curl_off_t);
947     break;
948   case CURLOPT_LOW_SPEED_LIMIT:
949     /*
950      * The low speed limit that if transfers are below this for
951      * CURLOPT_LOW_SPEED_TIME, the transfer is aborted.
952      */
953     data->set.low_speed_limit=va_arg(param, long);
954     break;
955   case CURLOPT_LOW_SPEED_TIME:
956     /*
957      * The low speed time that if transfers are below the set
958      * CURLOPT_LOW_SPEED_LIMIT during this time, the transfer is aborted.
959      */
960     data->set.low_speed_time=va_arg(param, long);
961     break;
962   case CURLOPT_URL:
963     /*
964      * The URL to fetch.
965      */
966     if(data->change.url_alloc) {
967       /* the already set URL is allocated, free it first! */
968       free(data->change.url);
969       data->change.url_alloc=FALSE;
970     }
971     data->set.set_url = va_arg(param, char *);
972     data->change.url = data->set.set_url;
973     data->change.url_changed = TRUE;
974     break;
975   case CURLOPT_PORT:
976     /*
977      * The port number to use when getting the URL
978      */
979     data->set.use_port = va_arg(param, long);
980     break;
981   case CURLOPT_TIMEOUT:
982     /*
983      * The maximum time you allow curl to use for a single transfer
984      * operation.
985      */
986     data->set.timeout = va_arg(param, long);
987     break;
988   case CURLOPT_CONNECTTIMEOUT:
989     /*
990      * The maximum time you allow curl to use to connect.
991      */
992     data->set.connecttimeout = va_arg(param, long);
993     break;
994
995   case CURLOPT_USERPWD:
996     /*
997      * user:password to use in the operation
998      */
999     data->set.userpwd = va_arg(param, char *);
1000     break;
1001   case CURLOPT_POSTQUOTE:
1002     /*
1003      * List of RAW FTP commands to use after a transfer
1004      */
1005     data->set.postquote = va_arg(param, struct curl_slist *);
1006     break;
1007   case CURLOPT_PREQUOTE:
1008     /*
1009      * List of RAW FTP commands to use prior to RETR (Wesley Laxton)
1010      */
1011     data->set.prequote = va_arg(param, struct curl_slist *);
1012     break;
1013   case CURLOPT_QUOTE:
1014     /*
1015      * List of RAW FTP commands to use before a transfer
1016      */
1017     data->set.quote = va_arg(param, struct curl_slist *);
1018     break;
1019   case CURLOPT_PROGRESSFUNCTION:
1020     /*
1021      * Progress callback function
1022      */
1023     data->set.fprogress = va_arg(param, curl_progress_callback);
1024     if(data->set.fprogress)
1025       data->progress.callback = TRUE; /* no longer internal */
1026     else
1027       data->progress.callback = FALSE; /* NULL enforces internal */
1028
1029     break;
1030   case CURLOPT_PROGRESSDATA:
1031     /*
1032      * Custom client data to pass to the progress callback
1033      */
1034     data->set.progress_client = va_arg(param, void *);
1035     break;
1036   case CURLOPT_PROXYUSERPWD:
1037     /*
1038      * user:password needed to use the proxy
1039      */
1040     data->set.proxyuserpwd = va_arg(param, char *);
1041     break;
1042   case CURLOPT_RANGE:
1043     /*
1044      * What range of the file you want to transfer
1045      */
1046     data->set.set_range = va_arg(param, char *);
1047     break;
1048   case CURLOPT_RESUME_FROM:
1049     /*
1050      * Resume transfer at the give file position
1051      */
1052     data->set.set_resume_from = va_arg(param, long);
1053     break;
1054   case CURLOPT_RESUME_FROM_LARGE:
1055     /*
1056      * Resume transfer at the give file position
1057      */
1058     data->set.set_resume_from = va_arg(param, curl_off_t);
1059     break;
1060   case CURLOPT_DEBUGFUNCTION:
1061     /*
1062      * stderr write callback.
1063      */
1064     data->set.fdebug = va_arg(param, curl_debug_callback);
1065     /*
1066      * if the callback provided is NULL, it'll use the default callback
1067      */
1068     break;
1069   case CURLOPT_DEBUGDATA:
1070     /*
1071      * Set to a void * that should receive all error writes. This
1072      * defaults to CURLOPT_STDERR for normal operations.
1073      */
1074     data->set.debugdata = va_arg(param, void *);
1075     break;
1076   case CURLOPT_STDERR:
1077     /*
1078      * Set to a FILE * that should receive all error writes. This
1079      * defaults to stderr for normal operations.
1080      */
1081     data->set.err = va_arg(param, FILE *);
1082     if(!data->set.err)
1083       data->set.err = stderr;
1084     break;
1085   case CURLOPT_HEADERFUNCTION:
1086     /*
1087      * Set header write callback
1088      */
1089     data->set.fwrite_header = va_arg(param, curl_write_callback);
1090     break;
1091   case CURLOPT_WRITEFUNCTION:
1092     /*
1093      * Set data write callback
1094      */
1095     data->set.fwrite = va_arg(param, curl_write_callback);
1096     if(!data->set.fwrite)
1097       /* When set to NULL, reset to our internal default function */
1098       data->set.fwrite = (curl_write_callback)fwrite;
1099     break;
1100   case CURLOPT_READFUNCTION:
1101     /*
1102      * Read data callback
1103      */
1104     data->set.fread = va_arg(param, curl_read_callback);
1105     if(!data->set.fread)
1106       /* When set to NULL, reset to our internal default function */
1107       data->set.fread = (curl_read_callback)fread;
1108     break;
1109   case CURLOPT_IOCTLFUNCTION:
1110     /*
1111      * I/O control callback. Might be NULL.
1112      */
1113     data->set.ioctl = va_arg(param, curl_ioctl_callback);
1114     break;
1115   case CURLOPT_IOCTLDATA:
1116     /*
1117      * I/O control data pointer. Might be NULL.
1118      */
1119     data->set.ioctl_client = va_arg(param, void *);
1120     break;
1121   case CURLOPT_SSLCERT:
1122     /*
1123      * String that holds file name of the SSL certificate to use
1124      */
1125     data->set.cert = va_arg(param, char *);
1126     break;
1127   case CURLOPT_SSLCERTTYPE:
1128     /*
1129      * String that holds file type of the SSL certificate to use
1130      */
1131     data->set.cert_type = va_arg(param, char *);
1132     break;
1133   case CURLOPT_SSLKEY:
1134     /*
1135      * String that holds file name of the SSL certificate to use
1136      */
1137     data->set.key = va_arg(param, char *);
1138     break;
1139   case CURLOPT_SSLKEYTYPE:
1140     /*
1141      * String that holds file type of the SSL certificate to use
1142      */
1143     data->set.key_type = va_arg(param, char *);
1144     break;
1145   case CURLOPT_SSLKEYPASSWD:
1146     /*
1147      * String that holds the SSL private key password.
1148      */
1149     data->set.key_passwd = va_arg(param, char *);
1150     break;
1151   case CURLOPT_SSLENGINE:
1152     /*
1153      * String that holds the SSL crypto engine.
1154      */
1155     argptr = va_arg(param, char *);
1156     if (argptr && argptr[0])
1157        result = Curl_SSL_set_engine(data, argptr);
1158     break;
1159
1160   case CURLOPT_SSLENGINE_DEFAULT:
1161     /*
1162      * flag to set engine as default.
1163      */
1164     result = Curl_SSL_set_engine_default(data);
1165     break;
1166   case CURLOPT_CRLF:
1167     /*
1168      * Kludgy option to enable CRLF convertions. Subject for removal.
1169      */
1170     data->set.crlf = va_arg(param, long)?TRUE:FALSE;
1171     break;
1172   case CURLOPT_INTERFACE:
1173     /*
1174      * Set what interface to bind to when performing an operation and thus
1175      * what from-IP your connection will use.
1176      */
1177     data->set.device = va_arg(param, char *);
1178     break;
1179   case CURLOPT_KRB4LEVEL:
1180     /*
1181      * A string that defines the krb4 security level.
1182      */
1183     data->set.krb4_level = va_arg(param, char *);
1184     data->set.krb4=data->set.krb4_level?TRUE:FALSE;
1185     break;
1186   case CURLOPT_SSL_VERIFYPEER:
1187     /*
1188      * Enable peer SSL verifying.
1189      */
1190     data->set.ssl.verifypeer = va_arg(param, long);
1191     break;
1192   case CURLOPT_SSL_VERIFYHOST:
1193     /*
1194      * Enable verification of the CN contained in the peer certificate
1195      */
1196     data->set.ssl.verifyhost = va_arg(param, long);
1197     break;
1198   case CURLOPT_SSL_CTX_FUNCTION:
1199     /*
1200      * Set a SSL_CTX callback
1201      */
1202        data->set.ssl.fsslctx = va_arg(param, curl_ssl_ctx_callback);
1203     break;
1204   case CURLOPT_SSL_CTX_DATA:
1205     /*
1206      * Set a SSL_CTX callback parameter pointer
1207      */
1208     data->set.ssl.fsslctxp = va_arg(param, void *);
1209     break;
1210   case CURLOPT_CAINFO:
1211     /*
1212      * Set CA info for SSL connection. Specify file name of the CA certificate
1213      */
1214     data->set.ssl.CAfile = va_arg(param, char *);
1215     break;
1216   case CURLOPT_CAPATH:
1217     /*
1218      * Set CA path info for SSL connection. Specify directory name of the CA
1219      * certificates which have been prepared using openssl c_rehash utility.
1220      */
1221     /* This does not work on windows. */
1222     data->set.ssl.CApath = va_arg(param, char *);
1223     break;
1224   case CURLOPT_TELNETOPTIONS:
1225     /*
1226      * Set a linked list of telnet options
1227      */
1228     data->set.telnet_options = va_arg(param, struct curl_slist *);
1229     break;
1230
1231   case CURLOPT_BUFFERSIZE:
1232     /*
1233      * The application kindly asks for a differently sized receive buffer.
1234      * If it seems reasonable, we'll use it.
1235      */
1236     data->set.buffer_size = va_arg(param, long);
1237
1238     if((data->set.buffer_size> (BUFSIZE -1 )) ||
1239        (data->set.buffer_size < 1))
1240       data->set.buffer_size = 0; /* huge internal default */
1241
1242     break;
1243
1244   case CURLOPT_NOSIGNAL:
1245     /*
1246      * The application asks not to set any signal() or alarm() handlers,
1247      * even when using a timeout.
1248      */
1249     data->set.no_signal = va_arg(param, long) ? TRUE : FALSE;
1250     break;
1251
1252   case CURLOPT_SHARE:
1253     {
1254       struct Curl_share *set;
1255       set = va_arg(param, struct Curl_share *);
1256
1257       /* disconnect from old share, if any */
1258       if(data->share) {
1259         Curl_share_lock(data, CURL_LOCK_DATA_SHARE, CURL_LOCK_ACCESS_SINGLE);
1260
1261         if(data->share->hostcache == data->hostcache)
1262           data->hostcache = NULL;
1263
1264         if(data->share->cookies == data->cookies)
1265           data->cookies = NULL;
1266
1267         data->share->dirty--;
1268
1269         Curl_share_unlock(data, CURL_LOCK_DATA_SHARE);
1270         data->share = NULL;
1271       }
1272
1273       /* use new share if it set */
1274       data->share = set;
1275       if(data->share) {
1276
1277         Curl_share_lock(data, CURL_LOCK_DATA_SHARE, CURL_LOCK_ACCESS_SINGLE);
1278
1279         data->share->dirty++;
1280
1281         if(data->share->hostcache) {
1282           /* use shared host cache, first free own one if any */
1283           if(data->hostcache)
1284             Curl_hash_destroy(data->hostcache);
1285
1286           data->hostcache = data->share->hostcache;
1287         }
1288 #if !defined(CURL_DISABLE_HTTP) && !defined(CURL_DISABLE_COOKIES)
1289         if(data->share->cookies) {
1290           /* use shared cookie list, first free own one if any */
1291           if (data->cookies)
1292             Curl_cookie_cleanup(data->cookies);
1293           data->cookies = data->share->cookies;
1294         }
1295 #endif   /* CURL_DISABLE_HTTP */
1296         Curl_share_unlock(data, CURL_LOCK_DATA_SHARE);
1297
1298       }
1299 #if !defined(CURL_DISABLE_HTTP) && !defined(CURL_DISABLE_COOKIES)
1300       /* check cookie list is set */
1301       if(!data->cookies)
1302         data->cookies = Curl_cookie_init(data, NULL, NULL, TRUE );
1303 #endif   /* CURL_DISABLE_HTTP */
1304       /* check for host cache not needed,
1305        * it will be done by curl_easy_perform */
1306     }
1307     break;
1308
1309   case CURLOPT_PROXYTYPE:
1310     /*
1311      * Set proxy type. HTTP/SOCKS4/SOCKS5
1312      */
1313     data->set.proxytype = (curl_proxytype)va_arg(param, long);
1314     break;
1315
1316   case CURLOPT_PRIVATE:
1317     /*
1318      * Set private data pointer.
1319      */
1320     data->set.private_data = va_arg(param, char *);
1321     break;
1322
1323   case CURLOPT_MAXFILESIZE:
1324     /*
1325      * Set the maximum size of a file to download.
1326      */
1327     data->set.max_filesize = va_arg(param, long);
1328     break;
1329
1330   case CURLOPT_FTP_SSL:
1331     /*
1332      * Make FTP transfers attempt to use SSL/TLS.
1333      */
1334     data->set.ftp_ssl = (curl_ftpssl)va_arg(param, long);
1335     break;
1336
1337   case CURLOPT_FTPSSLAUTH:
1338     /*
1339      * Set a specific auth for FTP-SSL transfers.
1340      */
1341     data->set.ftpsslauth = (curl_ftpauth)va_arg(param, long);
1342     break;
1343
1344   case CURLOPT_IPRESOLVE:
1345     data->set.ip_version = va_arg(param, long);
1346     break;
1347
1348   case CURLOPT_MAXFILESIZE_LARGE:
1349     /*
1350      * Set the maximum size of a file to download.
1351      */
1352     data->set.max_filesize = va_arg(param, curl_off_t);
1353     break;
1354
1355   case CURLOPT_TCP_NODELAY:
1356     /*
1357      * Enable or disable TCP_NODELAY, which will disable/enable the Nagle
1358      * algorithm
1359      */
1360     data->set.tcp_nodelay = (bool)va_arg(param, long);
1361     break;
1362
1363   /*********** 3rd party transfer options ***********/
1364   case CURLOPT_SOURCE_URL:
1365     /*
1366      * SOURCE URL
1367      */
1368     data->set.source_url = va_arg(param, char *);
1369     data->set.printhost = (data->set.source_url != NULL);
1370     break;
1371
1372   case CURLOPT_SOURCE_USERPWD:
1373     /*
1374      * Use SOURCE USER[:PASSWORD]
1375      */
1376     data->set.source_userpwd = va_arg(param, char *);
1377     break;
1378
1379   case CURLOPT_SOURCE_QUOTE:
1380     /*
1381      * List of RAW FTP commands to use after a connect
1382      */
1383     data->set.source_quote = va_arg(param, struct curl_slist *);
1384     break;
1385
1386   case CURLOPT_SOURCE_PREQUOTE:
1387     /*
1388      * List of RAW FTP commands to use before a transfer on the source host
1389      */
1390     data->set.source_prequote = va_arg(param, struct curl_slist *);
1391     break;
1392
1393   case CURLOPT_SOURCE_POSTQUOTE:
1394     /*
1395      * List of RAW FTP commands to use after a transfer on the source host
1396      */
1397     data->set.source_postquote = va_arg(param, struct curl_slist *);
1398     break;
1399
1400   case CURLOPT_FTP_ACCOUNT:
1401     data->set.ftp_account = va_arg(param, char *);
1402     break;
1403
1404   default:
1405     /* unknown tag and its companion, just ignore: */
1406     result = CURLE_FAILED_INIT; /* correct this */
1407     break;
1408   }
1409
1410   return result;
1411 }
1412
1413 CURLcode Curl_disconnect(struct connectdata *conn)
1414 {
1415   struct SessionHandle *data;
1416   if(!conn)
1417     return CURLE_OK; /* this is closed and fine already */
1418
1419   data = conn->data;
1420
1421 #if defined(CURLDEBUG) && defined(AGGRESIVE_TEST)
1422   /* scan for DNS cache entries still marked as in use */
1423   Curl_hash_apply(data->hostcache,
1424                   NULL, Curl_scan_cache_used);
1425 #endif
1426
1427   Curl_hostcache_prune(data); /* kill old DNS cache entries */
1428
1429   /*
1430    * The range string is usually freed in curl_done(), but we might
1431    * get here *instead* if we fail prematurely. Thus we need to be able
1432    * to free this resource here as well.
1433    */
1434   if(conn->bits.rangestringalloc) {
1435     free(conn->range);
1436     conn->bits.rangestringalloc = FALSE;
1437   }
1438
1439   if((conn->ntlm.state != NTLMSTATE_NONE) ||
1440      (conn->proxyntlm.state != NTLMSTATE_NONE)) {
1441     /* Authentication data is a mix of connection-related and sessionhandle-
1442        related stuff. NTLM is connection-related so when we close the shop
1443        we shall forget. */
1444     data->state.authhost.done = FALSE;
1445     data->state.authhost.picked =
1446       data->state.authhost.want;
1447
1448     data->state.authproxy.done = FALSE;
1449     data->state.authproxy.picked =
1450       data->state.authhost.want;
1451
1452     data->state.authproblem = FALSE;
1453
1454 #if defined(USE_SSLEAY) || defined(USE_WINDOWS_SSPI)
1455     Curl_ntlm_cleanup(conn);
1456 #endif
1457   }
1458
1459   if(conn->curl_disconnect)
1460     /* This is set if protocol-specific cleanups should be made */
1461     conn->curl_disconnect(conn);
1462
1463   if(-1 != conn->connectindex) {
1464     /* unlink ourselves! */
1465     infof(data, "Closing connection #%ld\n", conn->connectindex);
1466     data->state.connects[conn->connectindex] = NULL;
1467   }
1468
1469   Curl_safefree(conn->proto.generic);
1470   Curl_safefree(conn->newurl);
1471   Curl_safefree(conn->pathbuffer); /* the URL path buffer */
1472
1473   Curl_safefree(conn->host.rawalloc); /* host name buffer */
1474   Curl_safefree(conn->proxy.rawalloc); /* proxy name buffer */
1475 #ifdef USE_LIBIDN
1476   if(conn->host.encalloc)
1477     idn_free(conn->host.encalloc); /* encoded host name buffer, must be freed
1478                                       with idn_free() since this was allocated
1479                                       by libidn */
1480   if(conn->proxy.encalloc)
1481     idn_free(conn->proxy.encalloc); /* encoded proxy name buffer, must be
1482                                        freed with idn_free() since this was
1483                                        allocated by libidn */
1484 #endif
1485   Curl_SSL_Close(conn);
1486
1487   /* close possibly still open sockets */
1488   if(CURL_SOCKET_BAD != conn->sock[SECONDARYSOCKET])
1489     sclose(conn->sock[SECONDARYSOCKET]);
1490   if(CURL_SOCKET_BAD != conn->sock[FIRSTSOCKET])
1491     sclose(conn->sock[FIRSTSOCKET]);
1492
1493   Curl_safefree(conn->user);
1494   Curl_safefree(conn->passwd);
1495   Curl_safefree(conn->proxyuser);
1496   Curl_safefree(conn->proxypasswd);
1497   Curl_safefree(conn->allocptr.proxyuserpwd);
1498   Curl_safefree(conn->allocptr.uagent);
1499   Curl_safefree(conn->allocptr.userpwd);
1500   Curl_safefree(conn->allocptr.accept_encoding);
1501   Curl_safefree(conn->allocptr.rangeline);
1502   Curl_safefree(conn->allocptr.ref);
1503   Curl_safefree(conn->allocptr.host);
1504   Curl_safefree(conn->allocptr.cookiehost);
1505   Curl_safefree(conn->ip_addr_str);
1506
1507 #if defined(USE_ARES) || defined(USE_THREADING_GETHOSTBYNAME) || \
1508     defined(USE_THREADING_GETADDRINFO)
1509   /* possible left-overs from the async name resolve */
1510   Curl_safefree(conn->async.hostname);
1511   Curl_safefree(conn->async.os_specific);
1512 #endif
1513
1514   Curl_free_ssl_config(&conn->ssl_config);
1515
1516   free(conn); /* free all the connection oriented data */
1517
1518   return CURLE_OK;
1519 }
1520
1521 /*
1522  * This function should return TRUE if the socket is to be assumed to
1523  * be dead. Most commonly this happens when the server has closed the
1524  * connection due to inactivity.
1525  */
1526 static bool SocketIsDead(curl_socket_t sock)
1527 {
1528   int sval;
1529   bool ret_val = TRUE;
1530
1531   sval = Curl_select(sock, CURL_SOCKET_BAD, 0);
1532   if(sval == 0)
1533     /* timeout */
1534     ret_val = FALSE;
1535
1536   return ret_val;
1537 }
1538
1539 /*
1540  * Given one filled in connection struct (named needle), this function should
1541  * detect if there already is one that have all the significant details
1542  * exactly the same and thus should be used instead.
1543  */
1544 static bool
1545 ConnectionExists(struct SessionHandle *data,
1546                  struct connectdata *needle,
1547                  struct connectdata **usethis)
1548 {
1549   long i;
1550   struct connectdata *check;
1551
1552   for(i=0; i< data->state.numconnects; i++) {
1553     bool match = FALSE;
1554     /*
1555      * Note that if we use a HTTP proxy, we check connections to that
1556      * proxy and not to the actual remote server.
1557      */
1558     check = data->state.connects[i];
1559     if(!check)
1560       /* NULL pointer means not filled-in entry */
1561       continue;
1562
1563     if((needle->protocol&PROT_SSL) != (check->protocol&PROT_SSL))
1564       /* don't do mixed SSL and non-SSL connections */
1565       continue;
1566
1567     if(!needle->bits.httpproxy || needle->protocol&PROT_SSL) {
1568       /* The requested connection does not use a HTTP proxy or it
1569          uses SSL. */
1570
1571       if(!(needle->protocol&PROT_SSL) && check->bits.httpproxy)
1572         /* we don't do SSL but the cached connection has a proxy,
1573            then don't match this */
1574         continue;
1575
1576       if(strequal(needle->protostr, check->protostr) &&
1577          strequal(needle->host.name, check->host.name) &&
1578          (needle->remote_port == check->remote_port) ) {
1579         if(needle->protocol & PROT_SSL) {
1580           /* This is SSL, verify that we're using the same
1581              ssl options as well */
1582           if(!Curl_ssl_config_matches(&needle->ssl_config,
1583                                       &check->ssl_config)) {
1584             continue;
1585           }
1586         }
1587         if((needle->protocol & PROT_FTP) ||
1588            ((needle->protocol & PROT_HTTP) &&
1589             (needle->data->state.authhost.want==CURLAUTH_NTLM))) {
1590           /* This is FTP or HTTP+NTLM, verify that we're using the same name
1591              and password as well */
1592           if(!strequal(needle->user, check->user) ||
1593              !strequal(needle->passwd, check->passwd)) {
1594             /* one of them was different */
1595             continue;
1596           }
1597         }
1598         match = TRUE;
1599       }
1600     }
1601     else { /* The requested needle connection is using a proxy,
1602               is the checked one using the same? */
1603       if(check->bits.httpproxy &&
1604          strequal(needle->proxy.name, check->proxy.name) &&
1605          needle->port == check->port) {
1606         /* This is the same proxy connection, use it! */
1607         match = TRUE;
1608       }
1609     }
1610
1611     if(match) {
1612       bool dead = SocketIsDead(check->sock[FIRSTSOCKET]);
1613       if(dead) {
1614         /*
1615          */
1616         infof(data, "Connection %d seems to be dead!\n", i);
1617         Curl_disconnect(check); /* disconnect resources */
1618         data->state.connects[i]=NULL; /* nothing here */
1619
1620         /* There's no need to continue searching, because we only store
1621            one connection for each unique set of identifiers */
1622         return FALSE;
1623       }
1624
1625       *usethis = check;
1626       return TRUE; /* yes, we found one to use! */
1627     }
1628   }
1629   return FALSE; /* no matching connecting exists */
1630 }
1631
1632 /*
1633  * This function frees/closes a connection in the connection cache. This
1634  * should take the previously set policy into account when deciding which
1635  * of the connections to kill.
1636  */
1637 static long
1638 ConnectionKillOne(struct SessionHandle *data)
1639 {
1640   long i;
1641   struct connectdata *conn;
1642   long highscore=-1;
1643   long connindex=-1;
1644   long score;
1645   struct timeval now;
1646
1647   now = Curl_tvnow();
1648
1649   for(i=0; i< data->state.numconnects; i++) {
1650     conn = data->state.connects[i];
1651
1652     if(!conn)
1653       continue;
1654
1655     /*
1656      * By using the set policy, we score each connection.
1657      */
1658     switch(data->set.closepolicy) {
1659     case CURLCLOSEPOLICY_LEAST_RECENTLY_USED:
1660     default:
1661       /*
1662        * Set higher score for the age passed since the connection
1663        * was used.
1664        */
1665       score = Curl_tvdiff(now, conn->now);
1666       break;
1667     case CURLCLOSEPOLICY_OLDEST:
1668       /*
1669        * Set higher score for the age passed since the connection
1670        * was created.
1671        */
1672       score = Curl_tvdiff(now, conn->created);
1673       break;
1674     }
1675
1676     if(score > highscore) {
1677       highscore = score;
1678       connindex = i;
1679     }
1680   }
1681   if(connindex >= 0) {
1682
1683     /* the winner gets the honour of being disconnected */
1684     (void) Curl_disconnect(data->state.connects[connindex]);
1685
1686     /* clean the array entry */
1687     data->state.connects[connindex] = NULL;
1688   }
1689
1690   return connindex; /* return the available index or -1 */
1691 }
1692
1693 /*
1694  * The given input connection struct pointer is to be stored. If the "cache"
1695  * is already full, we must clean out the most suitable using the previously
1696  * set policy.
1697  *
1698  * The given connection should be unique. That must've been checked prior to
1699  * this call.
1700  */
1701 static long
1702 ConnectionStore(struct SessionHandle *data,
1703                 struct connectdata *conn)
1704 {
1705   long i;
1706   for(i=0; i< data->state.numconnects; i++) {
1707     if(!data->state.connects[i])
1708       break;
1709   }
1710   if(i == data->state.numconnects) {
1711     /* there was no room available, kill one */
1712     i = ConnectionKillOne(data);
1713     infof(data, "Connection (#%d) was killed to make room\n", i);
1714   }
1715
1716   if(-1 != i) {
1717     /* only do this if a true index was returned, if -1 was returned there
1718        is no room in the cache for an unknown reason and we cannot store
1719        this there. */
1720     data->state.connects[i] = conn; /* fill in this */
1721     conn->connectindex = i; /* make the child know where the pointer to this
1722                                particular data is stored */
1723   }
1724   return i;
1725 }
1726
1727 /*
1728  * This function logs in to a SOCKS5 proxy and sends the specifies the final
1729  * desitination server.
1730  */
1731 static int handleSock5Proxy(const char *proxy_name,
1732                             const char *proxy_password,
1733                             struct connectdata *conn)
1734 {
1735   /*
1736     According to the RFC1928, section "6.  Replies". This is what a SOCK5
1737     replies:
1738
1739         +----+-----+-------+------+----------+----------+
1740         |VER | REP |  RSV  | ATYP | BND.ADDR | BND.PORT |
1741         +----+-----+-------+------+----------+----------+
1742         | 1  |  1  | X'00' |  1   | Variable |    2     |
1743         +----+-----+-------+------+----------+----------+
1744
1745     Where:
1746
1747     o  VER    protocol version: X'05'
1748     o  REP    Reply field:
1749     o  X'00' succeeded
1750   */
1751
1752   unsigned char socksreq[600]; /* room for large user/pw (255 max each) */
1753   ssize_t actualread;
1754   ssize_t written;
1755   int result;
1756   CURLcode code;
1757   int sock = conn->sock[FIRSTSOCKET];
1758
1759   Curl_nonblock(sock, FALSE);
1760
1761   socksreq[0] = 5; /* version */
1762   socksreq[1] = (char)(proxy_name ? 2 : 1); /* number of methods (below) */
1763   socksreq[2] = 0; /* no authentication */
1764   socksreq[3] = 2; /* username/password */
1765
1766   code = Curl_write(conn, sock, (char *)socksreq, (2 + (int)socksreq[1]),
1767                       &written);
1768   if ((code != CURLE_OK) || (written != (2 + (int)socksreq[1]))) {
1769     failf(conn->data, "Unable to send initial SOCKS5 request.");
1770     return 1;
1771   }
1772
1773   result=Curl_read(conn, sock, (char *)socksreq, 2, &actualread);
1774   if ((result != CURLE_OK) || (actualread != 2)) {
1775     failf(conn->data, "Unable to receive initial SOCKS5 response.");
1776     return 1;
1777   }
1778
1779   if (socksreq[0] != 5) {
1780     failf(conn->data, "Received invalid version in initial SOCKS5 response.");
1781     return 1;
1782   }
1783   if (socksreq[1] == 0) {
1784     /* Nothing to do, no authentication needed */
1785     ;
1786   }
1787   else if (socksreq[1] == 2) {
1788     /* Needs user name and password */
1789     int userlen, pwlen, len;
1790
1791     userlen = (int)strlen(proxy_name);
1792     pwlen = proxy_password?(int)strlen(proxy_password):0;
1793
1794     /*   username/password request looks like
1795      * +----+------+----------+------+----------+
1796      * |VER | ULEN |  UNAME   | PLEN |  PASSWD  |
1797      * +----+------+----------+------+----------+
1798      * | 1  |  1   | 1 to 255 |  1   | 1 to 255 |
1799      * +----+------+----------+------+----------+
1800      */
1801     len = 0;
1802     socksreq[len++] = 1;    /* username/pw subnegotiation version */
1803     socksreq[len++] = (char) userlen;
1804     memcpy(socksreq + len, proxy_name, (int) userlen);
1805     len += userlen;
1806     socksreq[len++] = (char) pwlen;
1807     memcpy(socksreq + len, proxy_password, (int) pwlen);
1808     len += pwlen;
1809
1810     code = Curl_write(conn, sock, (char *)socksreq, len, &written);
1811     if ((code != CURLE_OK) || (len != written)) {
1812       failf(conn->data, "Failed to send SOCKS5 sub-negotiation request.");
1813       return 1;
1814     }
1815
1816     result=Curl_read(conn, sock, (char *)socksreq, 2, &actualread);
1817     if ((result != CURLE_OK) || (actualread != 2)) {
1818       failf(conn->data, "Unable to receive SOCKS5 sub-negotiation response.");
1819       return 1;
1820     }
1821
1822     /* ignore the first (VER) byte */
1823     if (socksreq[1] != 0) { /* status */
1824       failf(conn->data, "User was rejected by the SOCKS5 server (%d %d).",
1825             socksreq[0], socksreq[1]);
1826       return 1;
1827     }
1828
1829     /* Everything is good so far, user was authenticated! */
1830   }
1831   else {
1832     /* error */
1833     if (socksreq[1] == 1) {
1834       failf(conn->data,
1835             "SOCKS5 GSSAPI per-message authentication is not supported.");
1836       return 1;
1837     }
1838     else if (socksreq[1] == 255) {
1839       if (!proxy_name || !*proxy_name) {
1840         failf(conn->data,
1841               "No authentication method was acceptable. (It is quite likely"
1842               " that the SOCKS5 server wanted a username/password, since none"
1843               " was supplied to the server on this connection.)");
1844       }
1845       else {
1846         failf(conn->data, "No authentication method was acceptable.");
1847       }
1848       return 1;
1849     }
1850     else {
1851       failf(conn->data,
1852             "Undocumented SOCKS5 mode attempted to be used by server.");
1853       return 1;
1854     }
1855   }
1856
1857   /* Authentication is complete, now specify destination to the proxy */
1858   socksreq[0] = 5; /* version (SOCKS5) */
1859   socksreq[1] = 1; /* connect */
1860   socksreq[2] = 0; /* must be zero */
1861   socksreq[3] = 1; /* IPv4 = 1 */
1862
1863   {
1864     struct Curl_dns_entry *dns;
1865     Curl_addrinfo *hp=NULL;
1866     int rc = Curl_resolv(conn, conn->host.name, (int)conn->remote_port, &dns);
1867
1868     if(rc == CURLRESOLV_ERROR)
1869       return 1;
1870
1871     if(rc == CURLRESOLV_PENDING)
1872       /* this requires that we're in "wait for resolve" state */
1873       rc = Curl_wait_for_resolv(conn, &dns);
1874
1875     /*
1876      * We cannot use 'hostent' as a struct that Curl_resolv() returns.  It
1877      * returns a Curl_addrinfo pointer that may not always look the same.
1878      */
1879     if(dns)
1880       hp=dns->addr;
1881     if (hp) {
1882       char buf[64];
1883       unsigned short ip[4];
1884       Curl_printable_address(hp, buf, sizeof(buf));
1885
1886       if(4 == sscanf( buf, "%hu.%hu.%hu.%hu",
1887                       &ip[0], &ip[1], &ip[2], &ip[3])) {
1888         socksreq[4] = (unsigned char)ip[0];
1889         socksreq[5] = (unsigned char)ip[1];
1890         socksreq[6] = (unsigned char)ip[2];
1891         socksreq[7] = (unsigned char)ip[3];
1892       }
1893       else
1894         hp = NULL; /* fail! */
1895
1896       Curl_resolv_unlock(conn->data, dns); /* not used anymore from now on */
1897     }
1898     if(!hp) {
1899       failf(conn->data, "Failed to resolve \"%s\" for SOCKS5 connect.",
1900             conn->host.name);
1901       return 1;
1902     }
1903   }
1904
1905   *((unsigned short*)&socksreq[8]) = htons(conn->remote_port);
1906
1907   {
1908     const int packetsize = 10;
1909
1910     code = Curl_write(conn, sock, (char *)socksreq, packetsize, &written);
1911     if ((code != CURLE_OK) || (written != packetsize)) {
1912       failf(conn->data, "Failed to send SOCKS5 connect request.");
1913       return 1;
1914     }
1915
1916     result = Curl_read(conn, sock, (char *)socksreq, packetsize, &actualread);
1917     if ((result != CURLE_OK) || (actualread != packetsize)) {
1918       failf(conn->data, "Failed to receive SOCKS5 connect request ack.");
1919       return 1;
1920     }
1921
1922     if (socksreq[0] != 5) { /* version */
1923       failf(conn->data,
1924             "SOCKS5 reply has wrong version, version should be 5.");
1925       return 1;
1926     }
1927     if (socksreq[1] != 0) { /* Anything besides 0 is an error */
1928         failf(conn->data,
1929               "Can't complete SOCKS5 connection to %d.%d.%d.%d:%d. (%d)",
1930               (unsigned char)socksreq[4], (unsigned char)socksreq[5],
1931               (unsigned char)socksreq[6], (unsigned char)socksreq[7],
1932               (unsigned int)ntohs(*(unsigned short*)(&socksreq[8])),
1933               socksreq[1]);
1934         return 1;
1935     }
1936   }
1937
1938   Curl_nonblock(sock, TRUE);
1939   return 0; /* Proxy was successful! */
1940 }
1941
1942 static CURLcode ConnectPlease(struct connectdata *conn,
1943                               struct Curl_dns_entry *hostaddr,
1944                               bool *connected)
1945 {
1946   CURLcode result;
1947   Curl_addrinfo *addr;
1948   struct SessionHandle *data = conn->data;
1949   char *hostname = data->change.proxy?conn->proxy.name:conn->host.name;
1950
1951   infof(data, "About to connect() to %s port %d\n",
1952         hostname, conn->port);
1953
1954   /*************************************************************
1955    * Connect to server/proxy
1956    *************************************************************/
1957   result= Curl_connecthost(conn,
1958                            hostaddr,
1959                            &conn->sock[FIRSTSOCKET],
1960                            &addr,
1961                            connected);
1962   if(CURLE_OK == result) {
1963     /* All is cool, then we store the current information */
1964     conn->dns_entry = hostaddr;
1965     conn->ip_addr = addr;
1966
1967     Curl_store_ip_addr(conn);
1968
1969     if (conn->data->set.proxytype == CURLPROXY_SOCKS5) {
1970       return handleSock5Proxy(conn->proxyuser,
1971                               conn->proxypasswd,
1972                               conn) ?
1973         CURLE_COULDNT_CONNECT : CURLE_OK;
1974     }
1975     else if (conn->data->set.proxytype == CURLPROXY_HTTP) {
1976       /* do nothing here. handled later. */
1977     }
1978     else {
1979       failf(conn->data, "unknown proxytype option given");
1980       return CURLE_COULDNT_CONNECT;
1981     }
1982   }
1983
1984   return result;
1985 }
1986
1987 /*
1988  * verboseconnect() displays verbose information after a connect
1989  */
1990 static void verboseconnect(struct connectdata *conn)
1991 {
1992   infof(conn->data, "Connected to %s (%s) port %d\n",
1993         conn->bits.httpproxy ? conn->proxy.dispname : conn->host.dispname,
1994         conn->ip_addr_str, conn->port);
1995 }
1996
1997 CURLcode Curl_protocol_fdset(struct connectdata *conn,
1998                              fd_set *read_fd_set,
1999                              fd_set *write_fd_set,
2000                              int *max_fdp)
2001 {
2002   CURLcode res = CURLE_OK;
2003   if(conn->curl_proto_fdset)
2004     res = conn->curl_proto_fdset(conn, read_fd_set, write_fd_set, max_fdp);
2005   return res;
2006 }
2007
2008 CURLcode Curl_doing_fdset(struct connectdata *conn,
2009                           fd_set *read_fd_set,
2010                           fd_set *write_fd_set,
2011                           int *max_fdp)
2012 {
2013   CURLcode res = CURLE_OK;
2014   if(conn && conn->curl_doing_fdset)
2015     res = conn->curl_doing_fdset(conn, read_fd_set, write_fd_set, max_fdp);
2016   return res;
2017 }
2018
2019 /*
2020  * We are doing protocol-specific connecting and this is being called over and
2021  * over from the multi interface until the connection phase is done on
2022  * protocol layer.
2023  */
2024
2025 CURLcode Curl_protocol_connecting(struct connectdata *conn, bool *done)
2026 {
2027   CURLcode result=CURLE_OK;
2028
2029   if(conn && conn->curl_connecting) {
2030     *done = FALSE;
2031     result = conn->curl_connecting(conn, done);
2032   }
2033   else
2034     *done = TRUE;
2035
2036   return result;
2037 }
2038
2039 /*
2040  * We are DOING this is being called over and over from the multi interface
2041  * until the DOING phase is done on protocol layer.
2042  */
2043
2044 CURLcode Curl_protocol_doing(struct connectdata *conn, bool *done)
2045 {
2046   CURLcode result=CURLE_OK;
2047
2048   if(conn && conn->curl_doing) {
2049     *done = FALSE;
2050     result = conn->curl_doing(conn, done);
2051   }
2052   else
2053     *done = TRUE;
2054
2055   return result;
2056 }
2057
2058 /*
2059  * We have discovered that the TCP connection has been successful, we can now
2060  * proceed with some action.
2061  *
2062  */
2063 CURLcode Curl_protocol_connect(struct connectdata *conn, bool *protocol_done)
2064 {
2065   struct SessionHandle *data = conn->data;
2066   CURLcode result=CURLE_OK;
2067
2068   *protocol_done = FALSE;
2069
2070   if(conn->bits.tcpconnect && conn->bits.protoconnstart) {
2071     /* We already are connected, get back. This may happen when the connect
2072        worked fine in the first call, like when we connect to a local server
2073        or proxy. Note that we don't know if the protocol is actually done.
2074
2075        Unless this protocol doesn't have any protocol-connect callback, as
2076        then we know we're done. */
2077     if(!conn->curl_connecting)
2078       *protocol_done = TRUE;
2079
2080     return CURLE_OK;
2081   }
2082
2083   if(!conn->bits.tcpconnect) {
2084
2085     Curl_pgrsTime(data, TIMER_CONNECT); /* connect done */
2086
2087     if(data->set.verbose)
2088       verboseconnect(conn);
2089   }
2090
2091   if(!conn->bits.protoconnstart) {
2092     if(conn->curl_connect) {
2093       /* is there a protocol-specific connect() procedure? */
2094
2095       /* Set start time here for timeout purposes in the connect procedure, it
2096          is later set again for the progress meter purpose */
2097       conn->now = Curl_tvnow();
2098
2099       /* Call the protocol-specific connect function */
2100       result = conn->curl_connect(conn, protocol_done);
2101     }
2102     else
2103       *protocol_done = TRUE;
2104
2105     /* it has started, possibly even completed but that knowledge isn't stored
2106        in this bit! */
2107     conn->bits.protoconnstart = TRUE;
2108   }
2109
2110   return result; /* pass back status */
2111 }
2112
2113 /*
2114  * Helpers for IDNA convertions.
2115  */
2116 #ifdef USE_LIBIDN
2117 static bool is_ASCII_name (const char *hostname)
2118 {
2119   const unsigned char *ch = (const unsigned char*)hostname;
2120
2121   while (*ch) {
2122     if (*ch++ & 0x80)
2123       return FALSE;
2124   }
2125   return TRUE;
2126 }
2127
2128 /*
2129  * Check if characters in hostname is allowed in Top Level Domain.
2130  */
2131 static bool tld_check_name (struct SessionHandle *data,
2132                             const char *ace_hostname)
2133 {
2134   size_t err_pos;
2135   char *uc_name = NULL;
2136   int rc;
2137
2138   /* Convert (and downcase) ACE-name back into locale's character set */
2139   rc = idna_to_unicode_lzlz(ace_hostname, &uc_name, 0);
2140   if (rc != IDNA_SUCCESS)
2141     return (FALSE);
2142
2143   rc = tld_check_lz(uc_name, &err_pos, NULL);
2144   if (rc == TLD_INVALID)
2145      infof(data, "WARNING: %s; pos %u = `%c'/0x%02X\n",
2146 #ifdef HAVE_TLD_STRERROR
2147            tld_strerror(rc),
2148 #else
2149            "<no msg>",
2150 #endif
2151            err_pos, uc_name[err_pos],
2152            uc_name[err_pos] & 255);
2153   else if (rc != TLD_SUCCESS)
2154        infof(data, "WARNING: TLD check for %s failed; %s\n",
2155              uc_name,
2156 #ifdef HAVE_TLD_STRERROR
2157              tld_strerror(rc)
2158 #else
2159              "<no msg>"
2160 #endif
2161          );
2162   if (uc_name)
2163      idn_free(uc_name);
2164   return (rc == TLD_SUCCESS);
2165 }
2166 #endif
2167
2168 static void fix_hostname(struct connectdata *conn, struct hostname *host)
2169 {
2170   /* set the name we use to display the host name */
2171   host->dispname = host->name;
2172
2173 #ifdef USE_LIBIDN
2174   /*************************************************************
2175    * Check name for non-ASCII and convert hostname to ACE form.
2176    *************************************************************/
2177   if (!is_ASCII_name(host->name) &&
2178       stringprep_check_version(LIBIDN_REQUIRED_VERSION)) {
2179     char *ace_hostname = NULL;
2180     struct SessionHandle *data = conn->data;
2181     int rc = idna_to_ascii_lz(host->name, &ace_hostname, 0);
2182     infof (data, "Input domain encoded as `%s'\n",
2183            stringprep_locale_charset ());
2184     if (rc != IDNA_SUCCESS)
2185       infof(data, "Failed to convert %s to ACE; %s\n",
2186             host->name, Curl_idn_strerror(conn,rc));
2187     else {
2188       tld_check_name(data, ace_hostname);
2189
2190       host->encalloc = ace_hostname;
2191       /* change the name pointer to point to the encoded hostname */
2192       host->name = host->encalloc;
2193     }
2194   }
2195 #else
2196   (void)conn; /* never used */
2197 #endif
2198 }
2199
2200
2201 /**
2202  * CreateConnection() sets up a new connectdata struct, or re-uses an already
2203  * existing one, and resolves host name.
2204  *
2205  * if this function returns CURLE_OK and *async is set to TRUE, the resolve
2206  * response will be coming asynchronously. If *async is FALSE, the name is
2207  * already resolved.
2208  *
2209  * @param data The sessionhandle pointer
2210  * @param in_connect is set to the next connection data pointer
2211  * @param addr is set to the new dns entry for this connection
2212  * @param async is set TRUE/FALSE depending on the nature of this lookup
2213  * @return CURLcode
2214  * @see SetupConnection()
2215  */
2216
2217 static CURLcode CreateConnection(struct SessionHandle *data,
2218                                  struct connectdata **in_connect,
2219                                  struct Curl_dns_entry **addr,
2220                                  bool *async)
2221 {
2222   char *tmp;
2223   char *at;
2224   CURLcode result=CURLE_OK;
2225   struct connectdata *conn;
2226   struct connectdata *conn_temp;
2227   size_t urllen;
2228   struct Curl_dns_entry *hostaddr;
2229 #if defined(HAVE_ALARM) && !defined(USE_ARES)
2230   unsigned int prev_alarm=0;
2231 #endif
2232   char endbracket;
2233   char user[MAX_CURL_USER_LENGTH];
2234   char passwd[MAX_CURL_PASSWORD_LENGTH];
2235   int rc;
2236   bool reuse;
2237
2238 #ifndef USE_ARES
2239 #ifdef SIGALRM
2240 #ifdef HAVE_SIGACTION
2241   struct sigaction keep_sigact;   /* store the old struct here */
2242   bool keep_copysig=FALSE;        /* did copy it? */
2243 #else
2244 #ifdef HAVE_SIGNAL
2245   void *keep_sigact;              /* store the old handler here */
2246 #endif /* HAVE_SIGNAL */
2247 #endif /* HAVE_SIGACTION */
2248 #endif /* SIGALRM */
2249 #endif /* USE_ARES */
2250
2251   *addr = NULL; /* nothing yet */
2252   *async = FALSE;
2253
2254   /*************************************************************
2255    * Check input data
2256    *************************************************************/
2257
2258   if(!data->change.url)
2259     return CURLE_URL_MALFORMAT;
2260
2261   /* First, split up the current URL in parts so that we can use the
2262      parts for checking against the already present connections. In order
2263      to not have to modify everything at once, we allocate a temporary
2264      connection data struct and fill in for comparison purposes. */
2265
2266   conn = (struct connectdata *)calloc(sizeof(struct connectdata), 1);
2267   if(!conn) {
2268     *in_connect = NULL; /* clear the pointer */
2269     return CURLE_OUT_OF_MEMORY;
2270   }
2271   /* We must set the return variable as soon as possible, so that our
2272      parent can cleanup any possible allocs we may have done before
2273      any failure */
2274   *in_connect = conn;
2275
2276   /* and we setup a few fields in case we end up actually using this struct */
2277   conn->data = data;           /* remember our daddy */
2278   conn->sock[FIRSTSOCKET] = CURL_SOCKET_BAD;     /* no file descriptor */
2279   conn->sock[SECONDARYSOCKET] = CURL_SOCKET_BAD; /* no file descriptor */
2280   conn->connectindex = -1;    /* no index */
2281   conn->bits.httpproxy = (data->change.proxy && *data->change.proxy &&
2282                           (data->set.proxytype == CURLPROXY_HTTP))?
2283     TRUE:FALSE; /* http proxy or not */
2284
2285   /* Default protocol-independent behavior doesn't support persistant
2286      connections, so we set this to force-close. Protocols that support
2287      this need to set this to FALSE in their "curl_do" functions. */
2288   conn->bits.close = TRUE;
2289
2290   /* maxdownload must be -1 on init, as 0 is a valid value! */
2291   conn->maxdownload = -1;  /* might have been used previously! */
2292
2293   /* Store creation time to help future close decision making */
2294   conn->created = Curl_tvnow();
2295
2296   conn->bits.use_range = data->set.set_range?TRUE:FALSE; /* range status */
2297   conn->range = data->set.set_range;              /* clone the range setting */
2298   conn->resume_from = data->set.set_resume_from;   /* inherite resume_from */
2299
2300   conn->bits.user_passwd = data->set.userpwd?1:0;
2301   conn->bits.proxy_user_passwd = data->set.proxyuserpwd?1:0;
2302   conn->bits.no_body = data->set.opt_no_body;
2303   conn->bits.tunnel_proxy = data->set.tunnel_thru_httpproxy;
2304   conn->bits.ftp_use_epsv = data->set.ftp_use_epsv;
2305   conn->bits.ftp_use_eprt = data->set.ftp_use_eprt;
2306   conn->bits.ftp_use_lprt = data->set.ftp_use_lprt;
2307
2308   /* This initing continues below, see the comment "Continue connectdata
2309    * initialization here" */
2310
2311   /***********************************************************
2312    * We need to allocate memory to store the path in. We get the size of the
2313    * full URL to be sure, and we need to make it at least 256 bytes since
2314    * other parts of the code will rely on this fact
2315    ***********************************************************/
2316 #define LEAST_PATH_ALLOC 256
2317   urllen=strlen(data->change.url);
2318   if(urllen < LEAST_PATH_ALLOC)
2319     urllen=LEAST_PATH_ALLOC;
2320
2321   conn->pathbuffer=(char *)malloc(urllen);
2322   if(NULL == conn->pathbuffer)
2323     return CURLE_OUT_OF_MEMORY; /* really bad error */
2324   conn->path = conn->pathbuffer;
2325
2326   conn->host.rawalloc=(char *)malloc(urllen);
2327   if(NULL == conn->host.rawalloc)
2328     return CURLE_OUT_OF_MEMORY;
2329   conn->host.name = conn->host.rawalloc;
2330   conn->host.name[0] = 0;
2331
2332   /*************************************************************
2333    * Parse the URL.
2334    *
2335    * We need to parse the url even when using the proxy, because we will need
2336    * the hostname and port in case we are trying to SSL connect through the
2337    * proxy -- and we don't know if we will need to use SSL until we parse the
2338    * url ...
2339    ************************************************************/
2340   if((2 == sscanf(data->change.url, "%15[^:]:%[^\n]",
2341                   conn->protostr,
2342                   conn->path)) && strequal(conn->protostr, "file")) {
2343     if(conn->path[0] == '/' && conn->path[1] == '/') {
2344       /* Allow omitted hostname (e.g. file:/<path>).  This is not strictly
2345        * speaking a valid file: URL by RFC 1738, but treating file:/<path> as
2346        * file://localhost/<path> is similar to how other schemes treat missing
2347        * hostnames.  See RFC 1808. */
2348
2349       /* This cannot be done with strcpy() in a portable manner, since the
2350          memory areas overlap! */
2351       memmove(conn->path, conn->path + 2, strlen(conn->path + 2)+1);
2352     }
2353     /*
2354      * we deal with file://<host>/<path> differently since it supports no
2355      * hostname other than "localhost" and "127.0.0.1", which is unique among
2356      * the URL protocols specified in RFC 1738
2357      */
2358     if(conn->path[0] != '/') {
2359       /* the URL included a host name, we ignore host names in file:// URLs
2360          as the standards don't define what to do with them */
2361       char *ptr=strchr(conn->path, '/');
2362       if(ptr) {
2363         /* there was a slash present
2364
2365            RFC1738 (section 3.1, page 5) says:
2366
2367            The rest of the locator consists of data specific to the scheme,
2368            and is known as the "url-path". It supplies the details of how the
2369            specified resource can be accessed. Note that the "/" between the
2370            host (or port) and the url-path is NOT part of the url-path.
2371
2372            As most agents use file://localhost/foo to get '/foo' although the
2373            slash preceeding foo is a separator and not a slash for the path,
2374            a URL as file://localhost//foo must be valid as well, to refer to
2375            the same file with an absolute path.
2376         */
2377
2378         if(ptr[1] && ('/' == ptr[1]))
2379           /* if there was two slashes, we skip the first one as that is then
2380              used truly as a separator */
2381           ptr++;
2382
2383         /* This cannot be made with strcpy, as the memory chunks overlap! */
2384         memmove(conn->path, ptr, strlen(ptr)+1);
2385       }
2386     }
2387
2388     strcpy(conn->protostr, "file"); /* store protocol string lowercase */
2389   }
2390   else {
2391     /* Set default path */
2392     strcpy(conn->path, "/");
2393
2394     if (2 > sscanf(data->change.url,
2395                    "%15[^\n:]://%[^\n/]%[^\n]",
2396                    conn->protostr,
2397                    conn->host.name, conn->path)) {
2398
2399       /*
2400        * The URL was badly formatted, let's try the browser-style _without_
2401        * protocol specified like 'http://'.
2402        */
2403       if((1 > sscanf(data->change.url, "%[^\n/]%[^\n]",
2404                      conn->host.name, conn->path)) ) {
2405         /*
2406          * We couldn't even get this format.
2407          */
2408         failf(data, "<url> malformed");
2409         return CURLE_URL_MALFORMAT;
2410       }
2411
2412       /*
2413        * Since there was no protocol part specified, we guess what protocol it
2414        * is based on the first letters of the server name.
2415        */
2416
2417       /* Note: if you add a new protocol, please update the list in
2418        * lib/version.c too! */
2419
2420       if(checkprefix("GOPHER.", conn->host.name))
2421         strcpy(conn->protostr, "gopher");
2422 #ifdef USE_SSLEAY
2423       else if(checkprefix("FTPS", conn->host.name))
2424         strcpy(conn->protostr, "ftps");
2425 #endif /* USE_SSLEAY */
2426       else if(checkprefix("FTP.", conn->host.name))
2427         strcpy(conn->protostr, "ftp");
2428       else if(checkprefix("TELNET.", conn->host.name))
2429         strcpy(conn->protostr, "telnet");
2430       else if (checkprefix("DICT.", conn->host.name))
2431         strcpy(conn->protostr, "DICT");
2432       else if (checkprefix("LDAP.", conn->host.name))
2433         strcpy(conn->protostr, "LDAP");
2434       else {
2435         strcpy(conn->protostr, "http");
2436       }
2437
2438       conn->protocol |= PROT_MISSING; /* not given in URL */
2439     }
2440   }
2441
2442   /* We search for '?' in the host name (but only on the right side of a
2443    * @-letter to allow ?-letters in username and password) to handle things
2444    * like http://example.com?param= (notice the missing '/').
2445    */
2446   at = strchr(conn->host.name, '@');
2447   if(at)
2448     tmp = strchr(at+1, '?');
2449   else
2450     tmp = strchr(conn->host.name, '?');
2451
2452   if(tmp) {
2453     /* The right part of the ?-letter needs to be moved to prefix
2454        the current path buffer! */
2455     size_t len = strlen(tmp);
2456     /* move the existing path plus the zero byte */
2457     memmove(conn->path+len+1, conn->path, strlen(conn->path)+1);
2458     conn->path[0]='/'; /* prepend the missing slash */
2459     memcpy(conn->path+1, tmp, len); /* now copy the prefix part */
2460     *tmp=0; /* now cut off the hostname at the ? */
2461   }
2462
2463   /* If the URL is malformatted (missing a '/' after hostname before path) we
2464    * insert a slash here. The only letter except '/' we accept to start a path
2465    * is '?'.
2466    */
2467   if(conn->path[0] == '?') {
2468     /* We need this function to deal with overlapping memory areas. We know
2469        that the memory area 'path' points to is 'urllen' bytes big and that
2470        is bigger than the path. Use +1 to move the zero byte too. */
2471     memmove(&conn->path[1], conn->path, strlen(conn->path)+1);
2472     conn->path[0] = '/';
2473   }
2474
2475   /*
2476    * So if the URL was A://B/C,
2477    *   conn->protostr is A
2478    *   conn->host.name is B
2479    *   conn->path is /C
2480    */
2481
2482   /*************************************************************
2483    * Take care of proxy authentication stuff
2484    *************************************************************/
2485   if(conn->bits.proxy_user_passwd) {
2486     char proxyuser[MAX_CURL_USER_LENGTH]="";
2487     char proxypasswd[MAX_CURL_PASSWORD_LENGTH]="";
2488
2489     sscanf(data->set.proxyuserpwd,
2490            "%" MAX_CURL_USER_LENGTH_TXT "[^:]:"
2491            "%" MAX_CURL_PASSWORD_LENGTH_TXT "[^\n]",
2492            proxyuser, proxypasswd);
2493
2494     conn->proxyuser = strdup(proxyuser);
2495     if(!conn->proxyuser)
2496       return CURLE_OUT_OF_MEMORY;
2497
2498     conn->proxypasswd = strdup(proxypasswd);
2499     if(!conn->proxypasswd)
2500       return CURLE_OUT_OF_MEMORY;
2501   }
2502
2503 #ifndef CURL_DISABLE_HTTP
2504   /*************************************************************
2505    * Detect what (if any) proxy to use
2506    *************************************************************/
2507   if(!data->change.proxy) {
2508     /* If proxy was not specified, we check for default proxy environment
2509      * variables, to enable i.e Lynx compliance:
2510      *
2511      * http_proxy=http://some.server.dom:port/
2512      * https_proxy=http://some.server.dom:port/
2513      * ftp_proxy=http://some.server.dom:port/
2514      * gopher_proxy=http://some.server.dom:port/
2515      * no_proxy=domain1.dom,host.domain2.dom
2516      *   (a comma-separated list of hosts which should
2517      *   not be proxied, or an asterisk to override
2518      *   all proxy variables)
2519      * all_proxy=http://some.server.dom:port/
2520      *   (seems to exist for the CERN www lib. Probably
2521      *   the first to check for.)
2522      *
2523      * For compatibility, the all-uppercase versions of these variables are
2524      * checked if the lowercase versions don't exist.
2525      */
2526     char *no_proxy=NULL;
2527     char *no_proxy_tok_buf;
2528     char *proxy=NULL;
2529     char proxy_env[128];
2530
2531     no_proxy=curl_getenv("no_proxy");
2532     if(!no_proxy)
2533       no_proxy=curl_getenv("NO_PROXY");
2534
2535     if(!no_proxy || !strequal("*", no_proxy)) {
2536       /* NO_PROXY wasn't specified or it wasn't just an asterisk */
2537       char *nope;
2538
2539       nope=no_proxy?strtok_r(no_proxy, ", ", &no_proxy_tok_buf):NULL;
2540       while(nope) {
2541         size_t namelen;
2542         char *endptr = strchr(conn->host.name, ':');
2543         if(endptr)
2544           namelen=endptr-conn->host.name;
2545         else
2546           namelen=strlen(conn->host.name);
2547
2548         if(strlen(nope) <= namelen) {
2549           char *checkn=
2550             conn->host.name + namelen - strlen(nope);
2551           if(checkprefix(nope, checkn)) {
2552             /* no proxy for this host! */
2553             break;
2554           }
2555         }
2556         nope=strtok_r(NULL, ", ", &no_proxy_tok_buf);
2557       }
2558       if(!nope) {
2559         /* It was not listed as without proxy */
2560         char *protop = conn->protostr;
2561         char *envp = proxy_env;
2562         char *prox;
2563
2564         /* Now, build <protocol>_proxy and check for such a one to use */
2565         while(*protop)
2566           *envp++ = tolower((int)*protop++);
2567
2568         /* append _proxy */
2569         strcpy(envp, "_proxy");
2570
2571         /* read the protocol proxy: */
2572         prox=curl_getenv(proxy_env);
2573
2574         /*
2575          * We don't try the uppercase version of HTTP_PROXY because of
2576          * security reasons:
2577          *
2578          * When curl is used in a webserver application
2579          * environment (cgi or php), this environment variable can
2580          * be controlled by the web server user by setting the
2581          * http header 'Proxy:' to some value.
2582          *
2583          * This can cause 'internal' http/ftp requests to be
2584          * arbitrarily redirected by any external attacker.
2585          */
2586         if(!prox && !strequal("http_proxy", proxy_env)) {
2587           /* There was no lowercase variable, try the uppercase version: */
2588           for(envp = proxy_env; *envp; envp++)
2589             *envp = toupper((int)*envp);
2590           prox=curl_getenv(proxy_env);
2591         }
2592
2593         if(prox && *prox) { /* don't count "" strings */
2594           proxy = prox; /* use this */
2595         }
2596         else {
2597           proxy = curl_getenv("all_proxy"); /* default proxy to use */
2598           if(!proxy)
2599             proxy=curl_getenv("ALL_PROXY");
2600         }
2601
2602         if(proxy && *proxy) {
2603           /* we have a proxy here to set */
2604           char *ptr;
2605           char proxyuser[MAX_CURL_USER_LENGTH];
2606           char proxypasswd[MAX_CURL_PASSWORD_LENGTH];
2607
2608           char *fineptr;
2609
2610           /* skip the possible protocol piece */
2611           ptr=strstr(proxy, "://");
2612           if(ptr)
2613             ptr += 3;
2614           else
2615             ptr = proxy;
2616
2617           fineptr = ptr;
2618
2619           /* check for an @-letter */
2620           ptr = strchr(ptr, '@');
2621           if(ptr && (2 == sscanf(fineptr,
2622                                  "%" MAX_CURL_USER_LENGTH_TXT"[^:]:"
2623                                  "%" MAX_CURL_PASSWORD_LENGTH_TXT "[^@]",
2624                                  proxyuser, proxypasswd))) {
2625             CURLcode res = CURLE_OK;
2626
2627             /* found user and password, rip them out */
2628             Curl_safefree(conn->proxyuser);
2629             conn->proxyuser = strdup(proxyuser);
2630
2631             if(!conn->proxyuser)
2632               res = CURLE_OUT_OF_MEMORY;
2633             else {
2634               Curl_safefree(conn->proxypasswd);
2635               conn->proxypasswd = strdup(proxypasswd);
2636
2637               if(!conn->proxypasswd)
2638                 res = CURLE_OUT_OF_MEMORY;
2639             }
2640
2641             if(CURLE_OK == res) {
2642               conn->bits.proxy_user_passwd = TRUE; /* enable it */
2643               ptr = strdup(ptr+1); /* the right side of the @-letter */
2644
2645               if(ptr) {
2646                 free(proxy); /* free the former proxy string */
2647                 proxy = ptr; /* now use this instead */
2648               }
2649               else
2650                 res = CURLE_OUT_OF_MEMORY;
2651             }
2652
2653             if(res) {
2654               free(proxy); /* free the allocated proxy string */
2655               return res;
2656             }
2657           }
2658
2659           data->change.proxy = proxy;
2660           data->change.proxy_alloc=TRUE; /* this needs to be freed later */
2661           conn->bits.httpproxy = TRUE;
2662         }
2663       } /* if (!nope) - it wasn't specified non-proxy */
2664     } /* NO_PROXY wasn't specified or '*' */
2665     if(no_proxy)
2666       free(no_proxy);
2667   } /* if not using proxy */
2668 #endif /* CURL_DISABLE_HTTP */
2669
2670   /*************************************************************
2671    * No protocol part in URL was used, add it!
2672    *************************************************************/
2673   if(conn->protocol&PROT_MISSING) {
2674     /* We're guessing prefixes here and if we're told to use a proxy or if
2675        we're gonna follow a Location: later or... then we need the protocol
2676        part added so that we have a valid URL. */
2677     char *reurl;
2678
2679     reurl = aprintf("%s://%s", conn->protostr, data->change.url);
2680
2681     if(!reurl)
2682       return CURLE_OUT_OF_MEMORY;
2683
2684     data->change.url = reurl;
2685     data->change.url_alloc = TRUE; /* free this later */
2686     conn->protocol &= ~PROT_MISSING; /* switch that one off again */
2687   }
2688
2689 #ifndef CURL_DISABLE_HTTP
2690   /************************************************************
2691    * RESUME on a HTTP page is a tricky business. First, let's just check that
2692    * 'range' isn't used, then set the range parameter and leave the resume as
2693    * it is to inform about this situation for later use. We will then
2694    * "attempt" to resume, and if we're talking to a HTTP/1.1 (or later)
2695    * server, we will get the document resumed. If we talk to a HTTP/1.0
2696    * server, we just fail since we can't rewind the file writing from within
2697    * this function.
2698    ***********************************************************/
2699   if(conn->resume_from) {
2700     if(!conn->bits.use_range) {
2701       /* if it already was in use, we just skip this */
2702       conn->range = aprintf("%" FORMAT_OFF_T "-", conn->resume_from);
2703       if(!conn->range)
2704         return CURLE_OUT_OF_MEMORY;
2705       conn->bits.rangestringalloc = TRUE; /* mark as allocated */
2706       conn->bits.use_range = 1; /* switch on range usage */
2707     }
2708   }
2709 #endif
2710   /*************************************************************
2711    * Setup internals depending on protocol
2712    *************************************************************/
2713
2714   if (strequal(conn->protostr, "HTTP")) {
2715 #ifndef CURL_DISABLE_HTTP
2716     conn->port = (data->set.use_port && data->state.allow_port)?
2717       data->set.use_port:PORT_HTTP;
2718     conn->remote_port = PORT_HTTP;
2719     conn->protocol |= PROT_HTTP;
2720     conn->curl_do = Curl_http;
2721     conn->curl_do_more = NULL;
2722     conn->curl_done = Curl_http_done;
2723     conn->curl_connect = Curl_http_connect;
2724 #else
2725     failf(data, LIBCURL_NAME
2726           " was built with HTTP disabled, http: not supported!");
2727     return CURLE_UNSUPPORTED_PROTOCOL;
2728 #endif
2729   }
2730   else if (strequal(conn->protostr, "HTTPS")) {
2731 #if defined(USE_SSLEAY) && !defined(CURL_DISABLE_HTTP)
2732
2733     conn->port = (data->set.use_port && data->state.allow_port)?
2734       data->set.use_port:PORT_HTTPS;
2735     conn->remote_port = PORT_HTTPS;
2736     conn->protocol |= PROT_HTTP|PROT_HTTPS|PROT_SSL;
2737
2738     conn->curl_do = Curl_http;
2739     conn->curl_do_more = NULL;
2740     conn->curl_done = Curl_http_done;
2741     conn->curl_connect = Curl_http_connect;
2742
2743 #else /* USE_SSLEAY */
2744     failf(data, LIBCURL_NAME
2745           " was built with SSL disabled, https: not supported!");
2746     return CURLE_UNSUPPORTED_PROTOCOL;
2747 #endif /* !USE_SSLEAY */
2748   }
2749   else if (strequal(conn->protostr, "GOPHER")) {
2750 #ifndef CURL_DISABLE_GOPHER
2751     conn->port = (data->set.use_port && data->state.allow_port)?
2752       data->set.use_port:PORT_GOPHER;
2753     conn->remote_port = PORT_GOPHER;
2754     /* Skip /<item-type>/ in path if present */
2755     if (isdigit((int)conn->path[1])) {
2756       conn->path = strchr(&conn->path[1], '/');
2757       if (conn->path == NULL)
2758         conn->path = conn->pathbuffer;
2759     }
2760     conn->protocol |= PROT_GOPHER;
2761     conn->curl_do = Curl_http;
2762     conn->curl_do_more = NULL;
2763     conn->curl_done = Curl_http_done;
2764 #else
2765     failf(data, LIBCURL_NAME
2766           " was built with GOPHER disabled, gopher: not supported!");
2767 #endif
2768   }
2769   else if(strequal(conn->protostr, "FTP") ||
2770           strequal(conn->protostr, "FTPS")) {
2771
2772 #ifndef CURL_DISABLE_FTP
2773     char *type;
2774     int port = PORT_FTP;
2775
2776     if(strequal(conn->protostr, "FTPS")) {
2777 #ifdef USE_SSLEAY
2778       conn->protocol |= PROT_FTPS|PROT_SSL;
2779       conn->ssl[SECONDARYSOCKET].use = TRUE; /* send data securely */
2780       port = PORT_FTPS;
2781 #else
2782       failf(data, LIBCURL_NAME
2783             " was built with SSL disabled, ftps: not supported!");
2784       return CURLE_UNSUPPORTED_PROTOCOL;
2785 #endif /* !USE_SSLEAY */
2786     }
2787
2788     conn->port = (data->set.use_port && data->state.allow_port)?
2789       data->set.use_port:port;
2790     conn->remote_port = port;
2791     conn->protocol |= PROT_FTP;
2792
2793     if(data->change.proxy &&
2794        *data->change.proxy &&
2795        !data->set.tunnel_thru_httpproxy) {
2796       /* Unless we have asked to tunnel ftp operations through the proxy, we
2797          switch and use HTTP operations only */
2798       if(conn->protocol & PROT_FTPS) {
2799         /* FTPS is a hacked protocol and does not work through your
2800            ordinary http proxy! */
2801         failf(data, "ftps does not work through http proxy!");
2802         return CURLE_UNSUPPORTED_PROTOCOL;
2803       }
2804 #ifndef CURL_DISABLE_HTTP
2805       conn->curl_do = Curl_http;
2806       conn->curl_done = Curl_http_done;
2807 #else
2808       failf(data, "FTP over http proxy requires HTTP support built-in!");
2809       return CURLE_UNSUPPORTED_PROTOCOL;
2810 #endif
2811     }
2812     else {
2813       conn->curl_do = Curl_ftp;
2814       conn->curl_do_more = Curl_ftp_nextconnect;
2815       conn->curl_done = Curl_ftp_done;
2816       conn->curl_connect = Curl_ftp_connect;
2817       conn->curl_connecting = Curl_ftp_multi_statemach;
2818       conn->curl_doing = Curl_ftp_doing;
2819       conn->curl_proto_fdset = Curl_ftp_fdset;
2820       conn->curl_doing_fdset = Curl_ftp_fdset;
2821       conn->curl_disconnect = Curl_ftp_disconnect;
2822     }
2823
2824     conn->path++; /* don't include the initial slash */
2825
2826     /* FTP URLs support an extension like ";type=<typecode>" that
2827      * we'll try to get now! */
2828     type=strstr(conn->path, ";type=");
2829     if(!type) {
2830       type=strstr(conn->host.rawalloc, ";type=");
2831     }
2832     if(type) {
2833       char command;
2834       *type=0;                     /* it was in the middle of the hostname */
2835       command = toupper((int)type[6]);
2836       switch(command) {
2837       case 'A': /* ASCII mode */
2838         data->set.ftp_ascii = 1;
2839         break;
2840       case 'D': /* directory mode */
2841         data->set.ftp_list_only = 1;
2842         break;
2843       case 'I': /* binary mode */
2844       default:
2845         /* switch off ASCII */
2846         data->set.ftp_ascii = 0;
2847         break;
2848       }
2849     }
2850 #else /* CURL_DISABLE_FTP */
2851     failf(data, LIBCURL_NAME
2852           " was built with FTP disabled, ftp/ftps: not supported!");
2853     return CURLE_UNSUPPORTED_PROTOCOL;
2854 #endif
2855   }
2856   else if(strequal(conn->protostr, "TELNET")) {
2857 #ifndef CURL_DISABLE_TELNET
2858     /* telnet testing factory */
2859     conn->protocol |= PROT_TELNET;
2860
2861     conn->port = (data->set.use_port && data->state.allow_port)?
2862       data->set.use_port: PORT_TELNET;
2863     conn->remote_port = PORT_TELNET;
2864     conn->curl_do = Curl_telnet;
2865     conn->curl_done = Curl_telnet_done;
2866 #else
2867     failf(data, LIBCURL_NAME
2868           " was built with TELNET disabled!");
2869 #endif
2870   }
2871   else if (strequal(conn->protostr, "DICT")) {
2872 #ifndef CURL_DISABLE_DICT
2873     conn->protocol |= PROT_DICT;
2874     conn->port = (data->set.use_port && data->state.allow_port)?
2875       data->set.use_port:PORT_DICT;
2876     conn->remote_port = PORT_DICT;
2877     conn->curl_do = Curl_dict;
2878     conn->curl_done = NULL; /* no DICT-specific done */
2879 #else
2880     failf(data, LIBCURL_NAME
2881           " was built with DICT disabled!");
2882 #endif
2883   }
2884   else if (strequal(conn->protostr, "LDAP")) {
2885 #ifndef CURL_DISABLE_LDAP
2886     conn->protocol |= PROT_LDAP;
2887     conn->port = (data->set.use_port && data->state.allow_port)?
2888       data->set.use_port:PORT_LDAP;
2889     conn->remote_port = PORT_LDAP;
2890     conn->curl_do = Curl_ldap;
2891     conn->curl_done = NULL; /* no LDAP-specific done */
2892 #else
2893     failf(data, LIBCURL_NAME
2894           " was built with LDAP disabled!");
2895 #endif
2896   }
2897   else if (strequal(conn->protostr, "FILE")) {
2898 #ifndef CURL_DISABLE_FILE
2899     conn->protocol |= PROT_FILE;
2900
2901     conn->curl_do = Curl_file;
2902     conn->curl_done = Curl_file_done;
2903
2904     /* anyway, this is supposed to be the connect function so we better
2905        at least check that the file is present here! */
2906     result = Curl_file_connect(conn);
2907
2908     /* Setup a "faked" transfer that'll do nothing */
2909     if(CURLE_OK == result) {
2910       conn->bits.tcpconnect = TRUE; /* we are "connected */
2911       result = Curl_Transfer(conn, -1, -1, FALSE, NULL, /* no download */
2912                              -1, NULL); /* no upload */
2913     }
2914
2915     return result;
2916 #else
2917     failf(data, LIBCURL_NAME
2918           " was built with FILE disabled!");
2919 #endif
2920   }
2921   else {
2922     /* We fell through all checks and thus we don't support the specified
2923        protocol */
2924     failf(data, "Unsupported protocol: %s", conn->protostr);
2925     return CURLE_UNSUPPORTED_PROTOCOL;
2926   }
2927
2928   if(data->change.proxy && *data->change.proxy) {
2929     /* If this is supposed to use a proxy, we need to figure out the proxy
2930        host name name, so that we can re-use an existing connection
2931        that may exist registered to the same proxy host. */
2932
2933     char *prox_portno;
2934     char *endofprot;
2935
2936     /* We need to make a duplicate of the proxy so that we can modify the
2937        string safely. */
2938     char *proxydup=strdup(data->change.proxy);
2939
2940     /* We use 'proxyptr' to point to the proxy name from now on... */
2941     char *proxyptr=proxydup;
2942
2943     if(NULL == proxydup) {
2944       failf(data, "memory shortage");
2945       return CURLE_OUT_OF_MEMORY;
2946     }
2947
2948     /* Daniel Dec 10, 1998:
2949        We do the proxy host string parsing here. We want the host name and the
2950        port name. Accept a protocol:// prefix, even though it should just be
2951        ignored. */
2952
2953     /* 1. skip the protocol part if present */
2954     endofprot=strstr(proxyptr, "://");
2955     if(endofprot) {
2956       proxyptr = endofprot+3;
2957     }
2958
2959     /* allow user to specify proxy.server.com:1080 if desired */
2960     prox_portno = strchr (proxyptr, ':');
2961     if (prox_portno) {
2962       *prox_portno = 0x0; /* cut off number from host name */
2963       prox_portno ++;
2964       /* now set the local port number */
2965       conn->port = atoi(prox_portno);
2966     }
2967     else if(data->set.proxyport) {
2968       /* None given in the proxy string, then get the default one if it is
2969          given */
2970       conn->port = data->set.proxyport;
2971     }
2972
2973     /* now, clone the cleaned proxy host name */
2974     conn->proxy.rawalloc = strdup(proxyptr);
2975     conn->proxy.name = conn->proxy.rawalloc;
2976
2977     free(proxydup); /* free the duplicate pointer and not the modified */
2978     if(!conn->proxy.rawalloc)
2979       return CURLE_OUT_OF_MEMORY;
2980   }
2981
2982   /*************************************************************
2983    * If the protcol is using SSL and HTTP proxy is used, we set
2984    * the tunnel_proxy bit.
2985    *************************************************************/
2986   if((conn->protocol&PROT_SSL) && conn->bits.httpproxy)
2987     conn->bits.tunnel_proxy = TRUE;
2988
2989   /*************************************************************
2990    * Take care of user and password authentication stuff
2991    *************************************************************/
2992
2993   /*
2994    * Inputs: data->set.userpwd   (CURLOPT_USERPWD)
2995    *         data->set.fpasswd   (CURLOPT_PASSWDFUNCTION)
2996    *         data->set.use_netrc (CURLOPT_NETRC)
2997    *         conn->host.name
2998    *         netrc file
2999    *         hard-coded defaults
3000    *
3001    * Outputs: (almost :- all currently undefined)
3002    *          conn->bits.user_passwd  - non-zero if non-default passwords exist
3003    *          conn->user              - non-zero length if defined
3004    *          conn->passwd            -   ditto
3005    *          conn->host.name          - remove user name and password
3006    */
3007
3008   /* At this point, we're hoping all the other special cases have
3009    * been taken care of, so conn->host.name is at most
3010    *    [user[:password]]@]hostname
3011    *
3012    * We need somewhere to put the embedded details, so do that first.
3013    */
3014
3015   user[0] =0;   /* to make everything well-defined */
3016   passwd[0]=0;
3017
3018   if (conn->protocol & (PROT_FTP|PROT_HTTP)) {
3019     /* This is a FTP or HTTP URL, we will now try to extract the possible
3020      * user+password pair in a string like:
3021      * ftp://user:password@ftp.my.site:8021/README */
3022     char *ptr=strchr(conn->host.name, '@');
3023     char *userpass = conn->host.name;
3024     if(ptr != NULL) {
3025       /* there's a user+password given here, to the left of the @ */
3026
3027       conn->host.name = ++ptr;
3028
3029       /* So the hostname is sane.  Only bother interpreting the
3030        * results if we could care.  It could still be wasted
3031        * work because it might be overtaken by the programmatically
3032        * set user/passwd, but doing that first adds more cases here :-(
3033        */
3034
3035       if (data->set.use_netrc != CURL_NETRC_REQUIRED) {
3036         /* We could use the one in the URL */
3037
3038         conn->bits.user_passwd = 1; /* enable user+password */
3039
3040         if(*userpass != ':') {
3041           /* the name is given, get user+password */
3042           sscanf(userpass, "%127[^:@]:%127[^@]",
3043                  user, passwd);
3044         }
3045         else
3046           /* no name given, get the password only */
3047           sscanf(userpass, ":%127[^@]", passwd);
3048
3049         if(user[0]) {
3050           char *newname=curl_unescape(user, 0);
3051           if(!newname)
3052             return CURLE_OUT_OF_MEMORY;
3053           if(strlen(newname) < sizeof(user))
3054             strcpy(user, newname);
3055
3056           /* if the new name is longer than accepted, then just use
3057              the unconverted name, it'll be wrong but what the heck */
3058           free(newname);
3059         }
3060         if (passwd[0]) {
3061           /* we have a password found in the URL, decode it! */
3062           char *newpasswd=curl_unescape(passwd, 0);
3063           if(!newpasswd)
3064             return CURLE_OUT_OF_MEMORY;
3065           if(strlen(newpasswd) < sizeof(passwd))
3066             strcpy(passwd, newpasswd);
3067
3068           free(newpasswd);
3069         }
3070       }
3071     }
3072   }
3073
3074   /*************************************************************
3075    * Figure out the remote port number
3076    *
3077    * No matter if we use a proxy or not, we have to figure out the remote
3078    * port number of various reasons.
3079    *
3080    * To be able to detect port number flawlessly, we must not confuse them
3081    * IPv6-specified addresses in the [0::1] style. (RFC2732)
3082    *
3083    * The conn->host.name is currently [user:passwd@]host[:port] where host
3084    * could be a hostname, IPv4 address or IPv6 address.
3085    *************************************************************/
3086   if((1 == sscanf(conn->host.name, "[%*39[0-9a-fA-F:.]%c", &endbracket)) &&
3087      (']' == endbracket)) {
3088     /* this is a RFC2732-style specified IP-address */
3089     conn->bits.ipv6_ip = TRUE;
3090
3091     conn->host.name++; /* pass the starting bracket */
3092     tmp = strchr(conn->host.name, ']');
3093     *tmp = 0; /* zero terminate */
3094     tmp++; /* pass the ending bracket */
3095     if(':' != *tmp)
3096       tmp = NULL; /* no port number available */
3097   }
3098   else
3099     tmp = strrchr(conn->host.name, ':');
3100
3101   if (tmp) {
3102     char *rest;
3103     unsigned long port;
3104
3105     port=strtoul(tmp+1, &rest, 10);  /* Port number must be decimal */
3106
3107     if (rest != (tmp+1) && *rest == '\0') {
3108       /* The colon really did have only digits after it,
3109        * so it is either a port number or a mistake */
3110
3111       if (port > 0xffff) {   /* Single unix standard says port numbers are
3112                               * 16 bits long */
3113         failf(data, "Port number too large: %lu", port);
3114         return CURLE_URL_MALFORMAT;
3115       }
3116
3117       *tmp = '\0'; /* cut off the name there */
3118       conn->remote_port = (unsigned short)port;
3119     }
3120   }
3121
3122   /* Programmatically set password:
3123    *   - always applies, if available
3124    *   - takes precedence over the values we just set above
3125    * so scribble it over the top.
3126    * User-supplied passwords are assumed not to need unescaping.
3127    *
3128    * user_password is set in "inherite initial knowledge' above,
3129    * so it doesn't have to be set in this block
3130    */
3131   if (data->set.userpwd != NULL) {
3132     /* the name is given, get user+password */
3133     sscanf(data->set.userpwd,
3134            "%" MAX_CURL_USER_LENGTH_TXT "[^:]:"
3135            "%" MAX_CURL_PASSWORD_LENGTH_TXT "[^\n]",
3136            user, passwd);
3137   }
3138
3139   if (data->set.use_netrc != CURL_NETRC_IGNORED) {
3140     if(Curl_parsenetrc(conn->host.name,
3141                        user, passwd,
3142                        data->set.netrc_file)) {
3143       infof(data, "Couldn't find host %s in the " DOT_CHAR "netrc file, using defaults\n",
3144             conn->host.name);
3145     }
3146     else
3147       conn->bits.user_passwd = 1; /* enable user+password */
3148   }
3149
3150   /* If our protocol needs a password and we have none, use the defaults */
3151   if ( (conn->protocol & PROT_FTP) &&
3152        !conn->bits.user_passwd) {
3153
3154     conn->user = strdup(CURL_DEFAULT_USER);
3155     conn->passwd = strdup(CURL_DEFAULT_PASSWORD);
3156     /* This is the default password, so DON'T set conn->bits.user_passwd */
3157   }
3158   else {
3159     /* store user + password, zero-length if not set */
3160     conn->user = strdup(user);
3161     conn->passwd = strdup(passwd);
3162   }
3163   if(!conn->user || !conn->passwd)
3164     return CURLE_OUT_OF_MEMORY;
3165
3166   /*************************************************************
3167    * Check the current list of connections to see if we can
3168    * re-use an already existing one or if we have to create a
3169    * new one.
3170    *************************************************************/
3171
3172   /* get a cloned copy of the SSL config situation stored in the
3173      connection struct */
3174   if(!Curl_clone_ssl_config(&data->set.ssl, &conn->ssl_config))
3175     return CURLE_OUT_OF_MEMORY;
3176
3177   /* reuse_fresh is TRUE if we are told to use a new connection by force, but
3178      we only acknowledge this option if this is not a re-used connection
3179      already (which happens due to follow-location or during a HTTP
3180      authentication phase). */
3181   if(data->set.reuse_fresh && !data->state.this_is_a_follow)
3182     reuse = FALSE;
3183   else
3184     reuse = ConnectionExists(data, conn, &conn_temp);
3185
3186   if(reuse) {
3187     /*
3188      * We already have a connection for this, we got the former connection
3189      * in the conn_temp variable and thus we need to cleanup the one we
3190      * just allocated before we can move along and use the previously
3191      * existing one.
3192      */
3193     struct connectdata *old_conn = conn;
3194
3195     if(old_conn->proxy.rawalloc)
3196       free(old_conn->proxy.rawalloc);
3197
3198     /* free the SSL config struct from this connection struct as this was
3199        allocated in vain and is targeted for destruction */
3200     Curl_free_ssl_config(&conn->ssl_config);
3201
3202     conn = conn_temp;        /* use this connection from now on */
3203
3204     /* get the user+password information from the old_conn struct since it may
3205      * be new for this request even when we re-use an existing connection */
3206     conn->bits.user_passwd = old_conn->bits.user_passwd;
3207     if (conn->bits.user_passwd) {
3208       /* use the new user namd and password though */
3209       Curl_safefree(conn->user);
3210       Curl_safefree(conn->passwd);
3211       conn->user = old_conn->user;
3212       conn->passwd = old_conn->passwd;
3213       old_conn->user = NULL;
3214       old_conn->passwd = NULL;
3215     }
3216
3217     conn->bits.proxy_user_passwd = old_conn->bits.proxy_user_passwd;
3218     if (conn->bits.proxy_user_passwd) {
3219       /* use the new proxy user name and proxy password though */
3220       Curl_safefree(conn->proxyuser);
3221       Curl_safefree(conn->proxypasswd);
3222       conn->proxyuser = old_conn->proxyuser;
3223       conn->proxypasswd = old_conn->proxypasswd;
3224       old_conn->proxyuser = NULL;
3225       old_conn->proxypasswd = NULL;
3226     }
3227
3228     /* host can change, when doing keepalive with a proxy ! */
3229     if (conn->bits.httpproxy) {
3230       free(conn->host.rawalloc);
3231       conn->host=old_conn->host;
3232     }
3233
3234     /* get the newly set value, not the old one */
3235     conn->bits.no_body = old_conn->bits.no_body;
3236
3237     if (!conn->bits.httpproxy)
3238       free(old_conn->host.rawalloc); /* free the newly allocated name buffer */
3239
3240     free(conn->pathbuffer); /* free the newly allocated path pointer */
3241     conn->pathbuffer = old_conn->pathbuffer; /* use the old one */
3242     conn->path = old_conn->path;
3243
3244     /* re-use init */
3245     conn->bits.reuse = TRUE; /* yes, we're re-using here */
3246     conn->bits.chunk = FALSE; /* always assume not chunked unless told
3247                                  otherwise */
3248     conn->maxdownload = -1;  /* might have been used previously! */
3249
3250     Curl_safefree(old_conn->user);
3251     Curl_safefree(old_conn->passwd);
3252     Curl_safefree(old_conn->proxyuser);
3253     Curl_safefree(old_conn->proxypasswd);
3254
3255     if(old_conn->bits.rangestringalloc)
3256       free(old_conn->range);
3257
3258     free(old_conn);          /* we don't need this anymore */
3259
3260     /*
3261      * If we're doing a resumed transfer, we need to setup our stuff
3262      * properly.
3263      */
3264     conn->resume_from = data->set.set_resume_from;
3265     if (conn->resume_from) {
3266       if (conn->bits.rangestringalloc == TRUE)
3267         free(conn->range);
3268       conn->range = aprintf("%" FORMAT_OFF_T "-", conn->resume_from);
3269       if(!conn->range)
3270         return CURLE_OUT_OF_MEMORY;
3271
3272       /* tell ourselves to fetch this range */
3273       conn->bits.use_range = TRUE;        /* enable range download */
3274       conn->bits.rangestringalloc = TRUE; /* mark range string allocated */
3275     }
3276     else if (data->set.set_range) {
3277       /* There is a range, but is not a resume, useful for random ftp access */
3278       conn->range = strdup(data->set.set_range);
3279       if(!conn->range)
3280         return CURLE_OUT_OF_MEMORY;
3281       conn->bits.rangestringalloc = TRUE; /* mark range string allocated */
3282       conn->bits.use_range = TRUE;        /* enable range download */
3283     }
3284     else
3285       conn->bits.use_range = FALSE; /* disable range download */
3286
3287     *in_connect = conn;      /* return this instead! */
3288
3289     infof(data, "Re-using existing connection! (#%ld) with host %s\n",
3290           conn->connectindex,
3291           conn->bits.httpproxy?conn->proxy.dispname:conn->host.dispname);
3292   }
3293   else {
3294     /*
3295      * This is a brand new connection, so let's store it in the connection
3296      * cache of ours!
3297      */
3298     ConnectionStore(data, conn);
3299   }
3300
3301   /* Continue connectdata initialization here.
3302    *
3303    * Inherit the proper values from the urldata struct AFTER we have arranged
3304    * the persistant conncetion stuff */
3305   conn->fread = data->set.fread;
3306   conn->fread_in = data->set.in;
3307
3308   conn->bits.upload_chunky =
3309     ((conn->protocol&PROT_HTTP) &&
3310      data->set.upload &&
3311      (data->set.infilesize == -1) &&
3312      (data->set.httpversion != CURL_HTTP_VERSION_1_0))?
3313     /* HTTP, upload, unknown file size and not HTTP 1.0 */
3314     TRUE:
3315   /* else, no chunky upload */
3316   FALSE;
3317
3318 #ifndef USE_ARES
3319   /*************************************************************
3320    * Set timeout if that is being used, and we're not using an asynchronous
3321    * name resolve.
3322    *************************************************************/
3323   if((data->set.timeout || data->set.connecttimeout) && !data->set.no_signal) {
3324     /*************************************************************
3325      * Set signal handler to catch SIGALRM
3326      * Store the old value to be able to set it back later!
3327      *************************************************************/
3328
3329 #ifdef SIGALRM
3330 #ifdef HAVE_SIGACTION
3331     struct sigaction sigact;
3332     sigaction(SIGALRM, NULL, &sigact);
3333     keep_sigact = sigact;
3334     keep_copysig = TRUE; /* yes, we have a copy */
3335     sigact.sa_handler = alarmfunc;
3336 #ifdef SA_RESTART
3337     /* HPUX doesn't have SA_RESTART but defaults to that behaviour! */
3338     sigact.sa_flags &= ~SA_RESTART;
3339 #endif
3340     /* now set the new struct */
3341     sigaction(SIGALRM, &sigact, NULL);
3342 #else /* HAVE_SIGACTION */
3343     /* no sigaction(), revert to the much lamer signal() */
3344 #ifdef HAVE_SIGNAL
3345     keep_sigact = signal(SIGALRM, alarmfunc);
3346 #endif
3347 #endif /* HAVE_SIGACTION */
3348
3349     /* We set the timeout on the name resolving phase first, separately from
3350      * the download/upload part to allow a maximum time on everything. This is
3351      * a signal-based timeout, why it won't work and shouldn't be used in
3352      * multi-threaded environments. */
3353
3354 #ifdef HAVE_ALARM
3355     /* alarm() makes a signal get sent when the timeout fires off, and that
3356        will abort system calls */
3357     prev_alarm = alarm(data->set.connecttimeout?
3358                        data->set.connecttimeout:
3359                        data->set.timeout);
3360     /* We can expect the conn->created time to be "now", as that was just
3361        recently set in the beginning of this function and nothing slow
3362        has been done since then until now. */
3363 #endif
3364 #endif /* SIGALRM */
3365   }
3366 #endif /* USE_ARES */
3367
3368   /*************************************************************
3369    * Resolve the name of the server or proxy
3370    *************************************************************/
3371   if(conn->bits.reuse) {
3372     /* re-used connection, no resolving is necessary */
3373     hostaddr = NULL;
3374     /* we'll need to clear conn->dns_entry later in Curl_disconnect() */
3375
3376     if (conn->bits.httpproxy)
3377       fix_hostname(conn, &conn->host);
3378   }
3379   else {
3380     /* this is a fresh connect */
3381
3382     /* set a pointer to the hostname we display */
3383     fix_hostname(conn, &conn->host);
3384
3385     if(!data->change.proxy || !*data->change.proxy) {
3386       /* If not connecting via a proxy, extract the port from the URL, if it is
3387        * there, thus overriding any defaults that might have been set above. */
3388       conn->port =  conn->remote_port; /* it is the same port */
3389
3390       /* Resolve target host right on */
3391       rc = Curl_resolv(conn, conn->host.name, (int)conn->port, &hostaddr);
3392       if(rc == CURLRESOLV_PENDING)
3393         *async = TRUE;
3394
3395       else if(!hostaddr) {
3396         failf(data, "Couldn't resolve host '%s'", conn->host.dispname);
3397         result =  CURLE_COULDNT_RESOLVE_HOST;
3398         /* don't return yet, we need to clean up the timeout first */
3399       }
3400     }
3401     else {
3402       /* This is a proxy that hasn't been resolved yet. */
3403
3404       /* IDN-fix the proxy name */
3405       fix_hostname(conn, &conn->proxy);
3406
3407       /* resolve proxy */
3408       rc = Curl_resolv(conn, conn->proxy.name, (int)conn->port, &hostaddr);
3409
3410       if(rc == CURLRESOLV_PENDING)
3411         *async = TRUE;
3412
3413       else if(!hostaddr) {
3414         failf(data, "Couldn't resolve proxy '%s'", conn->proxy.dispname);
3415         result = CURLE_COULDNT_RESOLVE_PROXY;
3416         /* don't return yet, we need to clean up the timeout first */
3417       }
3418     }
3419   }
3420   *addr = hostaddr;
3421
3422 #if defined(HAVE_ALARM) && defined(SIGALRM) && !defined(USE_ARES)
3423   if((data->set.timeout || data->set.connecttimeout) && !data->set.no_signal) {
3424 #ifdef HAVE_SIGACTION
3425     if(keep_copysig) {
3426       /* we got a struct as it looked before, now put that one back nice
3427          and clean */
3428       sigaction(SIGALRM, &keep_sigact, NULL); /* put it back */
3429     }
3430 #else
3431 #ifdef HAVE_SIGNAL
3432     /* restore the previous SIGALRM handler */
3433     signal(SIGALRM, keep_sigact);
3434 #endif
3435 #endif /* HAVE_SIGACTION */
3436
3437     /* switch back the alarm() to either zero or to what it was before minus
3438        the time we spent until now! */
3439     if(prev_alarm) {
3440       /* there was an alarm() set before us, now put it back */
3441       unsigned long elapsed_ms = Curl_tvdiff(Curl_tvnow(), conn->created);
3442       unsigned long alarm_set;
3443
3444       /* the alarm period is counted in even number of seconds */
3445       alarm_set = prev_alarm - elapsed_ms/1000;
3446
3447       if(!alarm_set ||
3448          ((alarm_set >= 0x80000000) && (prev_alarm < 0x80000000)) ) {
3449         /* if the alarm time-left reached zero or turned "negative" (counted
3450            with unsigned values), we should fire off a SIGALRM here, but we
3451            won't, and zero would be to switch it off so we never set it to
3452            less than 1! */
3453         alarm(1);
3454         result = CURLE_OPERATION_TIMEOUTED;
3455         failf(data, "Previous alarm fired off!");
3456       }
3457       else
3458         alarm((unsigned int)alarm_set);
3459     }
3460     else
3461       alarm(0); /* just shut it off */
3462   }
3463 #endif
3464
3465   return result;
3466 }
3467
3468 /* SetupConnection() should be called after the name resolve initiated in
3469  * CreateConnection() is all done.
3470  */
3471
3472 static CURLcode SetupConnection(struct connectdata *conn,
3473                                 struct Curl_dns_entry *hostaddr,
3474                                 bool *protocol_done)
3475 {
3476   struct SessionHandle *data = conn->data;
3477   CURLcode result=CURLE_OK;
3478
3479   Curl_pgrsTime(data, TIMER_NAMELOOKUP);
3480
3481   if(conn->protocol & PROT_FILE) {
3482     /* There's nothing in this function to setup if we're only doing
3483        a file:// transfer */
3484     *protocol_done = TRUE;
3485     return result;
3486   }
3487   *protocol_done = FALSE; /* default to not done */
3488
3489   /*************************************************************
3490    * Send user-agent to HTTP proxies even if the target protocol
3491    * isn't HTTP.
3492    *************************************************************/
3493   if((conn->protocol&PROT_HTTP) ||
3494      (data->change.proxy && *data->change.proxy)) {
3495     if(data->set.useragent) {
3496       Curl_safefree(conn->allocptr.uagent);
3497       conn->allocptr.uagent =
3498         aprintf("User-Agent: %s\015\012", data->set.useragent);
3499       if(!conn->allocptr.uagent)
3500         return CURLE_OUT_OF_MEMORY;
3501     }
3502   }
3503
3504   conn->bytecount = 0;
3505   conn->headerbytecount = 0;
3506
3507   if(CURL_SOCKET_BAD == conn->sock[FIRSTSOCKET]) {
3508     bool connected = FALSE;
3509
3510     /* Connect only if not already connected! */
3511     result = ConnectPlease(conn, hostaddr, &connected);
3512
3513     if(connected) {
3514       result = Curl_protocol_connect(conn, protocol_done);
3515       if(CURLE_OK == result)
3516         conn->bits.tcpconnect = TRUE;
3517     }
3518     else
3519       conn->bits.tcpconnect = FALSE;
3520
3521
3522     if(CURLE_OK != result)
3523       return result;
3524   }
3525   else {
3526     Curl_pgrsTime(data, TIMER_CONNECT); /* we're connected already */
3527     conn->bits.tcpconnect = TRUE;
3528     *protocol_done = TRUE;
3529     if(data->set.verbose)
3530       verboseconnect(conn);
3531   }
3532
3533   conn->now = Curl_tvnow(); /* time this *after* the connect is done, we
3534                                set this here perhaps a second time */
3535
3536 #ifdef __EMX__
3537   /* 20000330 mgs
3538    * the check is quite a hack...
3539    * we're calling _fsetmode to fix the problem with fwrite converting newline
3540    * characters (you get mangled text files, and corrupted binary files when
3541    * you download to stdout and redirect it to a file). */
3542
3543   if ((data->set.out)->_handle == NULL) {
3544     _fsetmode(stdout, "b");
3545   }
3546 #endif
3547
3548   return CURLE_OK;
3549 }
3550
3551 CURLcode Curl_connect(struct SessionHandle *data,
3552                       struct connectdata **in_connect,
3553                       bool *asyncp,
3554                       bool *protocol_done)
3555 {
3556   CURLcode code;
3557   struct Curl_dns_entry *dns;
3558
3559   *asyncp = FALSE; /* assume synchronous resolves by default */
3560
3561   /* call the stuff that needs to be called */
3562   code = CreateConnection(data, in_connect, &dns, asyncp);
3563
3564   if(CURLE_OK == code) {
3565     /* no error */
3566     if(dns || !*asyncp)
3567       /* If an address is available it means that we already have the name
3568          resolved, OR it isn't async.
3569          If so => continue connecting from here */
3570       code = SetupConnection(*in_connect, dns, protocol_done);
3571     /* else
3572          response will be received and treated async wise */
3573   }
3574
3575   if(CURLE_OK != code) {
3576     /* We're not allowed to return failure with memory left allocated
3577        in the connectdata struct, free those here */
3578     if(*in_connect) {
3579       Curl_disconnect(*in_connect); /* close the connection */
3580       *in_connect = NULL;           /* return a NULL */
3581     }
3582   }
3583
3584   return code;
3585 }
3586
3587 /* Call this function after Curl_connect() has returned async=TRUE and
3588    then a successful name resolve has been received.
3589
3590    Note: this function disconnects and frees the conn data in case of
3591    resolve failure */
3592 CURLcode Curl_async_resolved(struct connectdata *conn,
3593                              bool *protocol_done)
3594 {
3595 #if defined(USE_ARES) || defined(USE_THREADING_GETHOSTBYNAME) || \
3596     defined(USE_THREADING_GETADDRINFO)
3597   CURLcode code = SetupConnection(conn, conn->async.dns, protocol_done);
3598
3599   if(code)
3600     /* We're not allowed to return failure with memory left allocated
3601        in the connectdata struct, free those here */
3602     Curl_disconnect(conn); /* close the connection */
3603
3604   return code;
3605 #else
3606   (void)conn;
3607   (void)protocol_done;
3608   return CURLE_OK;
3609 #endif
3610 }
3611
3612
3613 CURLcode Curl_done(struct connectdata **connp,
3614                    CURLcode status) /* an error if this is called after an
3615                                        error was detected */
3616 {
3617   CURLcode result;
3618   struct connectdata *conn = *connp;
3619   struct SessionHandle *data=conn->data;
3620
3621   /* cleanups done even if the connection is re-used */
3622   if(conn->bits.rangestringalloc) {
3623     free(conn->range);
3624     conn->bits.rangestringalloc = FALSE;
3625   }
3626
3627   if(conn->dns_entry) {
3628     Curl_resolv_unlock(data, conn->dns_entry); /* done with this */
3629     conn->dns_entry = NULL;
3630   }
3631
3632   /* Cleanup possible redirect junk */
3633   if(conn->newurl) {
3634     free(conn->newurl);
3635     conn->newurl = NULL;
3636   }
3637
3638   /* this calls the protocol-specific function pointer previously set */
3639   if(conn->curl_done)
3640     result = conn->curl_done(conn, status);
3641   else
3642     result = CURLE_OK;
3643
3644   Curl_pgrsDone(conn); /* done with the operation */
3645
3646   /* if data->set.reuse_forbid is TRUE, it means the libcurl client has
3647      forced us to close this no matter what we think.
3648
3649      if conn->bits.close is TRUE, it means that the connection should be
3650      closed in spite of all our efforts to be nice, due to protocol
3651      restrictions in our or the server's end */
3652   if(data->set.reuse_forbid || conn->bits.close) {
3653     CURLcode res2;
3654     res2 = Curl_disconnect(conn); /* close the connection */
3655
3656     *connp = NULL; /* to make the caller of this function better detect that
3657                       this was actually killed here */
3658
3659     /* If we had an error already, make sure we return that one. But
3660        if we got a new error, return that. */
3661     if(!result && res2)
3662       result = res2;
3663   }
3664   else
3665     infof(data, "Connection #%ld to host %s left intact\n",
3666           conn->connectindex,
3667           conn->bits.httpproxy?conn->proxy.dispname:conn->host.dispname);
3668
3669   return result;
3670 }
3671
3672 CURLcode Curl_do(struct connectdata **connp, bool *done)
3673 {
3674   CURLcode result=CURLE_OK;
3675   struct connectdata *conn = *connp;
3676   struct SessionHandle *data=conn->data;
3677
3678   conn->bits.do_more = FALSE; /* by default there's no curl_do_more() to use */
3679
3680   if(conn->curl_do) {
3681     /* generic protocol-specific function pointer set in curl_connect() */
3682     result = conn->curl_do(conn, done);
3683
3684     /* This was formerly done in transfer.c, but we better do it here */
3685
3686     if((CURLE_SEND_ERROR == result) && conn->bits.reuse) {
3687       /* This was a re-use of a connection and we got a write error in the
3688        * DO-phase. Then we DISCONNECT this connection and have another attempt
3689        * to CONNECT and then DO again! The retry cannot possibly find another
3690        * connection to re-use, since we only keep one possible connection for
3691        * each.  */
3692
3693       infof(data, "Re-used connection seems dead, get a new one\n");
3694
3695       conn->bits.close = TRUE; /* enforce close of this connection */
3696       result = Curl_done(&conn, result); /* we are so done with this */
3697
3698       /* conn may no longer be a good pointer */
3699
3700       if(CURLE_OK == result) {
3701         bool async;
3702         bool protocol_done = TRUE;
3703
3704         /* Now, redo the connect and get a new connection */
3705         result = Curl_connect(data, connp, &async, &protocol_done);
3706         if(CURLE_OK == result) {
3707           /* We have connected or sent away a name resolve query fine */
3708
3709           conn = *connp; /* setup conn to again point to something nice */
3710           if(async) {
3711             /* Now, if async is TRUE here, we need to wait for the name
3712                to resolve */
3713             result = Curl_wait_for_resolv(conn, NULL);
3714             if(result)
3715               return result;
3716
3717             /* Resolved, continue with the connection */
3718             result = Curl_async_resolved(conn, &protocol_done);
3719             if(result)
3720               return result;
3721           }
3722
3723           /* ... finally back to actually retry the DO phase */
3724           result = conn->curl_do(conn, done);
3725         }
3726       }
3727     }
3728   }
3729   return result;
3730 }
3731
3732 CURLcode Curl_do_more(struct connectdata *conn)
3733 {
3734   CURLcode result=CURLE_OK;
3735
3736   if(conn->curl_do_more)
3737     result = conn->curl_do_more(conn);
3738
3739   return result;
3740 }
3741
3742 static bool safe_strequal(char* str1, char* str2)
3743 {
3744   if(str1 && str2)
3745     /* both pointers point to something then compare them */
3746     return strequal(str1, str2);
3747   else
3748     /* if both pointers are NULL then treat them as equal */
3749     return (!str1 && !str2);
3750 }
3751
3752 bool
3753 Curl_ssl_config_matches(struct ssl_config_data* data,
3754                         struct ssl_config_data* needle)
3755 {
3756   if((data->version == needle->version) &&
3757      (data->verifypeer == needle->verifypeer) &&
3758      (data->verifyhost == needle->verifyhost) &&
3759      safe_strequal(data->CApath, needle->CApath) &&
3760      safe_strequal(data->CAfile, needle->CAfile) &&
3761      safe_strequal(data->random_file, needle->random_file) &&
3762      safe_strequal(data->egdsocket, needle->egdsocket) &&
3763      safe_strequal(data->cipher_list, needle->cipher_list))
3764     return TRUE;
3765
3766   return FALSE;
3767 }
3768
3769 bool
3770 Curl_clone_ssl_config(struct ssl_config_data *source,
3771                       struct ssl_config_data *dest)
3772 {
3773   dest->verifyhost = source->verifyhost;
3774   dest->verifypeer = source->verifypeer;
3775   dest->version = source->version;
3776
3777   if(source->CAfile) {
3778     dest->CAfile = strdup(source->CAfile);
3779     if(!dest->CAfile)
3780       return FALSE;
3781   }
3782
3783   if(source->CApath) {
3784     dest->CApath = strdup(source->CApath);
3785     if(!dest->CApath)
3786       return FALSE;
3787   }
3788
3789   if(source->cipher_list) {
3790     dest->cipher_list = strdup(source->cipher_list);
3791     if(!dest->cipher_list)
3792       return FALSE;
3793   }
3794
3795   if(source->egdsocket) {
3796     dest->egdsocket = strdup(source->egdsocket);
3797     if(!dest->egdsocket)
3798       return FALSE;
3799   }
3800
3801   if(source->random_file) {
3802     dest->random_file = strdup(source->random_file);
3803     if(!dest->random_file)
3804       return FALSE;
3805   }
3806
3807   return TRUE;
3808 }
3809
3810 void Curl_free_ssl_config(struct ssl_config_data* sslc)
3811 {
3812   if(sslc->CAfile)
3813     free(sslc->CAfile);
3814
3815   if(sslc->CApath)
3816     free(sslc->CApath);
3817
3818   if(sslc->cipher_list)
3819     free(sslc->cipher_list);
3820
3821   if(sslc->egdsocket)
3822     free(sslc->egdsocket);
3823
3824   if(sslc->random_file)
3825     free(sslc->random_file);
3826 }
3827