Add a sponsor page
[privoxy.git] / jcc.c
1 const char jcc_rcs[] = "$Id: jcc.c,v 1.445 2016/05/25 10:51:10 fabiankeil Exp $";
2 /*********************************************************************
3  *
4  * File        :  $Source: /cvsroot/ijbswa/current/jcc.c,v $
5  *
6  * Purpose     :  Main file.  Contains main() method, main loop, and
7  *                the main connection-handling function.
8  *
9  * Copyright   :  Written by and Copyright (C) 2001-2016 the
10  *                Privoxy team. http://www.privoxy.org/
11  *
12  *                Based on the Internet Junkbuster originally written
13  *                by and Copyright (C) 1997 Anonymous Coders and
14  *                Junkbusters Corporation.  http://www.junkbusters.com
15  *
16  *                This program is free software; you can redistribute it
17  *                and/or modify it under the terms of the GNU General
18  *                Public License as published by the Free Software
19  *                Foundation; either version 2 of the License, or (at
20  *                your option) any later version.
21  *
22  *                This program is distributed in the hope that it will
23  *                be useful, but WITHOUT ANY WARRANTY; without even the
24  *                implied warranty of MERCHANTABILITY or FITNESS FOR A
25  *                PARTICULAR PURPOSE.  See the GNU General Public
26  *                License for more details.
27  *
28  *                The GNU General Public License should be included with
29  *                this file.  If not, you can view it at
30  *                http://www.gnu.org/copyleft/gpl.html
31  *                or write to the Free Software Foundation, Inc., 59
32  *                Temple Place - Suite 330, Boston, MA  02111-1307, USA.
33  *
34  *********************************************************************/
35
36
37 #include "config.h"
38
39 #include <stdio.h>
40 #include <sys/types.h>
41 #include <stdlib.h>
42 #include <string.h>
43 #include <signal.h>
44 #include <fcntl.h>
45 #include <errno.h>
46 #include <assert.h>
47
48 #ifdef _WIN32
49 # ifndef FEATURE_PTHREAD
50 #  ifndef STRICT
51 #   define STRICT
52 #  endif
53 #  include <windows.h>
54 #  include <process.h>
55 # endif /* ndef FEATURE_PTHREAD */
56
57 # include "win32.h"
58 # ifndef _WIN_CONSOLE
59 #  include "w32log.h"
60 # endif /* ndef _WIN_CONSOLE */
61 # include "w32svrapi.h"
62
63 #else /* ifndef _WIN32 */
64
65 # if !defined (__OS2__)
66 # include <unistd.h>
67 # include <sys/wait.h>
68 # endif /* ndef __OS2__ */
69 # include <sys/time.h>
70 # include <sys/stat.h>
71 # include <sys/ioctl.h>
72
73 #ifdef sun
74 #include <sys/termios.h>
75 #endif /* sun */
76
77 #ifdef unix
78 #include <pwd.h>
79 #include <grp.h>
80 #endif
81
82 # include <signal.h>
83
84 # ifdef __BEOS__
85 #  include <socket.h>  /* BeOS has select() for sockets only. */
86 #  include <OS.h>      /* declarations for threads and stuff. */
87 # endif
88
89 # if defined(__EMX__) || defined(__OS2__)
90 #  include <sys/select.h>  /* OS/2/EMX needs a little help with select */
91 # endif
92 # ifdef __OS2__
93 #define INCL_DOS
94 # include <os2.h>
95 #define bzero(B,N) memset(B,0x00,n)
96 # endif
97
98 # ifndef FD_ZERO
99 #  include <select.h>
100 # endif
101
102 #endif
103
104 #include "project.h"
105 #include "list.h"
106 #include "jcc.h"
107 #include "filters.h"
108 #include "loaders.h"
109 #include "parsers.h"
110 #include "miscutil.h"
111 #include "errlog.h"
112 #include "jbsockets.h"
113 #include "gateway.h"
114 #include "actions.h"
115 #include "cgi.h"
116 #include "loadcfg.h"
117 #include "urlmatch.h"
118 #ifdef FEATURE_CLIENT_TAGS
119 #include "client-tags.h"
120 #endif
121
122 const char jcc_h_rcs[] = JCC_H_VERSION;
123 const char project_h_rcs[] = PROJECT_H_VERSION;
124
125 int daemon_mode = 1;
126 struct client_states clients[1];
127 struct file_list     files[1];
128
129 #ifdef FEATURE_STATISTICS
130 int urls_read     = 0;     /* total nr of urls read inc rejected */
131 int urls_rejected = 0;     /* total nr of urls rejected */
132 #endif /* def FEATURE_STATISTICS */
133
134 #ifdef FEATURE_GRACEFUL_TERMINATION
135 int g_terminate = 0;
136 #endif
137
138 #if !defined(_WIN32) && !defined(__OS2__) && !defined(AMIGA)
139 static void sig_handler(int the_signal);
140 #endif
141 static int client_protocol_is_unsupported(const struct client_state *csp, char *req);
142 static jb_err get_request_destination_elsewhere(struct client_state *csp, struct list *headers);
143 static jb_err get_server_headers(struct client_state *csp);
144 static const char *crunch_reason(const struct http_response *rsp);
145 static void send_crunch_response(const struct client_state *csp, struct http_response *rsp);
146 static char *get_request_line(struct client_state *csp);
147 static jb_err receive_client_request(struct client_state *csp);
148 static jb_err parse_client_request(struct client_state *csp);
149 static void build_request_line(struct client_state *csp, const struct forward_spec *fwd, char **request_line);
150 static jb_err change_request_destination(struct client_state *csp);
151 static void chat(struct client_state *csp);
152 static void serve(struct client_state *csp);
153 #if !defined(_WIN32) || defined(_WIN_CONSOLE)
154 static void usage(const char *myname);
155 #endif
156 static void initialize_mutexes(void);
157 static jb_socket bind_port_helper(const char *haddr, int hport);
158 static void bind_ports_helper(struct configuration_spec *config, jb_socket sockets[]);
159 static void close_ports_helper(jb_socket sockets[]);
160 static void listen_loop(void);
161
162 #ifdef AMIGA
163 void serve(struct client_state *csp);
164 #else /* ifndef AMIGA */
165 static void serve(struct client_state *csp);
166 #endif /* def AMIGA */
167
168 #ifdef __BEOS__
169 static int32 server_thread(void *data);
170 #endif /* def __BEOS__ */
171
172 #ifdef _WIN32
173 #define sleep(N)  Sleep(((N) * 1000))
174 #endif
175
176 #ifdef __OS2__
177 #define sleep(N)  DosSleep(((N) * 100))
178 #endif
179
180 #ifdef MUTEX_LOCKS_AVAILABLE
181 /*
182  * XXX: Does the locking stuff really belong in this file?
183  */
184 privoxy_mutex_t log_mutex;
185 privoxy_mutex_t log_init_mutex;
186 privoxy_mutex_t connection_reuse_mutex;
187
188 #ifdef FEATURE_EXTERNAL_FILTERS
189 privoxy_mutex_t external_filter_mutex;
190 #endif
191 #ifdef FEATURE_CLIENT_TAGS
192 privoxy_mutex_t client_tags_mutex;
193 #endif
194
195 #if !defined(HAVE_GETHOSTBYADDR_R) || !defined(HAVE_GETHOSTBYNAME_R)
196 privoxy_mutex_t resolver_mutex;
197 #endif /* !defined(HAVE_GETHOSTBYADDR_R) || !defined(HAVE_GETHOSTBYNAME_R) */
198
199 #ifndef HAVE_GMTIME_R
200 privoxy_mutex_t gmtime_mutex;
201 #endif /* ndef HAVE_GMTIME_R */
202
203 #ifndef HAVE_LOCALTIME_R
204 privoxy_mutex_t localtime_mutex;
205 #endif /* ndef HAVE_GMTIME_R */
206
207 #ifndef HAVE_RANDOM
208 privoxy_mutex_t rand_mutex;
209 #endif /* ndef HAVE_RANDOM */
210
211 #endif /* def MUTEX_LOCKS_AVAILABLE */
212
213 #if defined(unix)
214 const char *basedir = NULL;
215 const char *pidfile = NULL;
216 static int received_hup_signal = 0;
217 #endif /* defined unix */
218
219 /* HTTP snipplets. */
220 static const char CSUCCEED[] =
221    "HTTP/1.1 200 Connection established\r\n\r\n";
222
223 static const char CHEADER[] =
224    "HTTP/1.1 400 Invalid header received from client\r\n"
225    "Content-Type: text/plain\r\n"
226    "Connection: close\r\n\r\n"
227    "Invalid header received from client.\r\n";
228
229 static const char FTP_RESPONSE[] =
230    "HTTP/1.1 400 Invalid request received from client\r\n"
231    "Content-Type: text/plain\r\n"
232    "Connection: close\r\n\r\n"
233    "Invalid request. Privoxy doesn't support FTP.\r\n";
234
235 static const char GOPHER_RESPONSE[] =
236    "HTTP/1.1 400 Invalid request received from client\r\n"
237    "Content-Type: text/plain\r\n"
238    "Connection: close\r\n\r\n"
239    "Invalid request. Privoxy doesn't support gopher.\r\n";
240
241 /* XXX: should be a template */
242 static const char MISSING_DESTINATION_RESPONSE[] =
243    "HTTP/1.1 400 Bad request received from client\r\n"
244    "Content-Type: text/plain\r\n"
245    "Connection: close\r\n\r\n"
246    "Bad request. Privoxy was unable to extract the destination.\r\n";
247
248 /* XXX: should be a template */
249 static const char INVALID_SERVER_HEADERS_RESPONSE[] =
250    "HTTP/1.1 502 Server or forwarder response invalid\r\n"
251    "Content-Type: text/plain\r\n"
252    "Connection: close\r\n\r\n"
253    "Bad response. The server or forwarder response doesn't look like HTTP.\r\n";
254
255 /* XXX: should be a template */
256 static const char MESSED_UP_REQUEST_RESPONSE[] =
257    "HTTP/1.1 400 Malformed request after rewriting\r\n"
258    "Content-Type: text/plain\r\n"
259    "Connection: close\r\n\r\n"
260    "Bad request. Messed up with header filters.\r\n";
261
262 static const char TOO_MANY_CONNECTIONS_RESPONSE[] =
263    "HTTP/1.1 503 Too many open connections\r\n"
264    "Content-Type: text/plain\r\n"
265    "Connection: close\r\n\r\n"
266    "Maximum number of open connections reached.\r\n";
267
268 static const char CLIENT_CONNECTION_TIMEOUT_RESPONSE[] =
269    "HTTP/1.1 504 Connection timeout\r\n"
270    "Content-Type: text/plain\r\n"
271    "Connection: close\r\n\r\n"
272    "The connection timed out because the client request didn't arrive in time.\r\n";
273
274 static const char CLIENT_BODY_PARSE_ERROR_RESPONSE[] =
275    "HTTP/1.1 400 Failed reading client body\r\n"
276    "Content-Type: text/plain\r\n"
277    "Connection: close\r\n\r\n"
278    "Failed parsing or buffering the chunk-encoded client body.\r\n";
279
280 static const char UNSUPPORTED_CLIENT_EXPECTATION_ERROR_RESPONSE[] =
281    "HTTP/1.1 417 Expecting too much\r\n"
282    "Content-Type: text/plain\r\n"
283    "Connection: close\r\n\r\n"
284    "Privoxy detected an unsupported Expect header value.\r\n";
285
286 /* A function to crunch a response */
287 typedef struct http_response *(*crunch_func_ptr)(struct client_state *);
288
289 /* Crunch function flags */
290 #define CF_NO_FLAGS        0
291 /* Cruncher applies to forced requests as well */
292 #define CF_IGNORE_FORCE    1
293 /* Crunched requests are counted for the block statistics */
294 #define CF_COUNT_AS_REJECT 2
295
296 /* A crunch function and its flags */
297 struct cruncher
298 {
299    const crunch_func_ptr cruncher;
300    const int flags;
301 };
302
303 static int crunch_response_triggered(struct client_state *csp, const struct cruncher crunchers[]);
304
305 /* Complete list of cruncher functions */
306 static const struct cruncher crunchers_all[] = {
307    { direct_response, CF_COUNT_AS_REJECT|CF_IGNORE_FORCE},
308    { block_url,       CF_COUNT_AS_REJECT },
309 #ifdef FEATURE_TRUST
310    { trust_url,       CF_COUNT_AS_REJECT },
311 #endif /* def FEATURE_TRUST */
312    { redirect_url,    CF_NO_FLAGS  },
313    { dispatch_cgi,    CF_IGNORE_FORCE},
314    { NULL,            0 }
315 };
316
317 /* Light version, used after tags are applied */
318 static const struct cruncher crunchers_light[] = {
319    { block_url,       CF_COUNT_AS_REJECT },
320    { redirect_url,    CF_NO_FLAGS },
321    { NULL,            0 }
322 };
323
324
325 /*
326  * XXX: Don't we really mean
327  *
328  * #if defined(unix)
329  *
330  * here?
331  */
332 #if !defined(_WIN32) && !defined(__OS2__) && !defined(AMIGA)
333 /*********************************************************************
334  *
335  * Function    :  sig_handler
336  *
337  * Description :  Signal handler for different signals.
338  *                Exit gracefully on TERM and INT
339  *                or set a flag that will cause the errlog
340  *                to be reopened by the main thread on HUP.
341  *
342  * Parameters  :
343  *          1  :  the_signal = the signal cause this function to call
344  *
345  * Returns     :  -
346  *
347  *********************************************************************/
348 static void sig_handler(int the_signal)
349 {
350    switch(the_signal)
351    {
352       case SIGTERM:
353       case SIGINT:
354          log_error(LOG_LEVEL_INFO, "exiting by signal %d .. bye", the_signal);
355 #if defined(unix)
356          if (pidfile)
357          {
358             unlink(pidfile);
359          }
360 #endif /* unix */
361          exit(the_signal);
362          break;
363
364       case SIGHUP:
365 #if defined(unix)
366          received_hup_signal = 1;
367 #endif
368          break;
369
370       default:
371          /*
372           * We shouldn't be here, unless we catch signals
373           * in main() that we can't handle here!
374           */
375          log_error(LOG_LEVEL_FATAL, "sig_handler: exiting on unexpected signal %d", the_signal);
376    }
377    return;
378
379 }
380 #endif
381
382
383 /*********************************************************************
384  *
385  * Function    :  client_protocol_is_unsupported
386  *
387  * Description :  Checks if the client used a known unsupported
388  *                protocol and deals with it by sending an error
389  *                response.
390  *
391  * Parameters  :
392  *          1  :  csp = Current client state (buffers, headers, etc...)
393  *          2  :  req = the first request line send by the client
394  *
395  * Returns     :  TRUE if an error response has been generated, or
396  *                FALSE if the request doesn't look invalid.
397  *
398  *********************************************************************/
399 static int client_protocol_is_unsupported(const struct client_state *csp, char *req)
400 {
401    /*
402     * If it's a FTP or gopher request, we don't support it.
403     *
404     * These checks are better than nothing, but they might
405     * not work in all configurations and some clients might
406     * have problems digesting the answer.
407     *
408     * They should, however, never cause more problems than
409     * Privoxy's old behaviour (returning the misleading HTML
410     * error message:
411     *
412     * "Could not resolve http://(ftp|gopher)://example.org").
413     */
414    if (!strncmpic(req, "GET ftp://", 10) || !strncmpic(req, "GET gopher://", 13))
415    {
416       const char *response = NULL;
417       const char *protocol = NULL;
418
419       if (!strncmpic(req, "GET ftp://", 10))
420       {
421          response = FTP_RESPONSE;
422          protocol = "FTP";
423       }
424       else
425       {
426          response = GOPHER_RESPONSE;
427          protocol = "GOPHER";
428       }
429       log_error(LOG_LEVEL_ERROR,
430          "%s tried to use Privoxy as %s proxy: %s",
431          csp->ip_addr_str, protocol, req);
432       log_error(LOG_LEVEL_CLF,
433          "%s - - [%T] \"%s\" 400 0", csp->ip_addr_str, req);
434       freez(req);
435       write_socket(csp->cfd, response, strlen(response));
436
437       return TRUE;
438    }
439
440    return FALSE;
441 }
442
443
444 /*********************************************************************
445  *
446  * Function    :  client_has_unsupported_expectations
447  *
448  * Description :  Checks if the client used an unsupported expectation
449  *                in which case an error message is delivered.
450  *
451  * Parameters  :
452  *          1  :  csp = Current client state (buffers, headers, etc...)
453  *
454  * Returns     :  TRUE if an error response has been generated, or
455  *                FALSE if the request doesn't look invalid.
456  *
457  *********************************************************************/
458 static int client_has_unsupported_expectations(const struct client_state *csp)
459 {
460    if ((csp->flags & CSP_FLAG_UNSUPPORTED_CLIENT_EXPECTATION))
461    {
462       log_error(LOG_LEVEL_ERROR,
463          "Rejecting request from client %s with unsupported Expect header value",
464          csp->ip_addr_str);
465       log_error(LOG_LEVEL_CLF,
466          "%s - - [%T] \"%s\" 417 0", csp->ip_addr_str, csp->http->cmd);
467       write_socket(csp->cfd, UNSUPPORTED_CLIENT_EXPECTATION_ERROR_RESPONSE,
468          strlen(UNSUPPORTED_CLIENT_EXPECTATION_ERROR_RESPONSE));
469
470       return TRUE;
471    }
472
473    return FALSE;
474
475 }
476
477
478 /*********************************************************************
479  *
480  * Function    :  get_request_destination_elsewhere
481  *
482  * Description :  If the client's request was redirected into
483  *                Privoxy without the client's knowledge,
484  *                the request line lacks the destination host.
485  *
486  *                This function tries to get it elsewhere,
487  *                provided accept-intercepted-requests is enabled.
488  *
489  *                "Elsewhere" currently only means "Host: header",
490  *                but in the future we may ask the redirecting
491  *                packet filter to look the destination up.
492  *
493  *                If the destination stays unknown, an error
494  *                response is send to the client and headers
495  *                are freed so that chat() can return directly.
496  *
497  * Parameters  :
498  *          1  :  csp = Current client state (buffers, headers, etc...)
499  *          2  :  headers = a header list
500  *
501  * Returns     :  JB_ERR_OK if the destination is now known, or
502  *                JB_ERR_PARSE if it isn't.
503  *
504  *********************************************************************/
505 static jb_err get_request_destination_elsewhere(struct client_state *csp, struct list *headers)
506 {
507    char *req;
508
509    if (!(csp->config->feature_flags & RUNTIME_FEATURE_ACCEPT_INTERCEPTED_REQUESTS))
510    {
511       log_error(LOG_LEVEL_ERROR, "%s's request: \'%s\' is invalid."
512          " Privoxy isn't configured to accept intercepted requests.",
513          csp->ip_addr_str, csp->http->cmd);
514       /* XXX: Use correct size */
515       log_error(LOG_LEVEL_CLF, "%s - - [%T] \"%s\" 400 0",
516          csp->ip_addr_str, csp->http->cmd);
517
518       write_socket(csp->cfd, CHEADER, strlen(CHEADER));
519       destroy_list(headers);
520
521       return JB_ERR_PARSE;
522    }
523    else if (JB_ERR_OK == get_destination_from_headers(headers, csp->http))
524    {
525 #ifndef FEATURE_EXTENDED_HOST_PATTERNS
526       /* Split the domain we just got for pattern matching */
527       init_domain_components(csp->http);
528 #endif
529
530       return JB_ERR_OK;
531    }
532    else
533    {
534       /* We can't work without destination. Go spread the news.*/
535
536       req = list_to_text(headers);
537       chomp(req);
538       /* XXX: Use correct size */
539       log_error(LOG_LEVEL_CLF, "%s - - [%T] \"%s\" 400 0",
540          csp->ip_addr_str, csp->http->cmd);
541       log_error(LOG_LEVEL_ERROR,
542          "Privoxy was unable to get the destination for %s's request:\n%s\n%s",
543          csp->ip_addr_str, csp->http->cmd, req);
544       freez(req);
545
546       write_socket(csp->cfd, MISSING_DESTINATION_RESPONSE, strlen(MISSING_DESTINATION_RESPONSE));
547       destroy_list(headers);
548
549       return JB_ERR_PARSE;
550    }
551    /*
552     * TODO: If available, use PF's ioctl DIOCNATLOOK as last resort
553     * to get the destination IP address, use it as host directly
554     * or do a reverse DNS lookup first.
555     */
556 }
557
558
559 /*********************************************************************
560  *
561  * Function    :  get_server_headers
562  *
563  * Description :  Parses server headers in iob and fills them
564  *                into csp->headers so that they can later be
565  *                handled by sed().
566  *
567  * Parameters  :
568  *          1  :  csp = Current client state (buffers, headers, etc...)
569  *
570  * Returns     :  JB_ERR_OK if everything went fine, or
571  *                JB_ERR_PARSE if the headers were incomplete.
572  *
573  *********************************************************************/
574 static jb_err get_server_headers(struct client_state *csp)
575 {
576    int continue_hack_in_da_house = 0;
577    char * header;
578
579    while (((header = get_header(csp->iob)) != NULL) || continue_hack_in_da_house)
580    {
581       if (header == NULL)
582       {
583          /*
584           * continue hack in da house. Ignore the ending of
585           * this head and continue enlisting header lines.
586           * The reason is described below.
587           */
588          enlist(csp->headers, "");
589          continue_hack_in_da_house = 0;
590          continue;
591       }
592       else if (0 == strncmpic(header, "HTTP/1.1 100", 12))
593       {
594          /*
595           * It's a bodyless continue response, don't
596           * stop header parsing after reaching its end.
597           *
598           * As a result Privoxy will concatenate the
599           * next response's head and parse and deliver
600           * the headers as if they belonged to one request.
601           *
602           * The client will separate them because of the
603           * empty line between them.
604           *
605           * XXX: What we're doing here is clearly against
606           * the intended purpose of the continue header,
607           * and under some conditions (HTTP/1.0 client request)
608           * it's a standard violation.
609           *
610           * Anyway, "sort of against the spec" is preferable
611           * to "always getting confused by Continue responses"
612           * (Privoxy's behaviour before this hack was added)
613           */
614          log_error(LOG_LEVEL_HEADER, "Continue hack in da house.");
615          continue_hack_in_da_house = 1;
616       }
617       else if (*header == '\0')
618       {
619          /*
620           * If the header is empty, but the Continue hack
621           * isn't active, we can assume that we reached the
622           * end of the buffer before we hit the end of the
623           * head.
624           *
625           * Inform the caller an let it decide how to handle it.
626           */
627          return JB_ERR_PARSE;
628       }
629
630       if (JB_ERR_MEMORY == enlist(csp->headers, header))
631       {
632          /*
633           * XXX: Should we quit the request and return a
634           * out of memory error page instead?
635           */
636          log_error(LOG_LEVEL_ERROR,
637             "Out of memory while enlisting server headers. %s lost.",
638             header);
639       }
640       freez(header);
641    }
642
643    return JB_ERR_OK;
644 }
645
646
647 /*********************************************************************
648  *
649  * Function    :  crunch_reason
650  *
651  * Description :  Translates the crunch reason code into a string.
652  *
653  * Parameters  :
654  *          1  :  rsp = a http_response
655  *
656  * Returns     :  A string with the crunch reason or an error description.
657  *
658  *********************************************************************/
659 static const char *crunch_reason(const struct http_response *rsp)
660 {
661    char * reason = NULL;
662
663    assert(rsp != NULL);
664    if (rsp == NULL)
665    {
666       return "Internal error while searching for crunch reason";
667    }
668
669    switch (rsp->crunch_reason)
670    {
671       case UNSUPPORTED:
672          reason = "Unsupported HTTP feature";
673          break;
674       case BLOCKED:
675          reason = "Blocked";
676          break;
677       case UNTRUSTED:
678          reason = "Untrusted";
679          break;
680       case REDIRECTED:
681          reason = "Redirected";
682          break;
683       case CGI_CALL:
684          reason = "CGI Call";
685          break;
686       case NO_SUCH_DOMAIN:
687          reason = "DNS failure";
688          break;
689       case FORWARDING_FAILED:
690          reason = "Forwarding failed";
691          break;
692       case CONNECT_FAILED:
693          reason = "Connection failure";
694          break;
695       case OUT_OF_MEMORY:
696          reason = "Out of memory (may mask other reasons)";
697          break;
698       case CONNECTION_TIMEOUT:
699          reason = "Connection timeout";
700          break;
701       case NO_SERVER_DATA:
702          reason = "No server data received";
703          break;
704       default:
705          reason = "No reason recorded";
706          break;
707    }
708
709    return reason;
710 }
711
712
713 /*********************************************************************
714  *
715  * Function    :  log_applied_actions
716  *
717  * Description :  Logs the applied actions if LOG_LEVEL_ACTIONS is
718  *                enabled.
719  *
720  * Parameters  :
721  *          1  :  actions = Current action spec to log
722  *
723  * Returns     :  Nothing.
724  *
725  *********************************************************************/
726 static void log_applied_actions(const struct current_action_spec *actions)
727 {
728    /*
729     * The conversion to text requires lots of memory allocations so
730     * we only do the conversion if the user is actually interested.
731     */
732    if (debug_level_is_enabled(LOG_LEVEL_ACTIONS))
733    {
734       char *actions_as_text = actions_to_line_of_text(actions);
735       log_error(LOG_LEVEL_ACTIONS, "%s", actions_as_text);
736       freez(actions_as_text);
737    }
738 }
739
740
741 /*********************************************************************
742  *
743  * Function    :  send_crunch_response
744  *
745  * Description :  Delivers already prepared response for
746  *                intercepted requests, logs the interception
747  *                and frees the response.
748  *
749  * Parameters  :
750  *          1  :  csp = Current client state (buffers, headers, etc...)
751  *          1  :  rsp = Fully prepared response. Will be freed on exit.
752  *
753  * Returns     :  Nothing.
754  *
755  *********************************************************************/
756 static void send_crunch_response(const struct client_state *csp, struct http_response *rsp)
757 {
758       const struct http_request *http = csp->http;
759       char status_code[4];
760
761       assert(rsp != NULL);
762       assert(rsp->head != NULL);
763
764       if (rsp == NULL)
765       {
766          log_error(LOG_LEVEL_FATAL, "NULL response in send_crunch_response.");
767       }
768
769       /*
770        * Extract the status code from the actual head
771        * that will be send to the client. It is the only
772        * way to get it right for all requests, including
773        * the fixed ones for out-of-memory problems.
774        *
775        * A head starts like this: 'HTTP/1.1 200...'
776        *                           0123456789|11
777        *                                     10
778        */
779       status_code[0] = rsp->head[9];
780       status_code[1] = rsp->head[10];
781       status_code[2] = rsp->head[11];
782       status_code[3] = '\0';
783
784       /* Log that the request was crunched and why. */
785       log_applied_actions(csp->action);
786       log_error(LOG_LEVEL_CRUNCH, "%s: %s", crunch_reason(rsp), http->url);
787       log_error(LOG_LEVEL_CLF, "%s - - [%T] \"%s\" %s %u",
788          csp->ip_addr_str, http->ocmd, status_code, rsp->content_length);
789
790       /* Write the answer to the client */
791       if (write_socket(csp->cfd, rsp->head, rsp->head_length)
792        || write_socket(csp->cfd, rsp->body, rsp->content_length))
793       {
794          /* There is nothing we can do about it. */
795          log_error(LOG_LEVEL_ERROR,
796             "Couldn't deliver the error message through client socket %d: %E",
797             csp->cfd);
798       }
799
800       /* Clean up and return */
801       if (cgi_error_memory() != rsp)
802       {
803          free_http_response(rsp);
804       }
805       return;
806 }
807
808
809 /*********************************************************************
810  *
811  * Function    :  crunch_response_triggered
812  *
813  * Description :  Checks if the request has to be crunched,
814  *                and delivers the crunch response if necessary.
815  *
816  * Parameters  :
817  *          1  :  csp = Current client state (buffers, headers, etc...)
818  *          2  :  crunchers = list of cruncher functions to run
819  *
820  * Returns     :  TRUE if the request was answered with a crunch response
821  *                FALSE otherwise.
822  *
823  *********************************************************************/
824 static int crunch_response_triggered(struct client_state *csp, const struct cruncher crunchers[])
825 {
826    struct http_response *rsp = NULL;
827    const struct cruncher *c;
828
829    /*
830     * If CGI request crunching is disabled,
831     * check the CGI dispatcher out of order to
832     * prevent unintentional blocks or redirects.
833     */
834    if (!(csp->config->feature_flags & RUNTIME_FEATURE_CGI_CRUNCHING)
835        && (NULL != (rsp = dispatch_cgi(csp))))
836    {
837       /* Deliver, log and free the interception response. */
838       send_crunch_response(csp, rsp);
839       csp->flags |= CSP_FLAG_CRUNCHED;
840       return TRUE;
841    }
842
843    for (c = crunchers; c->cruncher != NULL; c++)
844    {
845       /*
846        * Check the cruncher if either Privoxy is toggled
847        * on and the request isn't forced, or if the cruncher
848        * applies to forced requests as well.
849        */
850       if (((csp->flags & CSP_FLAG_TOGGLED_ON) &&
851           !(csp->flags & CSP_FLAG_FORCED)) ||
852           (c->flags & CF_IGNORE_FORCE))
853       {
854          rsp = c->cruncher(csp);
855          if (NULL != rsp)
856          {
857             /* Deliver, log and free the interception response. */
858             send_crunch_response(csp, rsp);
859             csp->flags |= CSP_FLAG_CRUNCHED;
860 #ifdef FEATURE_STATISTICS
861             if (c->flags & CF_COUNT_AS_REJECT)
862             {
863                csp->flags |= CSP_FLAG_REJECTED;
864             }
865 #endif /* def FEATURE_STATISTICS */
866
867             return TRUE;
868          }
869       }
870    }
871
872    return FALSE;
873 }
874
875
876 /*********************************************************************
877  *
878  * Function    :  build_request_line
879  *
880  * Description :  Builds the HTTP request line.
881  *
882  *                If a HTTP forwarder is used it expects the whole URL,
883  *                web servers only get the path.
884  *
885  * Parameters  :
886  *          1  :  csp = Current client state (buffers, headers, etc...)
887  *          2  :  fwd = The forwarding spec used for the request
888  *                XXX: Should use http->fwd instead.
889  *          3  :  request_line = The old request line which will be replaced.
890  *
891  * Returns     :  Nothing. Terminates in case of memory problems.
892  *
893  *********************************************************************/
894 static void build_request_line(struct client_state *csp, const struct forward_spec *fwd, char **request_line)
895 {
896    struct http_request *http = csp->http;
897
898    assert(http->ssl == 0);
899
900    /*
901     * Downgrade http version from 1.1 to 1.0
902     * if +downgrade action applies.
903     */
904    if ((csp->action->flags & ACTION_DOWNGRADE)
905      && (!strcmpic(http->ver, "HTTP/1.1")))
906    {
907       freez(http->ver);
908       http->ver = strdup_or_die("HTTP/1.0");
909    }
910
911    /*
912     * Rebuild the request line.
913     */
914    freez(*request_line);
915    *request_line = strdup(http->gpc);
916    string_append(request_line, " ");
917
918    if (fwd->forward_host && fwd->type != FORWARD_WEBSERVER)
919    {
920       string_append(request_line, http->url);
921    }
922    else
923    {
924       string_append(request_line, http->path);
925    }
926    string_append(request_line, " ");
927    string_append(request_line, http->ver);
928
929    if (*request_line == NULL)
930    {
931       log_error(LOG_LEVEL_FATAL, "Out of memory writing HTTP command");
932    }
933    log_error(LOG_LEVEL_HEADER, "New HTTP Request-Line: %s", *request_line);
934 }
935
936
937 /*********************************************************************
938  *
939  * Function    :  change_request_destination
940  *
941  * Description :  Parse a (rewritten) request line and regenerate
942  *                the http request data.
943  *
944  * Parameters  :
945  *          1  :  csp = Current client state (buffers, headers, etc...)
946  *
947  * Returns     :  Forwards the parse_http_request() return code.
948  *                Terminates in case of memory problems.
949  *
950  *********************************************************************/
951 static jb_err change_request_destination(struct client_state *csp)
952 {
953    struct http_request *http = csp->http;
954    jb_err err;
955
956    log_error(LOG_LEVEL_REDIRECTS, "Rewrite detected: %s",
957       csp->headers->first->str);
958    free_http_request(http);
959    err = parse_http_request(csp->headers->first->str, http);
960    if (JB_ERR_OK != err)
961    {
962       log_error(LOG_LEVEL_ERROR, "Couldn't parse rewritten request: %s.",
963          jb_err_to_string(err));
964    }
965
966    return err;
967 }
968
969
970 #ifdef FEATURE_CONNECTION_KEEP_ALIVE
971 /*********************************************************************
972  *
973  * Function    :  server_response_is_complete
974  *
975  * Description :  Determines whether we should stop reading
976  *                from the server socket.
977  *
978  * Parameters  :
979  *          1  :  csp = Current client state (buffers, headers, etc...)
980  *          2  :  content_length = Length of content received so far.
981  *
982  * Returns     :  TRUE if the response is complete,
983  *                FALSE otherwise.
984  *
985  *********************************************************************/
986 static int server_response_is_complete(struct client_state *csp,
987    unsigned long long content_length)
988 {
989    int content_length_known = !!(csp->flags & CSP_FLAG_CONTENT_LENGTH_SET);
990
991    if (!strcmpic(csp->http->gpc, "HEAD"))
992    {
993       /*
994        * "HEAD" implies no body, we are thus expecting
995        * no content. XXX: incomplete "list" of methods?
996        */
997       csp->expected_content_length = 0;
998       content_length_known = TRUE;
999       csp->flags |= CSP_FLAG_SERVER_CONTENT_LENGTH_SET;
1000    }
1001
1002    if (csp->http->status == 204 || csp->http->status == 304)
1003    {
1004       /*
1005        * Expect no body. XXX: incomplete "list" of status codes?
1006        */
1007       csp->expected_content_length = 0;
1008       content_length_known = TRUE;
1009       csp->flags |= CSP_FLAG_SERVER_CONTENT_LENGTH_SET;
1010    }
1011
1012    return (content_length_known && ((0 == csp->expected_content_length)
1013             || (csp->expected_content_length <= content_length)));
1014 }
1015
1016
1017 #ifdef FEATURE_CONNECTION_SHARING
1018 /*********************************************************************
1019  *
1020  * Function    :  wait_for_alive_connections
1021  *
1022  * Description :  Waits for alive connections to timeout.
1023  *
1024  * Parameters  :  N/A
1025  *
1026  * Returns     :  N/A
1027  *
1028  *********************************************************************/
1029 static void wait_for_alive_connections(void)
1030 {
1031    int connections_alive = close_unusable_connections();
1032
1033    while (0 < connections_alive)
1034    {
1035       log_error(LOG_LEVEL_CONNECT,
1036          "Waiting for %d connections to timeout.",
1037          connections_alive);
1038       sleep(60);
1039       connections_alive = close_unusable_connections();
1040    }
1041
1042    log_error(LOG_LEVEL_CONNECT, "No connections to wait for left.");
1043
1044 }
1045 #endif /* def FEATURE_CONNECTION_SHARING */
1046
1047
1048 /*********************************************************************
1049  *
1050  * Function    :  save_connection_destination
1051  *
1052  * Description :  Remembers a connection for reuse later on.
1053  *
1054  * Parameters  :
1055  *          1  :  sfd  = Open socket to remember.
1056  *          2  :  http = The destination for the connection.
1057  *          3  :  fwd  = The forwarder settings used.
1058  *          3  :  server_connection  = storage.
1059  *
1060  * Returns     : void
1061  *
1062  *********************************************************************/
1063 void save_connection_destination(jb_socket sfd,
1064                                  const struct http_request *http,
1065                                  const struct forward_spec *fwd,
1066                                  struct reusable_connection *server_connection)
1067 {
1068    assert(sfd != JB_INVALID_SOCKET);
1069    assert(NULL != http->host);
1070
1071    server_connection->sfd = sfd;
1072    server_connection->host = strdup_or_die(http->host);
1073    server_connection->port = http->port;
1074
1075    assert(NULL != fwd);
1076    assert(server_connection->gateway_host == NULL);
1077    assert(server_connection->gateway_port == 0);
1078    assert(server_connection->forwarder_type == 0);
1079    assert(server_connection->forward_host == NULL);
1080    assert(server_connection->forward_port == 0);
1081
1082    server_connection->forwarder_type = fwd->type;
1083    if (NULL != fwd->gateway_host)
1084    {
1085       server_connection->gateway_host = strdup_or_die(fwd->gateway_host);
1086    }
1087    else
1088    {
1089       server_connection->gateway_host = NULL;
1090    }
1091    server_connection->gateway_port = fwd->gateway_port;
1092
1093    if (NULL != fwd->forward_host)
1094    {
1095       server_connection->forward_host = strdup_or_die(fwd->forward_host);
1096    }
1097    else
1098    {
1099       server_connection->forward_host = NULL;
1100    }
1101    server_connection->forward_port = fwd->forward_port;
1102 }
1103
1104
1105 /*********************************************************************
1106  *
1107  * Function    : verify_request_length
1108  *
1109  * Description : Checks if we already got the whole client requests
1110  *               and sets CSP_FLAG_CLIENT_REQUEST_COMPLETELY_READ if
1111  *               we do.
1112  *
1113  *               Data that doesn't belong to the current request is
1114  *               either thrown away to let the client retry on a clean
1115  *               socket, or stashed to be dealt with after the current
1116  *               request is served.
1117  *
1118  * Parameters  :
1119  *          1  :  csp = Current client state (buffers, headers, etc...)
1120  *
1121  * Returns     :  void
1122  *
1123  *********************************************************************/
1124 static void verify_request_length(struct client_state *csp)
1125 {
1126    unsigned long long buffered_request_bytes =
1127       (unsigned long long)(csp->client_iob->eod - csp->client_iob->cur);
1128
1129    if ((csp->expected_client_content_length != 0)
1130       && (buffered_request_bytes != 0))
1131    {
1132       if (csp->expected_client_content_length >= buffered_request_bytes)
1133       {
1134          csp->expected_client_content_length -= buffered_request_bytes;
1135          log_error(LOG_LEVEL_CONNECT, "Reduced expected bytes to %llu "
1136             "to account for the %llu ones we already got.",
1137             csp->expected_client_content_length, buffered_request_bytes);
1138       }
1139       else
1140       {
1141          assert(csp->client_iob->eod > csp->client_iob->cur + csp->expected_client_content_length);
1142          csp->client_iob->eod = csp->client_iob->cur + csp->expected_client_content_length;
1143          log_error(LOG_LEVEL_CONNECT, "Reducing expected bytes to 0. "
1144             "Marking the server socket tainted after throwing %llu bytes away.",
1145             buffered_request_bytes - csp->expected_client_content_length);
1146          csp->expected_client_content_length = 0;
1147          csp->flags |= CSP_FLAG_SERVER_SOCKET_TAINTED;
1148       }
1149
1150       if (csp->expected_client_content_length == 0)
1151       {
1152          csp->flags |= CSP_FLAG_CLIENT_REQUEST_COMPLETELY_READ;
1153       }
1154    }
1155
1156    if (!(csp->flags & CSP_FLAG_CLIENT_REQUEST_COMPLETELY_READ)
1157       && ((csp->client_iob->cur < csp->client_iob->eod)
1158          || (csp->expected_client_content_length != 0)))
1159    {
1160       if (strcmpic(csp->http->gpc, "GET")
1161          && strcmpic(csp->http->gpc, "HEAD")
1162          && strcmpic(csp->http->gpc, "TRACE")
1163          && strcmpic(csp->http->gpc, "OPTIONS")
1164          && strcmpic(csp->http->gpc, "DELETE"))
1165       {
1166          /* XXX: this is an incomplete hack */
1167          csp->flags &= ~CSP_FLAG_CLIENT_REQUEST_COMPLETELY_READ;
1168          log_error(LOG_LEVEL_CONNECT, "There better be a request body.");
1169       }
1170       else
1171       {
1172          csp->flags |= CSP_FLAG_CLIENT_REQUEST_COMPLETELY_READ;
1173
1174          if ((csp->config->feature_flags & RUNTIME_FEATURE_TOLERATE_PIPELINING) == 0)
1175          {
1176             csp->flags |= CSP_FLAG_SERVER_SOCKET_TAINTED;
1177             log_error(LOG_LEVEL_CONNECT,
1178                "Possible pipeline attempt detected. The connection will not "
1179                "be kept alive and we will only serve the first request.");
1180             /* Nuke the pipelined requests from orbit, just to be sure. */
1181             clear_iob(csp->client_iob);
1182          }
1183          else
1184          {
1185             /*
1186              * Keep the pipelined data around for now, we'll deal with
1187              * it once we're done serving the current request.
1188              */
1189             csp->flags |= CSP_FLAG_PIPELINED_REQUEST_WAITING;
1190             assert(csp->client_iob->eod >= csp->client_iob->cur);
1191             log_error(LOG_LEVEL_CONNECT, "Complete client request followed by "
1192                "%d bytes of pipelined data received.",
1193                (int)(csp->client_iob->eod - csp->client_iob->cur));
1194          }
1195       }
1196    }
1197    else
1198    {
1199       csp->flags |= CSP_FLAG_CLIENT_REQUEST_COMPLETELY_READ;
1200       log_error(LOG_LEVEL_CONNECT, "Complete client request received.");
1201    }
1202 }
1203 #endif /* FEATURE_CONNECTION_KEEP_ALIVE */
1204
1205
1206 /*********************************************************************
1207  *
1208  * Function    :  mark_server_socket_tainted
1209  *
1210  * Description :  Makes sure we don't reuse a server socket
1211  *                (if we didn't read everything the server sent
1212  *                us reusing the socket would lead to garbage).
1213  *
1214  * Parameters  :
1215  *          1  :  csp = Current client state (buffers, headers, etc...)
1216  *
1217  * Returns     :  void.
1218  *
1219  *********************************************************************/
1220 static void mark_server_socket_tainted(struct client_state *csp)
1221 {
1222    /*
1223     * For consistency we always mark the server socket
1224     * tainted, however, to reduce the log noise we only
1225     * emit a log message if the server socket could have
1226     * actually been reused.
1227     */
1228    if ((csp->flags & CSP_FLAG_SERVER_CONNECTION_KEEP_ALIVE)
1229       && !(csp->flags & CSP_FLAG_SERVER_SOCKET_TAINTED))
1230    {
1231       log_error(LOG_LEVEL_CONNECT,
1232          "Marking the server socket %d tainted.",
1233          csp->server_connection.sfd);
1234    }
1235    csp->flags |= CSP_FLAG_SERVER_SOCKET_TAINTED;
1236 }
1237
1238 /*********************************************************************
1239  *
1240  * Function    :  get_request_line
1241  *
1242  * Description : Read the client request line.
1243  *
1244  * Parameters  :
1245  *          1  :  csp = Current client state (buffers, headers, etc...)
1246  *
1247  * Returns     :  Pointer to request line or NULL in case of errors.
1248  *
1249  *********************************************************************/
1250 static char *get_request_line(struct client_state *csp)
1251 {
1252    char buf[BUFFER_SIZE];
1253    char *request_line = NULL;
1254    int len;
1255
1256    memset(buf, 0, sizeof(buf));
1257
1258    if ((csp->flags & CSP_FLAG_PIPELINED_REQUEST_WAITING) != 0)
1259    {
1260       /*
1261        * If there are multiple pipelined requests waiting,
1262        * the flag will be set again once the next request
1263        * has been parsed.
1264        */
1265       csp->flags &= ~CSP_FLAG_PIPELINED_REQUEST_WAITING;
1266
1267       request_line = get_header(csp->client_iob);
1268       if ((NULL != request_line) && ('\0' != *request_line))
1269       {
1270          return request_line;
1271       }
1272       else
1273       {
1274          log_error(LOG_LEVEL_CONNECT, "No complete request line "
1275             "received yet. Continuing reading from %d.", csp->cfd);
1276       }
1277    }
1278
1279    do
1280    {
1281       if (!data_is_available(csp->cfd, csp->config->socket_timeout))
1282       {
1283          if (socket_is_still_alive(csp->cfd))
1284          {
1285             log_error(LOG_LEVEL_CONNECT,
1286                "No request line on socket %d received in time. Timeout: %d.",
1287                csp->cfd, csp->config->socket_timeout);
1288             write_socket(csp->cfd, CLIENT_CONNECTION_TIMEOUT_RESPONSE,
1289                strlen(CLIENT_CONNECTION_TIMEOUT_RESPONSE));
1290          }
1291          else
1292          {
1293             log_error(LOG_LEVEL_CONNECT,
1294                "The client side of the connection on socket %d got "
1295                "closed without sending a complete request line.", csp->cfd);
1296          }
1297          return NULL;
1298       }
1299
1300       len = read_socket(csp->cfd, buf, sizeof(buf) - 1);
1301
1302       if (len <= 0) return NULL;
1303
1304       /*
1305        * If there is no memory left for buffering the
1306        * request, there is nothing we can do but hang up
1307        */
1308       if (add_to_iob(csp->client_iob, csp->config->buffer_limit, buf, len))
1309       {
1310          return NULL;
1311       }
1312
1313       request_line = get_header(csp->client_iob);
1314
1315    } while ((NULL != request_line) && ('\0' == *request_line));
1316
1317    return request_line;
1318
1319 }
1320
1321 enum chunk_status
1322 {
1323    CHUNK_STATUS_MISSING_DATA,
1324    CHUNK_STATUS_BODY_COMPLETE,
1325    CHUNK_STATUS_PARSE_ERROR
1326 };
1327
1328
1329 /*********************************************************************
1330  *
1331  * Function    :  chunked_body_is_complete
1332  *
1333  * Description :  Figures out whether or not a chunked body is complete.
1334  *
1335  *                Currently it always starts at the beginning of the
1336  *                buffer which is somewhat wasteful and prevents Privoxy
1337  *                from starting to forward the correctly parsed chunks
1338  *                as soon as theoretically possible.
1339  *
1340  *                Should be modified to work with a common buffer,
1341  *                and allow the caller to skip already parsed chunks.
1342  *
1343  *                This would allow the function to be used for unbuffered
1344  *                response bodies as well.
1345  *
1346  * Parameters  :
1347  *          1  :  iob = Buffer with the body to check.
1348  *          2  :  length = Length of complete body
1349  *
1350  * Returns     :  Enum with the result of the check.
1351  *
1352  *********************************************************************/
1353 static enum chunk_status chunked_body_is_complete(struct iob *iob, size_t *length)
1354 {
1355    unsigned int chunksize;
1356    char *p = iob->cur;
1357
1358    do
1359    {
1360       /*
1361        * We need at least a single digit, followed by "\r\n",
1362        * followed by an unknown amount of data, followed by "\r\n".
1363        */
1364       if (p + 5 > iob->eod)
1365       {
1366          return CHUNK_STATUS_MISSING_DATA;
1367       }
1368       if (sscanf(p, "%x", &chunksize) != 1)
1369       {
1370          return CHUNK_STATUS_PARSE_ERROR;
1371       }
1372
1373       /*
1374        * We want at least a single digit, followed by "\r\n",
1375        * followed by the specified amount of data, followed by "\r\n".
1376        */
1377       if (p + chunksize + 5 > iob->eod)
1378       {
1379          return CHUNK_STATUS_MISSING_DATA;
1380       }
1381
1382       /* Skip chunk-size. */
1383       p = strstr(p, "\r\n");
1384       if (NULL == p)
1385       {
1386          return CHUNK_STATUS_PARSE_ERROR;
1387       }
1388       /* Move beyond the chunkdata. */
1389       p += 2 + chunksize;
1390
1391       /* There should be another "\r\n" to skip */
1392       if (memcmp(p, "\r\n", 2))
1393       {
1394          return CHUNK_STATUS_PARSE_ERROR;
1395       }
1396       p += 2;
1397    } while (chunksize > 0U);
1398
1399    *length = (size_t)(p - iob->cur);
1400    assert(*length <= (size_t)(iob->eod - iob->cur));
1401    assert(p <= iob->eod);
1402
1403    return CHUNK_STATUS_BODY_COMPLETE;
1404
1405 }
1406
1407
1408 /*********************************************************************
1409  *
1410  * Function    : receive_chunked_client_request_body
1411  *
1412  * Description : Read the chunk-encoded client request body.
1413  *               Failures are dealt with.
1414  *
1415  * Parameters  :
1416  *          1  :  csp = Current client state (buffers, headers, etc...)
1417  *
1418  * Returns     :  JB_ERR_OK or JB_ERR_PARSE
1419  *
1420  *********************************************************************/
1421 static jb_err receive_chunked_client_request_body(struct client_state *csp)
1422 {
1423    size_t body_length;
1424    enum chunk_status status;
1425
1426    while (CHUNK_STATUS_MISSING_DATA ==
1427       (status = chunked_body_is_complete(csp->client_iob,&body_length)))
1428    {
1429       char buf[BUFFER_SIZE];
1430       int len;
1431
1432       if (!data_is_available(csp->cfd, csp->config->socket_timeout))
1433       {
1434          log_error(LOG_LEVEL_ERROR,
1435             "Timeout while waiting for the client body.");
1436          break;
1437       }
1438       len = read_socket(csp->cfd, buf, sizeof(buf) - 1);
1439       if (len <= 0)
1440       {
1441          log_error(LOG_LEVEL_ERROR, "Read the client body failed: %E");
1442          break;
1443       }
1444       if (add_to_iob(csp->client_iob, csp->config->buffer_limit, buf, len))
1445       {
1446          break;
1447       }
1448    }
1449    if (status != CHUNK_STATUS_BODY_COMPLETE)
1450    {
1451       write_socket(csp->cfd, CLIENT_BODY_PARSE_ERROR_RESPONSE,
1452          strlen(CLIENT_BODY_PARSE_ERROR_RESPONSE));
1453       log_error(LOG_LEVEL_CLF,
1454          "%s - - [%T] \"Failed reading chunked client body\" 400 0", csp->ip_addr_str);
1455       return JB_ERR_PARSE;
1456    }
1457    log_error(LOG_LEVEL_CONNECT,
1458       "Chunked client body completely read. Length: %d", body_length);
1459    csp->expected_client_content_length = body_length;
1460
1461    return JB_ERR_OK;
1462
1463 }
1464
1465
1466 #ifdef FEATURE_FORCE_LOAD
1467 /*********************************************************************
1468  *
1469  * Function    :  force_required
1470  *
1471  * Description : Checks a request line to see if it contains
1472  *               the FORCE_PREFIX. If it does, it is removed
1473  *               unless enforcing requests has beend disabled.
1474  *
1475  * Parameters  :
1476  *          1  :  request_line = HTTP request line
1477  *
1478  * Returns     :  TRUE if force is required, FALSE otherwise.
1479  *
1480  *********************************************************************/
1481 static int force_required(const struct client_state *csp, char *request_line)
1482 {
1483    char *p;
1484
1485    p = strstr(request_line, "http://");
1486    if (p != NULL)
1487    {
1488       /* Skip protocol */
1489       p += strlen("http://");
1490    }
1491    else
1492    {
1493       /* Intercepted request usually don't specify the protocol. */
1494       p = request_line;
1495    }
1496
1497    /* Go to the beginning of the path */
1498    p = strstr(p, "/");
1499    if (p == NULL)
1500    {
1501       /*
1502        * If the path is missing the request line is invalid and we
1503        * are done here. The client-visible rejection happens later on.
1504        */
1505       return 0;
1506    }
1507
1508    if (0 == strncmpic(p, FORCE_PREFIX, strlen(FORCE_PREFIX) - 1))
1509    {
1510       if (!(csp->config->feature_flags & RUNTIME_FEATURE_ENFORCE_BLOCKS))
1511       {
1512          /* XXX: Should clean more carefully */
1513          strclean(request_line, FORCE_PREFIX);
1514          log_error(LOG_LEVEL_FORCE,
1515             "Enforcing request: \"%s\".", request_line);
1516
1517          return 1;
1518       }
1519       log_error(LOG_LEVEL_FORCE,
1520          "Ignored force prefix in request: \"%s\".", request_line);
1521    }
1522
1523    return 0;
1524
1525 }
1526 #endif /* def FEATURE_FORCE_LOAD */
1527
1528
1529 /*********************************************************************
1530  *
1531  * Function    :  receive_client_request
1532  *
1533  * Description : Read the client's request (more precisely the
1534  *               client headers) and answer it if necessary.
1535  *
1536  * Parameters  :
1537  *          1  :  csp = Current client state (buffers, headers, etc...)
1538  *
1539  * Returns     :  JB_ERR_OK, JB_ERR_PARSE or JB_ERR_MEMORY
1540  *
1541  *********************************************************************/
1542 static jb_err receive_client_request(struct client_state *csp)
1543 {
1544    char buf[BUFFER_SIZE];
1545    char *p;
1546    char *req = NULL;
1547    struct http_request *http;
1548    int len;
1549    jb_err err;
1550
1551    /* Temporary copy of the client's headers before they get enlisted in csp->headers */
1552    struct list header_list;
1553    struct list *headers = &header_list;
1554
1555    /* We don't care if the arriving data is a valid HTTP request or not. */
1556    csp->requests_received_total++;
1557
1558    http = csp->http;
1559
1560    memset(buf, 0, sizeof(buf));
1561
1562    req = get_request_line(csp);
1563    if (req == NULL)
1564    {
1565       mark_server_socket_tainted(csp);
1566       return JB_ERR_PARSE;
1567    }
1568    assert(*req != '\0');
1569
1570    if (client_protocol_is_unsupported(csp, req))
1571    {
1572       return JB_ERR_PARSE;
1573    }
1574
1575 #ifdef FEATURE_FORCE_LOAD
1576    if (force_required(csp, req))
1577    {
1578       csp->flags |= CSP_FLAG_FORCED;
1579    }
1580 #endif /* def FEATURE_FORCE_LOAD */
1581
1582    err = parse_http_request(req, http);
1583    freez(req);
1584    if (JB_ERR_OK != err)
1585    {
1586       write_socket(csp->cfd, CHEADER, strlen(CHEADER));
1587       /* XXX: Use correct size */
1588       log_error(LOG_LEVEL_CLF, "%s - - [%T] \"Invalid request\" 400 0", csp->ip_addr_str);
1589       log_error(LOG_LEVEL_ERROR,
1590          "Couldn't parse request line received from %s: %s",
1591          csp->ip_addr_str, jb_err_to_string(err));
1592
1593       free_http_request(http);
1594       return JB_ERR_PARSE;
1595    }
1596
1597    /* grab the rest of the client's headers */
1598    init_list(headers);
1599    for (;;)
1600    {
1601       p = get_header(csp->client_iob);
1602
1603       if (p == NULL)
1604       {
1605          /* There are no additional headers to read. */
1606          break;
1607       }
1608
1609       if (*p == '\0')
1610       {
1611          /*
1612           * We didn't receive a complete header
1613           * line yet, get the rest of it.
1614           */
1615          if (!data_is_available(csp->cfd, csp->config->socket_timeout))
1616          {
1617             log_error(LOG_LEVEL_ERROR,
1618                "Stopped grabbing the client headers.");
1619             destroy_list(headers);
1620             return JB_ERR_PARSE;
1621          }
1622
1623          len = read_socket(csp->cfd, buf, sizeof(buf) - 1);
1624          if (len <= 0)
1625          {
1626             log_error(LOG_LEVEL_ERROR, "read from client failed: %E");
1627             destroy_list(headers);
1628             return JB_ERR_PARSE;
1629          }
1630
1631          if (add_to_iob(csp->client_iob, csp->config->buffer_limit, buf, len))
1632          {
1633             /*
1634              * If there is no memory left for buffering the
1635              * request, there is nothing we can do but hang up
1636              */
1637             destroy_list(headers);
1638             return JB_ERR_MEMORY;
1639          }
1640       }
1641       else
1642       {
1643          if (!strncmpic(p, "Transfer-Encoding:", 18))
1644          {
1645             /*
1646              * XXX: should be called through sed()
1647              *      but currently can't.
1648              */
1649             client_transfer_encoding(csp, &p);
1650          }
1651          /*
1652           * We were able to read a complete
1653           * header and can finally enlist it.
1654           */
1655          enlist(headers, p);
1656          freez(p);
1657       }
1658    }
1659
1660    if (http->host == NULL)
1661    {
1662       /*
1663        * If we still don't know the request destination,
1664        * the request is invalid or the client uses
1665        * Privoxy without its knowledge.
1666        */
1667       if (JB_ERR_OK != get_request_destination_elsewhere(csp, headers))
1668       {
1669          /*
1670           * Our attempts to get the request destination
1671           * elsewhere failed or Privoxy is configured
1672           * to only accept proxy requests.
1673           *
1674           * An error response has already been send
1675           * and we're done here.
1676           */
1677          return JB_ERR_PARSE;
1678       }
1679    }
1680
1681 #ifdef FEATURE_CLIENT_TAGS
1682    /* XXX: If the headers were enlisted sooner, passing csp would do. */
1683    set_client_address(csp, headers);
1684    get_tag_list_for_client(csp->client_tags, csp->client_address);
1685 #endif
1686
1687    /*
1688     * Determine the actions for this URL
1689     */
1690 #ifdef FEATURE_TOGGLE
1691    if (!(csp->flags & CSP_FLAG_TOGGLED_ON))
1692    {
1693       /* Most compatible set of actions (i.e. none) */
1694       init_current_action(csp->action);
1695    }
1696    else
1697 #endif /* ndef FEATURE_TOGGLE */
1698    {
1699       get_url_actions(csp, http);
1700    }
1701
1702    enlist(csp->headers, http->cmd);
1703
1704    /* Append the previously read headers */
1705    err = list_append_list_unique(csp->headers, headers);
1706    destroy_list(headers);
1707
1708    return err;
1709
1710 }
1711
1712
1713 /*********************************************************************
1714  *
1715  * Function    : parse_client_request
1716  *
1717  * Description : Parses the client's request and decides what to do
1718  *               with it.
1719  *
1720  *               Note that since we're not using select() we could get
1721  *               blocked here if a client connected, then didn't say
1722  *               anything!
1723  *
1724  * Parameters  :
1725  *          1  :  csp = Current client state (buffers, headers, etc...)
1726  *
1727  * Returns     :  JB_ERR_OK or JB_ERR_PARSE
1728  *
1729  *********************************************************************/
1730 static jb_err parse_client_request(struct client_state *csp)
1731 {
1732    struct http_request *http = csp->http;
1733    jb_err err;
1734
1735 #ifdef FEATURE_CONNECTION_KEEP_ALIVE
1736    if ((csp->config->feature_flags & RUNTIME_FEATURE_CONNECTION_KEEP_ALIVE)
1737     && (!strcmpic(csp->http->ver, "HTTP/1.1"))
1738     && (csp->http->ssl == 0))
1739    {
1740       /* Assume persistence until further notice */
1741       csp->flags |= CSP_FLAG_CLIENT_CONNECTION_KEEP_ALIVE;
1742    }
1743
1744    if (csp->http->ssl == 0)
1745    {
1746       /*
1747        * This whole block belongs to chat() but currently
1748        * has to be executed before sed().
1749        */
1750       if (csp->flags & CSP_FLAG_CHUNKED_CLIENT_BODY)
1751       {
1752          if (receive_chunked_client_request_body(csp) != JB_ERR_OK)
1753          {
1754             return JB_ERR_PARSE;
1755          }
1756       }
1757       else
1758       {
1759          csp->expected_client_content_length = get_expected_content_length(csp->headers);
1760       }
1761       verify_request_length(csp);
1762    }
1763 #endif /* def FEATURE_CONNECTION_KEEP_ALIVE */
1764
1765    err = sed(csp, FILTER_CLIENT_HEADERS);
1766    if (JB_ERR_OK != err)
1767    {
1768       log_error(LOG_LEVEL_ERROR, "Failed to parse client request from %s.",
1769          csp->ip_addr_str);
1770       log_error(LOG_LEVEL_CLF, "%s - - [%T] \"%s\" 400 0",
1771          csp->ip_addr_str, csp->http->cmd);
1772       write_socket(csp->cfd, CHEADER, strlen(CHEADER));
1773       return JB_ERR_PARSE;
1774    }
1775    csp->flags |= CSP_FLAG_CLIENT_HEADER_PARSING_DONE;
1776
1777    /* Check request line for rewrites. */
1778    if ((NULL == csp->headers->first->str)
1779       || (strcmp(http->cmd, csp->headers->first->str) &&
1780          (JB_ERR_OK != change_request_destination(csp))))
1781    {
1782       /*
1783        * A header filter broke the request line - bail out.
1784        */
1785       write_socket(csp->cfd, MESSED_UP_REQUEST_RESPONSE, strlen(MESSED_UP_REQUEST_RESPONSE));
1786       /* XXX: Use correct size */
1787       log_error(LOG_LEVEL_CLF,
1788          "%s - - [%T] \"Invalid request generated\" 500 0", csp->ip_addr_str);
1789       log_error(LOG_LEVEL_ERROR,
1790          "Invalid request line after applying header filters.");
1791       free_http_request(http);
1792
1793       return JB_ERR_PARSE;
1794    }
1795
1796    if (client_has_unsupported_expectations(csp))
1797    {
1798       return JB_ERR_PARSE;
1799    }
1800
1801    return JB_ERR_OK;
1802
1803 }
1804
1805
1806 /*********************************************************************
1807  *
1808  * Function    :  chat
1809  *
1810  * Description :  Once a connection from the client has been accepted,
1811  *                this function is called (via serve()) to handle the
1812  *                main business of the communication.  This function
1813  *                returns after dealing with a single request. It can
1814  *                be called multiple times with the same client socket
1815  *                if the client is keeping the connection alive.
1816  *
1817  *                The decision whether or not a client connection will
1818  *                be kept alive is up to the caller which also must
1819  *                close the client socket when done.
1820  *
1821  *                FIXME: chat is nearly thousand lines long.
1822  *                Ridiculous.
1823  *
1824  * Parameters  :
1825  *          1  :  csp = Current client state (buffers, headers, etc...)
1826  *
1827  * Returns     :  Nothing.
1828  *
1829  *********************************************************************/
1830 static void chat(struct client_state *csp)
1831 {
1832    char buf[BUFFER_SIZE];
1833    char *hdr;
1834    char *p;
1835    fd_set rfds;
1836    int n;
1837    jb_socket maxfd;
1838    int server_body;
1839    int ms_iis5_hack = 0;
1840    unsigned long long byte_count = 0;
1841    const struct forward_spec *fwd;
1842    struct http_request *http;
1843    long len = 0; /* for buffer sizes (and negative error codes) */
1844    int buffer_and_filter_content = 0;
1845
1846    /* Skeleton for HTTP response, if we should intercept the request */
1847    struct http_response *rsp;
1848    struct timeval timeout;
1849 #ifdef FEATURE_CONNECTION_KEEP_ALIVE
1850    int watch_client_socket;
1851 #endif
1852
1853    memset(buf, 0, sizeof(buf));
1854
1855    http = csp->http;
1856
1857    if (receive_client_request(csp) != JB_ERR_OK)
1858    {
1859       return;
1860    }
1861    if (parse_client_request(csp) != JB_ERR_OK)
1862    {
1863       return;
1864    }
1865
1866    /* decide how to route the HTTP request */
1867    fwd = forward_url(csp, http);
1868    if (NULL == fwd)
1869    {
1870       log_error(LOG_LEVEL_FATAL, "gateway spec is NULL!?!?  This can't happen!");
1871       /* Never get here - LOG_LEVEL_FATAL causes program exit */
1872       return;
1873    }
1874
1875    /*
1876     * build the http request to send to the server
1877     * we have to do one of the following:
1878     *
1879     * create = use the original HTTP request to create a new
1880     *          HTTP request that has either the path component
1881     *          without the http://domainspec (w/path) or the
1882     *          full orininal URL (w/url)
1883     *          Note that the path and/or the HTTP version may
1884     *          have been altered by now.
1885     *
1886     * connect = Open a socket to the host:port of the server
1887     *           and short-circuit server and client socket.
1888     *
1889     * pass =  Pass the request unchanged if forwarding a CONNECT
1890     *         request to a parent proxy. Note that we'll be sending
1891     *         the CFAIL message ourselves if connecting to the parent
1892     *         fails, but we won't send a CSUCCEED message if it works,
1893     *         since that would result in a double message (ours and the
1894     *         parent's). After sending the request to the parent, we simply
1895     *         tunnel.
1896     *
1897     * here's the matrix:
1898     *                        SSL
1899     *                    0        1
1900     *                +--------+--------+
1901     *                |        |        |
1902     *             0  | create | connect|
1903     *                | w/path |        |
1904     *  Forwarding    +--------+--------+
1905     *                |        |        |
1906     *             1  | create | pass   |
1907     *                | w/url  |        |
1908     *                +--------+--------+
1909     *
1910     */
1911
1912    if (http->ssl && connect_port_is_forbidden(csp))
1913    {
1914       const char *acceptable_connect_ports =
1915          csp->action->string[ACTION_STRING_LIMIT_CONNECT];
1916       assert(NULL != acceptable_connect_ports);
1917       log_error(LOG_LEVEL_INFO, "Request from %s marked for blocking. "
1918          "limit-connect{%s} doesn't allow CONNECT requests to %s",
1919          csp->ip_addr_str, acceptable_connect_ports, csp->http->hostport);
1920       csp->action->flags |= ACTION_BLOCK;
1921       http->ssl = 0;
1922    }
1923
1924    if (http->ssl == 0)
1925    {
1926       freez(csp->headers->first->str);
1927       build_request_line(csp, fwd, &csp->headers->first->str);
1928    }
1929
1930    /*
1931     * We have a request. Check if one of the crunchers wants it.
1932     */
1933    if (crunch_response_triggered(csp, crunchers_all))
1934    {
1935       /*
1936        * Yes. The client got the crunch response and we're done here.
1937        */
1938       return;
1939    }
1940
1941    log_applied_actions(csp->action);
1942    log_error(LOG_LEVEL_GPC, "%s%s", http->hostport, http->path);
1943
1944    if (fwd->forward_host)
1945    {
1946       log_error(LOG_LEVEL_CONNECT, "via [%s]:%d to: %s",
1947          fwd->forward_host, fwd->forward_port, http->hostport);
1948    }
1949    else
1950    {
1951       log_error(LOG_LEVEL_CONNECT, "to %s", http->hostport);
1952    }
1953
1954    /* here we connect to the server, gateway, or the forwarder */
1955
1956 #ifdef FEATURE_CONNECTION_KEEP_ALIVE
1957    if ((csp->server_connection.sfd != JB_INVALID_SOCKET)
1958       && socket_is_still_alive(csp->server_connection.sfd)
1959       && connection_destination_matches(&csp->server_connection, http, fwd))
1960    {
1961       log_error(LOG_LEVEL_CONNECT,
1962          "Reusing server socket %d connected to %s. Total requests: %u.",
1963          csp->server_connection.sfd, csp->server_connection.host,
1964          csp->server_connection.requests_sent_total);
1965    }
1966    else
1967    {
1968       if (csp->server_connection.sfd != JB_INVALID_SOCKET)
1969       {
1970 #ifdef FEATURE_CONNECTION_SHARING
1971          if (csp->config->feature_flags & RUNTIME_FEATURE_CONNECTION_SHARING)
1972          {
1973             remember_connection(&csp->server_connection);
1974          }
1975          else
1976 #endif /* def FEATURE_CONNECTION_SHARING */
1977          {
1978             log_error(LOG_LEVEL_CONNECT,
1979                "Closing server socket %d connected to %s. Total requests: %u.",
1980                csp->server_connection.sfd, csp->server_connection.host,
1981                csp->server_connection.requests_sent_total);
1982             close_socket(csp->server_connection.sfd);
1983          }
1984          mark_connection_closed(&csp->server_connection);
1985       }
1986 #endif /* def FEATURE_CONNECTION_KEEP_ALIVE */
1987
1988       csp->server_connection.sfd = forwarded_connect(fwd, http, csp);
1989
1990       if (csp->server_connection.sfd == JB_INVALID_SOCKET)
1991       {
1992          if ((fwd->type != SOCKS_NONE) && (fwd->type != FORWARD_WEBSERVER))
1993          {
1994             /* Socks error. */
1995             rsp = error_response(csp, "forwarding-failed");
1996          }
1997          else if (errno == EINVAL)
1998          {
1999             rsp = error_response(csp, "no-such-domain");
2000          }
2001          else
2002          {
2003             rsp = error_response(csp, "connect-failed");
2004          }
2005
2006          /* Write the answer to the client */
2007          if (rsp != NULL)
2008          {
2009             send_crunch_response(csp, rsp);
2010          }
2011
2012          /*
2013           * Temporary workaround to prevent already-read client
2014           * bodies from being parsed as new requests. For now we
2015           * err on the safe side and throw all the following
2016           * requests under the bus, even if no client body has been
2017           * buffered. A compliant client will repeat the dropped
2018           * requests on an untainted connection.
2019           *
2020           * The proper fix is to discard the no longer needed
2021           * client body in the buffer (if there is one) and to
2022           * continue parsing the bytes that follow.
2023           */
2024          drain_and_close_socket(csp->cfd);
2025          csp->cfd = JB_INVALID_SOCKET;
2026
2027          return;
2028       }
2029 #ifdef FEATURE_CONNECTION_KEEP_ALIVE
2030       save_connection_destination(csp->server_connection.sfd,
2031          http, fwd, &csp->server_connection);
2032       csp->server_connection.keep_alive_timeout =
2033          (unsigned)csp->config->keep_alive_timeout;
2034    }
2035 #endif /* def FEATURE_CONNECTION_KEEP_ALIVE */
2036
2037    csp->server_connection.requests_sent_total++;
2038
2039    if ((fwd->type == SOCKS_5T) && (NULL == csp->headers->first))
2040    {
2041       /* Client headers have been sent optimistically */
2042       assert(csp->headers->last == NULL);
2043    }
2044    else if (fwd->forward_host || (http->ssl == 0))
2045    {
2046       int write_failure;
2047       hdr = list_to_text(csp->headers);
2048       if (hdr == NULL)
2049       {
2050          /* FIXME Should handle error properly */
2051          log_error(LOG_LEVEL_FATAL, "Out of memory parsing client header");
2052       }
2053       list_remove_all(csp->headers);
2054
2055       /*
2056        * Write the client's (modified) header to the server
2057        * (along with anything else that may be in the buffer)
2058        */
2059       write_failure = 0 != write_socket(csp->server_connection.sfd, hdr, strlen(hdr));
2060       freez(hdr);
2061
2062       if (write_failure)
2063       {
2064          log_error(LOG_LEVEL_CONNECT,
2065             "Failed sending request headers to: %s: %E", http->hostport);
2066       }
2067       else if (((csp->flags & CSP_FLAG_PIPELINED_REQUEST_WAITING) == 0)
2068          && (flush_socket(csp->server_connection.sfd, csp->client_iob) < 0))
2069       {
2070          write_failure = 1;
2071          log_error(LOG_LEVEL_CONNECT,
2072             "Failed sending request body to: %s: %E", http->hostport);
2073       }
2074
2075       if (write_failure)
2076       {
2077          rsp = error_response(csp, "connect-failed");
2078          if (rsp)
2079          {
2080             send_crunch_response(csp, rsp);
2081          }
2082          return;
2083       }
2084    }
2085    else
2086    {
2087       /*
2088        * We're running an SSL tunnel and we're not forwarding,
2089        * so just ditch the client headers, send the "connect succeeded"
2090        * message to the client, flush the rest, and get out of the way.
2091        */
2092       list_remove_all(csp->headers);
2093       if (write_socket(csp->cfd, CSUCCEED, strlen(CSUCCEED)))
2094       {
2095          return;
2096       }
2097       clear_iob(csp->client_iob);
2098    }
2099
2100    log_error(LOG_LEVEL_CONNECT, "to %s successful", http->hostport);
2101
2102    /* XXX: should the time start earlier for optimistically sent data? */
2103    csp->server_connection.request_sent = time(NULL);
2104
2105    maxfd = (csp->cfd > csp->server_connection.sfd) ?
2106       csp->cfd : csp->server_connection.sfd;
2107
2108    /* pass data between the client and server
2109     * until one or the other shuts down the connection.
2110     */
2111
2112    server_body = 0;
2113
2114 #ifdef FEATURE_CONNECTION_KEEP_ALIVE
2115    watch_client_socket = 0 == (csp->flags & CSP_FLAG_PIPELINED_REQUEST_WAITING);
2116 #endif
2117
2118    for (;;)
2119    {
2120 #ifdef __OS2__
2121       /*
2122        * FD_ZERO here seems to point to an errant macro which crashes.
2123        * So do this by hand for now...
2124        */
2125       memset(&rfds,0x00,sizeof(fd_set));
2126 #else
2127       FD_ZERO(&rfds);
2128 #endif
2129 #ifdef FEATURE_CONNECTION_KEEP_ALIVE
2130       if (!watch_client_socket)
2131       {
2132          maxfd = csp->server_connection.sfd;
2133       }
2134       else
2135 #endif /* def FEATURE_CONNECTION_KEEP_ALIVE */
2136       {
2137          FD_SET(csp->cfd, &rfds);
2138       }
2139
2140       FD_SET(csp->server_connection.sfd, &rfds);
2141
2142 #ifdef FEATURE_CONNECTION_KEEP_ALIVE
2143       if ((csp->flags & CSP_FLAG_CHUNKED)
2144          && !(csp->flags & CSP_FLAG_CONTENT_LENGTH_SET)
2145          && ((csp->iob->eod - csp->iob->cur) >= 5)
2146          && !memcmp(csp->iob->eod-5, "0\r\n\r\n", 5))
2147       {
2148          /*
2149           * XXX: This check should be obsolete now,
2150           *      but let's wait a while to be sure.
2151           */
2152          log_error(LOG_LEVEL_CONNECT,
2153             "Looks like we got the last chunk together with "
2154             "the server headers but didn't detect it earlier. "
2155             "We better stop reading.");
2156          byte_count = (unsigned long long)(csp->iob->eod - csp->iob->cur);
2157          csp->expected_content_length = byte_count;
2158          csp->flags |= CSP_FLAG_CONTENT_LENGTH_SET;
2159       }
2160       if (server_body && server_response_is_complete(csp, byte_count))
2161       {
2162          if (csp->expected_content_length == byte_count)
2163          {
2164             log_error(LOG_LEVEL_CONNECT,
2165                "Done reading from server. Content length: %llu as expected. "
2166                "Bytes most recently read: %d.",
2167                byte_count, len);
2168          }
2169          else
2170          {
2171             log_error(LOG_LEVEL_CONNECT,
2172                "Done reading from server. Expected content length: %llu. "
2173                "Actual content length: %llu. Bytes most recently read: %d.",
2174                csp->expected_content_length, byte_count, len);
2175          }
2176          len = 0;
2177          /*
2178           * XXX: should not jump around,
2179           * chat() is complicated enough already.
2180           */
2181          goto reading_done;
2182       }
2183 #endif  /* FEATURE_CONNECTION_KEEP_ALIVE */
2184
2185       timeout.tv_sec = csp->config->socket_timeout;
2186       timeout.tv_usec = 0;
2187       n = select((int)maxfd+1, &rfds, NULL, NULL, &timeout);
2188
2189       if (n == 0)
2190       {
2191          log_error(LOG_LEVEL_ERROR,
2192             "Didn't receive data in time: %s", http->url);
2193          if ((byte_count == 0) && (http->ssl == 0))
2194          {
2195             send_crunch_response(csp, error_response(csp, "connection-timeout"));
2196          }
2197          mark_server_socket_tainted(csp);
2198          return;
2199       }
2200       else if (n < 0)
2201       {
2202          log_error(LOG_LEVEL_ERROR, "select() failed!: %E");
2203          mark_server_socket_tainted(csp);
2204          return;
2205       }
2206
2207       /*
2208        * This is the body of the browser's request,
2209        * just read and write it.
2210        *
2211        * XXX: Make sure the client doesn't use pipelining
2212        * behind Privoxy's back.
2213        */
2214       if (FD_ISSET(csp->cfd, &rfds))
2215       {
2216          int max_bytes_to_read = sizeof(buf) - 1;
2217
2218 #ifdef FEATURE_CONNECTION_KEEP_ALIVE
2219          if ((csp->flags & CSP_FLAG_CLIENT_REQUEST_COMPLETELY_READ))
2220          {
2221             if (data_is_available(csp->cfd, 0))
2222             {
2223                /*
2224                 * If the next request is already waiting, we have
2225                 * to stop select()ing the client socket. Otherwise
2226                 * we would always return right away and get nothing
2227                 * else done.
2228                 */
2229                watch_client_socket = 0;
2230                log_error(LOG_LEVEL_CONNECT,
2231                   "Stopping to watch the client socket %d. "
2232                   "There's already another request waiting.",
2233                   csp->cfd);
2234                continue;
2235             }
2236             /*
2237              * If the client socket is set, but there's no data
2238              * available on the socket, the client went fishing
2239              * and continuing talking to the server makes no sense.
2240              */
2241             log_error(LOG_LEVEL_CONNECT,
2242                "The client closed socket %d while "
2243                "the server socket %d is still open.",
2244                csp->cfd, csp->server_connection.sfd);
2245             mark_server_socket_tainted(csp);
2246             break;
2247          }
2248          if (csp->expected_client_content_length != 0)
2249          {
2250             if (csp->expected_client_content_length < (sizeof(buf) - 1))
2251             {
2252                max_bytes_to_read = (int)csp->expected_client_content_length;
2253             }
2254             log_error(LOG_LEVEL_CONNECT,
2255                "Waiting for up to %d bytes from the client.",
2256                max_bytes_to_read);
2257          }
2258          assert(max_bytes_to_read < sizeof(buf));
2259 #endif /* def FEATURE_CONNECTION_KEEP_ALIVE */
2260
2261          len = read_socket(csp->cfd, buf, max_bytes_to_read);
2262
2263          if (len <= 0)
2264          {
2265             /* XXX: not sure if this is necessary. */
2266             mark_server_socket_tainted(csp);
2267             break; /* "game over, man" */
2268          }
2269
2270 #ifdef FEATURE_CONNECTION_KEEP_ALIVE
2271          if (csp->expected_client_content_length != 0)
2272          {
2273             assert(len <= max_bytes_to_read);
2274             csp->expected_client_content_length -= (unsigned)len;
2275             log_error(LOG_LEVEL_CONNECT,
2276                "Expected client content length set to %llu "
2277                "after reading %d bytes.",
2278                csp->expected_client_content_length, len);
2279             if (csp->expected_client_content_length == 0)
2280             {
2281                log_error(LOG_LEVEL_CONNECT,
2282                   "Done reading from the client.");
2283                csp->flags |= CSP_FLAG_CLIENT_REQUEST_COMPLETELY_READ;
2284             }
2285          }
2286 #endif /* def FEATURE_CONNECTION_KEEP_ALIVE */
2287
2288          if (write_socket(csp->server_connection.sfd, buf, (size_t)len))
2289          {
2290             log_error(LOG_LEVEL_ERROR, "write to: %s failed: %E", http->host);
2291             mark_server_socket_tainted(csp);
2292             return;
2293          }
2294          continue;
2295       }
2296
2297       /*
2298        * The server wants to talk. It could be the header or the body.
2299        * If `hdr' is null, then it's the header otherwise it's the body.
2300        * FIXME: Does `hdr' really mean `host'? No.
2301        */
2302       if (FD_ISSET(csp->server_connection.sfd, &rfds))
2303       {
2304 #ifdef FEATURE_CONNECTION_KEEP_ALIVE
2305          /*
2306           * If we are buffering content, we don't want to eat up to
2307           * buffer-limit bytes if the client no longer cares about them.
2308           * If we aren't buffering, however, a dead client socket will be
2309           * noticed pretty much right away anyway, so we can reduce the
2310           * overhead by skipping the check.
2311           */
2312          if (buffer_and_filter_content && !socket_is_still_alive(csp->cfd))
2313          {
2314 #ifdef _WIN32
2315             log_error(LOG_LEVEL_CONNECT,
2316                "The server still wants to talk, but the client may already have hung up on us.");
2317 #else
2318             log_error(LOG_LEVEL_CONNECT,
2319                "The server still wants to talk, but the client hung up on us.");
2320             mark_server_socket_tainted(csp);
2321             return;
2322 #endif /* def _WIN32 */
2323          }
2324 #endif /* def FEATURE_CONNECTION_KEEP_ALIVE */
2325
2326          len = read_socket(csp->server_connection.sfd, buf, sizeof(buf) - 1);
2327
2328          if (len < 0)
2329          {
2330             log_error(LOG_LEVEL_ERROR, "read from: %s failed: %E", http->host);
2331
2332             if (http->ssl && (fwd->forward_host == NULL))
2333             {
2334                /*
2335                 * Just hang up. We already confirmed the client's CONNECT
2336                 * request with status code 200 and unencrypted content is
2337                 * no longer welcome.
2338                 */
2339                log_error(LOG_LEVEL_ERROR,
2340                   "CONNECT already confirmed. Unable to tell the client about the problem.");
2341                return;
2342             }
2343             else if (byte_count)
2344             {
2345                /*
2346                 * Just hang up. We already transmitted the original headers
2347                 * and parts of the original content and therefore missed the
2348                 * chance to send an error message (without risking data corruption).
2349                 *
2350                 * XXX: we could retry with a fancy range request here.
2351                 */
2352                log_error(LOG_LEVEL_ERROR, "Already forwarded the original headers. "
2353                   "Unable to tell the client about the problem.");
2354                mark_server_socket_tainted(csp);
2355                return;
2356             }
2357             /*
2358              * XXX: Consider handling the cases above the same.
2359              */
2360             mark_server_socket_tainted(csp);
2361             len = 0;
2362          }
2363
2364 #ifdef FEATURE_CONNECTION_KEEP_ALIVE
2365          if (csp->flags & CSP_FLAG_CHUNKED)
2366          {
2367             if ((len >= 5) && !memcmp(buf+len-5, "0\r\n\r\n", 5))
2368             {
2369                /* XXX: this is a temporary hack */
2370                log_error(LOG_LEVEL_CONNECT,
2371                   "Looks like we reached the end of the last chunk. "
2372                   "We better stop reading.");
2373                csp->expected_content_length = byte_count + (unsigned long long)len;
2374                csp->flags |= CSP_FLAG_CONTENT_LENGTH_SET;
2375             }
2376          }
2377          reading_done:
2378 #endif  /* FEATURE_CONNECTION_KEEP_ALIVE */
2379
2380          /*
2381           * Add a trailing zero to let be able to use string operations.
2382           * XXX: do we still need this with filter_popups gone?
2383           */
2384          buf[len] = '\0';
2385
2386          /*
2387           * Normally, this would indicate that we've read
2388           * as much as the server has sent us and we can
2389           * close the client connection.  However, Microsoft
2390           * in its wisdom has released IIS/5 with a bug that
2391           * prevents it from sending the trailing \r\n in
2392           * a 302 redirect header (and possibly other headers).
2393           * To work around this if we've haven't parsed
2394           * a full header we'll append a trailing \r\n
2395           * and see if this now generates a valid one.
2396           *
2397           * This hack shouldn't have any impacts.  If we've
2398           * already transmitted the header or if this is a
2399           * SSL connection, then we won't bother with this
2400           * hack.  So we only work on partially received
2401           * headers.  If we append a \r\n and this still
2402           * doesn't generate a valid header, then we won't
2403           * transmit anything to the client.
2404           */
2405          if (len == 0)
2406          {
2407
2408             if (server_body || http->ssl)
2409             {
2410                /*
2411                 * If we have been buffering up the document,
2412                 * now is the time to apply content modification
2413                 * and send the result to the client.
2414                 */
2415                if (buffer_and_filter_content)
2416                {
2417                   p = execute_content_filters(csp);
2418                   /*
2419                    * If content filtering fails, use the original
2420                    * buffer and length.
2421                    * (see p != NULL ? p : csp->iob->cur below)
2422                    */
2423                   if (NULL == p)
2424                   {
2425                      csp->content_length = (size_t)(csp->iob->eod - csp->iob->cur);
2426                   }
2427 #ifdef FEATURE_COMPRESSION
2428                   else if ((csp->flags & CSP_FLAG_CLIENT_SUPPORTS_DEFLATE)
2429                      && (csp->content_length > LOWER_LENGTH_LIMIT_FOR_COMPRESSION))
2430                   {
2431                      char *compressed_content = compress_buffer(p,
2432                         (size_t *)&csp->content_length, csp->config->compression_level);
2433                      if (compressed_content != NULL)
2434                      {
2435                         freez(p);
2436                         p = compressed_content;
2437                         csp->flags |= CSP_FLAG_BUFFERED_CONTENT_DEFLATED;
2438                      }
2439                   }
2440 #endif
2441
2442                   if (JB_ERR_OK != update_server_headers(csp))
2443                   {
2444                      log_error(LOG_LEVEL_FATAL,
2445                         "Failed to update server headers. after filtering.");
2446                   }
2447
2448                   hdr = list_to_text(csp->headers);
2449                   if (hdr == NULL)
2450                   {
2451                      /* FIXME Should handle error properly */
2452                      log_error(LOG_LEVEL_FATAL, "Out of memory parsing server header");
2453                   }
2454
2455                   if (write_socket(csp->cfd, hdr, strlen(hdr))
2456                    || write_socket(csp->cfd,
2457                          ((p != NULL) ? p : csp->iob->cur), (size_t)csp->content_length))
2458                   {
2459                      log_error(LOG_LEVEL_ERROR, "write modified content to client failed: %E");
2460                      freez(hdr);
2461                      freez(p);
2462                      mark_server_socket_tainted(csp);
2463                      return;
2464                   }
2465
2466                   freez(hdr);
2467                   freez(p);
2468                }
2469
2470                break; /* "game over, man" */
2471             }
2472
2473             /*
2474              * This is NOT the body, so
2475              * Let's pretend the server just sent us a blank line.
2476              */
2477             snprintf(buf, sizeof(buf), "\r\n");
2478             len = (int)strlen(buf);
2479
2480             /*
2481              * Now, let the normal header parsing algorithm below do its
2482              * job.  If it fails, we'll exit instead of continuing.
2483              */
2484
2485             ms_iis5_hack = 1;
2486          }
2487
2488          /*
2489           * If this is an SSL connection or we're in the body
2490           * of the server document, just write it to the client,
2491           * unless we need to buffer the body for later content-filtering
2492           */
2493          if (server_body || http->ssl)
2494          {
2495             if (buffer_and_filter_content)
2496             {
2497                /*
2498                 * If there is no memory left for buffering the content, or the buffer limit
2499                 * has been reached, switch to non-filtering mode, i.e. make & write the
2500                 * header, flush the iob and buf, and get out of the way.
2501                 */
2502                if (add_to_iob(csp->iob, csp->config->buffer_limit, buf, len))
2503                {
2504                   size_t hdrlen;
2505                   long flushed;
2506
2507                   log_error(LOG_LEVEL_INFO,
2508                      "Flushing header and buffers. Stepping back from filtering.");
2509
2510                   hdr = list_to_text(csp->headers);
2511                   if (hdr == NULL)
2512                   {
2513                      /*
2514                       * Memory is too tight to even generate the header.
2515                       * Send our static "Out-of-memory" page.
2516                       */
2517                      log_error(LOG_LEVEL_ERROR, "Out of memory while trying to flush.");
2518                      rsp = cgi_error_memory();
2519                      send_crunch_response(csp, rsp);
2520                      mark_server_socket_tainted(csp);
2521                      return;
2522                   }
2523                   hdrlen = strlen(hdr);
2524
2525                   if (write_socket(csp->cfd, hdr, hdrlen)
2526                    || ((flushed = flush_socket(csp->cfd, csp->iob)) < 0)
2527                    || (write_socket(csp->cfd, buf, (size_t)len)))
2528                   {
2529                      log_error(LOG_LEVEL_CONNECT,
2530                         "Flush header and buffers to client failed: %E");
2531                      freez(hdr);
2532                      mark_server_socket_tainted(csp);
2533                      return;
2534                   }
2535
2536                   /*
2537                    * Reset the byte_count to the amount of bytes
2538                    * we just flushed. len will be added a few lines below,
2539                    * hdrlen doesn't matter for LOG_LEVEL_CLF.
2540                    */
2541                   byte_count = (unsigned long long)flushed;
2542                   freez(hdr);
2543                   buffer_and_filter_content = 0;
2544                   server_body = 1;
2545                }
2546             }
2547             else
2548             {
2549                if (write_socket(csp->cfd, buf, (size_t)len))
2550                {
2551                   log_error(LOG_LEVEL_ERROR, "write to client failed: %E");
2552                   mark_server_socket_tainted(csp);
2553                   return;
2554                }
2555             }
2556             byte_count += (unsigned long long)len;
2557             continue;
2558          }
2559          else
2560          {
2561             /*
2562              * We're still looking for the end of the server's header.
2563              * Buffer up the data we just read.  If that fails, there's
2564              * little we can do but send our static out-of-memory page.
2565              */
2566             if (add_to_iob(csp->iob, csp->config->buffer_limit, buf, len))
2567             {
2568                log_error(LOG_LEVEL_ERROR, "Out of memory while looking for end of server headers.");
2569                rsp = cgi_error_memory();
2570                send_crunch_response(csp, rsp);
2571                mark_server_socket_tainted(csp);
2572                return;
2573             }
2574
2575             /* Convert iob into something sed() can digest */
2576             if (JB_ERR_PARSE == get_server_headers(csp))
2577             {
2578                if (ms_iis5_hack)
2579                {
2580                   /*
2581                    * Well, we tried our MS IIS/5 hack and it didn't work.
2582                    * The header is incomplete and there isn't anything
2583                    * we can do about it.
2584                    */
2585                   log_error(LOG_LEVEL_ERROR, "Invalid server headers. "
2586                      "Applying the MS IIS5 hack didn't help.");
2587                   log_error(LOG_LEVEL_CLF,
2588                      "%s - - [%T] \"%s\" 502 0", csp->ip_addr_str, http->cmd);
2589                   write_socket(csp->cfd, INVALID_SERVER_HEADERS_RESPONSE,
2590                      strlen(INVALID_SERVER_HEADERS_RESPONSE));
2591                   mark_server_socket_tainted(csp);
2592                   return;
2593                }
2594                else
2595                {
2596                   /*
2597                    * Since we have to wait for more from the server before
2598                    * we can parse the headers we just continue here.
2599                    */
2600                   log_error(LOG_LEVEL_CONNECT,
2601                      "Continuing buffering server headers from socket %d. "
2602                      "Bytes most recently read: %d.", csp->cfd, len);
2603                   continue;
2604                }
2605             }
2606             else
2607             {
2608                /*
2609                 * Account for the content bytes we
2610                 * might have gotten with the headers.
2611                 */
2612                assert(csp->iob->eod >= csp->iob->cur);
2613                byte_count = (unsigned long long)(csp->iob->eod - csp->iob->cur);
2614             }
2615
2616             /* Did we actually get anything? */
2617             if (NULL == csp->headers->first)
2618             {
2619                if ((csp->flags & CSP_FLAG_REUSED_CLIENT_CONNECTION))
2620                {
2621                   log_error(LOG_LEVEL_ERROR,
2622                      "No server or forwarder response received on socket %d. "
2623                      "Closing client socket %d without sending data.",
2624                      csp->server_connection.sfd, csp->cfd);
2625                   log_error(LOG_LEVEL_CLF,
2626                      "%s - - [%T] \"%s\" 502 0", csp->ip_addr_str, http->cmd);
2627                }
2628                else
2629                {
2630                   log_error(LOG_LEVEL_ERROR,
2631                      "No server or forwarder response received on socket %d.",
2632                      csp->server_connection.sfd);
2633                   send_crunch_response(csp, error_response(csp, "no-server-data"));
2634                }
2635                free_http_request(http);
2636                mark_server_socket_tainted(csp);
2637                return;
2638             }
2639
2640             assert(csp->headers->first->str);
2641             assert(!http->ssl);
2642             if (strncmpic(csp->headers->first->str, "HTTP", 4) &&
2643                 strncmpic(csp->headers->first->str, "ICY", 3))
2644             {
2645                /*
2646                 * It doesn't look like a HTTP (or Shoutcast) response:
2647                 * tell the client and log the problem.
2648                 */
2649                if (strlen(csp->headers->first->str) > 30)
2650                {
2651                   csp->headers->first->str[30] = '\0';
2652                }
2653                log_error(LOG_LEVEL_ERROR,
2654                   "Invalid server or forwarder response. Starts with: %s",
2655                   csp->headers->first->str);
2656                log_error(LOG_LEVEL_CLF,
2657                   "%s - - [%T] \"%s\" 502 0", csp->ip_addr_str, http->cmd);
2658                write_socket(csp->cfd, INVALID_SERVER_HEADERS_RESPONSE,
2659                   strlen(INVALID_SERVER_HEADERS_RESPONSE));
2660                free_http_request(http);
2661                mark_server_socket_tainted(csp);
2662                return;
2663             }
2664
2665             /*
2666              * We have now received the entire server header,
2667              * filter it and send the result to the client
2668              */
2669             if (JB_ERR_OK != sed(csp, FILTER_SERVER_HEADERS))
2670             {
2671                log_error(LOG_LEVEL_CLF,
2672                   "%s - - [%T] \"%s\" 502 0", csp->ip_addr_str, http->cmd);
2673                write_socket(csp->cfd, INVALID_SERVER_HEADERS_RESPONSE,
2674                   strlen(INVALID_SERVER_HEADERS_RESPONSE));
2675                free_http_request(http);
2676                mark_server_socket_tainted(csp);
2677                return;
2678             }
2679             hdr = list_to_text(csp->headers);
2680             if (hdr == NULL)
2681             {
2682                /* FIXME Should handle error properly */
2683                log_error(LOG_LEVEL_FATAL, "Out of memory parsing server header");
2684             }
2685
2686             if ((csp->flags & CSP_FLAG_CHUNKED)
2687                && !(csp->flags & CSP_FLAG_CONTENT_LENGTH_SET)
2688                && ((csp->iob->eod - csp->iob->cur) >= 5)
2689                && !memcmp(csp->iob->eod-5, "0\r\n\r\n", 5))
2690             {
2691                log_error(LOG_LEVEL_CONNECT,
2692                   "Looks like we got the last chunk together with "
2693                   "the server headers. We better stop reading.");
2694                byte_count = (unsigned long long)(csp->iob->eod - csp->iob->cur);
2695                csp->expected_content_length = byte_count;
2696                csp->flags |= CSP_FLAG_CONTENT_LENGTH_SET;
2697             }
2698
2699             csp->server_connection.response_received = time(NULL);
2700
2701             if (crunch_response_triggered(csp, crunchers_light))
2702             {
2703                /*
2704                 * One of the tags created by a server-header
2705                 * tagger triggered a crunch. We already
2706                 * delivered the crunch response to the client
2707                 * and are done here after cleaning up.
2708                 */
2709                 freez(hdr);
2710                 mark_server_socket_tainted(csp);
2711                 return;
2712             }
2713             /* Buffer and pcrs filter this if appropriate. */
2714
2715             if (!http->ssl) /* We talk plaintext */
2716             {
2717                buffer_and_filter_content = content_requires_filtering(csp);
2718             }
2719             /*
2720              * Only write if we're not buffering for content modification
2721              */
2722             if (!buffer_and_filter_content)
2723             {
2724                /*
2725                 * Write the server's (modified) header to
2726                 * the client (along with anything else that
2727                 * may be in the buffer)
2728                 */
2729
2730                if (write_socket(csp->cfd, hdr, strlen(hdr))
2731                 || ((len = flush_socket(csp->cfd, csp->iob)) < 0))
2732                {
2733                   log_error(LOG_LEVEL_CONNECT, "write header to client failed: %E");
2734
2735                   /*
2736                    * The write failed, so don't bother mentioning it
2737                    * to the client... it probably can't hear us anyway.
2738                    */
2739                   freez(hdr);
2740                   mark_server_socket_tainted(csp);
2741                   return;
2742                }
2743             }
2744
2745             /* we're finished with the server's header */
2746
2747             freez(hdr);
2748             server_body = 1;
2749
2750             /*
2751              * If this was a MS IIS/5 hack then it means the server
2752              * has already closed the connection. Nothing more to read.
2753              * Time to bail.
2754              */
2755             if (ms_iis5_hack)
2756             {
2757                log_error(LOG_LEVEL_ERROR,
2758                   "Closed server connection detected. "
2759                   "Applying the MS IIS5 hack didn't help.");
2760                log_error(LOG_LEVEL_CLF,
2761                   "%s - - [%T] \"%s\" 502 0", csp->ip_addr_str, http->cmd);
2762                write_socket(csp->cfd, INVALID_SERVER_HEADERS_RESPONSE,
2763                   strlen(INVALID_SERVER_HEADERS_RESPONSE));
2764                mark_server_socket_tainted(csp);
2765                return;
2766             }
2767          }
2768          continue;
2769       }
2770       mark_server_socket_tainted(csp);
2771       return; /* huh? we should never get here */
2772    }
2773
2774    if (csp->content_length == 0)
2775    {
2776       /*
2777        * If Privoxy didn't recalculate the Content-Length,
2778        * byte_count is still correct.
2779        */
2780       csp->content_length = byte_count;
2781    }
2782
2783 #ifdef FEATURE_CONNECTION_KEEP_ALIVE
2784    if ((csp->flags & CSP_FLAG_CONTENT_LENGTH_SET)
2785       && (csp->expected_content_length != byte_count))
2786    {
2787       log_error(LOG_LEVEL_CONNECT,
2788          "Received %llu bytes while expecting %llu.",
2789          byte_count, csp->expected_content_length);
2790       mark_server_socket_tainted(csp);
2791    }
2792 #endif
2793
2794    log_error(LOG_LEVEL_CLF, "%s - - [%T] \"%s\" 200 %llu",
2795       csp->ip_addr_str, http->ocmd, csp->content_length);
2796
2797    csp->server_connection.timestamp = time(NULL);
2798 }
2799
2800
2801 #ifdef FEATURE_CONNECTION_KEEP_ALIVE
2802 /*********************************************************************
2803  *
2804  * Function    :  prepare_csp_for_next_request
2805  *
2806  * Description :  Put the csp in a mostly vergin state.
2807  *
2808  * Parameters  :
2809  *          1  :  csp = Current client state (buffers, headers, etc...)
2810  *
2811  * Returns     :  N/A
2812  *
2813  *********************************************************************/
2814 static void prepare_csp_for_next_request(struct client_state *csp)
2815 {
2816    csp->content_type = 0;
2817    csp->content_length = 0;
2818    csp->expected_content_length = 0;
2819    csp->expected_client_content_length = 0;
2820    list_remove_all(csp->headers);
2821    clear_iob(csp->iob);
2822    freez(csp->error_message);
2823    free_http_request(csp->http);
2824    destroy_list(csp->headers);
2825    destroy_list(csp->tags);
2826 #ifdef FEATURE_CLIENT_TAGS
2827    destroy_list(csp->client_tags);
2828    freez(csp->client_address);
2829 #endif
2830    free_current_action(csp->action);
2831    if (NULL != csp->fwd)
2832    {
2833       unload_forward_spec(csp->fwd);
2834       csp->fwd = NULL;
2835    }
2836    /* XXX: Store per-connection flags someplace else. */
2837    csp->flags = (CSP_FLAG_ACTIVE | CSP_FLAG_REUSED_CLIENT_CONNECTION);
2838 #ifdef FEATURE_TOGGLE
2839    if (global_toggle_state)
2840 #endif /* def FEATURE_TOGGLE */
2841    {
2842       csp->flags |= CSP_FLAG_TOGGLED_ON;
2843    }
2844
2845    if (csp->client_iob->eod > csp->client_iob->cur)
2846    {
2847       long bytes_to_shift = csp->client_iob->cur - csp->client_iob->buf;
2848       size_t data_length  = (size_t)(csp->client_iob->eod - csp->client_iob->cur);
2849
2850       assert(bytes_to_shift > 0);
2851       assert(data_length > 0);
2852
2853       log_error(LOG_LEVEL_CONNECT, "Shifting %d pipelined bytes by %d bytes",
2854          data_length, bytes_to_shift);
2855       memmove(csp->client_iob->buf, csp->client_iob->cur, data_length);
2856       csp->client_iob->cur = csp->client_iob->buf;
2857       assert(csp->client_iob->eod == csp->client_iob->buf + bytes_to_shift + data_length);
2858       csp->client_iob->eod = csp->client_iob->buf + data_length;
2859       memset(csp->client_iob->eod, '\0', (size_t)bytes_to_shift);
2860
2861       csp->flags |= CSP_FLAG_PIPELINED_REQUEST_WAITING;
2862    }
2863    else
2864    {
2865       /*
2866        * We mainly care about resetting client_iob->cur so we don't
2867        * waste buffer space at the beginning and don't mess up the
2868        * request restoration done by cgi_show_request().
2869        *
2870        * Freeing the buffer itself isn't technically necessary,
2871        * but makes debugging more convenient.
2872        */
2873       clear_iob(csp->client_iob);
2874    }
2875 }
2876 #endif /* def FEATURE_CONNECTION_KEEP_ALIVE */
2877
2878
2879 /*********************************************************************
2880  *
2881  * Function    :  serve
2882  *
2883  * Description :  This is little more than chat.  We only "serve" to
2884  *                to close (or remember) any socket that chat may have
2885  *                opened.
2886  *
2887  * Parameters  :
2888  *          1  :  csp = Current client state (buffers, headers, etc...)
2889  *
2890  * Returns     :  N/A
2891  *
2892  *********************************************************************/
2893 #ifdef AMIGA
2894 void serve(struct client_state *csp)
2895 #else /* ifndef AMIGA */
2896 static void serve(struct client_state *csp)
2897 #endif /* def AMIGA */
2898 {
2899    int config_file_change_detected = 0; /* Only used for debugging */
2900 #ifdef FEATURE_CONNECTION_KEEP_ALIVE
2901 #ifdef FEATURE_CONNECTION_SHARING
2902    static int monitor_thread_running = 0;
2903 #endif /* def FEATURE_CONNECTION_SHARING */
2904    int continue_chatting = 0;
2905
2906    log_error(LOG_LEVEL_CONNECT, "Accepted connection from %s on socket %d",
2907       csp->ip_addr_str, csp->cfd);
2908
2909    do
2910    {
2911       unsigned int latency;
2912
2913       chat(csp);
2914
2915       /*
2916        * If the request has been crunched,
2917        * the calculated latency is zero.
2918        */
2919       latency = (unsigned)(csp->server_connection.response_received -
2920          csp->server_connection.request_sent) / 2;
2921
2922       if ((csp->flags & CSP_FLAG_CLIENT_CONNECTION_KEEP_ALIVE)
2923          && (csp->flags & CSP_FLAG_CRUNCHED)
2924          && (csp->expected_client_content_length != 0))
2925       {
2926          csp->flags |= CSP_FLAG_SERVER_SOCKET_TAINTED;
2927          log_error(LOG_LEVEL_CONNECT,
2928             "Tainting client socket %d due to unread data.", csp->cfd);
2929       }
2930
2931       continue_chatting = (csp->config->feature_flags
2932          & RUNTIME_FEATURE_CONNECTION_KEEP_ALIVE)
2933          && !(csp->flags & CSP_FLAG_SERVER_SOCKET_TAINTED)
2934          && (csp->cfd != JB_INVALID_SOCKET)
2935          && (csp->flags & CSP_FLAG_CLIENT_CONNECTION_KEEP_ALIVE)
2936          && ((csp->flags & CSP_FLAG_SERVER_CONTENT_LENGTH_SET)
2937             || (csp->flags & CSP_FLAG_CHUNKED));
2938
2939       if (!(csp->flags & CSP_FLAG_CRUNCHED)
2940          && (csp->server_connection.sfd != JB_INVALID_SOCKET))
2941       {
2942          if (!(csp->flags & CSP_FLAG_SERVER_KEEP_ALIVE_TIMEOUT_SET))
2943          {
2944             csp->server_connection.keep_alive_timeout = csp->config->default_server_timeout;
2945          }
2946          if (!(csp->flags & CSP_FLAG_SERVER_CONNECTION_KEEP_ALIVE)
2947             || (csp->flags & CSP_FLAG_SERVER_SOCKET_TAINTED)
2948             || !socket_is_still_alive(csp->server_connection.sfd)
2949             || !(latency < csp->server_connection.keep_alive_timeout))
2950          {
2951             log_error(LOG_LEVEL_CONNECT,
2952                "Closing server socket %d connected to %s. "
2953                "Keep-alive %u. Tainted: %u. Socket alive %u. Timeout: %u.",
2954                csp->server_connection.sfd, csp->server_connection.host,
2955                0 != (csp->flags & CSP_FLAG_SERVER_CONNECTION_KEEP_ALIVE),
2956                0 != (csp->flags & CSP_FLAG_SERVER_SOCKET_TAINTED),
2957                socket_is_still_alive(csp->server_connection.sfd),
2958                csp->server_connection.keep_alive_timeout);
2959 #ifdef FEATURE_CONNECTION_SHARING
2960             if (csp->config->feature_flags & RUNTIME_FEATURE_CONNECTION_SHARING)
2961             {
2962                forget_connection(csp->server_connection.sfd);
2963             }
2964 #endif /* def FEATURE_CONNECTION_SHARING */
2965             close_socket(csp->server_connection.sfd);
2966             mark_connection_closed(&csp->server_connection);
2967          }
2968       }
2969
2970       if (continue_chatting && any_loaded_file_changed(csp))
2971       {
2972          continue_chatting = 0;
2973          config_file_change_detected = 1;
2974       }
2975
2976       if (continue_chatting)
2977       {
2978          if (((csp->flags & CSP_FLAG_PIPELINED_REQUEST_WAITING) != 0)
2979             && socket_is_still_alive(csp->cfd))
2980          {
2981             log_error(LOG_LEVEL_CONNECT, "Client request %d has been "
2982                "pipelined on socket %d and the socket is still alive.",
2983                csp->requests_received_total+1, csp->cfd);
2984             prepare_csp_for_next_request(csp);
2985             continue;
2986          }
2987
2988          if (0 != (csp->flags & CSP_FLAG_CLIENT_CONNECTION_KEEP_ALIVE))
2989          {
2990             if (csp->server_connection.sfd != JB_INVALID_SOCKET)
2991             {
2992                log_error(LOG_LEVEL_CONNECT,
2993                   "Waiting for the next client request on socket %d. "
2994                   "Keeping the server socket %d to %s open.",
2995                   csp->cfd, csp->server_connection.sfd, csp->server_connection.host);
2996             }
2997             else
2998             {
2999                log_error(LOG_LEVEL_CONNECT,
3000                   "Waiting for the next client request on socket %d. "
3001                   "No server socket to keep open.", csp->cfd);
3002             }
3003          }
3004
3005          if ((csp->flags & CSP_FLAG_CLIENT_CONNECTION_KEEP_ALIVE)
3006             && data_is_available(csp->cfd, (int)csp->config->keep_alive_timeout)
3007             && socket_is_still_alive(csp->cfd))
3008          {
3009             log_error(LOG_LEVEL_CONNECT,
3010                "Client request %u arrived in time on socket %d.",
3011                csp->requests_received_total+1, csp->cfd);
3012             prepare_csp_for_next_request(csp);
3013          }
3014          else
3015          {
3016 #ifdef FEATURE_CONNECTION_SHARING
3017             if ((csp->config->feature_flags & RUNTIME_FEATURE_CONNECTION_SHARING)
3018                && (csp->server_connection.sfd != JB_INVALID_SOCKET)
3019                && (socket_is_still_alive(csp->server_connection.sfd)))
3020             {
3021                time_t time_open = time(NULL) - csp->server_connection.timestamp;
3022
3023                if (csp->server_connection.keep_alive_timeout < time_open - (time_t)latency)
3024                {
3025                   break;
3026                }
3027
3028                remember_connection(&csp->server_connection);
3029                csp->server_connection.sfd = JB_INVALID_SOCKET;
3030                drain_and_close_socket(csp->cfd);
3031                csp->cfd = JB_INVALID_SOCKET;
3032                privoxy_mutex_lock(&connection_reuse_mutex);
3033                if (!monitor_thread_running)
3034                {
3035                   monitor_thread_running = 1;
3036                   privoxy_mutex_unlock(&connection_reuse_mutex);
3037                   wait_for_alive_connections();
3038                   privoxy_mutex_lock(&connection_reuse_mutex);
3039                   monitor_thread_running = 0;
3040                }
3041                privoxy_mutex_unlock(&connection_reuse_mutex);
3042             }
3043 #endif /* def FEATURE_CONNECTION_SHARING */
3044             break;
3045          }
3046       }
3047       else if (csp->server_connection.sfd != JB_INVALID_SOCKET)
3048       {
3049          log_error(LOG_LEVEL_CONNECT,
3050             "Closing server socket %d connected to %s. Keep-alive: %u. "
3051             "Tainted: %u. Socket alive: %u. Timeout: %u. "
3052             "Configuration file change detected: %u",
3053             csp->server_connection.sfd, csp->server_connection.host,
3054             0 != (csp->flags & CSP_FLAG_SERVER_CONNECTION_KEEP_ALIVE),
3055             0 != (csp->flags & CSP_FLAG_SERVER_SOCKET_TAINTED),
3056             socket_is_still_alive(csp->server_connection.sfd),
3057             csp->server_connection.keep_alive_timeout,
3058             config_file_change_detected);
3059       }
3060    } while (continue_chatting);
3061
3062 #else
3063    chat(csp);
3064 #endif /* def FEATURE_CONNECTION_KEEP_ALIVE */
3065
3066    if (csp->server_connection.sfd != JB_INVALID_SOCKET)
3067    {
3068 #ifdef FEATURE_CONNECTION_SHARING
3069       if (csp->config->feature_flags & RUNTIME_FEATURE_CONNECTION_SHARING)
3070       {
3071          forget_connection(csp->server_connection.sfd);
3072       }
3073 #endif /* def FEATURE_CONNECTION_SHARING */
3074       close_socket(csp->server_connection.sfd);
3075    }
3076
3077 #ifdef FEATURE_CONNECTION_KEEP_ALIVE
3078    mark_connection_closed(&csp->server_connection);
3079 #endif
3080
3081    if (csp->cfd != JB_INVALID_SOCKET)
3082    {
3083       log_error(LOG_LEVEL_CONNECT, "Closing client socket %d. "
3084          "Keep-alive: %u. Socket alive: %u. Data available: %u. "
3085          "Configuration file change detected: %u. Requests received: %u.",
3086          csp->cfd, 0 != (csp->flags & CSP_FLAG_CLIENT_CONNECTION_KEEP_ALIVE),
3087          socket_is_still_alive(csp->cfd), data_is_available(csp->cfd, 0),
3088          config_file_change_detected, csp->requests_received_total);
3089       drain_and_close_socket(csp->cfd);
3090    }
3091
3092    csp->flags &= ~CSP_FLAG_ACTIVE;
3093
3094 }
3095
3096
3097 #ifdef __BEOS__
3098 /*********************************************************************
3099  *
3100  * Function    :  server_thread
3101  *
3102  * Description :  We only exist to call `serve' in a threaded environment.
3103  *
3104  * Parameters  :
3105  *          1  :  data = Current client state (buffers, headers, etc...)
3106  *
3107  * Returns     :  Always 0.
3108  *
3109  *********************************************************************/
3110 static int32 server_thread(void *data)
3111 {
3112    serve((struct client_state *) data);
3113    return 0;
3114
3115 }
3116 #endif
3117
3118
3119 #if !defined(_WIN32) || defined(_WIN_CONSOLE)
3120 /*********************************************************************
3121  *
3122  * Function    :  usage
3123  *
3124  * Description :  Print usage info & exit.
3125  *
3126  * Parameters  :  Pointer to argv[0] for identifying ourselves
3127  *
3128  * Returns     :  No. ,-)
3129  *
3130  *********************************************************************/
3131 static void usage(const char *myname)
3132 {
3133    printf("Privoxy version " VERSION " (" HOME_PAGE_URL ")\n"
3134           "Usage: %s [--config-test] "
3135 #if defined(unix)
3136           "[--chroot] "
3137 #endif /* defined(unix) */
3138           "[--help] "
3139 #if defined(unix)
3140           "[--no-daemon] [--pidfile pidfile] [--pre-chroot-nslookup hostname] [--user user[.group]] "
3141 #endif /* defined(unix) */
3142           "[--version] [configfile]\n"
3143           "Aborting\n", myname);
3144
3145    exit(2);
3146
3147 }
3148 #endif /* #if !defined(_WIN32) || defined(_WIN_CONSOLE) */
3149
3150
3151 #ifdef MUTEX_LOCKS_AVAILABLE
3152 /*********************************************************************
3153  *
3154  * Function    :  privoxy_mutex_lock
3155  *
3156  * Description :  Locks a mutex.
3157  *
3158  * Parameters  :
3159  *          1  :  mutex = The mutex to lock.
3160  *
3161  * Returns     :  Void. May exit in case of errors.
3162  *
3163  *********************************************************************/
3164 void privoxy_mutex_lock(privoxy_mutex_t *mutex)
3165 {
3166 #ifdef FEATURE_PTHREAD
3167    int err = pthread_mutex_lock(mutex);
3168    if (err)
3169    {
3170       if (mutex != &log_mutex)
3171       {
3172          log_error(LOG_LEVEL_FATAL,
3173             "Mutex locking failed: %s.\n", strerror(err));
3174       }
3175       exit(1);
3176    }
3177 #else
3178    EnterCriticalSection(mutex);
3179 #endif /* def FEATURE_PTHREAD */
3180 }
3181
3182
3183 /*********************************************************************
3184  *
3185  * Function    :  privoxy_mutex_unlock
3186  *
3187  * Description :  Unlocks a mutex.
3188  *
3189  * Parameters  :
3190  *          1  :  mutex = The mutex to unlock.
3191  *
3192  * Returns     :  Void. May exit in case of errors.
3193  *
3194  *********************************************************************/
3195 void privoxy_mutex_unlock(privoxy_mutex_t *mutex)
3196 {
3197 #ifdef FEATURE_PTHREAD
3198    int err = pthread_mutex_unlock(mutex);
3199    if (err)
3200    {
3201       if (mutex != &log_mutex)
3202       {
3203          log_error(LOG_LEVEL_FATAL,
3204             "Mutex unlocking failed: %s.\n", strerror(err));
3205       }
3206       exit(1);
3207    }
3208 #else
3209    LeaveCriticalSection(mutex);
3210 #endif /* def FEATURE_PTHREAD */
3211 }
3212
3213
3214 /*********************************************************************
3215  *
3216  * Function    :  privoxy_mutex_init
3217  *
3218  * Description :  Prepares a mutex.
3219  *
3220  * Parameters  :
3221  *          1  :  mutex = The mutex to initialize.
3222  *
3223  * Returns     :  Void. May exit in case of errors.
3224  *
3225  *********************************************************************/
3226 static void privoxy_mutex_init(privoxy_mutex_t *mutex)
3227 {
3228 #ifdef FEATURE_PTHREAD
3229    int err = pthread_mutex_init(mutex, 0);
3230    if (err)
3231    {
3232       printf("Fatal error. Mutex initialization failed: %s.\n",
3233          strerror(err));
3234       exit(1);
3235    }
3236 #else
3237    InitializeCriticalSection(mutex);
3238 #endif /* def FEATURE_PTHREAD */
3239 }
3240 #endif /* def MUTEX_LOCKS_AVAILABLE */
3241
3242 /*********************************************************************
3243  *
3244  * Function    :  initialize_mutexes
3245  *
3246  * Description :  Prepares mutexes if mutex support is available.
3247  *
3248  * Parameters  :  None
3249  *
3250  * Returns     :  Void, exits in case of errors.
3251  *
3252  *********************************************************************/
3253 static void initialize_mutexes(void)
3254 {
3255 #ifdef MUTEX_LOCKS_AVAILABLE
3256    /*
3257     * Prepare global mutex semaphores
3258     */
3259    privoxy_mutex_init(&log_mutex);
3260    privoxy_mutex_init(&log_init_mutex);
3261    privoxy_mutex_init(&connection_reuse_mutex);
3262 #ifdef FEATURE_EXTERNAL_FILTERS
3263    privoxy_mutex_init(&external_filter_mutex);
3264 #endif
3265 #ifdef FEATURE_CLIENT_TAGS
3266    privoxy_mutex_init(&client_tags_mutex);
3267 #endif
3268
3269    /*
3270     * XXX: The assumptions below are a bit naive
3271     * and can cause locks that aren't necessary.
3272     *
3273     * For example older FreeBSD versions (< 6.x?)
3274     * have no gethostbyname_r, but gethostbyname is
3275     * thread safe.
3276     */
3277 #if !defined(HAVE_GETHOSTBYADDR_R) || !defined(HAVE_GETHOSTBYNAME_R)
3278    privoxy_mutex_init(&resolver_mutex);
3279 #endif /* !defined(HAVE_GETHOSTBYADDR_R) || !defined(HAVE_GETHOSTBYNAME_R) */
3280    /*
3281     * XXX: should we use a single mutex for
3282     * localtime() and gmtime() as well?
3283     */
3284 #ifndef HAVE_GMTIME_R
3285    privoxy_mutex_init(&gmtime_mutex);
3286 #endif /* ndef HAVE_GMTIME_R */
3287
3288 #ifndef HAVE_LOCALTIME_R
3289    privoxy_mutex_init(&localtime_mutex);
3290 #endif /* ndef HAVE_GMTIME_R */
3291
3292 #ifndef HAVE_RANDOM
3293    privoxy_mutex_init(&rand_mutex);
3294 #endif /* ndef HAVE_RANDOM */
3295
3296 #endif /* def MUTEX_LOCKS_AVAILABLE */
3297 }
3298
3299
3300 /*********************************************************************
3301  *
3302  * Function    :  main
3303  *
3304  * Description :  Load the config file and start the listen loop.
3305  *                This function is a lot more *sane* with the `load_config'
3306  *                and `listen_loop' functions; although it stills does
3307  *                a *little* too much for my taste.
3308  *
3309  * Parameters  :
3310  *          1  :  argc = Number of parameters (including $0).
3311  *          2  :  argv = Array of (char *)'s to the parameters.
3312  *
3313  * Returns     :  1 if : can't open config file, unrecognized directive,
3314  *                stats requested in multi-thread mode, can't open the
3315  *                log file, can't open the jar file, listen port is invalid,
3316  *                any load fails, and can't bind port.
3317  *
3318  *                Else main never returns, the process must be signaled
3319  *                to terminate execution.  Or, on Windows, use the
3320  *                "File", "Exit" menu option.
3321  *
3322  *********************************************************************/
3323 #ifdef __MINGW32__
3324 int real_main(int argc, char **argv)
3325 #else
3326 int main(int argc, char **argv)
3327 #endif
3328 {
3329    int argc_pos = 0;
3330    int do_config_test = 0;
3331    unsigned int random_seed;
3332 #ifdef unix
3333    struct passwd *pw = NULL;
3334    struct group *grp = NULL;
3335    int do_chroot = 0;
3336    char *pre_chroot_nslookup_to_load_resolver = NULL;
3337 #endif
3338
3339    Argc = argc;
3340    Argv = argv;
3341
3342    configfile =
3343 #if !defined(_WIN32)
3344    "config"
3345 #else
3346    "config.txt"
3347 #endif
3348       ;
3349
3350    /* Prepare mutexes if supported and necessary. */
3351    initialize_mutexes();
3352
3353    /* Enable logging until further notice. */
3354    init_log_module();
3355
3356    /*
3357     * Parse the command line arguments
3358     *
3359     * XXX: simply printing usage information in case of
3360     * invalid arguments isn't particularly user friendly.
3361     */
3362    while (++argc_pos < argc)
3363    {
3364 #ifdef _WIN32
3365       /* Check to see if the service must be installed or uninstalled */
3366       if (strncmp(argv[argc_pos], "--install", 9) == 0)
3367       {
3368          const char *pName = argv[argc_pos] + 9;
3369          if (*pName == ':')
3370             pName++;
3371          exit((install_service(pName)) ? 0 : 1);
3372       }
3373       else if (strncmp(argv[argc_pos], "--uninstall", 11) == 0)
3374       {
3375          const char *pName = argv[argc_pos] + 11;
3376          if (*pName == ':')
3377             pName++;
3378          exit((uninstall_service(pName)) ? 0 : 1);
3379       }
3380       else if (strcmp(argv[argc_pos], "--service") == 0)
3381       {
3382          bRunAsService = TRUE;
3383          w32_set_service_cwd();
3384          atexit(w32_service_exit_notify);
3385       }
3386       else
3387 #endif /* defined(_WIN32) */
3388
3389
3390 #if !defined(_WIN32) || defined(_WIN_CONSOLE)
3391
3392       if (strcmp(argv[argc_pos], "--help") == 0)
3393       {
3394          usage(argv[0]);
3395       }
3396
3397       else if (strcmp(argv[argc_pos], "--version") == 0)
3398       {
3399          printf("Privoxy version " VERSION " (" HOME_PAGE_URL ")\n");
3400          exit(0);
3401       }
3402
3403 #if defined(unix)
3404
3405       else if (strcmp(argv[argc_pos], "--no-daemon") == 0)
3406       {
3407          set_debug_level(LOG_LEVEL_FATAL | LOG_LEVEL_ERROR | LOG_LEVEL_INFO);
3408          daemon_mode = 0;
3409       }
3410
3411       else if (strcmp(argv[argc_pos], "--pidfile") == 0)
3412       {
3413          if (++argc_pos == argc) usage(argv[0]);
3414          pidfile = strdup_or_die(argv[argc_pos]);
3415       }
3416
3417       else if (strcmp(argv[argc_pos], "--user") == 0)
3418       {
3419          char *user_arg;
3420          char *group_name;
3421
3422          if (++argc_pos == argc) usage(argv[argc_pos]);
3423
3424          user_arg = strdup_or_die(argv[argc_pos]);
3425          group_name = strchr(user_arg, '.');
3426          if (NULL != group_name)
3427          {
3428             /* Nul-terminate the user name */
3429             *group_name = '\0';
3430
3431             /* Skip the former delimiter to actually reach the group name */
3432             group_name++;
3433
3434             grp = getgrnam(group_name);
3435             if (NULL == grp)
3436             {
3437                log_error(LOG_LEVEL_FATAL, "Group '%s' not found.", group_name);
3438             }
3439          }
3440          pw = getpwnam(user_arg);
3441          if (NULL == pw)
3442          {
3443             log_error(LOG_LEVEL_FATAL, "User '%s' not found.", user_arg);
3444          }
3445
3446          freez(user_arg);
3447       }
3448
3449       else if (strcmp(argv[argc_pos], "--pre-chroot-nslookup") == 0)
3450       {
3451          if (++argc_pos == argc) usage(argv[0]);
3452          pre_chroot_nslookup_to_load_resolver = strdup_or_die(argv[argc_pos]);
3453       }
3454
3455       else if (strcmp(argv[argc_pos], "--chroot") == 0)
3456       {
3457          do_chroot = 1;
3458       }
3459 #endif /* defined(unix) */
3460
3461       else if (strcmp(argv[argc_pos], "--config-test") == 0)
3462       {
3463          do_config_test = 1;
3464       }
3465
3466       else if (argc_pos + 1 != argc)
3467       {
3468          /*
3469           * This is neither the last command line
3470           * option, nor was it recognized before,
3471           * therefore it must be invalid.
3472           */
3473          usage(argv[0]);
3474       }
3475       else
3476
3477 #endif /* defined(_WIN32) && !defined(_WIN_CONSOLE) */
3478       {
3479          configfile = argv[argc_pos];
3480       }
3481
3482    } /* -END- while (more arguments) */
3483
3484    show_version(Argv[0]);
3485
3486 #if defined(unix)
3487    if (*configfile != '/')
3488    {
3489       char cwd[BUFFER_SIZE];
3490       char *abs_file;
3491       size_t abs_file_size;
3492
3493       /* make config-filename absolute here */
3494       if (NULL == getcwd(cwd, sizeof(cwd)))
3495       {
3496          perror("failed to get current working directory");
3497          exit(1);
3498       }
3499
3500       basedir = strdup_or_die(cwd);
3501       /* XXX: why + 5? */
3502       abs_file_size = strlen(cwd) + strlen(configfile) + 5;
3503       abs_file = malloc_or_die(abs_file_size);
3504       strlcpy(abs_file, basedir, abs_file_size);
3505       strlcat(abs_file, "/", abs_file_size);
3506       strlcat(abs_file, configfile, abs_file_size);
3507       configfile = abs_file;
3508    }
3509 #endif /* defined unix */
3510
3511
3512    files->next = NULL;
3513    clients->next = NULL;
3514
3515    /* XXX: factor out initialising after the next stable release. */
3516 #ifdef AMIGA
3517    InitAmiga();
3518 #elif defined(_WIN32)
3519    InitWin32();
3520 #endif
3521
3522    random_seed = (unsigned int)time(NULL);
3523 #ifdef HAVE_RANDOM
3524    srandom(random_seed);
3525 #else
3526    srand(random_seed);
3527 #endif /* ifdef HAVE_RANDOM */
3528
3529    /*
3530     * Unix signal handling
3531     *
3532     * Catch the abort, interrupt and terminate signals for a graceful exit
3533     * Catch the hangup signal so the errlog can be reopened.
3534     * Ignore the broken pipe signals (FIXME: Why?)
3535     */
3536 #if !defined(_WIN32) && !defined(__OS2__) && !defined(AMIGA)
3537 {
3538    int idx;
3539    const int catched_signals[] = { SIGTERM, SIGINT, SIGHUP };
3540
3541    for (idx = 0; idx < SZ(catched_signals); idx++)
3542    {
3543 #ifdef sun /* FIXME: Is it safe to check for HAVE_SIGSET instead? */
3544       if (sigset(catched_signals[idx], sig_handler) == SIG_ERR)
3545 #else
3546       if (signal(catched_signals[idx], sig_handler) == SIG_ERR)
3547 #endif /* ifdef sun */
3548       {
3549          log_error(LOG_LEVEL_FATAL, "Can't set signal-handler for signal %d: %E", catched_signals[idx]);
3550       }
3551    }
3552
3553    if (signal(SIGPIPE, SIG_IGN) == SIG_ERR)
3554    {
3555       log_error(LOG_LEVEL_FATAL, "Can't set ignore-handler for SIGPIPE: %E");
3556    }
3557
3558 }
3559 #else /* ifdef _WIN32 */
3560 # ifdef _WIN_CONSOLE
3561    /*
3562     * We *are* in a windows console app.
3563     * Print a verbose messages about FAQ's and such
3564     */
3565    printf("%s", win32_blurb);
3566 # endif /* def _WIN_CONSOLE */
3567 #endif /* def _WIN32 */
3568
3569    if (do_config_test)
3570    {
3571       exit(NULL == load_config());
3572    }
3573
3574    /* Initialize the CGI subsystem */
3575    cgi_init_error_messages();
3576
3577    /*
3578     * If running on unix and without the --no-daemon
3579     * option, become a daemon. I.e. fork, detach
3580     * from tty and get process group leadership
3581     */
3582 #if defined(unix)
3583 {
3584    if (daemon_mode)
3585    {
3586       int fd;
3587       pid_t pid = fork();
3588
3589       if (pid < 0) /* error */
3590       {
3591          perror("fork");
3592          exit(3);
3593       }
3594       else if (pid != 0) /* parent */
3595       {
3596          int status;
3597          pid_t wpid;
3598          /*
3599           * must check for errors
3600           * child died due to missing files aso
3601           */
3602          sleep(1);
3603          wpid = waitpid(pid, &status, WNOHANG);
3604          if (wpid != 0)
3605          {
3606             exit(1);
3607          }
3608          exit(0);
3609       }
3610       /* child */
3611
3612       setsid();
3613
3614       /*
3615        * stderr (fd 2) will be closed later on,
3616        * when the config file has been parsed.
3617        */
3618       close(0);
3619       close(1);
3620
3621       /*
3622        * Reserve fd 0 and 1 to prevent abort() and friends
3623        * from sending stuff to the clients or servers.
3624        */
3625       fd = open("/dev/null", O_RDONLY);
3626       if (fd == -1)
3627       {
3628          log_error(LOG_LEVEL_FATAL, "Failed to open /dev/null: %E");
3629       }
3630       else if (fd != 0)
3631       {
3632          if (dup2(fd, 0) == -1)
3633          {
3634             log_error(LOG_LEVEL_FATAL, "Failed to reserve fd 0: %E");
3635          }
3636          close(fd);
3637       }
3638       fd = open("/dev/null", O_WRONLY);
3639       if (fd == -1)
3640       {
3641          log_error(LOG_LEVEL_FATAL, "Failed to open /dev/null: %E");
3642       }
3643       else if (fd != 1)
3644       {
3645          if (dup2(fd, 1) == -1)
3646          {
3647             log_error(LOG_LEVEL_FATAL, "Failed to reserve fd 1: %E");
3648          }
3649          close(fd);
3650       }
3651
3652 #ifdef FEATURE_EXTERNAL_FILTERS
3653       for (fd = 0; fd < 3; fd++)
3654       {
3655          mark_socket_for_close_on_execute(fd);
3656       }
3657 #endif
3658
3659       chdir("/");
3660
3661    } /* -END- if (daemon_mode) */
3662
3663    /*
3664     * As soon as we have written the PID file, we can switch
3665     * to the user and group ID indicated by the --user option
3666     */
3667    write_pid_file();
3668
3669    if (NULL != pw)
3670    {
3671       if (setgid((NULL != grp) ? grp->gr_gid : pw->pw_gid))
3672       {
3673          log_error(LOG_LEVEL_FATAL, "Cannot setgid(): Insufficient permissions.");
3674       }
3675       if (NULL != grp)
3676       {
3677          if (setgroups(1, &grp->gr_gid))
3678          {
3679             log_error(LOG_LEVEL_FATAL, "setgroups() failed: %E");
3680          }
3681       }
3682       else if (initgroups(pw->pw_name, pw->pw_gid))
3683       {
3684          log_error(LOG_LEVEL_FATAL, "initgroups() failed: %E");
3685       }
3686       if (do_chroot)
3687       {
3688          if (!pw->pw_dir)
3689          {
3690             log_error(LOG_LEVEL_FATAL, "Home directory for %s undefined", pw->pw_name);
3691          }
3692          /* Read the time zone file from /etc before doing chroot. */
3693          tzset();
3694          if (NULL != pre_chroot_nslookup_to_load_resolver
3695              && '\0' != pre_chroot_nslookup_to_load_resolver[0])
3696          {
3697             /* Initialize resolver library. */
3698             (void) resolve_hostname_to_ip(pre_chroot_nslookup_to_load_resolver);
3699          }
3700          if (chroot(pw->pw_dir) < 0)
3701          {
3702             log_error(LOG_LEVEL_FATAL, "Cannot chroot to %s", pw->pw_dir);
3703          }
3704          if (chdir ("/"))
3705          {
3706             log_error(LOG_LEVEL_FATAL, "Cannot chdir /");
3707          }
3708       }
3709       if (setuid(pw->pw_uid))
3710       {
3711          log_error(LOG_LEVEL_FATAL, "Cannot setuid(): Insufficient permissions.");
3712       }
3713       if (do_chroot)
3714       {
3715          char putenv_dummy[64];
3716
3717          strlcpy(putenv_dummy, "HOME=/", sizeof(putenv_dummy));
3718          if (putenv(putenv_dummy) != 0)
3719          {
3720             log_error(LOG_LEVEL_FATAL, "Cannot putenv(): HOME");
3721          }
3722
3723          snprintf(putenv_dummy, sizeof(putenv_dummy), "USER=%s", pw->pw_name);
3724          if (putenv(putenv_dummy) != 0)
3725          {
3726             log_error(LOG_LEVEL_FATAL, "Cannot putenv(): USER");
3727          }
3728       }
3729    }
3730    else if (do_chroot)
3731    {
3732       log_error(LOG_LEVEL_FATAL, "Cannot chroot without --user argument.");
3733    }
3734 }
3735 #endif /* defined unix */
3736
3737 #ifdef _WIN32
3738    /* This will be FALSE unless the command line specified --service
3739     */
3740    if (bRunAsService)
3741    {
3742       /* Yup, so now we must attempt to establish a connection
3743        * with the service dispatcher. This will only work if this
3744        * process was launched by the service control manager to
3745        * actually run as a service. If this isn't the case, i've
3746        * known it take around 30 seconds or so for the call to return.
3747        */
3748
3749       /* The StartServiceCtrlDispatcher won't return until the service is stopping */
3750       if (w32_start_service_ctrl_dispatcher(w32ServiceDispatchTable))
3751       {
3752          /* Service has run, and at this point is now being stopped, so just return */
3753          return 0;
3754       }
3755
3756 #ifdef _WIN_CONSOLE
3757       printf("Warning: Failed to connect to Service Control Dispatcher\nwhen starting as a service!\n");
3758 #endif
3759       /* An error occurred. Usually it's because --service was wrongly specified
3760        * and we were unable to connect to the Service Control Dispatcher because
3761        * it wasn't expecting us and is therefore not listening.
3762        *
3763        * For now, just continue below to call the listen_loop function.
3764        */
3765    }
3766 #endif /* def _WIN32 */
3767
3768    listen_loop();
3769
3770    /* NOTREACHED */
3771    return(-1);
3772
3773 }
3774
3775
3776 /*********************************************************************
3777  *
3778  * Function    :  bind_port_helper
3779  *
3780  * Description :  Bind the listen port.  Handles logging, and aborts
3781  *                on failure.
3782  *
3783  * Parameters  :
3784  *          1  :  haddr = Host address to bind to. Use NULL to bind to
3785  *                        INADDR_ANY.
3786  *          2  :  hport = Specifies port to bind to.
3787  *
3788  * Returns     :  Port that was opened.
3789  *
3790  *********************************************************************/
3791 static jb_socket bind_port_helper(const char *haddr, int hport)
3792 {
3793    int result;
3794    jb_socket bfd;
3795
3796    result = bind_port(haddr, hport, &bfd);
3797
3798    if (result < 0)
3799    {
3800       const char *bind_address = (NULL != haddr) ? haddr : "INADDR_ANY";
3801       switch(result)
3802       {
3803          case -3:
3804             log_error(LOG_LEVEL_FATAL,
3805                "can't bind to %s:%d: There may be another Privoxy "
3806                "or some other proxy running on port %d",
3807                bind_address, hport, hport);
3808
3809          case -2:
3810             log_error(LOG_LEVEL_FATAL,
3811                "can't bind to %s:%d: The hostname is not resolvable",
3812                bind_address, hport);
3813
3814          default:
3815             log_error(LOG_LEVEL_FATAL, "can't bind to %s:%d: %E",
3816                bind_address, hport);
3817       }
3818
3819       /* shouldn't get here */
3820       return JB_INVALID_SOCKET;
3821    }
3822
3823 #ifndef _WIN32
3824    if (bfd >= FD_SETSIZE)
3825    {
3826       log_error(LOG_LEVEL_FATAL,
3827          "Bind socket number too high to use select(): %d >= %d",
3828          bfd, FD_SETSIZE);
3829    }
3830 #endif
3831
3832    if (haddr == NULL)
3833    {
3834       log_error(LOG_LEVEL_INFO, "Listening on port %d on all IP addresses",
3835          hport);
3836    }
3837    else
3838    {
3839       log_error(LOG_LEVEL_INFO, "Listening on port %d on IP address %s",
3840          hport, haddr);
3841    }
3842
3843    return bfd;
3844 }
3845
3846
3847 /*********************************************************************
3848  *
3849  * Function    :  bind_ports_helper
3850  *
3851  * Description :  Bind the listen ports.  Handles logging, and aborts
3852  *                on failure.
3853  *
3854  * Parameters  :
3855  *          1  :  config = Privoxy configuration.  Specifies ports
3856  *                         to bind to.
3857  *          2  :  sockets = Preallocated array of opened sockets
3858  *                          corresponding to specification in config.
3859  *                          All non-opened sockets will be set to
3860  *                          JB_INVALID_SOCKET.
3861  *
3862  * Returns     :  Nothing. Inspect sockets argument.
3863  *
3864  *********************************************************************/
3865 static void bind_ports_helper(struct configuration_spec * config,
3866                               jb_socket sockets[])
3867 {
3868    int i;
3869
3870    for (i = 0; i < MAX_LISTENING_SOCKETS; i++)
3871    {
3872       if (config->hport[i])
3873       {
3874          sockets[i] = bind_port_helper(config->haddr[i], config->hport[i]);
3875       }
3876       else
3877       {
3878          sockets[i] = JB_INVALID_SOCKET;
3879       }
3880    }
3881    config->need_bind = 0;
3882 }
3883
3884
3885 /*********************************************************************
3886  *
3887  * Function    :  close_ports_helper
3888  *
3889  * Description :  Close listenings ports.
3890  *
3891  * Parameters  :
3892  *          1  :  sockets = Array of opened and non-opened sockets to
3893  *                          close. All sockets will be set to
3894  *                          JB_INVALID_SOCKET.
3895  *
3896  * Returns     :  Nothing.
3897  *
3898  *********************************************************************/
3899 static void close_ports_helper(jb_socket sockets[])
3900 {
3901    int i;
3902
3903    for (i = 0; i < MAX_LISTENING_SOCKETS; i++)
3904    {
3905       if (JB_INVALID_SOCKET != sockets[i])
3906       {
3907          close_socket(sockets[i]);
3908       }
3909       sockets[i] = JB_INVALID_SOCKET;
3910    }
3911 }
3912
3913
3914 #ifdef _WIN32
3915 /* Without this simple workaround we get this compiler warning from _beginthread
3916  *     warning C4028: formal parameter 1 different from declaration
3917  */
3918 void w32_service_listen_loop(void *p)
3919 {
3920    listen_loop();
3921 }
3922 #endif /* def _WIN32 */
3923
3924
3925 /*********************************************************************
3926  *
3927  * Function    :  listen_loop
3928  *
3929  * Description :  bind the listen port and enter a "FOREVER" listening loop.
3930  *
3931  * Parameters  :  N/A
3932  *
3933  * Returns     :  Never.
3934  *
3935  *********************************************************************/
3936 static void listen_loop(void)
3937 {
3938    struct client_states *csp_list = NULL;
3939    struct client_state *csp = NULL;
3940    jb_socket bfds[MAX_LISTENING_SOCKETS];
3941    struct configuration_spec *config;
3942    unsigned int active_threads = 0;
3943
3944    config = load_config();
3945
3946 #ifdef FEATURE_CONNECTION_SHARING
3947    /*
3948     * XXX: Should be relocated once it no
3949     * longer needs to emit log messages.
3950     */
3951    initialize_reusable_connections();
3952 #endif /* def FEATURE_CONNECTION_SHARING */
3953
3954    bind_ports_helper(config, bfds);
3955
3956 #ifdef FEATURE_GRACEFUL_TERMINATION
3957    while (!g_terminate)
3958 #else
3959    for (;;)
3960 #endif
3961    {
3962 #if !defined(FEATURE_PTHREAD) && !defined(_WIN32) && !defined(__BEOS__) && !defined(AMIGA) && !defined(__OS2__)
3963       while (waitpid(-1, NULL, WNOHANG) > 0)
3964       {
3965          /* zombie children */
3966       }
3967 #endif /* !defined(FEATURE_PTHREAD) && !defined(_WIN32) && !defined(__BEOS__) && !defined(AMIGA) */
3968
3969       /*
3970        * Free data that was used by died threads
3971        */
3972       active_threads = sweep();
3973
3974 #if defined(unix)
3975       /*
3976        * Re-open the errlog after HUP signal
3977        */
3978       if (received_hup_signal)
3979       {
3980          if (NULL != config->logfile)
3981          {
3982             init_error_log(Argv[0], config->logfile);
3983          }
3984          received_hup_signal = 0;
3985       }
3986 #endif
3987
3988       csp_list = zalloc_or_die(sizeof(*csp_list));
3989       csp = &csp_list->csp;
3990
3991       log_error(LOG_LEVEL_CONNECT,
3992          "Waiting for the next client connection. Currently active threads: %d",
3993          active_threads);
3994
3995       /*
3996        * This config may be outdated, but for accept_connection()
3997        * it's fresh enough.
3998        */
3999       csp->config = config;
4000
4001       if (!accept_connection(csp, bfds))
4002       {
4003          log_error(LOG_LEVEL_CONNECT, "accept failed: %E");
4004
4005 #ifdef AMIGA
4006          if (!childs)
4007          {
4008             exit(1);
4009          }
4010 #endif
4011          freez(csp_list);
4012          continue;
4013       }
4014
4015       csp->flags |= CSP_FLAG_ACTIVE;
4016       csp->server_connection.sfd = JB_INVALID_SOCKET;
4017
4018       csp->config = config = load_config();
4019
4020       if (config->need_bind)
4021       {
4022          /*
4023           * Since we were listening to the "old port", we will not see
4024           * a "listen" param change until the next request.  So, at
4025           * least 1 more request must be made for us to find the new
4026           * setting.  I am simply closing the old socket and binding the
4027           * new one.
4028           *
4029           * Which-ever is correct, we will serve 1 more page via the
4030           * old settings.  This should probably be a "show-proxy-args"
4031           * request.  This should not be a so common of an operation
4032           * that this will hurt people's feelings.
4033           */
4034
4035          close_ports_helper(bfds);
4036
4037          bind_ports_helper(config, bfds);
4038       }
4039
4040 #ifdef FEATURE_TOGGLE
4041       if (global_toggle_state)
4042 #endif /* def FEATURE_TOGGLE */
4043       {
4044          csp->flags |= CSP_FLAG_TOGGLED_ON;
4045       }
4046
4047       if (run_loader(csp))
4048       {
4049          log_error(LOG_LEVEL_FATAL, "a loader failed - must exit");
4050          /* Never get here - LOG_LEVEL_FATAL causes program exit */
4051       }
4052
4053 #ifdef FEATURE_ACL
4054       if (block_acl(NULL,csp))
4055       {
4056          log_error(LOG_LEVEL_CONNECT,
4057             "Connection from %s on %s (socket %d) dropped due to ACL",
4058             csp->ip_addr_str, csp->listen_addr_str, csp->cfd);
4059          close_socket(csp->cfd);
4060          freez(csp->ip_addr_str);
4061          freez(csp->listen_addr_str);
4062          freez(csp_list);
4063          continue;
4064       }
4065 #endif /* def FEATURE_ACL */
4066
4067       if ((0 != config->max_client_connections)
4068          && (active_threads >= config->max_client_connections))
4069       {
4070          log_error(LOG_LEVEL_CONNECT,
4071             "Rejecting connection from %s. Maximum number of connections reached.",
4072             csp->ip_addr_str);
4073          write_socket(csp->cfd, TOO_MANY_CONNECTIONS_RESPONSE,
4074             strlen(TOO_MANY_CONNECTIONS_RESPONSE));
4075          close_socket(csp->cfd);
4076          freez(csp->ip_addr_str);
4077          freez(csp->listen_addr_str);
4078          freez(csp_list);
4079          continue;
4080       }
4081
4082       /* add it to the list of clients */
4083       csp_list->next = clients->next;
4084       clients->next = csp_list;
4085
4086       if (config->multi_threaded)
4087       {
4088          int child_id;
4089
4090 /* this is a switch () statement in the C preprocessor - ugh */
4091 #undef SELECTED_ONE_OPTION
4092
4093 /* Use Pthreads in preference to native code */
4094 #if defined(FEATURE_PTHREAD) && !defined(SELECTED_ONE_OPTION)
4095 #define SELECTED_ONE_OPTION
4096          {
4097             pthread_t the_thread;
4098             pthread_attr_t attrs;
4099
4100             pthread_attr_init(&attrs);
4101             pthread_attr_setdetachstate(&attrs, PTHREAD_CREATE_DETACHED);
4102             errno = pthread_create(&the_thread, &attrs,
4103                (void * (*)(void *))serve, csp);
4104             child_id = errno ? -1 : 0;
4105             pthread_attr_destroy(&attrs);
4106          }
4107 #endif
4108
4109 #if defined(_WIN32) && !defined(_CYGWIN) && !defined(SELECTED_ONE_OPTION)
4110 #define SELECTED_ONE_OPTION
4111          child_id = _beginthread(
4112             (void (*)(void *))serve,
4113             64 * 1024,
4114             csp);
4115 #endif
4116
4117 #if defined(__OS2__) && !defined(SELECTED_ONE_OPTION)
4118 #define SELECTED_ONE_OPTION
4119          child_id = _beginthread(
4120             (void(* _Optlink)(void*))serve,
4121             NULL,
4122             64 * 1024,
4123             csp);
4124 #endif
4125
4126 #if defined(__BEOS__) && !defined(SELECTED_ONE_OPTION)
4127 #define SELECTED_ONE_OPTION
4128          {
4129             thread_id tid = spawn_thread
4130                (server_thread, "server", B_NORMAL_PRIORITY, csp);
4131
4132             if ((tid >= 0) && (resume_thread(tid) == B_OK))
4133             {
4134                child_id = (int) tid;
4135             }
4136             else
4137             {
4138                child_id = -1;
4139             }
4140          }
4141 #endif
4142
4143 #if defined(AMIGA) && !defined(SELECTED_ONE_OPTION)
4144 #define SELECTED_ONE_OPTION
4145          csp->cfd = ReleaseSocket(csp->cfd, -1);
4146
4147 #ifdef __amigaos4__
4148          child_id = (int)CreateNewProcTags(NP_Entry, (ULONG)server_thread,
4149                                            NP_Output, Output(),
4150                                            NP_CloseOutput, FALSE,
4151                                            NP_Name, (ULONG)"privoxy child",
4152                                            NP_Child, TRUE,
4153                                            TAG_DONE);
4154 #else
4155          child_id = (int)CreateNewProcTags(NP_Entry, (ULONG)server_thread,
4156                                            NP_Output, Output(),
4157                                            NP_CloseOutput, FALSE,
4158                                            NP_Name, (ULONG)"privoxy child",
4159                                            NP_StackSize, 200*1024,
4160                                            TAG_DONE);
4161 #endif
4162          if (0 != child_id)
4163          {
4164             childs++;
4165             ((struct Task *)child_id)->tc_UserData = csp;
4166             Signal((struct Task *)child_id, SIGF_SINGLE);
4167             Wait(SIGF_SINGLE);
4168          }
4169 #endif
4170
4171 #if !defined(SELECTED_ONE_OPTION)
4172          child_id = fork();
4173
4174          /* This block is only needed when using fork().
4175           * When using threads, the server thread was
4176           * created and run by the call to _beginthread().
4177           */
4178          if (child_id == 0)   /* child */
4179          {
4180             int rc = 0;
4181 #ifdef FEATURE_TOGGLE
4182             int inherited_toggle_state = global_toggle_state;
4183 #endif /* def FEATURE_TOGGLE */
4184
4185             serve(csp);
4186
4187             /*
4188              * If we've been toggled or we've blocked the request, tell Mom
4189              */
4190
4191 #ifdef FEATURE_TOGGLE
4192             if (inherited_toggle_state != global_toggle_state)
4193             {
4194                rc |= RC_FLAG_TOGGLED;
4195             }
4196 #endif /* def FEATURE_TOGGLE */
4197
4198 #ifdef FEATURE_STATISTICS
4199             if (csp->flags & CSP_FLAG_REJECTED)
4200             {
4201                rc |= RC_FLAG_BLOCKED;
4202             }
4203 #endif /* ndef FEATURE_STATISTICS */
4204
4205             _exit(rc);
4206          }
4207          else if (child_id > 0) /* parent */
4208          {
4209             /* in a fork()'d environment, the parent's
4210              * copy of the client socket and the CSP
4211              * are not used.
4212              */
4213             int child_status;
4214 #if !defined(_WIN32) && !defined(__CYGWIN__)
4215
4216             wait(&child_status);
4217
4218             /*
4219              * Evaluate child's return code: If the child has
4220              *  - been toggled, toggle ourselves
4221              *  - blocked its request, bump up the stats counter
4222              */
4223
4224 #ifdef FEATURE_TOGGLE
4225             if (WIFEXITED(child_status) && (WEXITSTATUS(child_status) & RC_FLAG_TOGGLED))
4226             {
4227                global_toggle_state = !global_toggle_state;
4228             }
4229 #endif /* def FEATURE_TOGGLE */
4230
4231 #ifdef FEATURE_STATISTICS
4232             urls_read++;
4233             if (WIFEXITED(child_status) && (WEXITSTATUS(child_status) & RC_FLAG_BLOCKED))
4234             {
4235                urls_rejected++;
4236             }
4237 #endif /* def FEATURE_STATISTICS */
4238
4239 #endif /* !defined(_WIN32) && defined(__CYGWIN__) */
4240             close_socket(csp->cfd);
4241             csp->flags &= ~CSP_FLAG_ACTIVE;
4242          }
4243 #endif
4244
4245 #undef SELECTED_ONE_OPTION
4246 /* end of cpp switch () */
4247
4248          if (child_id < 0)
4249          {
4250             /*
4251              * Spawning the child failed, assume it's because
4252              * there are too many children running already.
4253              * XXX: If you assume ...
4254              */
4255             log_error(LOG_LEVEL_ERROR,
4256                "Unable to take any additional connections: %E. Active threads: %d",
4257                active_threads);
4258             write_socket(csp->cfd, TOO_MANY_CONNECTIONS_RESPONSE,
4259                strlen(TOO_MANY_CONNECTIONS_RESPONSE));
4260             close_socket(csp->cfd);
4261             csp->flags &= ~CSP_FLAG_ACTIVE;
4262          }
4263       }
4264       else
4265       {
4266          serve(csp);
4267       }
4268    }
4269
4270    /* NOTREACHED unless FEATURE_GRACEFUL_TERMINATION is defined */
4271
4272    /* Clean up.  Aim: free all memory (no leaks) */
4273 #ifdef FEATURE_GRACEFUL_TERMINATION
4274
4275    log_error(LOG_LEVEL_ERROR, "Graceful termination requested");
4276
4277    unload_current_config_file();
4278    unload_current_actions_file();
4279    unload_current_re_filterfile();
4280 #ifdef FEATURE_TRUST
4281    unload_current_trust_file();
4282 #endif
4283
4284    if (config->multi_threaded)
4285    {
4286       int i = 60;
4287       do
4288       {
4289          sleep(1);
4290          sweep();
4291       } while ((clients->next != NULL) && (--i > 0));
4292
4293       if (i <= 0)
4294       {
4295          log_error(LOG_LEVEL_ERROR, "Graceful termination failed - still some live clients after 1 minute wait.");
4296       }
4297    }
4298    sweep();
4299    sweep();
4300
4301 #if defined(unix)
4302    freez(basedir);
4303 #endif
4304
4305 #if defined(_WIN32) && !defined(_WIN_CONSOLE)
4306    /* Cleanup - remove taskbar icon etc. */
4307    TermLogWindow();
4308 #endif
4309
4310    exit(0);
4311 #endif /* FEATURE_GRACEFUL_TERMINATION */
4312
4313 }
4314
4315
4316 /*
4317   Local Variables:
4318   tab-width: 3
4319   end:
4320 */