2003-01-19 Havoc Pennington <hp@pobox.com>
authorHavoc Pennington <hp@redhat.com>
Sun, 19 Jan 2003 05:14:46 +0000 (05:14 +0000)
committerHavoc Pennington <hp@redhat.com>
Sun, 19 Jan 2003 05:14:46 +0000 (05:14 +0000)
* dbus/dbus-connection.c (dbus_connection_get_is_authenticated):
new function

* dbus/dbus-server.c (dbus_server_set_max_connections)
(dbus_server_get_max_connections, dbus_server_get_n_connections):
keep track of current number of connections, and add API for
setting a max (but haven't implemented enforcing the max yet)

ChangeLog
dbus/dbus-connection-internal.h
dbus/dbus-connection.c
dbus/dbus-connection.h
dbus/dbus-server-protected.h
dbus/dbus-server-unix.c
dbus/dbus-server.c
dbus/dbus-server.h

index 3cccd3a..9751024 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,13 @@
+2003-01-19  Havoc Pennington  <hp@pobox.com>
+
+       * dbus/dbus-connection.c (dbus_connection_get_is_authenticated):
+       new function
+
+       * dbus/dbus-server.c (dbus_server_set_max_connections)
+       (dbus_server_get_max_connections, dbus_server_get_n_connections):
+       keep track of current number of connections, and add API for
+       setting a max (but haven't implemented enforcing the max yet)
+
 2003-01-18  Havoc Pennington  <hp@pobox.com>
 
        * dbus/dbus-transport-unix.c (unix_do_iteration): only do the
index 404e4ec..6ad5119 100644 (file)
@@ -27,6 +27,7 @@
 #include <dbus/dbus-connection.h>
 #include <dbus/dbus-message.h>
 #include <dbus/dbus-transport.h>
+#include <dbus/dbus-resources.h>
 
 DBUS_BEGIN_DECLS;
 
@@ -61,6 +62,9 @@ void            _dbus_connection_handler_destroyed      (DBusConnection *connect
                                                          DBusMessageHandler *handler);
 
 
+void            _dbus_connection_set_connection_counter (DBusConnection *connection,
+                                                         DBusCounter    *counter);
+
 dbus_bool_t       _dbus_message_handler_add_connection    (DBusMessageHandler *handler,
                                                            DBusConnection     *connection);
 void              _dbus_message_handler_remove_connection (DBusMessageHandler *handler,
index 5ffbc57..4b9d4ca 100644 (file)
@@ -93,6 +93,8 @@ struct DBusConnection
   DBusDataSlot *data_slots;        /**< Data slots */
   int           n_slots; /**< Slots allocated so far. */
 
+  DBusCounter *connection_counter; /**< Counter that we decrement when finalized */
+  
   int client_serial;            /**< Client serial. Increments each time a message is sent  */
   unsigned int disconnect_notified : 1; /**< Already called disconnect_function */
 };
@@ -390,6 +392,25 @@ _dbus_connection_handler_destroyed (DBusConnection     *connection,
     }
 }
 
+/**
+ * Adds the counter used to count the number of open connections.
+ * Increments the counter by one, and saves it to be decremented
+ * again when this connection is finalized.
+ *
+ * @param connection a #DBusConnection
+ * @param counter counter that tracks number of connections
+ */
+void
+_dbus_connection_set_connection_counter (DBusConnection *connection,
+                                         DBusCounter    *counter)
+{
+  _dbus_assert (connection->connection_counter == NULL);
+  
+  connection->connection_counter = counter;
+  _dbus_counter_ref (connection->connection_counter);
+  _dbus_counter_adjust (connection->connection_counter, 1);
+}
+
 /** @} */
 
 /**
@@ -475,6 +496,14 @@ dbus_connection_unref (DBusConnection *connection)
       dbus_connection_set_disconnect_function (connection,
                                                NULL, NULL, NULL);
 
+      if (connection->connection_counter != NULL)
+        {
+          /* subtract ourselves from the counter */
+          _dbus_counter_adjust (connection->connection_counter, - 1);
+          _dbus_counter_unref (connection->connection_counter);
+          connection->connection_counter = NULL;
+        }
+      
       _dbus_watch_list_free (connection->watches);
       connection->watches = NULL;
 
