diff options
| author | Havoc Pennington <hp@redhat.com> | 2003-04-25 23:50:34 +0000 | 
|---|---|---|
| committer | Havoc Pennington <hp@redhat.com> | 2003-04-25 23:50:34 +0000 | 
| commit | b3bd48edfc1aab0a9dc64bfa4c380d845d218e73 (patch) | |
| tree | 0ba9466c0b457769e9aa890906da532d875aac43 | |
| parent | 4b87aa40dfba668f8622873f2ea420b098704e41 (diff) | |
2003-04-25  Havoc Pennington  <hp@redhat.com>
        test suite is slightly hosed at the moment, will fix soon
	* bus/connection.c (bus_connections_expire_incomplete): fix to
	properly disable the timeout when required
	(bus_connection_set_name): check whether we can remove incomplete
	connections timeout after we complete each connection.
	* dbus/dbus-mainloop.c (check_timeout): fix this up a bit,
	probably still broken.
	* bus/services.c (bus_registry_acquire_service): implement max
	number of services owned, and honor allow/deny rules on which
	services a connection can own.
	* bus/connection.c (bus_connection_get_policy): report errors here
	* bus/activation.c: implement limit on number of pending
	activations
| -rw-r--r-- | ChangeLog | 21 | ||||
| -rw-r--r-- | bus/activation.c | 29 | ||||
| -rw-r--r-- | bus/bus.c | 32 | ||||
| -rw-r--r-- | bus/bus.h | 64 | ||||
| -rw-r--r-- | bus/config-parser.c | 17 | ||||
| -rw-r--r-- | bus/connection.c | 115 | ||||
| -rw-r--r-- | bus/connection.h | 5 | ||||
| -rw-r--r-- | bus/driver.c | 3 | ||||
| -rw-r--r-- | bus/services.c | 33 | ||||
| -rw-r--r-- | dbus/dbus-mainloop.c | 86 | ||||
| -rw-r--r-- | dbus/dbus-timeout.c | 2 | ||||
| -rw-r--r-- | doc/config-file.txt | 8 | ||||
| -rw-r--r-- | test/data/valid-config-files/basic.conf | 2 | 
13 files changed, 296 insertions, 121 deletions
| @@ -1,5 +1,26 @@  2003-04-25  Havoc Pennington  <hp@redhat.com> +        test suite is slightly hosed at the moment, will fix soon +	 +	* bus/connection.c (bus_connections_expire_incomplete): fix to +	properly disable the timeout when required +	(bus_connection_set_name): check whether we can remove incomplete +	connections timeout after we complete each connection. + +	* dbus/dbus-mainloop.c (check_timeout): fix this up a bit, +	probably still broken. + +	* bus/services.c (bus_registry_acquire_service): implement max +	number of services owned, and honor allow/deny rules on which  +	services a connection can own. + +	* bus/connection.c (bus_connection_get_policy): report errors here + +	* bus/activation.c: implement limit on number of pending +	activations + +2003-04-25  Havoc Pennington  <hp@redhat.com> +  	* dbus/dbus-transport.c (_dbus_transport_get_unix_user): fix bug  	where we used >= 0 instead of != DBUS_UID_UNSET. diff --git a/bus/activation.c b/bus/activation.c index a569e1a1..c50f1f28 100644 --- a/bus/activation.c +++ b/bus/activation.c @@ -45,6 +45,10 @@ struct BusActivation    DBusHashTable *pending_activations;    char *server_address;    BusContext *context; +  int n_pending_activations; /**< This is in fact the number of BusPendingActivationEntry, +                              * i.e. number of pending activation requests, not pending +                              * activations per se +                              */  };  typedef struct @@ -67,6 +71,7 @@ typedef struct    BusActivation *activation;    char *service_name;    DBusList *entries; +  int n_entries;    DBusBabysitter *babysitter;    DBusTimeout *timeout;    unsigned int timeout_added : 1; @@ -150,6 +155,11 @@ bus_pending_activation_unref (BusPendingActivation *pending_activation)        link = _dbus_list_get_next_link (&pending_activation->entries, link);      }    _dbus_list_clear (&pending_activation->entries); + +  pending_activation->activation->n_pending_activations -= +    pending_activation->n_entries; + +  _dbus_assert (pending_activation->activation->n_pending_activations >= 0);    dbus_free (pending_activation);  } @@ -394,6 +404,7 @@ bus_activation_new (BusContext        *context,    activation->refcount = 1;    activation->context = context; +  activation->n_pending_activations = 0;    if (!_dbus_string_copy_data (address, &activation->server_address))      { @@ -838,6 +849,15 @@ bus_activation_activate_service (BusActivation  *activation,    dbus_bool_t retval;    _DBUS_ASSERT_ERROR_IS_CLEAR (error); + +  if (activation->n_pending_activations >= +      bus_context_get_max_pending_activations (activation->context)) +    { +      dbus_set_error (error, DBUS_ERROR_LIMITS_EXCEEDED, +		      "The maximum number of pending activations has been reached, activation of %s failed", +		      service_name); +      return FALSE; +    }    entry = _dbus_hash_table_lookup_string (activation->entries, service_name); @@ -902,9 +922,6 @@ bus_activation_activate_service (BusActivation  *activation,    pending_activation = _dbus_hash_table_lookup_string (activation->pending_activations, service_name);    if (pending_activation)      { -      /* FIXME security - a client could keep sending activations over and -       * over, growing this queue. -       */        if (!_dbus_list_append (&pending_activation->entries, pending_activation_entry))  	{            _dbus_verbose ("Failed to append a new entry to pending activation\n"); @@ -913,6 +930,9 @@ bus_activation_activate_service (BusActivation  *activation,  	  bus_pending_activation_entry_free (pending_activation_entry);  	  return FALSE;  	} + +      pending_activation->n_entries += 1; +      pending_activation->activation->n_pending_activations += 1;      }    else      { @@ -980,6 +1000,9 @@ bus_activation_activate_service (BusActivation  *activation,  	  bus_pending_activation_entry_free (pending_activation_entry);	    	  return FALSE;  	} + +      pending_activation->n_entries += 1; +      pending_activation->activation->n_pending_activations += 1;        if (!_dbus_hash_table_insert_string (activation->pending_activations,  					   pending_activation->service_name, @@ -825,6 +825,18 @@ bus_context_get_max_connections_per_user (BusContext *context)    return context->limits.max_connections_per_user;  } +int +bus_context_get_max_pending_activations (BusContext *context) +{ +  return context->limits.max_pending_activations; +} + +int +bus_context_get_max_services_per_connection (BusContext *context) +{ +  return context->limits.max_services_per_connection; +} +  dbus_bool_t  bus_context_check_security_policy (BusContext     *context,                                     DBusConnection *sender, @@ -840,7 +852,13 @@ bus_context_check_security_policy (BusContext     *context,    if (sender != NULL)      {        _dbus_assert (dbus_connection_get_is_authenticated (sender)); -      sender_policy = bus_connection_get_policy (sender); +      sender_policy = bus_connection_get_policy (sender, error); +      if (sender_policy == NULL) +        { +          _DBUS_ASSERT_ERROR_IS_SET (error); +          return FALSE; +        } +      return FALSE;      }    else      sender_policy = NULL; @@ -848,12 +866,18 @@ bus_context_check_security_policy (BusContext     *context,    if (recipient != NULL)      {        _dbus_assert (dbus_connection_get_is_authenticated (recipient)); -      recipient_policy = bus_connection_get_policy (recipient); +      recipient_policy = bus_connection_get_policy (recipient, error); +      if (recipient_policy == NULL) +        { +          _DBUS_ASSERT_ERROR_IS_SET (error); +          return FALSE; +        } +      return FALSE;      }    else      recipient_policy = NULL; -  if (sender_policy && +  if (sender &&        !bus_client_policy_check_can_send (sender_policy,                                           context->registry, recipient,                                           message)) @@ -869,7 +893,7 @@ bus_context_check_security_policy (BusContext     *context,        return FALSE;      } -  if (recipient_policy && +  if (recipient &&        !bus_client_policy_check_can_receive (recipient_policy,                                              context->registry, sender,                                              message)) @@ -44,44 +44,46 @@ typedef struct BusTransaction   BusTransaction;  typedef struct  { -  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_incoming_bytes;          /**< How many incoming messages for a single connection */ +  long max_outgoing_bytes;          /**< How many outgoing bytes can be queued for a single 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 */ +  int max_pending_activations;      /**< Max number of pending activations for the entire bus */ +  int max_services_per_connection;  /**< Max number of owned services for a single connection */  } BusLimits; -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); - - +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); +int               bus_context_get_max_pending_activations     (BusContext       *context); +int               bus_context_get_max_services_per_connection (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/config-parser.c b/bus/config-parser.c index bd1c47b8..5e279639 100644 --- a/bus/config-parser.c +++ b/bus/config-parser.c @@ -306,7 +306,7 @@ bus_config_parser_new (const DBusString *basedir)     * and legitimate auth will fail.  If interactive auth (ask user for     * password) is allowed, then potentially it has to be quite long.     */      -  parser->limits.auth_timeout = 3000; /* 3 seconds */ +  parser->limits.auth_timeout = 30000; /* 30 seconds */    parser->limits.max_incomplete_connections = 32;    parser->limits.max_connections_per_user = 128; @@ -316,6 +316,9 @@ bus_config_parser_new (const DBusString *basedir)     * DOS all the other users.     */    parser->limits.max_completed_connections = 1024; + +  parser->limits.max_pending_activations = 256; +  parser->limits.max_services_per_connection = 256;    parser->refcount = 1; @@ -1215,6 +1218,18 @@ set_limit (BusConfigParser *parser,        must_be_int = TRUE;        parser->limits.max_connections_per_user = value;      } +  else if (strcmp (name, "max_pending_activations") == 0) +    { +      must_be_positive = TRUE; +      must_be_int = TRUE; +      parser->limits.max_pending_activations = value; +    } +  else if (strcmp (name, "max_services_per_connection") == 0) +    { +      must_be_positive = TRUE; +      must_be_int = TRUE; +      parser->limits.max_services_per_connection = value; +    }    else      {        dbus_set_error (error, DBUS_ERROR_FAILED, diff --git a/bus/connection.c b/bus/connection.c index 68429b2d..8907227c 100644 --- a/bus/connection.c +++ b/bus/connection.c @@ -52,6 +52,7 @@ typedef struct    DBusList *link_in_connection_list;    DBusConnection *connection;    DBusList *services_owned; +  int n_services_owned;    char *name;    DBusList *transaction_messages; /**< Stuff we need to send as part of a transaction */    DBusMessage *oom_message; @@ -387,6 +388,7 @@ free_connection_data (void *data)    /* services_owned should be NULL since we should be disconnected */    _dbus_assert (d->services_owned == NULL); +  _dbus_assert (d->n_services_owned == 0);    /* similarly */    _dbus_assert (d->transaction_messages == NULL); @@ -662,52 +664,54 @@ void  bus_connections_expire_incomplete (BusConnections *connections)  {        int next_interval; -  long tv_sec, tv_usec; -  DBusList *link; -  int auth_timeout; -   -  if (connections->incomplete == NULL) -    return; -  _dbus_get_current_time (&tv_sec, &tv_usec); -  auth_timeout = bus_context_get_auth_timeout (connections->context);    next_interval = -1; -  link = _dbus_list_get_first_link (&connections->incomplete); -  while (link != NULL) +  if (connections->incomplete != NULL)      { -      DBusList *next = _dbus_list_get_next_link (&connections->incomplete, link); -      DBusConnection *connection; -      BusConnectionData *d; -      double elapsed; +      long tv_sec, tv_usec; +      DBusList *link; +      int auth_timeout; -      connection = link->data; +      _dbus_get_current_time (&tv_sec, &tv_usec); +      auth_timeout = bus_context_get_auth_timeout (connections->context); +   +      link = _dbus_list_get_first_link (&connections->incomplete); +      while (link != NULL) +        { +          DBusList *next = _dbus_list_get_next_link (&connections->incomplete, link); +          DBusConnection *connection; +          BusConnectionData *d; +          double elapsed; -      d = BUS_CONNECTION_DATA (connection); +          connection = link->data; -      _dbus_assert (d != NULL); +          d = BUS_CONNECTION_DATA (connection); -      elapsed = ((double) tv_sec - (double) d->connection_tv_sec) * 1000.0 + -        ((double) tv_usec - (double) d->connection_tv_usec) / 1000.0; +          _dbus_assert (d != NULL); +       +          elapsed = ((double) tv_sec - (double) d->connection_tv_sec) * 1000.0 + +            ((double) tv_usec - (double) d->connection_tv_usec) / 1000.0; -      if (elapsed > (double) auth_timeout) -        { -          _dbus_verbose ("Timing out authentication for connection %p\n", connection); -          dbus_connection_disconnect (connection); -        } -      else -        { -          /* We can end the loop, since the connections are in oldest-first order */ -          next_interval = auth_timeout - (int) elapsed; -          _dbus_verbose ("Connection %p authentication expires in %d milliseconds\n", -                         connection, next_interval); +          if (elapsed >= (double) auth_timeout) +            { +              _dbus_verbose ("Timing out authentication for connection %p\n", connection); +              dbus_connection_disconnect (connection); +            } +          else +            { +              /* We can end the loop, since the connections are in oldest-first order */ +              next_interval = ((double)auth_timeout) - elapsed; +              _dbus_verbose ("Connection %p authentication expires in %d milliseconds\n", +                             connection, next_interval); -          break; -        } +              break; +            } -      link = next; +          link = next; +        }      } - +      if (next_interval >= 0)      {        _dbus_timeout_set_interval (connections->expire_timeout, @@ -717,13 +721,15 @@ bus_connections_expire_incomplete (BusConnections *connections)        _dbus_verbose ("Enabled incomplete connections timeout with interval %d, %d incomplete connections\n",                       next_interval, connections->n_incomplete);      } -  else +  else if (dbus_timeout_get_enabled (connections->expire_timeout))      {        _dbus_timeout_set_enabled (connections->expire_timeout, FALSE);        _dbus_verbose ("Disabled incomplete connections timeout, %d incomplete connections\n",                       connections->n_incomplete);      } +  else +    _dbus_verbose ("No need to disable incomplete connections timeout\n");  }  static dbus_bool_t @@ -731,6 +737,8 @@ expire_incomplete_timeout (void *data)  {    BusConnections *connections = data; +  _dbus_verbose ("Running %s\n", _DBUS_FUNCTION_NAME); +      /* note that this may remove the timeout */    bus_connections_expire_incomplete (connections); @@ -803,7 +811,8 @@ bus_connection_is_in_group (DBusConnection *connection,  }  BusClientPolicy* -bus_connection_get_policy (DBusConnection *connection) +bus_connection_get_policy (DBusConnection *connection, +                           DBusError      *error)  {    BusConnectionData *d; @@ -814,6 +823,9 @@ bus_connection_get_policy (DBusConnection *connection)    if (!dbus_connection_get_is_authenticated (connection))      {        _dbus_verbose ("Tried to get policy for unauthenticated connection!\n"); +      dbus_set_error (error, DBUS_ERROR_ACCESS_DENIED, +                      "Connection is not yet authenticated; the pre-authentication " +                      "implicit security policy is to deny everything");        return NULL;      } @@ -828,11 +840,19 @@ bus_connection_get_policy (DBusConnection *connection)        /* we may have a NULL policy on OOM or error getting list of         * groups for a user. In the latter case we don't handle it so -       * well currently, just keep pretending we're out of memory, -       * which is kind of bizarre. +       * well currently, as it will just keep failing over and over.         */      } +  if (d->policy == NULL) +    { +      dbus_set_error (error, DBUS_ERROR_ACCESS_DENIED, +                      "There was an error creating the security policy for connection \"%s\"; " +                      "all operations will fail for now.", +                      d->name ? d->name : "(inactive)"); +      return NULL; +    } +      return d->policy;  } @@ -1075,6 +1095,8 @@ bus_connection_add_owned_service_link (DBusConnection *connection,    _dbus_assert (d != NULL);    _dbus_list_append_link (&d->services_owned, link); + +  d->n_services_owned += 1;  }  dbus_bool_t @@ -1103,6 +1125,20 @@ bus_connection_remove_owned_service (DBusConnection *connection,    _dbus_assert (d != NULL);    _dbus_list_remove_last (&d->services_owned, service); + +  d->n_services_owned -= 1; +  _dbus_assert (d->n_services_owned >= 0); +} + +int +bus_connection_get_n_services_owned (DBusConnection *connection) +{ +  BusConnectionData *d; + +  d = BUS_CONNECTION_DATA (connection); +  _dbus_assert (d != NULL); +   +  return d->n_services_owned;  }  dbus_bool_t @@ -1144,6 +1180,9 @@ bus_connection_set_name (DBusConnection   *connection,    _dbus_assert (d->connections->n_incomplete >= 0);    _dbus_assert (d->connections->n_completed > 0); + +  /* See if we can remove the timeout */ +  bus_connections_expire_incomplete (d->connections);    return TRUE;  } diff --git a/bus/connection.h b/bus/connection.h index fe5a3769..ebfe2ad2 100644 --- a/bus/connection.h +++ b/bus/connection.h @@ -68,7 +68,7 @@ void        bus_connection_remove_owned_service   (DBusConnection *connection,                                                     BusService     *service);  void        bus_connection_add_owned_service_link (DBusConnection *connection,                                                     DBusList       *link); - +int         bus_connection_get_n_services_owned   (DBusConnection *connection);  /* called by driver.c */  dbus_bool_t bus_connection_set_name (DBusConnection               *connection, @@ -83,7 +83,8 @@ dbus_bool_t      bus_connection_is_in_group (DBusConnection       *connection,  dbus_bool_t      bus_connection_get_groups  (DBusConnection       *connection,                                               unsigned long       **groups,                                               int                  *n_groups); -BusClientPolicy* bus_connection_get_policy  (DBusConnection       *connection); +BusClientPolicy* bus_connection_get_policy  (DBusConnection       *connection, +                                             DBusError            *error);  /* transaction API so we can send or not send a block of messages as a whole */ diff --git a/bus/driver.c b/bus/driver.c index 299968f4..9839ff03 100644 --- a/bus/driver.c +++ b/bus/driver.c @@ -204,10 +204,11 @@ create_unique_client_name (BusRegistry *registry,     * for INT_MAX * INT_MAX combinations, should be pretty safe against     * wraparound.     */ +  /* FIXME these should be in BusRegistry rather than static vars */    static int next_major_number = 0;    static int next_minor_number = 0;    int len; - +      len = _dbus_string_get_length (str);    while (TRUE) diff --git a/bus/services.c b/bus/services.c index dfc3ed08..fc749d0d 100644 --- a/bus/services.c +++ b/bus/services.c @@ -30,6 +30,7 @@  #include "connection.h"  #include "utils.h"  #include "activation.h" +#include "policy.h"  struct BusService  { @@ -257,6 +258,7 @@ bus_registry_acquire_service (BusRegistry      *registry,    dbus_bool_t retval;    DBusConnection *old_owner;    DBusConnection *current_owner; +  BusClientPolicy *policy;    BusService *service;    retval = FALSE; @@ -283,6 +285,37 @@ bus_registry_acquire_service (BusRegistry      *registry,        goto out;      } + +  policy = bus_connection_get_policy (connection, error); +  if (policy == NULL) +    { +      _DBUS_ASSERT_ERROR_IS_SET (error); +      goto out; +    } + +  if (!bus_client_policy_check_can_own (policy, connection, +                                        service_name)) +    { +      dbus_set_error (error, DBUS_ERROR_ACCESS_DENIED, +                      "Connection \"%s\" is not allowed to own the service \"%s\" due " +                      "to security policies in the configuration file", +                      bus_connection_is_active (connection) ? +                      bus_connection_get_name (connection) : +                      "(inactive)"); +      goto out; +    } + +  if (bus_connection_get_n_services_owned (connection) >= +      bus_context_get_max_services_per_connection (registry->context)) +    { +      dbus_set_error (error, DBUS_ERROR_LIMITS_EXCEEDED, +                      "Connection \"%s\" is not allowed to own more services " +                      "(increase limits in configuration file if required)", +                      bus_connection_is_active (connection) ? +                      bus_connection_get_name (connection) : +                      "(inactive)"); +      goto out; +    }    service = bus_registry_lookup (registry, service_name); diff --git a/dbus/dbus-mainloop.c b/dbus/dbus-mainloop.c index 1d1af78c..60191882 100644 --- a/dbus/dbus-mainloop.c +++ b/dbus/dbus-mainloop.c @@ -356,10 +356,12 @@ check_timeout (unsigned long    tv_sec,    long interval_milliseconds;    int interval; +  /* I'm pretty sure this function could suck (a lot) less */ +      interval = dbus_timeout_get_interval (tcb->timeout); -  interval_seconds = interval / 1000; -  interval_milliseconds = interval - interval_seconds * 1000; +  interval_seconds = interval / 1000L; +  interval_milliseconds = interval % 1000L;    expiration_tv_sec = tcb->last_tv_sec + interval_seconds;    expiration_tv_usec = tcb->last_tv_usec + interval_milliseconds * 1000; @@ -368,44 +370,35 @@ check_timeout (unsigned long    tv_sec,        expiration_tv_usec -= 1000000;        expiration_tv_sec += 1;      } - -  if (expiration_tv_sec < tv_sec || -      (expiration_tv_sec == tv_sec && expiration_tv_usec < tv_usec)) -    { -      _dbus_verbose ("System clock went backward interval_seconds %ld interval_msecs %ld last_tv_sec %lu last_tv_usec %lu tv_sec %lu tv_usec %lu\n", -                     interval_seconds, interval_milliseconds, -                     tcb->last_tv_sec, tcb->last_tv_usec, tv_sec, tv_usec); -           -      /* The system time has been set backwards, reset the timeout to "interval" in the future */   -       -      tcb->last_tv_sec = tv_sec; -      tcb->last_tv_usec = tv_usec; - -      *timeout = interval; - -      return FALSE; -    }    sec_remaining = expiration_tv_sec - tv_sec; -  msec_remaining = (expiration_tv_usec - tv_usec) / 1000; - -#if 0 -  printf ("Interval is %ld seconds %ld msecs\n", -          interval_seconds, -          interval_milliseconds); -  printf ("Now is %lu seconds %lu usecs\n", -          tv_sec, tv_usec); -  printf ("Exp is %lu seconds %lu usecs\n", -          expiration_tv_sec, expiration_tv_usec); -  printf ("Pre-correction, remaining sec_remaining %ld msec_remaining %ld\n", sec_remaining, msec_remaining); +  /* need to force this to be signed, as it is intended to sometimes +   * produce a negative result +   */ +  msec_remaining = ((long) expiration_tv_usec - (long) tv_usec) / 1000L; + +#if MAINLOOP_SPEW +  _dbus_verbose ("Interval is %ld seconds %ld msecs\n", +                 interval_seconds, +                 interval_milliseconds); +  _dbus_verbose ("Now is  %lu seconds %lu usecs\n", +                 tv_sec, tv_usec); +  _dbus_verbose ("Last is %lu seconds %lu usecs\n", +                 tcb->last_tv_sec, tcb->last_tv_usec); +  _dbus_verbose ("Exp is  %lu seconds %lu usecs\n", +                 expiration_tv_sec, expiration_tv_usec); +  _dbus_verbose ("Pre-correction, sec_remaining %ld msec_remaining %ld\n", +                 sec_remaining, msec_remaining);  #endif    /* We do the following in a rather convoluted fashion to deal with     * the fact that we don't have an integral type big enough to hold -   * the difference of two timevals in millseconds. +   * the difference of two timevals in milliseconds.     */    if (sec_remaining < 0 || (sec_remaining == 0 && msec_remaining < 0)) -    msec_remaining = 0; +    { +      *timeout = 0; +    }    else      {        if (msec_remaining < 0) @@ -414,20 +407,29 @@ check_timeout (unsigned long    tv_sec,  	  sec_remaining -= 1;  	} -      if (msec_remaining > _DBUS_INT_MAX) -        { -          /* Not going to fit in a 32-bit integer */ -          msec_remaining = _DBUS_INT_MAX; -        } +      if (sec_remaining > (_DBUS_INT_MAX / 1000) || +          msec_remaining > _DBUS_INT_MAX) +        *timeout = _DBUS_INT_MAX; +      else +        *timeout = sec_remaining * 1000 + msec_remaining;              } -  *timeout = msec_remaining; +  if (*timeout > interval) +    { +      /* This indicates that the system clock probably moved backward */ +      _dbus_verbose ("System clock set backward! Resetting timeout.\n"); +       +      tcb->last_tv_sec = tv_sec; +      tcb->last_tv_usec = tv_usec; +      *timeout = interval; +    } +    #if MAINLOOP_SPEW    _dbus_verbose ("  timeout expires in %d milliseconds\n", *timeout);  #endif -  return msec_remaining == 0; +  return *timeout == 0;  }  dbus_bool_t @@ -708,6 +710,12 @@ _dbus_loop_iterate (DBusLoop     *loop,                    retval = TRUE;                  } +              else +                { +#if MAINLOOP_SPEW +                  _dbus_verbose ("  timeout has not expired\n"); +#endif +                }              }            link = next; diff --git a/dbus/dbus-timeout.c b/dbus/dbus-timeout.c index 74210f9a..1a2d2965 100644 --- a/dbus/dbus-timeout.c +++ b/dbus/dbus-timeout.c @@ -124,6 +124,8 @@ void  _dbus_timeout_set_interval (DBusTimeout *timeout,                              int          interval)  { +  _dbus_assert (interval >= 0); +      timeout->interval = interval;  } diff --git a/doc/config-file.txt b/doc/config-file.txt index ed3cdfab..e6e24e0f 100644 --- a/doc/config-file.txt +++ b/doc/config-file.txt @@ -135,9 +135,9 @@ Elements:      Available limits are:        "max_incoming_bytes"         : total size in bytes of messages -                                     incoming from a connection +                                     incoming from a single connection        "max_outgoing_bytes"         : total size in bytes of messages -                                     queued up for a connection +                                     queued up for a single connection        "max_message_size"           : max size of a single message in                                       bytes        "activation_timeout"         : milliseconds (thousandths) until  @@ -150,6 +150,10 @@ Elements:                                       connections        "max_connections_per_user"   : max number of completed connections from                                       the same user +      "max_pending_activations"    : max number of activations in +                                     progress at the same time +      "max_services_per_connection": max number of services a single  +                                     connection can own      Some notes: diff --git a/test/data/valid-config-files/basic.conf b/test/data/valid-config-files/basic.conf index 5addd692..4500ad70 100644 --- a/test/data/valid-config-files/basic.conf +++ b/test/data/valid-config-files/basic.conf @@ -19,5 +19,7 @@    <limit name="max_completed_connections">50</limit>      <limit name="max_incomplete_connections">80</limit>    <limit name="max_connections_per_user">64</limit> +  <limit name="max_pending_activations">64</limit> +  <limit name="max_services_per_connection">256</limit>  </busconfig> | 
