cvs commit: jakarta-tomcat-connectors/ajp/proxy proxy_util.c mod_proxy.h
mturk 2004/08/10 06:50:53 Modified:ajp/proxy proxy_util.c mod_proxy.h Log: Shared memory support. The shared memory is inside apache scoreboard. If it ever gets back ported we could use it on 2.0 Revision ChangesPath 1.23 +45 -12jakarta-tomcat-connectors/ajp/proxy/proxy_util.c Index: proxy_util.c === RCS file: /home/cvs/jakarta-tomcat-connectors/ajp/proxy/proxy_util.c,v retrieving revision 1.22 retrieving revision 1.23 diff -u -r1.22 -r1.23 --- proxy_util.c 9 Aug 2004 15:07:20 - 1.22 +++ proxy_util.c 10 Aug 2004 13:50:53 - 1.23 @@ -16,6 +16,7 @@ /* Utility routines for Apache proxy */ #include mod_proxy.h #include ap_mpm.h +#include scoreboard.h #include apr_version.h #if (APR_MAJOR_VERSION 1) @@ -23,6 +24,9 @@ #define apr_socket_create apr_socket_create_ex #endif +/* Global balancer counter */ +static int lb_workers = 0; + static int proxy_match_ipaddr(struct dirconn_entry *This, request_rec *r); static int proxy_match_domainname(struct dirconn_entry *This, request_rec *r); static int proxy_match_hostname(struct dirconn_entry *This, request_rec *r); @@ -1038,7 +1042,7 @@ return can not create thread mutex; } #endif - + return NULL; } @@ -1137,52 +1141,76 @@ } PROXY_DECLARE(void) -ap_proxy_add_worker_to_balancer(proxy_balancer *balancer, proxy_worker *worker) +ap_proxy_add_worker_to_balancer(apr_pool_t *pool, proxy_balancer *balancer, proxy_worker *worker) { int i; double median, ffactor = 0.0; -proxy_runtime_worker *runtime, *workers; +proxy_runtime_worker *runtime, *workers; +#if PROXY_HAS_SCOREBOARD +lb_score *score; +#else +void *score; +#endif +#if PROXY_HAS_SCOREBOARD +int mpm_daemons; + +ap_mpm_query(AP_MPMQ_HARD_LIMIT_DAEMONS, mpm_daemons); +/* Check if we are prefork or single child */ +if (worker-hmax mpm_daemons 1) +score = ap_get_scoreboard_lb(getpid(), lb_workers); +else +#endif +{ +/* Use the plain memory */ +score = apr_pcalloc(pool, sizeof(proxy_runtime_stat)); +} +if (!score) +return; runtime = apr_array_push(balancer-workers); runtime-w = worker; +runtime-s = (proxy_runtime_stat *)score; +runtime-s-id = lb_workers; +/* TODO: deal with the dynamic overflow */ +++lb_workers; /* Recalculate lbfactors */ workers = (proxy_runtime_worker *)balancer-workers-elts; for (i = 0; i balancer-workers-nelts; i++) { /* Set to the original configuration */ -workers[i].lbfactor = workers[i].w-lbfactor; -ffactor += workers[i].lbfactor; +workers[i].s-lbfactor = workers[i].w-lbfactor; +ffactor += workers[i].s-lbfactor; } if (ffactor 100.0) { int z = 0; for (i = 0; i balancer-workers-nelts; i++) { -if (workers[i].lbfactor == 0.0) +if (workers[i].s-lbfactor == 0.0) ++z; } if (z) { median = (100.0 - ffactor) / z; for (i = 0; i balancer-workers-nelts; i++) { -if (workers[i].lbfactor == 0.0) -workers[i].lbfactor = median; +if (workers[i].s-lbfactor == 0.0) +workers[i].s-lbfactor = median; } } else { median = (100.0 - ffactor) / balancer-workers-nelts; for (i = 0; i balancer-workers-nelts; i++) -workers[i].lbfactor += median; +workers[i].s-lbfactor += median; } } else if (ffactor 100.0) { median = (ffactor - 100.0) / balancer-workers-nelts; for (i = 0; i balancer-workers-nelts; i++) { -if (workers[i].lbfactor median) -workers[i].lbfactor -= median; +if (workers[i].s-lbfactor median) +workers[i].s-lbfactor -= median; } } for (i = 0; i balancer-workers-nelts; i++) { /* Update the status entires */ -workers[i].lbstatus = workers[i].lbfactor; +workers[i].s-lbstatus = workers[i].s-lbfactor; } } @@ -1756,4 +1784,9 @@ ap_run_pre_connection(conn-connection, conn-sock); return OK; +} + +PROXY_DECLARE(int) ap_proxy_lb_workers(void) +{ +return (lb_workers + PROXY_DYNAMIC_BALANCER_LIMIT); } 1.29 +25 -4 jakarta-tomcat-connectors/ajp/proxy/mod_proxy.h Index: mod_proxy.h === RCS file: /home/cvs/jakarta-tomcat-connectors/ajp/proxy/mod_proxy.h,v retrieving revision
cvs commit: jakarta-tomcat-connectors/ajp/proxy proxy_util.c mod_proxy.h
mturk 2004/08/05 10:41:16 Modified:ajp/proxy proxy_util.c mod_proxy.h Log: Add ap_proxy_connect_backend that will replace ap_proxy_connect_to_backend. It uses worker params for setting socket options and checks for conection's connect status. It works both on empty and acquired connections. Revision ChangesPath 1.15 +94 -1 jakarta-tomcat-connectors/ajp/proxy/proxy_util.c Index: proxy_util.c === RCS file: /home/cvs/jakarta-tomcat-connectors/ajp/proxy/proxy_util.c,v retrieving revision 1.14 retrieving revision 1.15 diff -u -r1.14 -r1.15 --- proxy_util.c 5 Aug 2004 16:26:02 - 1.14 +++ proxy_util.c 5 Aug 2004 17:41:15 - 1.15 @@ -1242,6 +1242,7 @@ return access_status; } +/* DEPRECATED */ PROXY_DECLARE(int) ap_proxy_connect_to_backend(apr_socket_t **newsock, const char *proxy_function, apr_sockaddr_t *backend_addr, @@ -1536,7 +1537,7 @@ char test_buffer[1]; apr_status_t socket_status; apr_interval_time_t current_timeout; - + /* save timeout */ apr_socket_timeout_get(sock, current_timeout); /* set no timeout */ @@ -1548,4 +1549,96 @@ return 0; else return 1; +} + +PROXY_DECLARE(int) ap_proxy_connect_backend(const char *proxy_function, +proxy_conn_rec *conn, +proxy_worker *worker, +proxy_server_conf *conf, +server_rec *s) +{ +apr_status_t rv; +int connected = 0; +int loglevel; +apr_sockaddr_t *backend_addr = worker-cp-addr; +apr_socket_t *newsock; + +if (conn-sock) { +/* This increases the connection pool size + * but the number of dropped connections is + * relatively small compared to connection lifetime + */ +if (!(connected = is_socket_connected(conn-sock))) { +apr_socket_close(conn-sock); +conn-sock = NULL; +} +} + +while (backend_addr !connected) { +if ((rv = apr_socket_create(newsock, backend_addr-family, +SOCK_STREAM, 0, conn-pool)) != APR_SUCCESS) { +loglevel = backend_addr-next ? APLOG_DEBUG : APLOG_ERR; +ap_log_error(APLOG_MARK, loglevel, rv, s, + proxy: %s: error creating fam %d socket for target %s, + proxy_function, + backend_addr-family, + worker-hostname); +/* this could be an IPv6 address from the DNS but the + * local machine won't give us an IPv6 socket; hopefully the + * DNS returned an additional address to try + */ +backend_addr = backend_addr-next; +continue; +} + +#if !defined(TPF) !defined(BEOS) +if (conf-recv_buffer_size 0 +(rv = apr_socket_opt_set(newsock, APR_SO_RCVBUF, + conf-recv_buffer_size))) { +ap_log_error(APLOG_MARK, APLOG_ERR, rv, s, + apr_socket_opt_set(SO_RCVBUF): Failed to set + ProxyReceiveBufferSize, using default); +} +#endif + +/* Set a timeout on the socket */ +if (worker-timeout_set == 1) { +apr_socket_timeout_set(newsock, worker-timeout); +} +else { + apr_socket_timeout_set(newsock, s-timeout); +} +/* Set a keepalive option */ +if (worker-keepalive) { +if ((rv = apr_socket_opt_set(newsock, +APR_SO_KEEPALIVE, 1)) != APR_SUCCESS) { +ap_log_error(APLOG_MARK, APLOG_ERR, rv, s, + apr_socket_opt_set(SO_KEEPALIVE): Failed to set + Keepalive); +} +} +ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, + proxy: %s: fam %d socket created to connect to %s, + proxy_function, backend_addr-family, worker-hostname); + +/* make the connection out of the socket */ +rv = apr_socket_connect(newsock, backend_addr); + +/* if an error occurred, loop round and try again */ +if (rv != APR_SUCCESS) { +apr_socket_close(newsock); +loglevel = backend_addr-next ? APLOG_DEBUG : APLOG_ERR; +ap_log_error(APLOG_MARK, loglevel, rv, s, + proxy: %s: attempt to connect to %pI (%s) failed, +
cvs commit: jakarta-tomcat-connectors/ajp/proxy proxy_util.c mod_proxy.h
mturk 2004/08/05 11:32:57 Modified:ajp/proxy proxy_util.c mod_proxy.h Log: Added ap_proxy_connection_create function that makes conn_rec for opened connection. It is used bt http(s) and ftp for bounding the backend connection to client connection with the same id's. Revision ChangesPath 1.16 +65 -4 jakarta-tomcat-connectors/ajp/proxy/proxy_util.c Index: proxy_util.c === RCS file: /home/cvs/jakarta-tomcat-connectors/ajp/proxy/proxy_util.c,v retrieving revision 1.15 retrieving revision 1.16 diff -u -r1.15 -r1.16 --- proxy_util.c 5 Aug 2004 17:41:15 - 1.15 +++ proxy_util.c 5 Aug 2004 18:32:57 - 1.16 @@ -1636,9 +1636,70 @@ backend_addr = backend_addr-next; continue; } -conn-sock = newsock; -conn-worker = worker; -connected= 1; + +conn-sock = newsock; +conn-worker = worker; +/* XXX: the hostname will go from proxy_conn_rec + * keep for now. + * We will 'optimize' later, both code and unneeded data + */ +conn-hostname = worker-hostname; +connected = 1; } -return connected ? 0 : 1; +return connected ? OK : DECLINED; +} + +PROXY_DECLARE(int) ap_proxy_connection_create(const char *proxy_function, + proxy_conn_rec *conn, + proxy_server_conf *conf, + conn_rec *c, + server_rec *s) +{ +proxy_worker *worker = conn-worker; +apr_sockaddr_t *backend_addr = worker-cp-addr; + +/* The socket is now open, create a new backend server connection +* +*/ +conn-connection = ap_run_create_connection(c-pool, s, conn-sock, +c-id, c-sbh, +c-bucket_alloc); + +if (!conn-connection) { +/* the peer reset the connection already; ap_run_create_connection() +* closed the socket +*/ +ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, + s, proxy: %s: an error occurred creating a + new connection to %pI (%s), proxy_function, + backend_addr, conn-hostname); +/* XXX: Will be closed when proxy_conn is closed */ +apr_socket_close(conn-sock); +conn-sock = NULL; +return HTTP_INTERNAL_SERVER_ERROR; +} + +/* For ssl connection to backend */ +if (conn-is_ssl) { +if (!ap_proxy_ssl_enable(conn-connection)) { +ap_log_error(APLOG_MARK, APLOG_ERR, 0, + s, proxy: %s: failed to enable ssl support + for %pI (%s), proxy_function, + backend_addr, conn-hostname); +return HTTP_INTERNAL_SERVER_ERROR; +} +} +else { +/* TODO: See if this will break FTP */ +ap_proxy_ssl_disable(conn-connection); +} + +ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, + proxy: %s: connection complete to %pI (%s), + proxy_function, backend_addr, conn-hostname); + +/* set up the connection filters */ +ap_run_pre_connection(conn-connection, conn-sock); + +return OK; } 1.22 +2 -1 jakarta-tomcat-connectors/ajp/proxy/mod_proxy.h Index: mod_proxy.h === RCS file: /home/cvs/jakarta-tomcat-connectors/ajp/proxy/mod_proxy.h,v retrieving revision 1.21 retrieving revision 1.22 diff -u -r1.21 -r1.22 --- mod_proxy.h 5 Aug 2004 17:46:58 - 1.21 +++ mod_proxy.h 5 Aug 2004 18:32:57 - 1.22 @@ -364,7 +364,8 @@ PROXY_DECLARE(apr_status_t) ap_proxy_close_connection(proxy_conn_rec *conn); PROXY_DECLARE(int) ap_proxy_connect_backend(const char *proxy_function, proxy_conn_rec *conn, proxy_worker *worker, proxy_server_conf *conf, server_rec *s); - +PROXY_DECLARE(int) ap_proxy_connection_create(const char *proxy_function, proxy_conn_rec *conn, + proxy_server_conf *conf, conn_rec *c, server_rec *s); /* For proxy_util */ extern module PROXY_DECLARE_DATA proxy_module; - To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]
cvs commit: jakarta-tomcat-connectors/ajp/proxy proxy_util.c mod_proxy.h
mturk 2004/08/05 12:09:13 Modified:ajp/proxy proxy_util.c mod_proxy.h Log: Added acquire and release connection functions. The acquire pulls the connection from the pool. The release returns the connection to the pool. Revision ChangesPath 1.17 +66 -54jakarta-tomcat-connectors/ajp/proxy/proxy_util.c Index: proxy_util.c === RCS file: /home/cvs/jakarta-tomcat-connectors/ajp/proxy/proxy_util.c,v retrieving revision 1.16 retrieving revision 1.17 diff -u -r1.16 -r1.17 --- proxy_util.c 5 Aug 2004 18:32:57 - 1.16 +++ proxy_util.c 5 Aug 2004 19:09:13 - 1.17 @@ -1366,83 +1366,102 @@ return APR_SUCCESS; } -/* Destroy the connection */ -PROXY_DECLARE(apr_status_t) ap_proxy_destroy_connection(proxy_conn_rec *conn) -{ -return connection_destructor(conn, NULL, NULL); -} - -/* Destroy the connection */ +/* Close the connection + * The proxy_conn_rec from now on can not be used + */ PROXY_DECLARE(apr_status_t) ap_proxy_close_connection(proxy_conn_rec *conn) { -apr_status_t rv = APR_EOF; -/* Close the socket */ -if (conn-sock) -rv = apr_socket_close(conn-sock); -conn-sock = NULL; -return rv; +if (conn-worker conn-worker-cp) +conn-worker-cp-conn = NULL; +return connection_destructor(conn, NULL, NULL); } -/* low level connection acquire/release functions - * they are hiding apr_reslist for nothreaded or prefork servers. - */ -static apr_status_t acquire_connection_low(proxy_conn_rec **conn, proxy_worker *worker) +static apr_status_t init_conn_worker(proxy_worker *worker, server_rec *s) { apr_status_t rv; #if APR_HAS_THREADS if (worker-hmax) { -rv = apr_reslist_acquire(worker-cp-res, (void **)conn); +rv = apr_reslist_create((worker-cp-res), +worker-min, worker-smax, +worker-hmax, worker-ttl, +connection_constructor, connection_destructor, +s, worker-cp-pool); +#if (APR_MAJOR_VERSION 0) +/* Set the acquire timeout */ +if (rv == APR_SUCCESS worker-acquire_set) +apr_reslist_timeout_set(worker-cp-res, worker-acquire); +#endif } else #endif { -*conn = worker-cp-conn; -worker-cp-conn = NULL; + +connection_constructor((void **)(worker-cp-conn), s, worker-cp-pool); rv = APR_SUCCESS; } return rv; } -static apr_status_t release_connection_low(proxy_conn_rec *conn, proxy_worker *worker) +PROXY_DECLARE(int) ap_proxy_acquire_connection(const char *proxy_function, + proxy_conn_rec **conn, + proxy_worker *worker, + server_rec *s) { -apr_status_t rv = APR_SUCCESS; +apr_status_t rv; #if APR_HAS_THREADS if (worker-hmax) { -rv = apr_reslist_release(worker-cp-res, (void *)conn); +rv = apr_reslist_acquire(worker-cp-res, (void **)conn); } else #endif { -worker-cp-conn = conn; +/* create the new connection if the previous was destroyed */ +if (!worker-cp-conn) +connection_constructor((void **)conn, s, worker-cp-pool); +else { +*conn = worker-cp-conn; +worker-cp-conn = NULL; +} +rv = APR_SUCCESS; } -return rv; -} +if (rv != APR_SUCCESS) { +ap_log_error(APLOG_MARK, APLOG_ERR, rv, s, + proxy: %s: failed to acquire connection for (%s), + proxy_function, worker-hostname); +return DECLINED; +} +return OK; +} -static apr_status_t init_conn_worker(proxy_worker *worker, server_rec *s) +PROXY_DECLARE(int) ap_proxy_release_connection(const char *proxy_function, + proxy_conn_rec *conn, + server_rec *s) { -apr_status_t rv; +apr_status_t rv = APR_SUCCESS; +proxy_worker *worker = conn-worker; + +if (!worker) { +/* something bad happened. Obviously bug. + * for now make a core dump. + */ +} #if APR_HAS_THREADS if (worker-hmax) { -rv = apr_reslist_create((worker-cp-res), -worker-min, worker-smax, -worker-hmax, worker-ttl, -connection_constructor, connection_destructor, -s, worker-cp-pool); -#if (APR_MAJOR_VERSION 0) -/* Set the
cvs commit: jakarta-tomcat-connectors/ajp/proxy proxy_util.c mod_proxy.h
mturk 2004/08/05 22:42:14 Modified:ajp/proxy proxy_util.c mod_proxy.h Log: Added close_on_recycle flags for creatin connections. This flag enables to distinguish between connection types. Also added a pool cleanup bound to connection pool that recycles the connection when client disconnects from server. Revision ChangesPath 1.18 +36 -1 jakarta-tomcat-connectors/ajp/proxy/proxy_util.c Index: proxy_util.c === RCS file: /home/cvs/jakarta-tomcat-connectors/ajp/proxy/proxy_util.c,v retrieving revision 1.17 retrieving revision 1.18 diff -u -r1.17 -r1.18 --- proxy_util.c 5 Aug 2004 19:09:13 - 1.17 +++ proxy_util.c 6 Aug 2004 05:42:14 - 1.18 @@ -1324,6 +1324,22 @@ return APR_SUCCESS; } +static apr_status_t connection_cleanup(void *theconn) +{ +proxy_conn_rec *conn = (proxy_conn_rec *)theconn; +/* deterimine if the connection need to be closed */ +if (conn-close_on_recycle) { +if (conn-sock) +apr_socket_close(conn-sock); +conn-sock = NULL; + +} +conn-connection = NULL; +ap_proxy_release_connection(NULL, conn, NULL); +/* Allways return the SUCCESS */ +return APR_SUCCESS; +} + /* reslist constructor */ static apr_status_t connection_constructor(void **resource, void *params, apr_pool_t *pool) @@ -1446,6 +1462,17 @@ * for now make a core dump. */ } + +/* Need to close the connection */ +if (conn-sock conn-close) { +apr_socket_close(conn-sock); +conn-sock = NULL; +} +conn-close = 0; +/* If there is a connection kill it's cleanup */ +if (conn-connection) +apr_pool_cleanup_kill(conn-connection-pool, conn, connection_cleanup); + #if APR_HAS_THREADS if (worker-hmax) { rv = apr_reslist_release(worker-cp-res, (void *)conn); @@ -1455,7 +1482,7 @@ { worker-cp-conn = conn; } -if (rv != APR_SUCCESS) { +if (rv != APR_SUCCESS proxy_function) { ap_log_error(APLOG_MARK, APLOG_ERR, rv, s, proxy: %s: failed to acquire connection for (%s), proxy_function, conn-hostname); @@ -1664,6 +1691,7 @@ PROXY_DECLARE(int) ap_proxy_connection_create(const char *proxy_function, proxy_conn_rec *conn, + int close_on_recycle, conn_rec *c, server_rec *s) { @@ -1705,6 +1733,7 @@ /* TODO: See if this will break FTP */ ap_proxy_ssl_disable(conn-connection); } +conn-close_on_recycle = close_on_recycle; ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, proxy: %s: connection complete to %pI (%s), @@ -1712,6 +1741,12 @@ /* set up the connection filters */ ap_run_pre_connection(conn-connection, conn-sock); + +/* register the connection cleanup to client connection + * so that the connection can be closed or reused + */ +apr_pool_cleanup_register(c-pool, (void *)conn, connection_cleanup, + apr_pool_cleanup_null); return OK; } 1.24 +2 -1 jakarta-tomcat-connectors/ajp/proxy/mod_proxy.h Index: mod_proxy.h === RCS file: /home/cvs/jakarta-tomcat-connectors/ajp/proxy/mod_proxy.h,v retrieving revision 1.23 retrieving revision 1.24 diff -u -r1.23 -r1.24 --- mod_proxy.h 5 Aug 2004 19:09:13 - 1.23 +++ mod_proxy.h 6 Aug 2004 05:42:14 - 1.24 @@ -192,6 +192,7 @@ apr_socket_t *sock; /* Connection socket */ apr_uint32_t flags; /* Conection flags */ int close; /* Close 'this' connection */ +int close_on_recycle; /* Close the connection when returning to pool */ proxy_worker *worker; /* Connection pool this connection belogns to */ void *data; /* per scheme connection data */ } proxy_conn_rec; @@ -364,7 +365,7 @@ PROXY_DECLARE(int) ap_proxy_release_connection(const char *proxy_function, proxy_conn_rec *conn, server_rec *s); PROXY_DECLARE(apr_status_t) ap_proxy_close_connection(proxy_conn_rec *conn); PROXY_DECLARE(int) ap_proxy_connect_backend(const char *proxy_function, proxy_conn_rec *conn, proxy_worker *worker, server_rec *s); -PROXY_DECLARE(int) ap_proxy_connection_create(const char *proxy_function, proxy_conn_rec *conn, conn_rec *c, server_rec *s); +PROXY_DECLARE(int) ap_proxy_connection_create(const char *proxy_function, proxy_conn_rec