# HG changeset patch # User Piotr Sikora <pi...@aviatrix.com> # Date 1708977618 0 # Mon Feb 26 20:00:18 2024 +0000 # Branch patch003 # Node ID 8edb4003177dac56301aed7f86f8d2a564b47552 # Parent f8d9fb94eab212f6e640b7a68ed111562e3157d5 Upstream: cleanup at shutdown.
Add "free_upstream" callback called on worker exit to free any per-upstream objects allocated from the heap. Found with LeakSanitizer. Signed-off-by: Piotr Sikora <pi...@aviatrix.com> diff -r f8d9fb94eab2 -r 8edb4003177d src/http/modules/ngx_http_upstream_random_module.c --- a/src/http/modules/ngx_http_upstream_random_module.c Mon Feb 26 20:00:16 2024 +0000 +++ b/src/http/modules/ngx_http_upstream_random_module.c Mon Feb 26 20:00:18 2024 +0000 @@ -114,6 +114,35 @@ } +static void +ngx_http_upstream_free_random(ngx_http_upstream_srv_conf_t *us) +{ +#if (NGX_HTTP_UPSTREAM_ZONE) + + ngx_http_upstream_rr_peers_t *peers; + ngx_http_upstream_random_srv_conf_t *rcf; + + peers = us->peer.data; + + if (peers->shpool) { + + rcf = ngx_http_conf_upstream_srv_conf(us, + ngx_http_upstream_random_module); + + if (rcf->ranges) { + ngx_log_debug1(NGX_LOG_DEBUG_HTTP, ngx_cycle->log, 0, + "free ranges: %p", rcf->ranges); + ngx_free(rcf->ranges); + rcf->ranges = NULL; + } + } + +#endif + + ngx_http_upstream_free_round_robin(us); +} + + static ngx_int_t ngx_http_upstream_update_random(ngx_pool_t *pool, ngx_http_upstream_srv_conf_t *us) @@ -465,6 +494,7 @@ } uscf->peer.init_upstream = ngx_http_upstream_init_random; + uscf->peer.free_upstream = ngx_http_upstream_free_random; uscf->flags = NGX_HTTP_UPSTREAM_CREATE |NGX_HTTP_UPSTREAM_WEIGHT diff -r f8d9fb94eab2 -r 8edb4003177d src/http/ngx_http_upstream.c --- a/src/http/ngx_http_upstream.c Mon Feb 26 20:00:16 2024 +0000 +++ b/src/http/ngx_http_upstream.c Mon Feb 26 20:00:18 2024 +0000 @@ -189,6 +189,8 @@ ngx_http_upstream_t *u, ngx_connection_t *c); #endif +static void ngx_http_upstream_worker_cleanup(ngx_cycle_t *cycle); + static ngx_http_upstream_header_t ngx_http_upstream_headers_in[] = { @@ -368,7 +370,7 @@ NULL, /* init process */ NULL, /* init thread */ NULL, /* exit thread */ - NULL, /* exit process */ + ngx_http_upstream_worker_cleanup, /* exit process */ NULL, /* exit master */ NGX_MODULE_V1_PADDING }; @@ -6829,3 +6831,29 @@ return NGX_CONF_OK; } + + +static void +ngx_http_upstream_worker_cleanup(ngx_cycle_t *cycle) +{ + ngx_uint_t i; + ngx_http_upstream_free_pt free; + ngx_http_upstream_srv_conf_t **uscfp; + ngx_http_upstream_main_conf_t *umcf; + + umcf = ngx_http_cycle_get_module_main_conf(cycle, ngx_http_upstream_module); + + if (umcf) { + + uscfp = umcf->upstreams.elts; + + for (i = 0; i < umcf->upstreams.nelts; i++) { + + free = uscfp[i]->peer.free_upstream + ? uscfp[i]->peer.free_upstream + : ngx_http_upstream_free_round_robin; + + free(uscfp[i]); + } + } +} diff -r f8d9fb94eab2 -r 8edb4003177d src/http/ngx_http_upstream.h --- a/src/http/ngx_http_upstream.h Mon Feb 26 20:00:16 2024 +0000 +++ b/src/http/ngx_http_upstream.h Mon Feb 26 20:00:18 2024 +0000 @@ -82,11 +82,13 @@ ngx_http_upstream_srv_conf_t *us); typedef ngx_int_t (*ngx_http_upstream_init_peer_pt)(ngx_http_request_t *r, ngx_http_upstream_srv_conf_t *us); +typedef void (*ngx_http_upstream_free_pt)(ngx_http_upstream_srv_conf_t *us); typedef struct { ngx_http_upstream_init_pt init_upstream; ngx_http_upstream_init_peer_pt init; + ngx_http_upstream_free_pt free_upstream; void *data; } ngx_http_upstream_peer_t; diff -r f8d9fb94eab2 -r 8edb4003177d src/http/ngx_http_upstream_round_robin.c --- a/src/http/ngx_http_upstream_round_robin.c Mon Feb 26 20:00:16 2024 +0000 +++ b/src/http/ngx_http_upstream_round_robin.c Mon Feb 26 20:00:18 2024 +0000 @@ -851,3 +851,34 @@ } #endif + + +void +ngx_http_upstream_free_round_robin(ngx_http_upstream_srv_conf_t *us) +{ +#if (NGX_HTTP_SSL) + + ngx_uint_t i; + ngx_http_upstream_rr_peer_t *peer; + ngx_http_upstream_rr_peers_t *peers; + + peers = us->peer.data; + +#if (NGX_HTTP_UPSTREAM_ZONE) + if (peers->shpool) { + return; + } +#endif + + for (peer = peers->peer, i = 0; peer; peer = peer->next, i++) { + + if (peer->ssl_session) { + ngx_log_debug1(NGX_LOG_DEBUG_HTTP, ngx_cycle->log, 0, + "free session: %p", peer->ssl_session); + ngx_ssl_free_session(peer->ssl_session); + peer->ssl_session = NULL; + } + } + +#endif +} diff -r f8d9fb94eab2 -r 8edb4003177d src/http/ngx_http_upstream_round_robin.h --- a/src/http/ngx_http_upstream_round_robin.h Mon Feb 26 20:00:16 2024 +0000 +++ b/src/http/ngx_http_upstream_round_robin.h Mon Feb 26 20:00:18 2024 +0000 @@ -144,6 +144,7 @@ void *data); void ngx_http_upstream_free_round_robin_peer(ngx_peer_connection_t *pc, void *data, ngx_uint_t state); +void ngx_http_upstream_free_round_robin(ngx_http_upstream_srv_conf_t *us); #if (NGX_HTTP_SSL) ngx_int_t diff -r f8d9fb94eab2 -r 8edb4003177d src/stream/ngx_stream_upstream.c --- a/src/stream/ngx_stream_upstream.c Mon Feb 26 20:00:16 2024 +0000 +++ b/src/stream/ngx_stream_upstream.c Mon Feb 26 20:00:18 2024 +0000 @@ -25,6 +25,8 @@ static void *ngx_stream_upstream_create_main_conf(ngx_conf_t *cf); static char *ngx_stream_upstream_init_main_conf(ngx_conf_t *cf, void *conf); +static void ngx_stream_upstream_worker_cleanup(ngx_cycle_t *cycle); + static ngx_command_t ngx_stream_upstream_commands[] = { @@ -68,7 +70,7 @@ NULL, /* init process */ NULL, /* init thread */ NULL, /* exit thread */ - NULL, /* exit process */ + ngx_stream_upstream_worker_cleanup, /* exit process */ NULL, /* exit master */ NGX_MODULE_V1_PADDING }; @@ -713,3 +715,30 @@ return NGX_CONF_OK; } + + +static void +ngx_stream_upstream_worker_cleanup(ngx_cycle_t *cycle) +{ + ngx_uint_t i; + ngx_stream_upstream_free_pt free; + ngx_stream_upstream_srv_conf_t **uscfp; + ngx_stream_upstream_main_conf_t *umcf; + + umcf = ngx_stream_cycle_get_module_main_conf(cycle, + ngx_stream_upstream_module); + + if (umcf) { + + uscfp = umcf->upstreams.elts; + + for (i = 0; i < umcf->upstreams.nelts; i++) { + + free = uscfp[i]->peer.free_upstream + ? uscfp[i]->peer.free_upstream + : ngx_stream_upstream_free_round_robin; + + free(uscfp[i]); + } + } +} diff -r f8d9fb94eab2 -r 8edb4003177d src/stream/ngx_stream_upstream.h --- a/src/stream/ngx_stream_upstream.h Mon Feb 26 20:00:16 2024 +0000 +++ b/src/stream/ngx_stream_upstream.h Mon Feb 26 20:00:18 2024 +0000 @@ -40,11 +40,13 @@ ngx_stream_upstream_srv_conf_t *us); typedef ngx_int_t (*ngx_stream_upstream_init_peer_pt)(ngx_stream_session_t *s, ngx_stream_upstream_srv_conf_t *us); +typedef void (*ngx_stream_upstream_free_pt)(ngx_stream_upstream_srv_conf_t *us); typedef struct { ngx_stream_upstream_init_pt init_upstream; ngx_stream_upstream_init_peer_pt init; + ngx_stream_upstream_free_pt free_upstream; void *data; } ngx_stream_upstream_peer_t; diff -r f8d9fb94eab2 -r 8edb4003177d src/stream/ngx_stream_upstream_random_module.c --- a/src/stream/ngx_stream_upstream_random_module.c Mon Feb 26 20:00:16 2024 +0000 +++ b/src/stream/ngx_stream_upstream_random_module.c Mon Feb 26 20:00:18 2024 +0000 @@ -112,6 +112,35 @@ } +static void +ngx_stream_upstream_free_random(ngx_stream_upstream_srv_conf_t *us) +{ +#if (NGX_STREAM_UPSTREAM_ZONE) + + ngx_stream_upstream_rr_peers_t *peers; + ngx_stream_upstream_random_srv_conf_t *rcf; + + peers = us->peer.data; + + if (peers->shpool) { + + rcf = ngx_stream_conf_upstream_srv_conf(us, + ngx_stream_upstream_random_module); + + if (rcf->ranges) { + ngx_log_debug1(NGX_LOG_DEBUG_STREAM, ngx_cycle->log, 0, + "free ranges: %p", rcf->ranges); + ngx_free(rcf->ranges); + rcf->ranges = NULL; + } + } + +#endif + + ngx_stream_upstream_free_round_robin(us); +} + + static ngx_int_t ngx_stream_upstream_update_random(ngx_pool_t *pool, ngx_stream_upstream_srv_conf_t *us) @@ -465,6 +494,7 @@ } uscf->peer.init_upstream = ngx_stream_upstream_init_random; + uscf->peer.free_upstream = ngx_stream_upstream_free_random; uscf->flags = NGX_STREAM_UPSTREAM_CREATE |NGX_STREAM_UPSTREAM_WEIGHT diff -r f8d9fb94eab2 -r 8edb4003177d src/stream/ngx_stream_upstream_round_robin.c --- a/src/stream/ngx_stream_upstream_round_robin.c Mon Feb 26 20:00:16 2024 +0000 +++ b/src/stream/ngx_stream_upstream_round_robin.c Mon Feb 26 20:00:18 2024 +0000 @@ -883,3 +883,34 @@ } #endif + + +void +ngx_stream_upstream_free_round_robin(ngx_stream_upstream_srv_conf_t *us) +{ +#if (NGX_STREAM_SSL) + + ngx_uint_t i; + ngx_stream_upstream_rr_peer_t *peer; + ngx_stream_upstream_rr_peers_t *peers; + + peers = us->peer.data; + +#if (NGX_STREAM_UPSTREAM_ZONE) + if (peers->shpool) { + return; + } +#endif + + for (peer = peers->peer, i = 0; peer; peer = peer->next, i++) { + + if (peer->ssl_session) { + ngx_log_debug1(NGX_LOG_DEBUG_STREAM, ngx_cycle->log, 0, + "free session: %p", peer->ssl_session); + ngx_ssl_free_session(peer->ssl_session); + peer->ssl_session = NULL; + } + } + +#endif +} diff -r f8d9fb94eab2 -r 8edb4003177d src/stream/ngx_stream_upstream_round_robin.h --- a/src/stream/ngx_stream_upstream_round_robin.h Mon Feb 26 20:00:16 2024 +0000 +++ b/src/stream/ngx_stream_upstream_round_robin.h Mon Feb 26 20:00:18 2024 +0000 @@ -142,6 +142,7 @@ void *data); void ngx_stream_upstream_free_round_robin_peer(ngx_peer_connection_t *pc, void *data, ngx_uint_t state); +void ngx_stream_upstream_free_round_robin(ngx_stream_upstream_srv_conf_t *us); #endif /* _NGX_STREAM_UPSTREAM_ROUND_ROBIN_H_INCLUDED_ */ _______________________________________________ nginx-devel mailing list nginx-devel@nginx.org https://mailman.nginx.org/mailman/listinfo/nginx-devel