From: Fabian Keil Date: Fri, 24 Apr 2009 15:29:43 +0000 (+0000) Subject: Allow to limit the number of of client connections. X-Git-Tag: v_3_0_13~112 X-Git-Url: http://www.privoxy.org/gitweb/contact.html?a=commitdiff_plain;h=8cae7e3a5026ceac91afc7e1f0f30a2ebd5ec1bc;p=privoxy.git Allow to limit the number of of client connections. --- diff --git a/doc/source/p-config.sgml b/doc/source/p-config.sgml index 2457d395..fff23cd1 100644 --- a/doc/source/p-config.sgml +++ b/doc/source/p-config.sgml @@ -3,7 +3,7 @@ Purpose : Used with other docs and files only. - $Id: p-config.sgml,v 2.48 2009/04/17 11:42:07 fabiankeil Exp $ + $Id: p-config.sgml,v 2.49 2009/04/19 17:39:55 fabiankeil Exp $ Copyright (C) 2001-2009 Privoxy Developers http://www.privoxy.org/ See LICENSE. @@ -95,7 +95,7 @@ Sample Configuration File for Privoxy v&p-version; - $Id: p-config.sgml,v 2.48 2009/04/17 11:42:07 fabiankeil Exp $ + $Id: p-config.sgml,v 2.49 2009/04/19 17:39:55 fabiankeil Exp $ Copyright (C) 2001-2009 Privoxy Developers http://www.privoxy.org/ @@ -2612,6 +2612,87 @@ forward-socks4, forward-socks4a and forward-socks5 +max-client-connections + + + Specifies: + + + Maximum number of client connections that will be served. + + + + + Type of value: + + + Positive number. + + + + + Default value: + + None + + + + Effect if unset: + + + Connections are served until a resource limit is reached. + + + + + Notes: + + + &my-app; creates one thread (or process) for every incoming client + connection that isn't rejected based on the access control settings. + + + If the system is powerful enough, &my-app; can theoretically deal with + several hundred (or thousand) connections at the same time, but some + operating systems enforce resource limits by shutting down offending + processes and their default limits may be below the ones &my-app; would + require under heavy load. + + + Configuring &my-app; to enforce a connection limit below the thread + or process limit used by the operating system makes sure this doesn't + happen. Simply increasing the operating system's limit would work too, + but if &my-app; isn't the only application running on the system, + you may actually want to limit the resources used by &my-app;. + + + If &my-app; is only used by a single trusted user, limiting the + number of client connections is probably unnecessary. If there + are multiple possibly untrusted users you probably still want to + additionally use a packet filter to limit the maximal number of + incoming connections per client. Otherwise a malicious user could + intentionally create a high number of connections to prevent other + users from using &my-app;. + + + Obviously using this option only makes sense if you choose a limit + below the one enforced by the operating system. + + + + + Examples: + + + max-client-connections 256 + + + + +@@max-client-connections 256]]> + + + diff --git a/jcc.c b/jcc.c index 83e3b3a1..7ca0f46f 100644 --- a/jcc.c +++ b/jcc.c @@ -1,4 +1,4 @@ -const char jcc_rcs[] = "$Id: jcc.c,v 1.243 2009/04/17 11:27:49 fabiankeil Exp $"; +const char jcc_rcs[] = "$Id: jcc.c,v 1.244 2009/04/17 11:34:34 fabiankeil Exp $"; /********************************************************************* * * File : $Source: /cvsroot/ijbswa/current/jcc.c,v $ @@ -33,6 +33,9 @@ const char jcc_rcs[] = "$Id: jcc.c,v 1.243 2009/04/17 11:27:49 fabiankeil Exp $" * * Revisions : * $Log: jcc.c,v $ + * Revision 1.244 2009/04/17 11:34:34 fabiankeil + * Style cosmetics for the IPv6 code. + * * Revision 1.243 2009/04/17 11:27:49 fabiankeil * Petr Pisar's privoxy-3.0.12-ipv6-3.diff. * @@ -4180,7 +4183,8 @@ static void listen_loop(void) { struct client_state *csp = NULL; jb_socket bfd; - struct configuration_spec * config; + struct configuration_spec *config; + unsigned int active_threads = 0; config = load_config(); @@ -4210,7 +4214,7 @@ static void listen_loop(void) /* * Free data that was used by died threads */ - sweep(); + active_threads = sweep(); #if defined(unix) /* @@ -4301,6 +4305,20 @@ static void listen_loop(void) } #endif /* def FEATURE_ACL */ + if ((0 != config->max_client_connections) + && (active_threads >= config->max_client_connections)) + { + log_error(LOG_LEVEL_CONNECT, + "Rejecting connection from %s. Maximum number of connections reached.", + csp->ip_addr_str); + write_socket(csp->cfd, TOO_MANY_CONNECTIONS_RESPONSE, + strlen(TOO_MANY_CONNECTIONS_RESPONSE)); + close_socket(csp->cfd); + freez(csp->ip_addr_str); + freez(csp); + continue; + } + /* add it to the list of clients */ csp->next = clients->next; clients->next = csp; diff --git a/loadcfg.c b/loadcfg.c index d1fb7c1e..fb804f8f 100644 --- a/loadcfg.c +++ b/loadcfg.c @@ -1,4 +1,4 @@ -const char loadcfg_rcs[] = "$Id: loadcfg.c,v 1.96 2009/04/17 11:38:28 fabiankeil Exp $"; +const char loadcfg_rcs[] = "$Id: loadcfg.c,v 1.97 2009/04/17 11:45:19 fabiankeil Exp $"; /********************************************************************* * * File : $Source: /cvsroot/ijbswa/current/loadcfg.c,v $ @@ -35,6 +35,10 @@ const char loadcfg_rcs[] = "$Id: loadcfg.c,v 1.96 2009/04/17 11:38:28 fabiankeil * * Revisions : * $Log: loadcfg.c,v $ + * Revision 1.97 2009/04/17 11:45:19 fabiankeil + * Replace HAVE_GETADDRINFO and HAVE_GETNAMEINFO macros + * with HAVE_RFC2553 macro. Original patch by Petr Pisar. + * * Revision 1.96 2009/04/17 11:38:28 fabiankeil * Add and use parse_forwarder_address() to reduce code duplication. * @@ -643,6 +647,7 @@ static struct file_list *current_configfile = NULL; #define hash_listen_address 1255650842ul /* "listen-address" */ #define hash_logdir 422889ul /* "logdir" */ #define hash_logfile 2114766ul /* "logfile" */ +#define hash_max_client_connections 3595884446ul /* "max-client-connections" */ #define hash_permit_access 3587953268ul /* "permit-access" */ #define hash_proxy_info_url 3903079059ul /* "proxy-info-url" */ #define hash_single_threaded 4250084780ul /* "single-threaded" */ @@ -848,6 +853,7 @@ struct configuration_spec * load_config(void) config->usermanual = strdup(USER_MANUAL_URL); config->proxy_args = strdup(""); config->forwarded_connect_retries = 0; + config->max_client_connections = 0; config->socket_timeout = 300; /* XXX: Should be a macro. */ config->feature_flags &= ~RUNTIME_FEATURE_CGI_TOGGLE; config->feature_flags &= ~RUNTIME_FEATURE_SPLIT_LARGE_FORMS; @@ -1423,6 +1429,20 @@ struct configuration_spec * load_config(void) } break; +/* ************************************************************************* + * max-client-connections number + * *************************************************************************/ + case hash_max_client_connections : + if (*arg != '\0') + { + int max_client_connections = atoi(arg); + if (0 <= max_client_connections) + { + config->max_client_connections = max_client_connections; + } + } + break; + /* ************************************************************************* * permit-access source-ip[/significant-bits] [dest-ip[/significant-bits]] * *************************************************************************/ diff --git a/loaders.c b/loaders.c index f33e2c2d..e7dbbe42 100644 --- a/loaders.c +++ b/loaders.c @@ -1,4 +1,4 @@ -const char loaders_rcs[] = "$Id: loaders.c,v 1.70 2009/03/01 18:34:24 fabiankeil Exp $"; +const char loaders_rcs[] = "$Id: loaders.c,v 1.71 2009/03/04 18:24:47 fabiankeil Exp $"; /********************************************************************* * * File : $Source: /cvsroot/ijbswa/current/loaders.c,v $ @@ -35,6 +35,9 @@ const char loaders_rcs[] = "$Id: loaders.c,v 1.70 2009/03/01 18:34:24 fabiankeil * * Revisions : * $Log: loaders.c,v $ + * Revision 1.71 2009/03/04 18:24:47 fabiankeil + * No need to create empty strings manually, strdup("") FTW. + * * Revision 1.70 2009/03/01 18:34:24 fabiankeil * Help clang understand that we aren't dereferencing * NULL pointers here. @@ -450,14 +453,15 @@ static struct file_list *current_re_filterfile[MAX_AF_FILES] = { * * Parameters : None * - * Returns : N/A + * Returns : The number of threads that are still active. * *********************************************************************/ -void sweep(void) +unsigned int sweep(void) { struct file_list *fl, *nfl; struct client_state *csp, *last_active; int i; + unsigned int active_threads = 0; /* clear all of the file's active flags */ for ( fl = files->next; NULL != fl; fl = fl->next ) @@ -512,10 +516,11 @@ void sweep(void) csp->tlist->active = 1; } #endif /* def FEATURE_TRUST */ - + + active_threads++; + last_active = csp; csp = csp->next; - } else /* @@ -577,6 +582,8 @@ void sweep(void) } } + return active_threads; + } diff --git a/loaders.h b/loaders.h index 30be6394..9d544c4b 100644 --- a/loaders.h +++ b/loaders.h @@ -1,6 +1,6 @@ #ifndef LOADERS_H_INCLUDED #define LOADERS_H_INCLUDED -#define LOADERS_H_VERSION "$Id: loaders.h,v 1.22 2007/06/01 14:12:38 fabiankeil Exp $" +#define LOADERS_H_VERSION "$Id: loaders.h,v 1.23 2008/03/30 14:52:10 fabiankeil Exp $" /********************************************************************* * * File : $Source: /cvsroot/ijbswa/current/loaders.h,v $ @@ -10,7 +10,7 @@ * the list of active loaders, and to automatically * unload files that are no longer in use. * - * Copyright : Written by and Copyright (C) 2001 the SourceForge + * Copyright : Written by and Copyright (C) 2001-2009 the * Privoxy team. http://www.privoxy.org/ * * Based on the Internet Junkbuster originally written @@ -37,6 +37,10 @@ * * Revisions : * $Log: loaders.h,v $ + * Revision 1.23 2008/03/30 14:52:10 fabiankeil + * Rename load_actions_file() and load_re_filterfile() + * as they load multiple files "now". + * * Revision 1.22 2007/06/01 14:12:38 fabiankeil * Add unload_forward_spec() in preparation for forward-override{}. * @@ -175,7 +179,7 @@ struct file_list; struct configuration_spec; struct url_spec; -extern void sweep(void); +extern unsigned int sweep(void); extern char *read_config_line(char *buf, size_t buflen, FILE *fp, unsigned long *linenum); extern int check_file_changed(const struct file_list * current, const char * filename, diff --git a/project.h b/project.h index d2422669..ccd29f30 100644 --- a/project.h +++ b/project.h @@ -1,7 +1,7 @@ #ifndef PROJECT_H_INCLUDED #define PROJECT_H_INCLUDED /** Version string. */ -#define PROJECT_H_VERSION "$Id: project.h,v 1.131 2009/04/17 11:34:35 fabiankeil Exp $" +#define PROJECT_H_VERSION "$Id: project.h,v 1.132 2009/04/17 11:45:19 fabiankeil Exp $" /********************************************************************* * * File : $Source: /cvsroot/ijbswa/current/project.h,v $ @@ -37,6 +37,10 @@ * * Revisions : * $Log: project.h,v $ + * Revision 1.132 2009/04/17 11:45:19 fabiankeil + * Replace HAVE_GETADDRINFO and HAVE_GETNAMEINFO macros + * with HAVE_RFC2553 macro. Original patch by Petr Pisar. + * * Revision 1.131 2009/04/17 11:34:35 fabiankeil * Style cosmetics for the IPv6 code. * @@ -1823,7 +1827,10 @@ struct configuration_spec struct forward_spec *forward; /** Number of retries in case a forwarded connection attempt fails */ - int forwarded_connect_retries; + int forwarded_connect_retries; + + /** Maximum number of client connections. */ + int max_client_connections; /* Timeout when waiting on sockets for data to become available. */ int socket_timeout;