summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHavoc Pennington <hp@redhat.com>2003-04-19 16:16:24 +0000
committerHavoc Pennington <hp@redhat.com>2003-04-19 16:16:24 +0000
commit983200f912f41ba75a873c011bfbcd3b0285bf4c (patch)
tree794516f892061dbbcfb036110d69850885edda3d
parentd3fb6f35716ff1d6f6644dea2043d539007811de (diff)
2003-04-19 Havoc Pennington <hp@pobox.com>
* bus/driver.c (bus_driver_handle_hello): check limits and return an error if they are exceeded. * bus/connection.c: maintain separate lists of active and inactive connections, and a count of each. Maintain count of completed connections per user. Implement code to check connection limits. * dbus/dbus-list.c (_dbus_list_unlink): export * bus/bus.c (bus_context_check_security_policy): enforce a maximum number of bytes in the message queue for a connection
-rw-r--r--ChangeLog14
-rw-r--r--bus/bus.c56
-rw-r--r--bus/bus.h51
-rw-r--r--bus/connection.c317
-rw-r--r--bus/connection.h10
-rw-r--r--bus/dispatch.c5
-rw-r--r--bus/driver.c15
-rw-r--r--dbus/dbus-connection.h8
-rw-r--r--dbus/dbus-list.c13
-rw-r--r--dbus/dbus-list.h2
-rw-r--r--dbus/dbus-sysdeps.c4
-rw-r--r--doc/TODO12
12 files changed, 428 insertions, 79 deletions
diff --git a/ChangeLog b/ChangeLog
index 779138a4..d9a2f6cb 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,17 @@
+2003-04-19 Havoc Pennington <hp@pobox.com>
+
+ * bus/driver.c (bus_driver_handle_hello): check limits and
+ return an error if they are exceeded.
+
+ * bus/connection.c: maintain separate lists of active and inactive
+ connections, and a count of each. Maintain count of completed
+ connections per user. Implement code to check connection limits.
+
+ * dbus/dbus-list.c (_dbus_list_unlink): export
+
+ * bus/bus.c (bus_context_check_security_policy): enforce a maximum
+ number of bytes in the message queue for a connection
+
2003-04-18 Havoc Pennington <hp@pobox.com>
* dbus/dbus-auth.c (record_mechanisms): memleak fixes
diff --git a/bus/bus.c b/bus/bus.c
index 2b0f5091..414f15e4 100644
--- a/bus/bus.c
+++ b/bus/bus.c
@@ -45,8 +45,11 @@ struct BusContext
BusRegistry *registry;
BusPolicy *policy;
DBusUserDatabase *user_database;
- int activation_timeout; /**< How long to wait for an activation to time out */
- int auth_timeout; /**< How long to wait for an authentication to time out */
+ long max_incoming_bytes; /**< How many incoming messages for a connection */
+ long max_outgoing_bytes; /**< How many outgoing bytes can be queued for a connection */
+ long max_message_size; /**< Max size of a single message in bytes */
+ int activation_timeout; /**< How long to wait for an activation to time out */
+ int auth_timeout; /**< How long to wait for an authentication to time out */
int max_completed_connections; /**< Max number of authorized connections */
int max_incomplete_connections; /**< Max number of incomplete connections */
int max_connections_per_user; /**< Max number of connections auth'd as same user */
@@ -210,6 +213,12 @@ new_connection_callback (DBusServer *server,
*/
dbus_connection_disconnect (new_connection);
}
+
+ dbus_connection_set_max_received_size (new_connection,
+ context->max_incoming_bytes);
+
+ dbus_connection_set_max_message_size (new_connection,
+ context->max_message_size);
/* on OOM, we won't have ref'd the connection so it will die. */
}
@@ -353,6 +362,11 @@ bus_context_new (const DBusString *config_file,
*/
if (!server_data_slot_ref ())
_dbus_assert_not_reached ("second ref of server data slot failed");
+
+ /* Make up some numbers! woot! */
+ context->max_incoming_bytes = _DBUS_ONE_MEGABYTE * 63;
+ context->max_outgoing_bytes = _DBUS_ONE_MEGABYTE * 63;
+ context->max_message_size = _DBUS_ONE_MEGABYTE * 32;
#ifdef DBUS_BUILD_TESTS
context->activation_timeout = 6000; /* 6 seconds */
@@ -375,7 +389,7 @@ bus_context_new (const DBusString *config_file,
* DOS all the other users.
*/
context->max_completed_connections = 1024;
-
+
context->user_database = _dbus_user_database_new ();
if (context->user_database == NULL)
{
@@ -818,6 +832,30 @@ bus_context_get_activation_timeout (BusContext *context)
return context->activation_timeout;
}
+int
+bus_context_get_auth_timeout (BusContext *context)
+{
+ return context->auth_timeout;
+}
+
+int
+bus_context_get_max_completed_connections (BusContext *context)
+{
+ return context->max_completed_connections;
+}
+
+int
+bus_context_get_max_incomplete_connections (BusContext *context)
+{
+ return context->max_incomplete_connections;
+}
+
+int
+bus_context_get_max_connections_per_user (BusContext *context)
+{
+ return context->max_connections_per_user;
+}
+
dbus_bool_t
bus_context_check_security_policy (BusContext *context,
DBusConnection *sender,
@@ -878,5 +916,17 @@ bus_context_check_security_policy (BusContext *context,
return FALSE;
}
+ /* See if limits on size have been exceeded */
+ if (recipient &&
+ dbus_connection_get_outgoing_size (recipient) >
+ context->max_outgoing_bytes)
+ {
+ const char *dest = dbus_message_get_service (message);
+ dbus_set_error (error, DBUS_ERROR_LIMITS_EXCEEDED,
+ "The destination service \"%s\" has a full message queue",
+ dest ? dest : DBUS_SERVICE_DBUS);
+ return FALSE;
+ }
+
return TRUE;
}
diff --git a/bus/bus.h b/bus/bus.h
index 7369d220..e4e6dabe 100644
--- a/bus/bus.h
+++ b/bus/bus.h
@@ -41,29 +41,34 @@ typedef struct BusRegistry BusRegistry;
typedef struct BusService BusService;
typedef struct BusTransaction BusTransaction;
-BusContext* bus_context_new (const DBusString *config_file,
- int print_addr_fd,
- DBusError *error);
-void bus_context_shutdown (BusContext *context);
-void bus_context_ref (BusContext *context);
-void bus_context_unref (BusContext *context);
-const char* bus_context_get_type (BusContext *context);
-const char* bus_context_get_address (BusContext *context);
-BusRegistry* bus_context_get_registry (BusContext *context);
-BusConnections* bus_context_get_connections (BusContext *context);
-BusActivation* bus_context_get_activation (BusContext *context);
-DBusLoop* bus_context_get_loop (BusContext *context);
-DBusUserDatabase* bus_context_get_user_database (BusContext *context);
-dbus_bool_t bus_context_allow_user (BusContext *context,
- unsigned long uid);
-BusClientPolicy* bus_context_create_client_policy (BusContext *context,
- DBusConnection *connection);
-int bus_context_get_activation_timeout (BusContext *context);
-dbus_bool_t bus_context_check_security_policy (BusContext *context,
- DBusConnection *sender,
- DBusConnection *recipient,
- DBusMessage *message,
- DBusError *error);
+BusContext* bus_context_new (const DBusString *config_file,
+ int print_addr_fd,
+ DBusError *error);
+void bus_context_shutdown (BusContext *context);
+void bus_context_ref (BusContext *context);
+void bus_context_unref (BusContext *context);
+const char* bus_context_get_type (BusContext *context);
+const char* bus_context_get_address (BusContext *context);
+BusRegistry* bus_context_get_registry (BusContext *context);
+BusConnections* bus_context_get_connections (BusContext *context);
+BusActivation* bus_context_get_activation (BusContext *context);
+DBusLoop* bus_context_get_loop (BusContext *context);
+DBusUserDatabase* bus_context_get_user_database (BusContext *context);
+dbus_bool_t bus_context_allow_user (BusContext *context,
+ unsigned long uid);
+BusClientPolicy* bus_context_create_client_policy (BusContext *context,
+ DBusConnection *connection);
+int bus_context_get_activation_timeout (BusContext *context);
+int bus_context_get_auth_timeout (BusContext *context);
+int bus_context_get_max_completed_connections (BusContext *context);
+int bus_context_get_max_incomplete_connections (BusContext *context);
+int bus_context_get_max_connections_per_user (BusContext *context);
+dbus_bool_t bus_context_check_security_policy (BusContext *context,
+ DBusConnection *sender,
+ DBusConnection *recipient,
+ DBusMessage *message,
+ DBusError *error);
+
#endif /* BUS_BUS_H */
diff --git a/bus/connection.c b/bus/connection.c
index 71ab0108..14081e2e 100644
--- a/bus/connection.c
+++ b/bus/connection.c
@@ -26,14 +26,19 @@
#include "services.h"
#include "utils.h"
#include <dbus/dbus-list.h>
+#include <dbus/dbus-hash.h>
static void bus_connection_remove_transactions (DBusConnection *connection);
struct BusConnections
{
int refcount;
- DBusList *list; /**< List of all the connections */
+ DBusList *completed; /**< List of all completed connections */
+ int n_completed; /**< Length of completed list */
+ DBusList *incomplete; /**< List of all not-yet-active connections */
+ int n_incomplete; /**< Length of incomplete list */
BusContext *context;
+ DBusHashTable *completed_by_user; /**< Number of completed connections for each UID */
};
static int connection_data_slot = -1;
@@ -42,6 +47,7 @@ static int connection_data_slot_refcount = 0;
typedef struct
{
BusConnections *connections;
+ DBusList *link_in_connection_list;
DBusConnection *connection;
DBusList *services_owned;
char *name;
@@ -96,6 +102,65 @@ connection_get_loop (DBusConnection *connection)
return bus_context_get_loop (d->connections->context);
}
+
+static int
+get_connections_for_uid (BusConnections *connections,
+ dbus_uid_t uid)
+{
+ void *val;
+ int current_count;
+
+ /* val is NULL is 0 when it isn't in the hash yet */
+
+ val = _dbus_hash_table_lookup_ulong (connections->completed_by_user,
+ uid);
+
+ current_count = _DBUS_POINTER_TO_INT (val);
+
+ return current_count;
+}
+
+static dbus_bool_t
+adjust_connections_for_uid (BusConnections *connections,
+ dbus_uid_t uid,
+ int adjustment)
+{
+ int current_count;
+
+ current_count = get_connections_for_uid (connections, uid);
+
+ _dbus_verbose ("Adjusting connection count for UID " DBUS_UID_FORMAT
+ ": was %d adjustment %d making %d\n",
+ uid, current_count, adjustment, current_count + adjustment);
+
+ _dbus_assert (current_count >= 0);
+
+ current_count += adjustment;
+
+ _dbus_assert (current_count >= 0);
+
+ if (current_count == 0)
+ {
+ _dbus_hash_table_remove_ulong (connections->completed_by_user, uid);
+ return TRUE;
+ }
+ else
+ {
+ dbus_bool_t retval;
+
+ retval = _dbus_hash_table_insert_ulong (connections->completed_by_user,
+ uid, _DBUS_INT_TO_POINTER (current_count));
+
+ /* only positive adjustment can fail as otherwise
+ * a hash entry should already exist
+ */
+ _dbus_assert (adjustment > 0 ||
+ (adjustment <= 0 && retval));
+
+ return retval;
+ }
+}
+
void
bus_connection_disconnected (DBusConnection *connection)
{
@@ -180,8 +245,34 @@ bus_connection_disconnected (DBusConnection *connection)
bus_connection_remove_transactions (connection);
- _dbus_list_remove (&d->connections->list, connection);
+ if (d->link_in_connection_list != NULL)
+ {
+ if (d->name != NULL)
+ {
+ unsigned long uid;
+
+ _dbus_list_remove_link (&d->connections->completed, d->link_in_connection_list);
+ d->link_in_connection_list = NULL;
+ d->connections->n_completed -= 1;
+ if (dbus_connection_get_unix_user (connection, &uid))
+ {
+ if (!adjust_connections_for_uid (d->connections,
+ uid, -1))
+ _dbus_assert_not_reached ("adjusting downward should never fail");
+ }
+ }
+ else
+ {
+ _dbus_list_remove_link (&d->connections->incomplete, d->link_in_connection_list);
+ d->link_in_connection_list = NULL;
+ d->connections->n_incomplete -= 1;
+ }
+
+ _dbus_assert (d->connections->n_incomplete >= 0);
+ _dbus_assert (d->connections->n_completed >= 0);
+ }
+
/* frees "d" as side effect */
dbus_connection_set_data (connection,
connection_data_slot,
@@ -323,6 +414,15 @@ bus_connections_new (BusContext *context)
connection_data_slot_unref ();
return NULL;
}
+
+ connections->completed_by_user = _dbus_hash_table_new (DBUS_HASH_ULONG,
+ NULL, NULL);
+ if (connections->completed_by_user == NULL)
+ {
+ dbus_free (connections);
+ connection_data_slot_unref ();
+ return NULL;
+ }
connections->refcount = 1;
connections->context = context;
@@ -344,19 +444,37 @@ bus_connections_unref (BusConnections *connections)
connections->refcount -= 1;
if (connections->refcount == 0)
{
- while (connections->list != NULL)
+ /* drop all incomplete */
+ while (connections->incomplete != NULL)
{
DBusConnection *connection;
- connection = connections->list->data;
+ connection = connections->incomplete->data;
dbus_connection_ref (connection);
dbus_connection_disconnect (connection);
bus_connection_disconnected (connection);
dbus_connection_unref (connection);
}
+
+ _dbus_assert (connections->n_incomplete == 0);
- _dbus_list_clear (&connections->list);
+ /* drop all real connections */
+ while (connections->completed != NULL)
+ {
+ DBusConnection *connection;
+
+ connection = connections->completed->data;
+
+ dbus_connection_ref (connection);
+ dbus_connection_disconnect (connection);
+ bus_connection_disconnected (connection);
+ dbus_connection_unref (connection);
+ }
+
+ _dbus_assert (connections->n_completed == 0);
+
+ _dbus_hash_table_unref (connections->completed_by_user);
dbus_free (connections);
@@ -405,8 +523,7 @@ bus_connections_setup_connection (BusConnections *connections,
NULL,
connection, NULL))
goto out;
-
-
+
dbus_connection_set_unix_user_function (connection,
allow_user_function,
NULL, NULL);
@@ -415,16 +532,14 @@ bus_connections_setup_connection (BusConnections *connections,
dispatch_status_function,
bus_context_get_loop (connections->context),
NULL);
+
+ d->link_in_connection_list = _dbus_list_alloc_link (connection);
+ if (d->link_in_connection_list == NULL)
+ goto out;
/* Setup the connection with the dispatcher */
if (!bus_dispatch_add_connection (connection))
goto out;
-
- if (!_dbus_list_append (&connections->list, connection))
- {
- bus_dispatch_remove_connection (connection);
- goto out;
- }
if (dbus_connection_get_dispatch_status (connection) != DBUS_DISPATCH_COMPLETE)
{
@@ -434,13 +549,36 @@ bus_connections_setup_connection (BusConnections *connections,
goto out;
}
}
+
+ _dbus_list_append_link (&connections->incomplete, d->link_in_connection_list);
+ connections->n_incomplete += 1;
dbus_connection_ref (connection);
+
+ /* Note that we might disconnect ourselves here, but it only takes
+ * effect on return to the main loop.
+ */
+ if (connections->n_incomplete >
+ bus_context_get_max_incomplete_connections (connections->context))
+ {
+ _dbus_verbose ("Number of incomplete connections exceeds max, dropping oldest one\n");
+
+ _dbus_assert (connections->incomplete != NULL);
+ /* Disconnect the oldest unauthenticated connection. FIXME
+ * would it be more secure to drop a *random* connection? This
+ * algorithm seems to mean that if someone can create new
+ * connections quickly enough, they can keep anyone else from
+ * completing authentication. But random may or may not really
+ * help with that, a more elaborate solution might be required.
+ */
+ dbus_connection_disconnect (connections->incomplete->data);
+ }
+
retval = TRUE;
out:
if (!retval)
- {
+ {
if (!dbus_connection_set_watch_functions (connection,
NULL, NULL, NULL,
connection,
@@ -463,6 +601,13 @@ bus_connections_setup_connection (BusConnections *connections,
connection_data_slot,
NULL, NULL))
_dbus_assert_not_reached ("failed to set connection data to null");
+
+ if (d->link_in_connection_list != NULL)
+ {
+ _dbus_assert (d->link_in_connection_list->next == NULL);
+ _dbus_assert (d->link_in_connection_list->prev == NULL);
+ _dbus_list_free_link (d->link_in_connection_list);
+ }
}
return retval;
@@ -567,6 +712,67 @@ bus_connection_get_policy (DBusConnection *connection)
return d->policy;
}
+static dbus_bool_t
+foreach_active (BusConnections *connections,
+ BusConnectionForeachFunction function,
+ void *data)
+{
+ DBusList *link;
+
+ link = _dbus_list_get_first_link (&connections->completed);
+ while (link != NULL)
+ {
+ DBusConnection *connection = link->data;
+ DBusList *next = _dbus_list_get_next_link (&connections->completed, link);
+
+ if (!(* function) (connection, data))
+ return FALSE;
+
+ link = next;
+ }
+
+ return TRUE;
+}
+
+static dbus_bool_t
+foreach_inactive (BusConnections *connections,
+ BusConnectionForeachFunction function,
+ void *data)
+{
+ DBusList *link;
+
+ link = _dbus_list_get_first_link (&connections->incomplete);
+ while (link != NULL)
+ {
+ DBusConnection *connection = link->data;
+ DBusList *next = _dbus_list_get_next_link (&connections->incomplete, link);
+
+ if (!(* function) (connection, data))
+ return FALSE;
+
+ link = next;
+ }
+
+ return TRUE;
+}
+
+/**
+ * Calls function on each active connection; if the function returns
+ * #FALSE, stops iterating. Active connections are authenticated
+ * and have sent a Hello message.
+ *
+ * @param connections the connections object
+ * @param function the function
+ * @param data data to pass to it as a second arg
+ */
+void
+bus_connections_foreach_active (BusConnections *connections,
+ BusConnectionForeachFunction function,
+ void *data)
+{
+ foreach_active (connections, function, data);
+}
+
/**
* Calls function on each connection; if the function returns
* #FALSE, stops iterating.
@@ -578,21 +784,12 @@ bus_connection_get_policy (DBusConnection *connection)
void
bus_connections_foreach (BusConnections *connections,
BusConnectionForeachFunction function,
- void *data)
+ void *data)
{
- DBusList *link;
-
- link = _dbus_list_get_first_link (&connections->list);
- while (link != NULL)
- {
- DBusConnection *connection = link->data;
- DBusList *next = _dbus_list_get_next_link (&connections->list, link);
+ if (!foreach_active (connections, function, data))
+ return;
- if (!(* function) (connection, data))
- break;
-
- link = next;
- }
+ foreach_inactive (connections, function, data);
}
BusContext*
@@ -789,17 +986,40 @@ bus_connection_set_name (DBusConnection *connection,
const DBusString *name)
{
BusConnectionData *d;
+ unsigned long uid;
d = BUS_CONNECTION_DATA (connection);
_dbus_assert (d != NULL);
_dbus_assert (d->name == NULL);
-
+
if (!_dbus_string_copy_data (name, &d->name))
return FALSE;
_dbus_assert (d->name != NULL);
_dbus_verbose ("Name %s assigned to %p\n", d->name, connection);
+
+ if (dbus_connection_get_unix_user (connection, &uid))
+ {
+ if (!adjust_connections_for_uid (d->connections,
+ uid, 1))
+ {
+ dbus_free (d->name);
+ d->name = NULL;
+ return FALSE;
+ }
+ }
+
+ /* Now the connection is active, move it between lists */
+ _dbus_list_unlink (&d->connections->incomplete,
+ d->link_in_connection_list);
+ d->connections->n_incomplete -= 1;
+ _dbus_list_append_link (&d->connections->completed,
+ d->link_in_connection_list);
+ d->connections->n_completed += 1;
+
+ _dbus_assert (d->connections->n_incomplete >= 0);
+ _dbus_assert (d->connections->n_completed > 0);
return TRUE;
}
@@ -815,6 +1035,47 @@ bus_connection_get_name (DBusConnection *connection)
return d->name;
}
+/**
+ * Check whether completing the passed-in connection would
+ * exceed limits, and if so set error and return #FALSE
+ */
+dbus_bool_t
+bus_connections_check_limits (BusConnections *connections,
+ DBusConnection *requesting_completion,
+ DBusError *error)
+{
+ BusConnectionData *d;
+ unsigned long uid;
+
+ d = BUS_CONNECTION_DATA (requesting_completion);
+ _dbus_assert (d != NULL);
+
+ _dbus_assert (d->name == NULL);
+
+ if (connections->n_completed >=
+ bus_context_get_max_completed_connections (connections->context))
+ {
+ dbus_set_error (error, DBUS_ERROR_LIMITS_EXCEEDED,
+ "The maximum number of active connections has been reached");
+ return FALSE;
+ }
+
+ if (dbus_connection_get_unix_user (requesting_completion, &uid))
+ {
+ if (get_connections_for_uid (connections, uid) >=
+ bus_context_get_max_connections_per_user (connections->context))
+ {
+ dbus_set_error (error, DBUS_ERROR_LIMITS_EXCEEDED,
+ "The maximum number of active connections for UID %lu has been reached",
+ uid);
+ return FALSE;
+ }
+ }
+
+ return TRUE;
+}
+
+
/*
* Transactions
*
diff --git a/bus/connection.h b/bus/connection.h
index c429007b..0d4d3a10 100644
--- a/bus/connection.h
+++ b/bus/connection.h
@@ -40,12 +40,18 @@ dbus_bool_t bus_connections_setup_connection (BusConnections *
void bus_connections_foreach (BusConnections *connections,
BusConnectionForeachFunction function,
void *data);
+void bus_connections_foreach_active (BusConnections *connections,
+ BusConnectionForeachFunction function,
+ void *data);
BusContext* bus_connections_get_context (BusConnections *connections);
-
-BusContext* bus_connection_get_context (DBusConnection *connection);
+BusContext* bus_connection_get_context (DBusConnection *connection);
BusConnections* bus_connection_get_connections (DBusConnection *connection);
BusRegistry* bus_connection_get_registry (DBusConnection *connection);
BusActivation* bus_connection_get_activation (DBusConnection *connection);
+dbus_bool_t bus_connections_check_limits (BusConnections *connections,
+ DBusConnection *requesting_completion,
+ DBusError *error);
+
dbus_bool_t bus_connection_is_active (DBusConnection *connection);
diff --git a/bus/dispatch.c b/bus/dispatch.c
index d1c19fd3..c1e67d6a 100644
--- a/bus/dispatch.c
+++ b/bus/dispatch.c
@@ -48,9 +48,6 @@ static dbus_bool_t
send_one_message (DBusConnection *connection, void *data)
{
SendMessageData *d = data;
-
- if (!bus_connection_is_active (connection))
- return TRUE;
if (!bus_context_check_security_policy (d->context,
d->sender,
@@ -93,7 +90,7 @@ bus_dispatch_broadcast_message (BusTransaction *transaction,
d.transaction = transaction;
d.error = &tmp_error;
- bus_connections_foreach (connections, send_one_message, &d);
+ bus_connections_foreach_active (connections, send_one_message, &d);
if (dbus_error_is_set (&tmp_error))
{
diff --git a/bus/driver.c b/bus/driver.c
index c52020b5..bc58f556 100644
--- a/bus/driver.c
+++ b/bus/driver.c
@@ -262,8 +262,23 @@ bus_driver_handle_hello (DBusConnection *connection,
BusService *service;
dbus_bool_t retval;
BusRegistry *registry;
+ BusConnections *connections;
_DBUS_ASSERT_ERROR_IS_CLEAR (error);
+
+ /* Note that when these limits are exceeded we don't disconnect the
+ * connection; we just sort of leave it hanging there until it times
+ * out or disconnects itself or is dropped due to the max number of
+ * incomplete connections. It's even OK if the connection wants to
+ * retry the hello message, we support that.
+ */
+ connections = bus_connection_get_connections (connection);
+ if (!bus_connections_check_limits (connections, connection,
+ error))
+ {
+ _DBUS_ASSERT_ERROR_IS_SET (error);
+ return FALSE;
+ }
if (!_dbus_string_init (&unique_name))
{
diff --git a/dbus/dbus-connection.h b/dbus/dbus-connection.h
index 6e8a9f15..c2206cd3 100644
--- a/dbus/dbus-connection.h
+++ b/dbus/dbus-connection.h
@@ -183,11 +183,11 @@ void* dbus_connection_get_data (DBusConnection *connection,
void dbus_connection_set_change_sigpipe (dbus_bool_t will_modify_sigpipe);
-void dbus_connection_set_max_message_size (DBusConnection *connection,
- long size);
-long dbus_connection_get_max_message_size (DBusConnection *connection);
+void dbus_connection_set_max_message_size (DBusConnection *connection,
+ long size);
+long dbus_connection_get_max_message_size (DBusConnection *connection);
void dbus_connection_set_max_received_size (DBusConnection *connection,
- long size);
+ long size);
long dbus_connection_get_max_received_size (DBusConnection *connection);
long dbus_connection_get_outgoing_size (DBusConnection *connection);
diff --git a/dbus/dbus-list.c b/dbus/dbus-list.c
index 5f4c67ca..235ed275 100644
--- a/dbus/dbus-list.c
+++ b/dbus/dbus-list.c
@@ -470,7 +470,15 @@ _dbus_list_remove_last (DBusList **list,
return FALSE;
}
-static void
+/**
+ * Removes the given link from the list, but doesn't
+ * free it. _dbus_list_remove_link() both removes the
+ * link and also frees it.
+ *
+ * @param list the list
+ * @param link the link in the list
+ */
+void
_dbus_list_unlink (DBusList **list,
DBusList *link)
{
@@ -487,6 +495,9 @@ _dbus_list_unlink (DBusList **list,
if (*list == link)
*list = link->next;
}
+
+ link->next = NULL;
+ link->prev = NULL;
}
/**
diff --git a/dbus/dbus-list.h b/dbus/dbus-list.h
index ad74dfd0..f3b37ef8 100644
--- a/dbus/dbus-list.h
+++ b/dbus/dbus-list.h
@@ -74,6 +74,8 @@ dbus_bool_t _dbus_list_copy (DBusList **list,
int _dbus_list_get_length (DBusList **list);
DBusList* _dbus_list_alloc_link (void *data);
void _dbus_list_free_link (DBusList *link);
+void _dbus_list_unlink (DBusList **list,
+ DBusList *link);
void _dbus_list_append_link (DBusList **list,
DBusList *link);
void _dbus_list_prepend_link (DBusList **list,
diff --git a/dbus/dbus-sysdeps.c b/dbus/dbus-sysdeps.c
index 62aa0b4b..7673085f 100644
--- a/dbus/dbus-sysdeps.c
+++ b/dbus/dbus-sysdeps.c
@@ -470,8 +470,8 @@ _dbus_listen_unix_socket (const char *path,
* But there doesn't seem to be a good way to do this.
*
* Just to be extra careful, I threw in the stat() - clearly
- * the stat() can't *fix* any security issue, but it probably
- * makes it harder to exploit.
+ * the stat() can't *fix* any security issue, but it at least
+ * avoids inadvertent/accidental data loss.
*/
{
struct stat sb;
diff --git a/doc/TODO b/doc/TODO
index e6fe6bce..a02804a1 100644
--- a/doc/TODO
+++ b/doc/TODO
@@ -21,10 +21,6 @@
- Activation needs some careful additional thinking-through.
- - Recursive/composite/etc. types and associated API, see mailing list.
-
- - Configuration file (working on that now)
-
- Property list feature on message bus (list of properties associated
with a connection). May also include message matching rules
that involve the properties of the source or destination
@@ -46,9 +42,6 @@
- We might consider returning a "no such operation" error in dbus-connection.c
for unhandled messages.
- - Abstract the user database, so you can use something other than the system password
- database.
-
- The convenience functions in dbus-bus.h should perhaps have
the signatures that they would have if they were autogenerated
stubs. e.g. the acquire service function. We should also evaluate
@@ -60,9 +53,6 @@
some basic spec'ing out of the GLib/Qt level stubs/skels stuff will be
needed to understand the right approach.
- - sync up DBusWatch and DBusTimeout so that handle_watch() is a method on DBusWatch
- similar to the way timeouts work
-
- there are various bits of code to manage ref/unref of data slots, that should
be merged into a generic facility
@@ -85,7 +75,5 @@
- We have a limit on the number of messages a connection can send, but
not on how many can be buffered for a given connection.
- - make client serial and reply serial unsigned and add dbus_message_get_is_reply()
-
- other apps can send you a fake DBUS_MESSAGE_LOCAL_DISCONNECT; need to
check for that and disallow it.