From 0b726872b72563861e88f8e3b85842fc5559f40a Mon Sep 17 00:00:00 2001 From: Hossein Yavari Date: Fri, 27 Feb 2026 10:57:11 -0500 Subject: [PATCH] MT#55283 Add configurable HTTP idle (keepalive) timeout - Add --http-idle-timeout option (seconds; 0 = libwebsockets default, 5s for HTTP/1.1) - Pass keepalive_timeout to libwebsockets when creating HTTP and HTTPS vhosts - Reject negative values; default 0 preserves existing behaviour - Document in docs/rtpengine.md and etc/rtpengine.conf - Extend auto-daemon-tests-http.pl to run with --http-idle-timeout=5 Closes #2077 Change-Id: I134bd08a0b82aa95e8e7c28e75a65ca783cb91d9 --- daemon/main.c | 3 +++ daemon/websocket.c | 2 ++ docs/rtpengine.md | 7 +++++++ etc/rtpengine.conf | 1 + include/main.h | 1 + t/auto-daemon-tests-http.pl | 2 +- 6 files changed, 15 insertions(+), 1 deletion(-) diff --git a/daemon/main.c b/daemon/main.c index f21bb3ec0..a2b3b02ed 100644 --- a/daemon/main.c +++ b/daemon/main.c @@ -820,6 +820,7 @@ static void options(int *argc, char ***argv, charp_ht templates) { #if LWS_LIBRARY_VERSION_MAJOR >= 3 || (LWS_LIBRARY_VERSION_MAJOR == 2 && LWS_LIBRARY_VERSION_MINOR >= 1) { "http-buf-size", 0,0, G_OPTION_ARG_INT, &rtpe_config.http_buf_size,"Send buffer size for HTTP and WS in kB","INT"}, #endif + { "http-idle-timeout", 0,0, G_OPTION_ARG_INT, &rtpe_config.http_keepalive_timeout,"Seconds to allow idle HTTP/HTTPS keepalive (0 = libwebsockets default, 5s for HTTP/1.1)","INT"}, { "software-id", 0,0, G_OPTION_ARG_STRING, &rtpe_config.software_id,"Identification string of this software presented to external systems","STRING"}, { "poller-per-thread", 0,0, G_OPTION_ARG_NONE, &rtpe_config.poller_per_thread, "Use poller per thread", NULL }, { "timer-accuracy", 0,0,G_OPTION_ARG_INT, &rtpe_config.timer_accuracy,"Minimum number of microseconds to sleep","INT"}, @@ -1084,6 +1085,8 @@ static void options(int *argc, char ***argv, charp_ht templates) { if (rtpe_config.http_buf_size >= max_buf_size) die("Option 'http-buf-size' too large (must be <%zu)", max_buf_size); #endif + if (rtpe_config.http_keepalive_timeout < 0) + die("Option 'http-idle-timeout' must be >= 0"); if (graphitep) { if (!endpoint_parse_any_getaddrinfo_full(&rtpe_config.graphite_ep, graphitep)) diff --git a/daemon/websocket.c b/daemon/websocket.c index 2c2267443..72702d962 100644 --- a/daemon/websocket.c +++ b/daemon/websocket.c @@ -1195,6 +1195,7 @@ int websocket_init(void) { .port = ep->port, .iface = g_strdup(sockaddr_print_buf(&ep->address)), .protocols = websocket_protocols, + .keepalive_timeout = rtpe_config.http_keepalive_timeout, #if LWS_LIBRARY_VERSION_MAJOR >= 3 || (LWS_LIBRARY_VERSION_MAJOR == 2 && LWS_LIBRARY_VERSION_MINOR >= 1) .pt_serv_buf_size = wci.pt_serv_buf_size, #endif @@ -1245,6 +1246,7 @@ int websocket_init(void) { .port = ep->port, .iface = g_strdup(sockaddr_print_buf(&ep->address)), .protocols = websocket_protocols, + .keepalive_timeout = rtpe_config.http_keepalive_timeout, .ssl_cert_filepath = rtpe_config.https_cert, .ssl_private_key_filepath = rtpe_config.https_key ? : rtpe_config.https_cert, .options = LWS_SERVER_OPTION_DO_SSL_GLOBAL_INIT, diff --git a/docs/rtpengine.md b/docs/rtpengine.md index 003989102..9916abbd7 100644 --- a/docs/rtpengine.md +++ b/docs/rtpengine.md @@ -1068,6 +1068,13 @@ call to inject-DTMF won't be sent to __\-\-dtmf-log-dest=__ or __\-\-listen-tcp- megabyte) or larger if you experience high WS activity, to improve performance and prevent possible protocol hiccups. +- __\-\-http-idle-timeout=__*INT* + + Seconds to allow idle HTTP/HTTPS keepalive connections before the server + closes them. If zero (the default), the libwebsockets default is used + (5 seconds for HTTP/1.1). Set to a positive value (e.g. 60) to align with + load balancer idle timeouts or to keep connections open longer. + - __\-\-software-id=__*STRING* Sets a free-form string that is used to identify this software towards external diff --git a/etc/rtpengine.conf b/etc/rtpengine.conf index 4c8d37c43..bb020033d 100644 --- a/etc/rtpengine.conf +++ b/etc/rtpengine.conf @@ -50,6 +50,7 @@ tos = 184 # media-num-threads = 8 # http-threads = 4 # http-buf-size = 1024 +# http-idle-timeout = 0 port-min = 30000 port-max = 39999 diff --git a/include/main.h b/include/main.h index d1e0aee24..d6957304d 100644 --- a/include/main.h +++ b/include/main.h @@ -95,6 +95,7 @@ enum endpoint_learning { X(ng_client_timeout) \ X(ng_client_retries) \ X(http_buf_size) \ + X(http_keepalive_timeout) \ #define RTPE_CONFIG_INT64_PARAMS \ X(bw_limit) \ diff --git a/t/auto-daemon-tests-http.pl b/t/auto-daemon-tests-http.pl index 5a1060615..fc4f8e4f9 100644 --- a/t/auto-daemon-tests-http.pl +++ b/t/auto-daemon-tests-http.pl @@ -15,7 +15,7 @@ my $wav_file = "\x52\x49\x46\x46\x64\x06\x00\x00\x57\x41\x56\x45\x66\x6d\x74\x20 $NGCP::Rtpengine::AutoTest::host = 'http://localhost:6666/ng'; autotest_start(qw(--config-file=none -t -1 -i 203.0.113.1 -i 2001:db8:4321::1 - --listen-http=localhost:6666 -f -L 7 -E)) + --listen-http=localhost:6666 --http-idle-timeout=5 -f -L 7 -E)) or die;