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