@@ -553,6 +582,20 @@ dbus_connection_get_is_connected (DBusConnection *connection)
 }
 
 /**
+ * Gets whether the connection was authenticated. (Note that
+ * if the connection was authenticated then disconnected,
+ * this function still returns #TRUE)
+ *
+ * @param connection the connection
+ * @returns #TRUE if the connection was ever authenticated
+ */
+dbus_bool_t
+dbus_connection_get_is_authenticated (DBusConnection *connection)
+{
+  return _dbus_transport_get_is_authenticated (connection->transport);
+}
+
+/**
  * Adds a message to the outgoing message queue. Does not block to
  * write the message to the network; that happens asynchronously. to
  * force the message to be written, call dbus_connection_flush().
index 31653a5..a973e5d 100644 (file)
@@ -63,18 +63,18 @@ typedef void (* DBusRemoveWatchFunction) (DBusWatch      *watch,
 typedef void (* DBusDisconnectFunction)  (DBusConnection *connection,
                                           void           *data);
 
-DBusConnection* dbus_connection_open             (const char     *address,
-                                                  DBusResultCode *result);
-void            dbus_connection_ref              (DBusConnection *connection);
-void            dbus_connection_unref            (DBusConnection *connection);
-void            dbus_connection_disconnect       (DBusConnection *connection);
-dbus_bool_t     dbus_connection_get_is_connected (DBusConnection *connection);
-void            dbus_connection_flush            (DBusConnection *connection);
-
-int          dbus_connection_get_n_messages      (DBusConnection *connection);
-DBusMessage* dbus_connection_peek_message        (DBusConnection *connection);
-DBusMessage* dbus_connection_pop_message         (DBusConnection *connection);
-dbus_bool_t  dbus_connection_dispatch_message    (DBusConnection *connection);
+DBusConnection* dbus_connection_open                 (const char     *address,
+                                                      DBusResultCode *result);
+void            dbus_connection_ref                  (DBusConnection *connection);
+void            dbus_connection_unref                (DBusConnection *connection);
+void            dbus_connection_disconnect           (DBusConnection *connection);
+dbus_bool_t     dbus_connection_get_is_connected     (DBusConnection *connection);
+dbus_bool_t     dbus_connection_get_is_authenticated (DBusConnection *connection);
+void            dbus_connection_flush                (DBusConnection *connection);
+int             dbus_connection_get_n_messages       (DBusConnection *connection);
+DBusMessage*    dbus_connection_peek_message         (DBusConnection *connection);
+DBusMessage*    dbus_connection_pop_message          (DBusConnection *connection);
+dbus_bool_t     dbus_connection_dispatch_message     (DBusConnection *connection);
 
 dbus_bool_t dbus_connection_send_message            (DBusConnection     *connection,
                                                      DBusMessage        *message,
index fb57c2e..5e1ad55 100644 (file)
@@ -26,6 +26,7 @@
 #include <dbus/dbus-internals.h>
 #include <dbus/dbus-server.h>
 #include <dbus/dbus-watch.h>
+#include <dbus/dbus-resources.h>
 
 DBUS_BEGIN_DECLS;
 
@@ -51,7 +52,13 @@ struct DBusServer
 {
   int refcount;                               /**< Reference count. */
   const DBusServerVTable *vtable;             /**< Virtual methods for this instance. */
-  DBusWatchList *watches;
+  DBusWatchList *watches;                     /**< Our watches */
+
+  DBusCounter *connection_counter;            /**< Number of non-finalized DBusConnection
+                                               *   to this server
+                                               */
+
+  int max_connections;                        /**< Max number of connections allowed at once. */
   
   DBusNewConnectionFunction  new_connection_function;
   /**< Callback to invoke when a new connection is created. */
