From: Ondřej Kuzník Date: Tue, 16 Dec 2025 17:09:41 +0000 (+0000) Subject: ITS#10415 Add sockbuf_max_pending_client X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=03005f10b7eb5f735f51997c6991c9786310f3ea;p=thirdparty%2Fopenldap.git ITS#10415 Add sockbuf_max_pending_client --- diff --git a/doc/man/man5/lloadd.conf.5 b/doc/man/man5/lloadd.conf.5 index d5bd14cbbb..4c0a3d7885 100644 --- a/doc/man/man5/lloadd.conf.5 +++ b/doc/man/man5/lloadd.conf.5 @@ -331,6 +331,10 @@ Specify the maximum LDAP PDU size accepted coming from upstream connections. The default is 4194303. .TP +.B sockbuf_max_pending_client +Specify the maximum amount of data we can store toward a client connection. +The default is 0, with no limit on the data being buffered. +.TP .B tcp-buffer [listener=] [{read|write}=] Specify the size of the TCP buffer. A global value for both read and write TCP buffers related to any listener diff --git a/servers/lloadd/config.c b/servers/lloadd/config.c index eb41d9d7f9..3b557aaf45 100644 --- a/servers/lloadd/config.c +++ b/servers/lloadd/config.c @@ -82,6 +82,7 @@ int lload_write_coherence = 0; ber_len_t sockbuf_max_incoming_client = LLOAD_SB_MAX_INCOMING_CLIENT; ber_len_t sockbuf_max_incoming_upstream = LLOAD_SB_MAX_INCOMING_UPSTREAM; +ber_len_t sockbuf_max_pending_client = 0; int lload_conn_max_pdus_per_cycle = LLOAD_CONN_MAX_PDUS_PER_CYCLE_DEFAULT; @@ -155,6 +156,7 @@ enum { CFG_IOTHREADS, CFG_MAXBUF_CLIENT, CFG_MAXBUF_UPSTREAM, + CFG_MAXBUF_PENDING, CFG_FEATURE, CFG_THREADQS, CFG_TLS_ECNAME, @@ -340,6 +342,18 @@ static ConfigTable config_back_cf_table[] = { NULL, { .v_ber_t = LLOAD_SB_MAX_INCOMING_UPSTREAM } }, + { "sockbuf_max_pending_client", "max", 2, 2, 0, + ARG_BER_LEN_T|ARG_MAGIC|CFG_MAXBUF_PENDING, + &config_generic, + "( OLcfgBkAt:41.1 " + "NAME 'olcBkLloadSockbufMaxPendingClient' " + "DESC 'The maximum amount of buffer space available per connection' " + "EQUALITY integerMatch " + "SYNTAX OMsInteger " + "SINGLE-VALUE )", + NULL, + { .v_ber_t = 0 } + }, { "tcp-buffer", "[listener=] [{read|write}=]size", 0, 0, 0, #ifdef LDAP_TCP_BUFFER ARG_MAGIC, @@ -824,6 +838,7 @@ static ConfigOCs lloadocs[] = { "$ olcBkLloadRestrictExop " "$ olcBkLloadRestrictControl " "$ olcBkLloadListen " + "$ olcBkLloadSockbufMaxPendingClient " ") )", Cft_Backend, config_back_cf_table, NULL, @@ -894,6 +909,9 @@ config_generic( ConfigArgs *c ) case CFG_MAXBUF_UPSTREAM: c->value_uint = sockbuf_max_incoming_upstream; break; + case CFG_MAXBUF_PENDING: + c->value_uint = sockbuf_max_pending_client; + break; case CFG_RESCOUNT: c->value_uint = lload_conn_max_pdus_per_cycle; break; @@ -1097,6 +1115,9 @@ config_generic( ConfigArgs *c ) case CFG_MAXBUF_UPSTREAM: sockbuf_max_incoming_upstream = c->value_uint; break; + case CFG_MAXBUF_PENDING: + sockbuf_max_pending_client = c->value_uint; + break; case CFG_CLIENT_PENDING: lload_client_max_pending = c->value_uint; break; diff --git a/servers/lloadd/proto-lload.h b/servers/lloadd/proto-lload.h index 2887021b01..52d1656a02 100644 --- a/servers/lloadd/proto-lload.h +++ b/servers/lloadd/proto-lload.h @@ -236,6 +236,7 @@ LDAP_SLAPD_F (void) upstream_destroy( LloadConnection *c ); LDAP_SLAPD_V (ber_len_t) sockbuf_max_incoming_client; LDAP_SLAPD_V (ber_len_t) sockbuf_max_incoming_upstream; +LDAP_SLAPD_V (ber_len_t) sockbuf_max_pending_client; LDAP_SLAPD_V (int) lload_conn_max_pdus_per_cycle; LDAP_SLAPD_V (int) lload_write_coherence; diff --git a/servers/lloadd/upstream.c b/servers/lloadd/upstream.c index 41e529e129..af03a357aa 100644 --- a/servers/lloadd/upstream.c +++ b/servers/lloadd/upstream.c @@ -22,6 +22,7 @@ #include #include "lload.h" +#include "../../libraries/liblber/lber-int.h" /* get ber_ptrlen() */ #include "lutil.h" #include "lutil_ldap.h" @@ -90,6 +91,12 @@ forward_response( LloadConnection *client, LloadOperation *op, BerElement *ber ) checked_lock( &client->c_io_mutex ); output = client->c_pendingber; + if ( sockbuf_max_pending_client && output && + ber_ptrlen( output ) >= sockbuf_max_pending_client ) { + ber_free( ber, 1 ); + checked_unlock( &client->c_io_mutex ); + return -1; + } if ( output == NULL && (output = ber_alloc()) == NULL ) { ber_free( ber, 1 ); checked_unlock( &client->c_io_mutex );