From 8a5751cc96dd085fcbcc34bef77499306bddc0c0 Mon Sep 17 00:00:00 2001 From: Fabian Keil Date: Wed, 13 May 2009 18:22:45 +0000 Subject: [PATCH 1/1] Respect the server's keep-alive value if it's below ours. --- gateway.c | 20 ++++++++++++++----- gateway.h | 8 ++++++-- jcc.c | 11 +++++++--- parsers.c | 60 ++++++++++++++++++++++++++++++++++++++++++++++++++++++- project.h | 12 +++++++++-- 5 files changed, 98 insertions(+), 13 deletions(-) diff --git a/gateway.c b/gateway.c index 8aaf7e28..524ccffc 100644 --- a/gateway.c +++ b/gateway.c @@ -1,4 +1,4 @@ -const char gateway_rcs[] = "$Id: gateway.c,v 1.50 2009/05/10 10:19:23 fabiankeil Exp $"; +const char gateway_rcs[] = "$Id: gateway.c,v 1.51 2009/05/13 18:20:54 fabiankeil Exp $"; /********************************************************************* * * File : $Source: /cvsroot/ijbswa/current/gateway.c,v $ @@ -34,6 +34,9 @@ const char gateway_rcs[] = "$Id: gateway.c,v 1.50 2009/05/10 10:19:23 fabiankeil * * Revisions : * $Log: gateway.c,v $ + * Revision 1.51 2009/05/13 18:20:54 fabiankeil + * There's no reason for keep_alive_timeout to be signed. + * * Revision 1.50 2009/05/10 10:19:23 fabiankeil * Reenable server-side-only keep-alive support, but only share * outgoing connections if the connection-sharing option is set. @@ -392,12 +395,16 @@ extern void initialize_reusable_connections(void) * 1 : sfd = Open socket to remember. * 2 : http = The destination for the connection. * 3 : fwd = The forwarder settings used. + * 4 : timeout = Number of seconds after which the + * connection shouldn't be reused. * * Returns : void * *********************************************************************/ -void remember_connection(jb_socket sfd, const struct http_request *http, - const struct forward_spec *fwd) +void remember_connection(jb_socket sfd, + const struct http_request *http, + const struct forward_spec *fwd, + unsigned int timeout) { unsigned int slot = 0; int free_slot_found = FALSE; @@ -445,6 +452,7 @@ void remember_connection(jb_socket sfd, const struct http_request *http, reusable_connection[slot].port = http->port; reusable_connection[slot].in_use = 0; reusable_connection[slot].timestamp = time(NULL); + reusable_connection[slot].keep_alive_timeout = timeout; assert(NULL != fwd); assert(reusable_connection[slot].gateway_host == NULL); @@ -505,6 +513,7 @@ void mark_connection_closed(struct reusable_connection *closed_connection) freez(closed_connection->host); closed_connection->port = 0; closed_connection->timestamp = 0; + closed_connection->keep_alive_timeout = 0; closed_connection->forwarder_type = SOCKS_NONE; freez(closed_connection->gateway_host); closed_connection->gateway_port = 0; @@ -635,14 +644,15 @@ int close_unusable_connections(void) { time_t time_open = time(NULL) - reusable_connection[slot].timestamp; - if (keep_alive_timeout < time_open) + if (reusable_connection[slot].keep_alive_timeout < time_open) { log_error(LOG_LEVEL_CONNECT, "The connection to %s:%d in slot %d timed out. " "Closing socket %d. Timeout is: %d.", reusable_connection[slot].host, reusable_connection[slot].port, slot, - reusable_connection[slot].sfd, keep_alive_timeout); + reusable_connection[slot].sfd, + reusable_connection[slot].keep_alive_timeout); close_socket(reusable_connection[slot].sfd); mark_connection_closed(&reusable_connection[slot]); } diff --git a/gateway.h b/gateway.h index e89ff34b..3868c2bd 100644 --- a/gateway.h +++ b/gateway.h @@ -1,6 +1,6 @@ #ifndef GATEWAY_H_INCLUDED #define GATEWAY_H_INCLUDED -#define GATEWAY_H_VERSION "$Id: gateway.h,v 1.13 2009/05/10 10:12:30 fabiankeil Exp $" +#define GATEWAY_H_VERSION "$Id: gateway.h,v 1.14 2009/05/13 18:20:54 fabiankeil Exp $" /********************************************************************* * * File : $Source: /cvsroot/ijbswa/current/gateway.h,v $ @@ -36,6 +36,9 @@ * * Revisions : * $Log: gateway.h,v $ + * Revision 1.14 2009/05/13 18:20:54 fabiankeil + * There's no reason for keep_alive_timeout to be signed. + * * Revision 1.13 2009/05/10 10:12:30 fabiankeil * Initial keep-alive support for the client socket. * Temporarily disable the server-side-only keep-alive code. @@ -131,7 +134,8 @@ extern void initialize_reusable_connections(void); extern void forget_connection(jb_socket sfd); extern void remember_connection(jb_socket sfd, const struct http_request *http, - const struct forward_spec *fwd); + const struct forward_spec *fwd, + unsigned int timeout); extern int close_unusable_connections(void); extern void mark_connection_closed(struct reusable_connection *closed_connection); extern int connection_destination_matches(const struct reusable_connection *connection, diff --git a/jcc.c b/jcc.c index a98df8ba..db38ba27 100644 --- a/jcc.c +++ b/jcc.c @@ -1,4 +1,4 @@ -const char jcc_rcs[] = "$Id: jcc.c,v 1.247 2009/05/10 10:19:23 fabiankeil Exp $"; +const char jcc_rcs[] = "$Id: jcc.c,v 1.248 2009/05/10 10:25:19 fabiankeil Exp $"; /********************************************************************* * * File : $Source: /cvsroot/ijbswa/current/jcc.c,v $ @@ -33,6 +33,9 @@ const char jcc_rcs[] = "$Id: jcc.c,v 1.247 2009/05/10 10:19:23 fabiankeil Exp $" * * Revisions : * $Log: jcc.c,v $ + * Revision 1.248 2009/05/10 10:25:19 fabiankeil + * Change wait_for_alive_connection() prototype to use (void). + * * Revision 1.247 2009/05/10 10:19:23 fabiankeil * Reenable server-side-only keep-alive support, but only share * outgoing connections if the connection-sharing option is set. @@ -2899,6 +2902,7 @@ static void chat(struct client_state *csp) } #ifdef FEATURE_CONNECTION_KEEP_ALIVE save_connection_destination(csp->sfd, http, fwd, &csp->server_connection); + csp->server_connection.keep_alive_timeout = (unsigned)csp->config->keep_alive_timeout; } #endif /* def FEATURE_CONNECTION_KEEP_ALIVE */ @@ -3536,7 +3540,7 @@ static void serve(struct client_state *csp) csp->sfd, csp->server_connection.host); if ((csp->flags & CSP_FLAG_CLIENT_CONNECTION_KEEP_ALIVE) - && data_is_available(csp->cfd, csp->config->keep_alive_timeout) + && data_is_available(csp->cfd, (int)csp->server_connection.keep_alive_timeout) && socket_is_still_usable(csp->cfd)) { log_error(LOG_LEVEL_CONNECT, "Client request arrived in " @@ -3572,7 +3576,8 @@ static void serve(struct client_state *csp) if ((csp->config->feature_flags & RUNTIME_FEATURE_CONNECTION_SHARING)) { remember_connection(csp->sfd, csp->http, - forward_url(csp, csp->http)); + forward_url(csp, csp->http), + csp->server_connection.keep_alive_timeout); csp->sfd = JB_INVALID_SOCKET; close_socket(csp->cfd); csp->cfd = JB_INVALID_SOCKET; diff --git a/parsers.c b/parsers.c index bef06eaf..a76c0515 100644 --- a/parsers.c +++ b/parsers.c @@ -1,4 +1,4 @@ -const char parsers_rcs[] = "$Id: parsers.c,v 1.154 2009/03/13 14:10:07 fabiankeil Exp $"; +const char parsers_rcs[] = "$Id: parsers.c,v 1.155 2009/05/10 10:12:30 fabiankeil Exp $"; /********************************************************************* * * File : $Source: /cvsroot/ijbswa/current/parsers.c,v $ @@ -44,6 +44,10 @@ const char parsers_rcs[] = "$Id: parsers.c,v 1.154 2009/03/13 14:10:07 fabiankei * * Revisions : * $Log: parsers.c,v $ + * Revision 1.155 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.154 2009/03/13 14:10:07 fabiankeil * Fix some more harmless warnings on amd64. * @@ -986,6 +990,7 @@ static jb_err server_content_disposition(struct client_state *csp, char **header #ifdef FEATURE_CONNECTION_KEEP_ALIVE static jb_err server_save_content_length(struct client_state *csp, char **header); +static jb_err server_keep_alive(struct client_state *csp, char **header); #endif /* def FEATURE_CONNECTION_KEEP_ALIVE */ static jb_err client_host_adder (struct client_state *csp); @@ -1055,6 +1060,7 @@ static const struct parsers server_patterns[] = { { "Content-Encoding:", 17, server_content_encoding }, #ifdef FEATURE_CONNECTION_KEEP_ALIVE { "Content-Length:", 15, server_save_content_length }, + { "Keep-Alive:", 11, server_keep_alive }, #else { "Keep-Alive:", 11, crumble }, #endif /* def FEATURE_CONNECTION_KEEP_ALIVE */ @@ -2432,6 +2438,58 @@ static jb_err server_connection(struct client_state *csp, char **header) return JB_ERR_OK; } + +#ifdef FEATURE_CONNECTION_KEEP_ALIVE +/********************************************************************* + * + * Function : server_keep_alive + * + * Description : Stores the servers keep alive timeout. + * + * Parameters : + * 1 : csp = Current client state (buffers, headers, etc...) + * 2 : header = On input, pointer to header to modify. + * On output, pointer to the modified header, or NULL + * to remove the header. This function frees the + * original string if necessary. + * + * Returns : JB_ERR_OK. + * + *********************************************************************/ +static jb_err server_keep_alive(struct client_state *csp, char **header) +{ + unsigned int keep_alive_timeout; + const char *timeout_position = strstr(*header, "timeout="); + + if ((NULL != timeout_position) + && (1 != sscanf(timeout_position, "timeout=%u", &keep_alive_timeout))) + { + log_error(LOG_LEVEL_ERROR, "Couldn't parse: %s", *header); + } + else + { + if (keep_alive_timeout < csp->server_connection.keep_alive_timeout) + { + log_error(LOG_LEVEL_HEADER, + "Reducing keep-alive timeout from %u to %u.", + csp->server_connection.keep_alive_timeout, keep_alive_timeout); + csp->server_connection.keep_alive_timeout = keep_alive_timeout; + } + else + { + /* XXX: Is this log worthy? */ + log_error(LOG_LEVEL_HEADER, + "Server keep-alive timeout is %u. Sticking with %u.", + keep_alive_timeout, csp->server_connection.keep_alive_timeout); + } + } + + return JB_ERR_OK; +} +#endif /* def FEATURE_CONNECTION_KEEP_ALIVE */ + + + /********************************************************************* * * Function : client_connection diff --git a/project.h b/project.h index 2b0292ae..8b6c4290 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.135 2009/05/10 10:19:23 fabiankeil Exp $" +#define PROJECT_H_VERSION "$Id: project.h,v 1.136 2009/05/13 18:20:54 fabiankeil Exp $" /********************************************************************* * * File : $Source: /cvsroot/ijbswa/current/project.h,v $ @@ -37,6 +37,9 @@ * * Revisions : * $Log: project.h,v $ + * Revision 1.136 2009/05/13 18:20:54 fabiankeil + * There's no reason for keep_alive_timeout to be signed. + * * Revision 1.135 2009/05/10 10:19:23 fabiankeil * Reenable server-side-only keep-alive support, but only share * outgoing connections if the connection-sharing option is set. @@ -1321,6 +1324,11 @@ struct reusable_connection jb_socket sfd; int in_use; time_t timestamp; + /* + * Number of seconds after which this + * connection will no longer be reused. + */ + unsigned int keep_alive_timeout; char *host; int port; @@ -1879,7 +1887,7 @@ struct configuration_spec int socket_timeout; #ifdef FEATURE_CONNECTION_KEEP_ALIVE - /* Number of seconds after which an open connection will no longer be reused. */ + /* Maximum number of seconds after which an open connection will no longer be reused. */ unsigned int keep_alive_timeout; #endif -- 2.39.2