From 029f27038bef2c80e99dde3359c0ad86cab29594 Mon Sep 17 00:00:00 2001 From: Fabian Keil Date: Sun, 10 May 2009 10:19:23 +0000 Subject: [PATCH] Reenable server-side-only keep-alive support, but only share outgoing connections if the connection-sharing option is set. --- doc/source/p-config.sgml | 115 ++++++++++++++++++++++++++++++++++----- gateway.c | 15 +++-- jcc.c | 81 +++++++++++++++++---------- loadcfg.c | 24 +++++++- project.h | 9 ++- 5 files changed, 197 insertions(+), 47 deletions(-) diff --git a/doc/source/p-config.sgml b/doc/source/p-config.sgml index fff23cd1..c622cf2c 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.49 2009/04/19 17:39:55 fabiankeil Exp $ + $Id: p-config.sgml,v 2.50 2009/04/24 15:29:43 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.49 2009/04/19 17:39:55 fabiankeil Exp $ + $Id: p-config.sgml,v 2.50 2009/04/24 15:29:43 fabiankeil Exp $ Copyright (C) 2001-2009 Privoxy Developers http://www.privoxy.org/ @@ -2512,19 +2512,87 @@ forward-socks4, forward-socks4a and forward-socks5 Effect if unset: - Connections are not reused. + Connections are not kept alive. Notes: + + This option allows clients to keep the connection to &my-app; + alive. If the server supports it, &my-app; will keep + the connection to the server alive as well. Under certain + circumstances this may result in speed-ups. + + + By default, &my-app; will close the connection to the server if + the client connection gets closed, or if the specified timeout + has been reached without a new request coming in. This behaviour + can be changed with the connection-sharing option. + This option has no effect if Privoxy has been compiled without keep-alive support. + + Examples: + + + keep-alive-timeout 300 + + + + +@@keep-alive-timeout 300]]> + + + +connection-sharing + + + Specifies: + + + Whether or not outgoing connections that have been kept alive + should be shared between different incoming connections. + + + + + Type of value: + + + 0 or 1 + + + + + Default value: + + None + + + + Effect if unset: + + + Connections are not shared. + + + + + Notes: + + + This option has no effect if Privoxy + has been compiled without keep-alive support, or if it's disabled. + + + Notes: @@ -2533,13 +2601,34 @@ forward-socks4, forward-socks4a and forward-socks5 There are also a few privacy implications you should be aware of. - Outgoing connections are shared between clients (if there are more - than one) and closing the client that initiated the outgoing connection - does not affect the connection between &my-app; and the server unless - the client's request hasn't been completed yet. If the outgoing connection - is idle, it will not be closed until either Privoxy's - or the server's timeout is reached. While it's open, the server knows - that the system running &my-app; is still there. + If this option is effective, outgoing connections are shared between + clients (if there are more than one) and closing the client that initiated + the outgoing connection does no longer affect the connection between &my-app; + and the server unless the client's request hasn't been completed yet. + + + If the outgoing connection is idle, it will not be closed until either + Privoxy's or the server's timeout is reached. + While it's open, the server knows that the system running &my-app; is still + there. + + + If there are more than one client (maybe even belonging to multiple users), + they will be able to reuse each others connections. This is potentially + dangerous in case of authentication schemes like NTLM where only the + connection is authenticated, instead of requiring authentication for + each request. + + + If there is only a single client, and if said client can keep connections + alive on its own, enabling this option has next to no effect. If the client + doesn't support connection keep-alive, enabling this option may make sense + as it allows &my-app; to keep outgoing connections alive even if the client + itself doesn't support it. + + + This option should only be used by experienced users who + understand the risks and can weight them against the benefits. @@ -2547,12 +2636,12 @@ forward-socks4, forward-socks4a and forward-socks5 Examples: - keep-alive-timeout 300 + connection-sharing 1 -@@keep-alive-timeout 300]]> +@@#connection-sharing 1]]> @@ -2689,7 +2778,7 @@ forward-socks4, forward-socks4a and forward-socks5 -@@max-client-connections 256]]> +@@#max-client-connections 256]]> diff --git a/gateway.c b/gateway.c index 31816093..3c251fe3 100644 --- a/gateway.c +++ b/gateway.c @@ -1,4 +1,4 @@ -const char gateway_rcs[] = "$Id: gateway.c,v 1.48 2009/02/13 17:20:36 fabiankeil Exp $"; +const char gateway_rcs[] = "$Id: gateway.c,v 1.49 2009/05/10 10:12:30 fabiankeil Exp $"; /********************************************************************* * * File : $Source: /cvsroot/ijbswa/current/gateway.c,v $ @@ -34,6 +34,10 @@ const char gateway_rcs[] = "$Id: gateway.c,v 1.48 2009/02/13 17:20:36 fabiankeil * * Revisions : * $Log: gateway.c,v $ + * Revision 1.49 2009/05/10 10:12:30 fabiankeil + * Initial keep-alive support for the client socket. + * Temporarily disable the server-side-only keep-alive code. + * * Revision 1.48 2009/02/13 17:20:36 fabiankeil * Reword keep-alive support warning and only show * it #if !defined(HAVE_POLL) && !defined(_WIN32). @@ -800,10 +804,13 @@ jb_socket forwarded_connect(const struct forward_spec * fwd, jb_socket sfd = JB_INVALID_SOCKET; #ifdef FEATURE_CONNECTION_KEEP_ALIVE - sfd = get_reusable_connection(http, fwd); - if (JB_INVALID_SOCKET != sfd) + if ((csp->config->feature_flags & RUNTIME_FEATURE_CONNECTION_SHARING)) { - return sfd; + sfd = get_reusable_connection(http, fwd); + if (JB_INVALID_SOCKET != sfd) + { + return sfd; + } } #endif /* def FEATURE_CONNECTION_KEEP_ALIVE */ diff --git a/jcc.c b/jcc.c index 5991a72d..7ab3f324 100644 --- a/jcc.c +++ b/jcc.c @@ -1,4 +1,4 @@ -const char jcc_rcs[] = "$Id: jcc.c,v 1.245 2009/04/24 15:29:43 fabiankeil Exp $"; +const char jcc_rcs[] = "$Id: jcc.c,v 1.246 2009/05/10 10:12:30 fabiankeil Exp $"; /********************************************************************* * * File : $Source: /cvsroot/ijbswa/current/jcc.c,v $ @@ -33,6 +33,10 @@ const char jcc_rcs[] = "$Id: jcc.c,v 1.245 2009/04/24 15:29:43 fabiankeil Exp $" * * Revisions : * $Log: jcc.c,v $ + * Revision 1.246 2009/05/10 10:12:30 fabiankeil + * Initial keep-alive support for the client socket. + * Temporarily disable the server-side-only keep-alive code. + * * Revision 1.245 2009/04/24 15:29:43 fabiankeil * Allow to limit the number of of client connections. * @@ -3507,6 +3511,7 @@ static void serve(struct client_state *csp) #endif /* def AMIGA */ { #ifdef FEATURE_CONNECTION_KEEP_ALIVE + static int monitor_thread_running = 0; int continue_chatting = 0; do { @@ -3519,30 +3524,6 @@ static void serve(struct client_state *csp) && (csp->sfd != JB_INVALID_SOCKET) && socket_is_still_usable(csp->sfd); - /* - * Get the csp in a mostly vergin state again. - * XXX: Should be done elsewhere. - */ - csp->content_type = 0; - csp->content_length = 0; - csp->expected_content_length = 0; - list_remove_all(csp->headers); - freez(csp->iob->buf); - memset(csp->iob, 0, sizeof(csp->iob)); - freez(csp->error_message); - free_http_request(csp->http); - destroy_list(csp->headers); - destroy_list(csp->tags); - free_current_action(csp->action); - if (NULL != csp->fwd) - { - unload_forward_spec(csp->fwd); - csp->fwd = NULL; - } - - /* XXX: Store per-connection flags someplace else. */ - csp->flags = CSP_FLAG_ACTIVE | (csp->flags & CSP_FLAG_TOGGLED_ON); - if (continue_chatting) { log_error(LOG_LEVEL_CONNECT, @@ -3556,13 +3537,52 @@ static void serve(struct client_state *csp) { log_error(LOG_LEVEL_CONNECT, "Client request arrived in " "time or the client closed the connection."); + /* + * Get the csp in a mostly vergin state again. + * XXX: Should be done elsewhere. + */ + csp->content_type = 0; + csp->content_length = 0; + csp->expected_content_length = 0; + list_remove_all(csp->headers); + freez(csp->iob->buf); + memset(csp->iob, 0, sizeof(csp->iob)); + freez(csp->error_message); + free_http_request(csp->http); + destroy_list(csp->headers); + destroy_list(csp->tags); + free_current_action(csp->action); + if (NULL != csp->fwd) + { + unload_forward_spec(csp->fwd); + csp->fwd = NULL; + } + + /* XXX: Store per-connection flags someplace else. */ + csp->flags = CSP_FLAG_ACTIVE | (csp->flags & CSP_FLAG_TOGGLED_ON); } else { log_error(LOG_LEVEL_CONNECT, - "No additional client request received in time. " - "Closing server socket %d, initially opened for %s.", - csp->sfd, csp->server_connection.host); + "No additional client request received in time."); + if ((csp->config->feature_flags & RUNTIME_FEATURE_CONNECTION_SHARING)) + { + remember_connection(csp->sfd, csp->http, + forward_url(csp, csp->http)); + csp->sfd = JB_INVALID_SOCKET; + close_socket(csp->cfd); + csp->cfd = JB_INVALID_SOCKET; + privoxy_mutex_lock(&connection_reuse_mutex); + if (!monitor_thread_running) + { + monitor_thread_running = 1; + privoxy_mutex_unlock(&connection_reuse_mutex); + wait_for_alive_connections(); + privoxy_mutex_lock(&connection_reuse_mutex); + monitor_thread_running = 0; + } + privoxy_mutex_unlock(&connection_reuse_mutex); + } break; } } @@ -3573,12 +3593,17 @@ static void serve(struct client_state *csp) "Closing.", csp->sfd, csp->server_connection.host); } } while (continue_chatting); + + mark_connection_closed(&csp->server_connection); #else chat(csp); #endif /* def FEATURE_CONNECTION_KEEP_ALIVE */ if (csp->sfd != JB_INVALID_SOCKET) { +#ifdef FEATURE_CONNECTION_KEEP_ALIVE + forget_connection(csp->sfd); +#endif /* def FEATURE_CONNECTION_KEEP_ALIVE */ close_socket(csp->sfd); } diff --git a/loadcfg.c b/loadcfg.c index 4942ca45..0d026e4c 100644 --- a/loadcfg.c +++ b/loadcfg.c @@ -1,4 +1,4 @@ -const char loadcfg_rcs[] = "$Id: loadcfg.c,v 1.98 2009/04/24 15:29:43 fabiankeil Exp $"; +const char loadcfg_rcs[] = "$Id: loadcfg.c,v 1.99 2009/05/10 10:12:30 fabiankeil Exp $"; /********************************************************************* * * File : $Source: /cvsroot/ijbswa/current/loadcfg.c,v $ @@ -35,6 +35,10 @@ const char loadcfg_rcs[] = "$Id: loadcfg.c,v 1.98 2009/04/24 15:29:43 fabiankeil * * Revisions : * $Log: loadcfg.c,v $ + * Revision 1.99 2009/05/10 10:12:30 fabiankeil + * Initial keep-alive support for the client socket. + * Temporarily disable the server-side-only keep-alive code. + * * Revision 1.98 2009/04/24 15:29:43 fabiankeil * Allow to limit the number of of client connections. * @@ -633,6 +637,7 @@ static struct file_list *current_configfile = NULL; #define hash_allow_cgi_request_crunching 258915987ul /* "allow-cgi-request-crunching" */ #define hash_buffer_limit 1881726070ul /* "buffer-limit */ #define hash_confdir 1978389ul /* "confdir" */ +#define hash_connection_sharing 1348841265ul /* "connection-sharing" */ #define hash_debug 78263ul /* "debug" */ #define hash_deny_access 1227333715ul /* "deny-access" */ #define hash_enable_edit_actions 2517097536ul /* "enable-edit-actions" */ @@ -858,6 +863,7 @@ struct configuration_spec * load_config(void) #ifdef FEATURE_CONNECTION_KEEP_ALIVE config->keep_alive_timeout = DEFAULT_KEEP_ALIVE_TIMEOUT; config->feature_flags &= ~RUNTIME_FEATURE_CONNECTION_KEEP_ALIVE; + config->feature_flags &= ~RUNTIME_FEATURE_CONNECTION_SHARING; #endif config->feature_flags &= ~RUNTIME_FEATURE_CGI_TOGGLE; config->feature_flags &= ~RUNTIME_FEATURE_SPLIT_LARGE_FORMS; @@ -994,6 +1000,22 @@ struct configuration_spec * load_config(void) config->confdir = make_path( NULL, arg); break; +/* ************************************************************************* + * connection-sharing (0|1) + * *************************************************************************/ +#ifdef FEATURE_CONNECTION_KEEP_ALIVE + case hash_connection_sharing : + if ((*arg != '\0') && (0 != atoi(arg))) + { + config->feature_flags |= RUNTIME_FEATURE_CONNECTION_SHARING; + } + else + { + config->feature_flags &= ~RUNTIME_FEATURE_CONNECTION_SHARING; + } + break; +#endif + /* ************************************************************************* * debug n * Specifies debug level, multiple values are ORed together. diff --git a/project.h b/project.h index 0fab7ff0..8b83f65b 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.133 2009/04/24 15:29:43 fabiankeil Exp $" +#define PROJECT_H_VERSION "$Id: project.h,v 1.134 2009/05/10 10:12:30 fabiankeil Exp $" /********************************************************************* * * File : $Source: /cvsroot/ijbswa/current/project.h,v $ @@ -37,6 +37,10 @@ * * Revisions : * $Log: project.h,v $ + * Revision 1.134 2009/05/10 10:12:30 fabiankeil + * Initial keep-alive support for the client socket. + * Temporarily disable the server-side-only keep-alive code. + * * Revision 1.133 2009/04/24 15:29:43 fabiankeil * Allow to limit the number of of client connections. * @@ -1766,6 +1770,9 @@ struct access_control_list /** configuration_spec::feature_flags: Try to keep the connection to the server alive. */ #define RUNTIME_FEATURE_CONNECTION_KEEP_ALIVE 128U +/** configuration_spec::feature_flags: Share outgoing connections between different client connections. */ +#define RUNTIME_FEATURE_CONNECTION_SHARING 256U + /** * Data loaded from the configuration file. * -- 2.39.2