index c9a494e..23bbdab 100644 (file)
@@ -94,6 +94,9 @@ handle_new_client_fd (DBusServer *server,
   if (connection == NULL)
     return;
 
+  _dbus_connection_set_connection_counter (connection,
+                                           server->connection_counter);
+  
   /* See if someone wants to handle this new connection,
    * self-referencing for paranoia
    */
index c4b36bd..994a100 100644 (file)
@@ -61,6 +61,16 @@ _dbus_server_init_base (DBusServer             *server,
   if (server->watches == NULL)
     return FALSE;
 
+  server->connection_counter = _dbus_counter_new ();
+  if (server->connection_counter == NULL)
+    {
+      _dbus_watch_list_free (server->watches);
+      server->watches = NULL;
+      return FALSE;
+    }
+
+  server->max_connections = 256; /* same as an X server, seems like a nice default */
+  
   return TRUE;
 }
 
@@ -79,6 +89,7 @@ _dbus_server_finalize_base (DBusServer *server)
     dbus_server_disconnect (server);
 
   _dbus_watch_list_free (server->watches);
+  _dbus_counter_unref (server->connection_counter);
 }
 
 /**
@@ -295,5 +306,70 @@ dbus_server_handle_watch (DBusServer              *server,
   (* server->vtable->handle_watch) (server, watch, condition);
 }
 
+/**
+ * Sets the maximum number of connections that can be open at one
+ * time for this server. If the maximum is reached, and another
+ * client tries to connect, then the oldest unauthenticated client
+ * will be dropped. If no unauthenticated client exists, then
+ * the new connection will be refused.
+ *
+ * If the maximum is set to a number lower than the current
+ * number of connections, no current connections are
+ * disconnected.
+ *
+ * @todo honoring max_connections has not been implemented
+ * yet. The only real work involved is keeping a list
+ * of live connections on the DBusServer so the oldest
+ * unauthenticated client can be located when required.
+ * 
+ * @todo for a systemwide daemon, we need a max number of connections
+ * per user, since any user can authenticate a bunch of connections
+ * and create a DOS.
+ *
+ * @todo a single process might listen on multiple mechanisms
+ * (multiple DBusServer) and might want the max connections
+ * value to span all those servers. Should consider
+ * changing the API accordingly, though I'm inclined to
+ * punt this to the app that wants to do it instead of
+ * putting it in the library.
+ * 
+ * @param server the server
+ * @param max_connections maximum number of connections allowed
+ */
+void
+dbus_server_set_max_connections (DBusServer *server,
+                                 int         max_connections)
+{
+  server->max_connections = max_connections;
+}
+
+/**
+ * Gets the maximum number of connections that can be active
+ * at a time for this server.
+ *
+ * @param server the server
+ * @returns maximum number of connections at once
+ */
+int
+dbus_server_get_max_connections (DBusServer *server)
+{
+  return server->max_connections;
+}
+
+/**
+ * Gets the number of #DBusConnection to this server that
+ * have not yet been finalized. i.e. all #DBusConnection that
+ * were passed to #DBusNewConnectionFunction and have not yet been
+ * finalized will count in this total.
+ *
+ * @param server the server
+ * @param returns the number of connections
+ */
+int
+dbus_server_get_n_connections (DBusServer *server)
+{
+  return _dbus_counter_get_value (server->connection_counter);
+}
+
 /** @} */
 
index 83f7610..8471457 100644 (file)
@@ -60,6 +60,11 @@ void dbus_server_handle_watch                (DBusServer                *server,
                                               unsigned int               condition);
 
 
+void dbus_server_set_max_connections         (DBusServer                *server,
+                                              int                        max_connections);
+int  dbus_server_get_max_connections         (DBusServer                *server);
+
+int  dbus_server_get_n_connections           (DBusServer                *server);
 
 DBUS_END_DECLS;