Merge branch 'master' into 'main'

Add a limit for pending messages to a single service

See merge request dbus/dbus!456
This commit is contained in:
Marek Maślanka 2025-09-26 14:53:54 +00:00
commit fdb40bff37
11 changed files with 57 additions and 4 deletions

View file

@ -1513,6 +1513,12 @@ bus_context_get_max_replies_per_connection (BusContext *context)
return context->limits.max_replies_per_connection;
}
int
bus_context_get_max_messages_for_service_per_connection (BusContext *context)
{
return context->limits.max_messages_for_service_per_connection;
}
int
bus_context_get_reply_timeout (BusContext *context)
{

View file

@ -67,6 +67,7 @@ typedef struct
int max_services_per_connection; /**< Max number of owned services for a single connection */
int max_match_rules_per_connection; /**< Max number of match rules for a single connection */
int max_replies_per_connection; /**< Max number of replies that can be pending for each connection */
int max_messages_for_service_per_connection; /**< Max number of messages that can be pending for a single service per connection */
int reply_timeout; /**< How long to wait before timing out a reply */
int max_containers; /**< Max number of restricted servers for app-containers */
int max_containers_per_user; /**< Max number of restricted servers for app-containers, per user */
@ -129,6 +130,8 @@ int bus_context_get_max_pending_activations (BusContext
int bus_context_get_max_services_per_connection (BusContext *context);
int bus_context_get_max_match_rules_per_connection (BusContext *context);
int bus_context_get_max_replies_per_connection (BusContext *context);
int bus_context_get_max_messages_for_service_per_connection
(BusContext *context);
int bus_context_get_reply_timeout (BusContext *context);
int bus_context_get_max_containers (BusContext *context);
int bus_context_get_max_containers_per_user (BusContext *context);

View file

@ -554,6 +554,12 @@ bus_config_parser_new (const DBusString *basedir,
* that require a reply
*/
parser->limits.max_replies_per_connection = 128;
/* Limit the maximum number of pending messages for a single service
* per connection. The default is half the pending replies limit for
* the connection.
*/
parser->limits.max_messages_for_service_per_connection = 64;
}
parser->refcount = 1;
@ -2189,6 +2195,12 @@ set_limit (BusConfigParser *parser,
must_be_int = TRUE;
parser->limits.max_replies_per_connection = value;
}
else if (strcmp (name, "max_messages_for_service_per_connection") == 0)
{
must_be_positive = TRUE;
must_be_int = TRUE;
parser->limits.max_messages_for_service_per_connection = value;
}
else if (strcmp (name, "max_containers") == 0)
{
must_be_positive = TRUE;
@ -3496,6 +3508,7 @@ limits_equal (const BusLimits *a,
&& a->max_services_per_connection == b->max_services_per_connection
&& a->max_match_rules_per_connection == b->max_match_rules_per_connection
&& a->max_replies_per_connection == b->max_replies_per_connection
&& a->max_messages_for_service_per_connection == b->max_messages_for_service_per_connection
&& a->reply_timeout == b->reply_timeout);
}

View file

@ -1960,7 +1960,8 @@ bus_connections_expect_reply (BusConnections *connections,
dbus_uint32_t reply_serial;
DBusList *link;
CancelPendingReplyData *cprd;
int count;
int wait_for_replies_count;
int service_outgoing_msg_count;
int limit;
_dbus_assert (will_get_reply != NULL);
@ -1973,7 +1974,8 @@ bus_connections_expect_reply (BusConnections *connections,
reply_serial = dbus_message_get_serial (reply_to_this);
link = bus_expire_list_get_first_link (connections->pending_replies);
count = 0;
wait_for_replies_count = 0;
service_outgoing_msg_count = 0;
while (link != NULL)
{
pending = link->data;
@ -1990,12 +1992,31 @@ bus_connections_expect_reply (BusConnections *connections,
link = bus_expire_list_get_next_link (connections->pending_replies,
link);
if (pending->will_get_reply == will_get_reply)
++count;
++wait_for_replies_count;
if (pending->will_send_reply == will_send_reply)
++service_outgoing_msg_count;
}
limit = bus_context_get_max_messages_for_service_per_connection (connections->context);
if (service_outgoing_msg_count >= limit)
{
bus_context_log (connections->context, DBUS_SYSTEM_LOG_WARNING,
"the maximum number of pending messages for "
"\"%s\" (%s) has been reached "
"(max_messages_for_service_per_connection=%d)",
bus_connection_get_name (will_send_reply),
bus_connection_get_loginfo (will_send_reply),
limit);
dbus_set_error (error, DBUS_ERROR_LIMITS_EXCEEDED,
"the maximum number of pending messages for service per connection has been reached");
return FALSE;
}
limit = bus_context_get_max_replies_per_connection (connections->context);
if (count >= limit)
if (wait_for_replies_count >= limit)
{
bus_context_log (connections->context, DBUS_SYSTEM_LOG_WARNING,
"The maximum number of pending replies for "

View file

@ -76,5 +76,6 @@
<limit name="max_names_per_connection">50000</limit>
<limit name="max_match_rules_per_connection">50000</limit>
<limit name="max_replies_per_connection">50000</limit>
<limit name="max_messages_for_service_per_connection">25000</limit>
</busconfig>

View file

@ -126,6 +126,7 @@
<!-- <limit name="max_names_per_connection">512</limit> -->
<!-- <limit name="max_match_rules_per_connection">512</limit> -->
<!-- <limit name="max_replies_per_connection">128</limit> -->
<!-- <limit name="max_messages_for_service_per_connection">64</limit> -->
<!-- Config files are placed here that among other things, punch
holes in the above policy for specific services. -->

View file

@ -854,6 +854,9 @@ Available limit names are:</para>
"max_replies_per_connection" : max number of pending method
replies per connection
(number of calls-in-progress)
"max_messages_for_service_per_connection": max number of pending method
calls for a single service per
connection.
"reply_timeout" : milliseconds (thousandths)
until a method call times out
</literallayout> <!-- .fi -->

View file

@ -84,6 +84,7 @@
<limit name="max_names_per_connection">50000</limit>
<limit name="max_match_rules_per_connection">50000</limit>
<limit name="max_replies_per_connection">50000</limit>
<limit name="max_messages_for_service_per_connection">25000</limit>
<limit name="reply_timeout">300000</limit>
</busconfig>

View file

@ -18,4 +18,5 @@
<!-- Avoid reaching this limit -->
<limit name="max_replies_per_connection">1000000</limit>
<limit name="max_messages_for_service_per_connection">500000</limit>
</busconfig>

View file

@ -15,4 +15,6 @@
</policy>
<limit name="max_replies_per_connection">3</limit>
<!-- Ensure that the limit for sending messages to a single service is not reached -->
<limit name="max_messages_for_service_per_connection">10000</limit>
</busconfig>

View file

@ -57,4 +57,5 @@
<limit name="max_names_per_connection">50000</limit>
<limit name="max_match_rules_per_connection">50000</limit>
<limit name="max_replies_per_connection">50000</limit>
<limit name="max_messages_for_service_per_connection">25000</limit>
</busconfig>