# HG changeset patch
# User Piotr Sikora <piotr@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 <piotr@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