eeab273ceefb410161e5a1c8380817070a97e911
[platform/upstream/dbus.git] / bus / connection.c
1 /* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
2 /* connection.c  Client connections
3  *
4  * Copyright (C) 2003  Red Hat, Inc.
5  * Copyright (C) 2013  Samsung Electronics
6  *
7  * Licensed under the Academic Free License version 2.1
8  * 
9  * This program is free software; you can redistribute it and/or modify
10  * it under the terms of the GNU General Public License as published by
11  * the Free Software Foundation; either version 2 of the License, or
12  * (at your option) any later version.
13  *
14  * This program is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17  * GNU General Public License for more details.
18  * 
19  * You should have received a copy of the GNU General Public License
20  * along with this program; if not, write to the Free Software
21  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
22  *
23  */
24
25 #include <config.h>
26 #include "connection.h"
27 #include "dispatch.h"
28 #include "policy.h"
29 #include "services.h"
30 #include "utils.h"
31 #include "signals.h"
32 #include "expirelist.h"
33 #include "selinux.h"
34 #include <dbus/dbus-list.h>
35 #include <dbus/dbus-hash.h>
36 #include <dbus/dbus-timeout.h>
37
38 /* Trim executed commands to this length; we want to keep logs readable */
39 #define MAX_LOG_COMMAND_LEN 50
40
41 static void bus_connection_remove_transactions (DBusConnection *connection);
42
43 typedef struct
44 {
45   BusExpireItem expire_item;
46
47   DBusConnection *will_get_reply;
48   DBusConnection *will_send_reply;
49
50   dbus_uint32_t reply_serial;
51   
52 } BusPendingReply;
53
54 struct BusConnections
55 {
56   int refcount;
57   DBusList *completed;  /**< List of all completed connections */
58   int n_completed;      /**< Length of completed list */
59   DBusList *incomplete; /**< List of all not-yet-active connections */
60   int n_incomplete;     /**< Length of incomplete list */
61   BusContext *context;
62   DBusHashTable *completed_by_user; /**< Number of completed connections for each UID */
63   DBusTimeout *expire_timeout; /**< Timeout for expiring incomplete connections. */
64   int stamp;                   /**< Incrementing number */
65   BusExpireList *pending_replies; /**< List of pending replies */
66
67 #ifdef DBUS_ENABLE_STATS
68   int total_match_rules;
69   int peak_match_rules;
70   int peak_match_rules_per_conn;
71
72   int total_bus_names;
73   int peak_bus_names;
74   int peak_bus_names_per_conn;
75 #endif
76 };
77
78 static dbus_int32_t connection_data_slot = -1;
79
80 typedef struct
81 {
82   BusConnections *connections;
83   DBusList *link_in_connection_list;
84   DBusConnection *connection;
85   DBusList *services_owned;
86   int n_services_owned;
87   DBusList *match_rules;
88   int n_match_rules;
89   char *name;
90   DBusList *transaction_messages; /**< Stuff we need to send as part of a transaction */
91   DBusMessage *oom_message;
92   DBusPreallocatedSend *oom_preallocated;
93   BusClientPolicy *policy;
94
95   char *cached_loginfo_string;
96   BusSELinuxID *selinux_id;
97
98   long connection_tv_sec;  /**< Time when we connected (seconds component) */
99   long connection_tv_usec; /**< Time when we connected (microsec component) */
100   int stamp;               /**< connections->stamp last time we were traversed */
101
102 #ifdef DBUS_ENABLE_STATS
103   int peak_match_rules;
104   int peak_bus_names;
105 #endif
106 } BusConnectionData;
107
108 static dbus_bool_t bus_pending_reply_expired (BusExpireList *list,
109                                               DBusList      *link,
110                                               void          *data);
111
112 static void bus_connection_drop_pending_replies (BusConnections  *connections,
113                                                  DBusConnection  *connection);
114
115 static dbus_bool_t expire_incomplete_timeout (void *data);
116
117 #define BUS_CONNECTION_DATA(connection) (dbus_connection_get_data ((connection), connection_data_slot))
118
119 static DBusLoop*
120 connection_get_loop (DBusConnection *connection)
121 {
122   BusConnectionData *d;
123
124   d = BUS_CONNECTION_DATA (connection);
125
126   return bus_context_get_loop (d->connections->context);
127 }
128
129
130 static int
131 get_connections_for_uid (BusConnections *connections,
132                          dbus_uid_t      uid)
133 {
134   void *val;
135   int current_count;
136
137   /* val is NULL is 0 when it isn't in the hash yet */
138   
139   val = _dbus_hash_table_lookup_uintptr (connections->completed_by_user,
140                                        uid);
141
142   current_count = _DBUS_POINTER_TO_INT (val);
143
144   return current_count;
145 }
146
147 static dbus_bool_t
148 adjust_connections_for_uid (BusConnections *connections,
149                             dbus_uid_t      uid,
150                             int             adjustment)
151 {
152   int current_count;
153
154   current_count = get_connections_for_uid (connections, uid);
155
156   _dbus_verbose ("Adjusting connection count for UID " DBUS_UID_FORMAT
157                  ": was %d adjustment %d making %d\n",
158                  uid, current_count, adjustment, current_count + adjustment);
159   
160   _dbus_assert (current_count >= 0);
161   
162   current_count += adjustment;
163
164   _dbus_assert (current_count >= 0);
165
166   if (current_count == 0)
167     {
168       _dbus_hash_table_remove_uintptr (connections->completed_by_user, uid);
169       return TRUE;
170     }
171   else
172     {
173       dbus_bool_t retval;
174       
175       retval = _dbus_hash_table_insert_uintptr (connections->completed_by_user,
176                                               uid, _DBUS_INT_TO_POINTER (current_count));
177
178       /* only positive adjustment can fail as otherwise
179        * a hash entry should already exist
180        */
181       _dbus_assert (adjustment > 0 ||
182                     (adjustment <= 0 && retval));
183
184       return retval;
185     }
186 }
187
188 void
189 bus_connection_disconnected (DBusConnection *connection)
190 {
191   BusConnectionData *d;
192   BusService *service;
193   BusMatchmaker *matchmaker;
194   dbus_bool_t is_phantom = FALSE;
195   
196   d = BUS_CONNECTION_DATA (connection);
197   _dbus_assert (d != NULL);
198
199   _dbus_verbose ("%s disconnected, dropping all service ownership and releasing\n",
200                  d->name ? d->name : "(inactive)");
201
202   if(bus_context_is_kdbus(d->connections->context) && (strcmp(bus_connection_get_name(connection), ":1.1")))
203       is_phantom = TRUE;
204
205   /* Delete our match rules */
206   if (d->n_match_rules > 0)
207     {
208       matchmaker = bus_context_get_matchmaker (d->connections->context);
209       bus_matchmaker_disconnected (matchmaker, connection);
210     }
211   
212   /* Drop any service ownership. Unfortunately, this requires
213    * memory allocation and there doesn't seem to be a good way to
214    * handle it other than sleeping; we can't "fail" the operation of
215    * disconnecting a client, and preallocating a broadcast "service is
216    * now gone" message for every client-service pair seems kind of
217    * involved.
218    */
219   while ((service = _dbus_list_get_last (&d->services_owned)))
220     {
221       BusTransaction *transaction;
222       DBusError error;
223
224     retry:
225       
226       dbus_error_init (&error);
227         
228       while ((transaction = bus_transaction_new (d->connections->context)) == NULL)
229         _dbus_wait_for_memory ();
230         
231       if (!bus_service_remove_owner (service, connection,
232                                      transaction, &error))
233         {
234           _DBUS_ASSERT_ERROR_IS_SET (&error);
235           
236           if (dbus_error_has_name (&error, DBUS_ERROR_NO_MEMORY))
237             {
238               dbus_error_free (&error);
239               bus_transaction_cancel_and_free (transaction);
240               _dbus_wait_for_memory ();
241               goto retry;
242             }
243           else
244             {
245               _dbus_verbose ("Failed to remove service owner: %s %s\n",
246                              error.name, error.message);
247               _dbus_assert_not_reached ("Removing service owner failed for non-memory-related reason");
248             }
249         }
250         
251       bus_transaction_execute_and_free (transaction);
252     }
253
254   bus_dispatch_remove_connection (connection);
255   
256   /* no more watching */
257   if (!dbus_connection_set_watch_functions (connection,
258                                             NULL, NULL, NULL,
259                                             connection,
260                                             NULL))
261     _dbus_assert_not_reached ("setting watch functions to NULL failed");
262
263   if (!dbus_connection_set_timeout_functions (connection,
264                                               NULL, NULL, NULL,
265                                               connection,
266                                               NULL))
267     _dbus_assert_not_reached ("setting timeout functions to NULL failed");
268   
269   dbus_connection_set_unix_user_function (connection,
270                                           NULL, NULL, NULL);
271   dbus_connection_set_windows_user_function (connection,
272                                              NULL, NULL, NULL);
273   
274   dbus_connection_set_dispatch_status_function (connection,
275                                                 NULL, NULL, NULL);
276   
277   bus_connection_remove_transactions (connection);
278
279   if (d->link_in_connection_list != NULL)
280     {
281       if (d->name != NULL)
282         {
283           unsigned long uid;
284           
285           _dbus_list_remove_link (&d->connections->completed, d->link_in_connection_list);
286           d->link_in_connection_list = NULL;
287           d->connections->n_completed -= 1;
288
289           if (dbus_connection_get_unix_user (connection, &uid))
290             {
291               if (!adjust_connections_for_uid (d->connections,
292                                                uid, -1))
293                 _dbus_assert_not_reached ("adjusting downward should never fail");
294             }
295         }
296       else
297         {
298           _dbus_list_remove_link (&d->connections->incomplete, d->link_in_connection_list);
299           d->link_in_connection_list = NULL;
300           d->connections->n_incomplete -= 1;
301         }
302       
303       _dbus_assert (d->connections->n_incomplete >= 0);
304       _dbus_assert (d->connections->n_completed >= 0);
305     }
306
307   bus_connection_drop_pending_replies (d->connections, connection);
308   
309   /* frees "d" as side effect */
310   dbus_connection_set_data (connection,
311                             connection_data_slot,
312                             NULL, NULL);
313   if(is_phantom)
314       dbus_connection_unref_phantom(connection);
315   else
316       dbus_connection_unref (connection);
317 }
318
319 static dbus_bool_t
320 add_connection_watch (DBusWatch      *watch,
321                       void           *data)
322 {
323   DBusConnection *connection = data;
324
325   return _dbus_loop_add_watch (connection_get_loop (connection), watch);
326 }
327
328 static void
329 remove_connection_watch (DBusWatch      *watch,
330                          void           *data)
331 {
332   DBusConnection *connection = data;
333   
334   _dbus_loop_remove_watch (connection_get_loop (connection), watch);
335 }
336
337 static void
338 toggle_connection_watch (DBusWatch      *watch,
339                          void           *data)
340 {
341   DBusConnection *connection = data;
342
343   _dbus_loop_toggle_watch (connection_get_loop (connection), watch);
344 }
345
346 static dbus_bool_t
347 add_connection_timeout (DBusTimeout    *timeout,
348                         void           *data)
349 {
350   DBusConnection *connection = data;
351   
352   return _dbus_loop_add_timeout (connection_get_loop (connection), timeout);
353 }
354
355 static void
356 remove_connection_timeout (DBusTimeout    *timeout,
357                            void           *data)
358 {
359   DBusConnection *connection = data;
360   
361   _dbus_loop_remove_timeout (connection_get_loop (connection), timeout);
362 }
363
364 static void
365 dispatch_status_function (DBusConnection    *connection,
366                           DBusDispatchStatus new_status,
367                           void              *data)
368 {
369   DBusLoop *loop = data;
370   
371   if (new_status != DBUS_DISPATCH_COMPLETE)
372     {
373       while (!_dbus_loop_queue_dispatch (loop, connection))
374         _dbus_wait_for_memory ();
375     }
376 }
377
378 static dbus_bool_t
379 allow_unix_user_function (DBusConnection *connection,
380                           unsigned long   uid,
381                           void           *data)
382 {
383   BusConnectionData *d;
384     
385   d = BUS_CONNECTION_DATA (connection);
386
387   _dbus_assert (d != NULL);
388   
389   return bus_context_allow_unix_user (d->connections->context, uid);
390 }
391
392 static void
393 free_connection_data (void *data)
394 {
395   BusConnectionData *d = data;
396
397   /* services_owned should be NULL since we should be disconnected */
398   _dbus_assert (d->services_owned == NULL);
399   _dbus_assert (d->n_services_owned == 0);
400   /* similarly */
401   _dbus_assert (d->transaction_messages == NULL);
402
403   if (d->oom_preallocated)
404     dbus_connection_free_preallocated_send (d->connection, d->oom_preallocated);
405
406   if (d->oom_message)
407     dbus_message_unref (d->oom_message);
408
409   if (d->policy)
410     bus_client_policy_unref (d->policy);
411
412   if (d->selinux_id)
413     bus_selinux_id_unref (d->selinux_id);
414   
415   dbus_free (d->cached_loginfo_string);
416   
417   dbus_free (d->name);
418   
419   dbus_free (d);
420 }
421
422 BusConnections*
423 bus_connections_new (BusContext *context)
424 {
425   BusConnections *connections;
426
427   if (!dbus_connection_allocate_data_slot (&connection_data_slot))
428     goto failed_0;
429
430   connections = dbus_new0 (BusConnections, 1);
431   if (connections == NULL)
432     goto failed_1;
433
434   connections->completed_by_user = _dbus_hash_table_new (DBUS_HASH_UINTPTR,
435                                                          NULL, NULL);
436   if (connections->completed_by_user == NULL)
437     goto failed_2;
438
439   connections->expire_timeout = _dbus_timeout_new (100, /* irrelevant */
440                                                    expire_incomplete_timeout,
441                                                    connections, NULL);
442   if (connections->expire_timeout == NULL)
443     goto failed_3;
444
445   _dbus_timeout_set_enabled (connections->expire_timeout, FALSE);
446
447   connections->pending_replies = bus_expire_list_new (bus_context_get_loop (context),
448                                                       bus_context_get_reply_timeout (context),
449                                                       bus_pending_reply_expired,
450                                                       connections);
451   if (connections->pending_replies == NULL)
452     goto failed_4;
453   
454   if (!_dbus_loop_add_timeout (bus_context_get_loop (context),
455                                connections->expire_timeout))
456     goto failed_5;
457   
458   connections->refcount = 1;
459   connections->context = context;
460   
461   return connections;
462
463  failed_5:
464   bus_expire_list_free (connections->pending_replies);
465  failed_4:
466   _dbus_timeout_unref (connections->expire_timeout);
467  failed_3:
468   _dbus_hash_table_unref (connections->completed_by_user);
469  failed_2:
470   dbus_free (connections);
471  failed_1:
472   dbus_connection_free_data_slot (&connection_data_slot);
473  failed_0:
474   return NULL;
475 }
476
477 BusConnections *
478 bus_connections_ref (BusConnections *connections)
479 {
480   _dbus_assert (connections->refcount > 0);
481   connections->refcount += 1;
482
483   return connections;
484 }
485
486 void
487 bus_connections_unref (BusConnections *connections)
488 {
489   _dbus_assert (connections->refcount > 0);
490   connections->refcount -= 1;
491   if (connections->refcount == 0)
492     {
493       /* drop all incomplete */
494       while (connections->incomplete != NULL)
495         {
496           DBusConnection *connection;
497
498           connection = connections->incomplete->data;
499
500           dbus_connection_ref (connection);
501           dbus_connection_close (connection);
502           bus_connection_disconnected (connection);
503           dbus_connection_unref (connection);
504         }
505
506       _dbus_assert (connections->n_incomplete == 0);
507       
508       /* drop all real connections */
509       while (connections->completed != NULL)
510         {
511           DBusConnection *connection;
512
513           connection = connections->completed->data;
514
515           dbus_connection_ref (connection);
516           dbus_connection_close (connection);
517           bus_connection_disconnected (connection);
518           dbus_connection_unref (connection);
519         }
520
521       _dbus_assert (connections->n_completed == 0);
522
523       bus_expire_list_free (connections->pending_replies);
524       
525       _dbus_loop_remove_timeout (bus_context_get_loop (connections->context),
526                                  connections->expire_timeout);
527       
528       _dbus_timeout_unref (connections->expire_timeout);
529       
530       _dbus_hash_table_unref (connections->completed_by_user);
531       
532       dbus_free (connections);
533
534       dbus_connection_free_data_slot (&connection_data_slot);
535     }
536 }
537
538 /* Used for logging */
539 static dbus_bool_t
540 cache_peer_loginfo_string (BusConnectionData *d, 
541                            DBusConnection    *connection)
542 {
543   DBusString loginfo_buf;
544   unsigned long uid;
545   unsigned long pid;
546   char *windows_sid;
547   dbus_bool_t prev_added;
548
549   if (!_dbus_string_init (&loginfo_buf))
550     return FALSE;
551   
552   prev_added = FALSE;
553   if (dbus_connection_get_unix_user (connection, &uid))
554     {
555       if (!_dbus_string_append_printf (&loginfo_buf, "uid=%ld", uid))
556         goto oom;
557       else
558         prev_added = TRUE;
559     }
560
561   if (dbus_connection_get_unix_process_id (connection, &pid))
562     {
563       if (prev_added)
564         {
565           if (!_dbus_string_append_byte (&loginfo_buf, ' '))
566             goto oom;
567         }
568       if (!_dbus_string_append_printf (&loginfo_buf, "pid=%ld comm=\"", pid))
569         goto oom;
570       /* Ignore errors here; we may not have permissions to read the
571        * proc file. */
572       _dbus_command_for_pid (pid, &loginfo_buf, MAX_LOG_COMMAND_LEN, NULL);
573       if (!_dbus_string_append_byte (&loginfo_buf, '"'))
574         goto oom;
575     }
576
577   if (dbus_connection_get_windows_user (connection, &windows_sid))
578     {
579       dbus_bool_t did_append;
580       did_append = _dbus_string_append_printf (&loginfo_buf,
581                                                "sid=\"%s\" ", windows_sid);
582       dbus_free (windows_sid);
583       if (!did_append)
584         goto oom;
585     }
586
587   if (!_dbus_string_steal_data (&loginfo_buf, &(d->cached_loginfo_string)))
588     goto oom;
589
590   _dbus_string_free (&loginfo_buf); 
591
592   return TRUE;
593 oom:
594    _dbus_string_free (&loginfo_buf);
595    return FALSE;
596 }
597
598 dbus_bool_t
599 bus_connections_setup_connection (BusConnections *connections,
600                                   DBusConnection *connection)
601 {
602
603   BusConnectionData *d;
604   dbus_bool_t retval;
605   DBusError error;
606
607   
608   d = dbus_new0 (BusConnectionData, 1);
609   
610   if (d == NULL)
611     return FALSE;
612
613   d->connections = connections;
614   d->connection = connection;
615   
616   _dbus_get_monotonic_time (&d->connection_tv_sec,
617                             &d->connection_tv_usec);
618   
619   _dbus_assert (connection_data_slot >= 0);
620   
621   if (!dbus_connection_set_data (connection,
622                                  connection_data_slot,
623                                  d, free_connection_data))
624     {
625       dbus_free (d);
626       return FALSE;
627     }
628
629   dbus_connection_set_route_peer_messages (connection, TRUE);
630   
631   retval = FALSE;
632
633   dbus_error_init (&error);
634   d->selinux_id = bus_selinux_init_connection_id (connection,
635                                                   &error);
636   if (dbus_error_is_set (&error))
637     {
638       /* This is a bit bogus because we pretend all errors
639        * are OOM; this is done because we know that in bus.c
640        * an OOM error disconnects the connection, which is
641        * the same thing we want on any other error.
642        */
643       dbus_error_free (&error);
644       goto out;
645     }
646
647   if (!dbus_connection_set_watch_functions (connection,
648                                             add_connection_watch,
649                                             remove_connection_watch,
650                                             toggle_connection_watch,
651                                             connection,
652                                             NULL))
653     goto out;
654   
655   if (!dbus_connection_set_timeout_functions (connection,
656                                               add_connection_timeout,
657                                               remove_connection_timeout,
658                                               NULL,
659                                               connection, NULL))
660     goto out;
661
662   /* For now we don't need to set a Windows user function because
663    * there are no policies in the config file controlling what
664    * Windows users can connect. The default 'same user that owns the
665    * bus can connect' behavior of DBusConnection is fine on Windows.
666    */
667   dbus_connection_set_unix_user_function (connection,
668                                           allow_unix_user_function,
669                                           NULL, NULL);
670
671   dbus_connection_set_dispatch_status_function (connection,
672                                                 dispatch_status_function,
673                                                 bus_context_get_loop (connections->context),
674                                                 NULL);
675
676   d->link_in_connection_list = _dbus_list_alloc_link (connection);
677   if (d->link_in_connection_list == NULL)
678     goto out;
679   
680   /* Setup the connection with the dispatcher */
681   if (!bus_dispatch_add_connection (connection))
682     goto out;
683
684   if (dbus_connection_get_dispatch_status (connection) != DBUS_DISPATCH_COMPLETE)
685     {
686       if (!_dbus_loop_queue_dispatch (bus_context_get_loop (connections->context), connection))
687         {
688           bus_dispatch_remove_connection (connection);
689           goto out;
690         }
691     }
692
693   _dbus_list_append_link (&connections->incomplete, d->link_in_connection_list);
694   connections->n_incomplete += 1;
695   
696   dbus_connection_ref (connection);
697
698   /* Note that we might disconnect ourselves here, but it only takes
699    * effect on return to the main loop. We call this to free up
700    * expired connections if possible, and to queue the timeout for our
701    * own expiration.
702    */
703   bus_connections_expire_incomplete (connections);
704   
705   /* And we might also disconnect ourselves here, but again it
706    * only takes effect on return to main loop.
707    */
708   if (connections->n_incomplete >
709       bus_context_get_max_incomplete_connections (connections->context))
710     {
711       _dbus_verbose ("Number of incomplete connections exceeds max, dropping oldest one\n");
712       
713       _dbus_assert (connections->incomplete != NULL);
714       /* Disconnect the oldest unauthenticated connection.  FIXME
715        * would it be more secure to drop a *random* connection?  This
716        * algorithm seems to mean that if someone can create new
717        * connections quickly enough, they can keep anyone else from
718        * completing authentication. But random may or may not really
719        * help with that, a more elaborate solution might be required.
720        */
721       dbus_connection_close (connections->incomplete->data);
722     }
723   
724   retval = TRUE;
725
726  out:
727   if (!retval)
728     {
729       if (d->selinux_id)
730         bus_selinux_id_unref (d->selinux_id);
731       d->selinux_id = NULL;
732       
733       if (!dbus_connection_set_watch_functions (connection,
734                                                 NULL, NULL, NULL,
735                                                 connection,
736                                                 NULL))
737         _dbus_assert_not_reached ("setting watch functions to NULL failed");
738       
739       if (!dbus_connection_set_timeout_functions (connection,
740                                                   NULL, NULL, NULL,
741                                                   connection,
742                                                   NULL))
743         _dbus_assert_not_reached ("setting timeout functions to NULL failed");
744
745       dbus_connection_set_unix_user_function (connection,
746                                               NULL, NULL, NULL);
747
748       dbus_connection_set_windows_user_function (connection,
749                                                  NULL, NULL, NULL);
750       
751       dbus_connection_set_dispatch_status_function (connection,
752                                                     NULL, NULL, NULL);
753
754       if (d->link_in_connection_list != NULL)
755         {
756           _dbus_assert (d->link_in_connection_list->next == NULL);
757           _dbus_assert (d->link_in_connection_list->prev == NULL);
758           _dbus_list_free_link (d->link_in_connection_list);
759           d->link_in_connection_list = NULL;
760         }
761       
762       if (!dbus_connection_set_data (connection,
763                                      connection_data_slot,
764                                      NULL, NULL))
765         _dbus_assert_not_reached ("failed to set connection data to null");
766
767       /* "d" has now been freed */
768     }
769   
770   return retval;
771 }
772
773 void
774 bus_connections_expire_incomplete (BusConnections *connections)
775 {    
776   int next_interval;
777
778   next_interval = -1;
779   
780   if (connections->incomplete != NULL)
781     {
782       long tv_sec, tv_usec;
783       DBusList *link;
784       int auth_timeout;
785       
786       _dbus_get_monotonic_time (&tv_sec, &tv_usec);
787       auth_timeout = bus_context_get_auth_timeout (connections->context);
788   
789       link = _dbus_list_get_first_link (&connections->incomplete);
790       while (link != NULL)
791         {
792           DBusList *next = _dbus_list_get_next_link (&connections->incomplete, link);
793           DBusConnection *connection;
794           BusConnectionData *d;
795           double elapsed;
796       
797           connection = link->data;
798       
799           d = BUS_CONNECTION_DATA (connection);
800       
801           _dbus_assert (d != NULL);
802       
803           elapsed = ELAPSED_MILLISECONDS_SINCE (d->connection_tv_sec,
804                                                 d->connection_tv_usec,
805                                                 tv_sec, tv_usec);
806
807           if (elapsed >= (double) auth_timeout)
808             {
809               _dbus_verbose ("Timing out authentication for connection %p\n", connection);
810               dbus_connection_close (connection);
811             }
812           else
813             {
814               /* We can end the loop, since the connections are in oldest-first order */
815               next_interval = ((double)auth_timeout) - elapsed;
816               _dbus_verbose ("Connection %p authentication expires in %d milliseconds\n",
817                              connection, next_interval);
818           
819               break;
820             }
821       
822           link = next;
823         }
824     }
825
826   bus_expire_timeout_set_interval (connections->expire_timeout,
827                                    next_interval);
828 }
829
830 static dbus_bool_t
831 expire_incomplete_timeout (void *data)
832 {
833   BusConnections *connections = data;
834
835   _dbus_verbose ("Running\n");
836   
837   /* note that this may remove the timeout */
838   bus_connections_expire_incomplete (connections);
839
840   return TRUE;
841 }
842
843 dbus_bool_t
844 bus_connection_get_unix_groups  (DBusConnection   *connection,
845                                  unsigned long   **groups,
846                                  int              *n_groups,
847                                  DBusError        *error)
848 {
849   unsigned long uid;
850
851   *groups = NULL;
852   *n_groups = 0;
853
854   if (dbus_connection_get_unix_user (connection, &uid))
855     {
856       if (!_dbus_unix_groups_from_uid (uid, groups, n_groups))
857         {
858           _dbus_verbose ("Did not get any groups for UID %lu\n",
859                          uid);
860           return FALSE;
861         }
862       else
863         {
864           _dbus_verbose ("Got %d groups for UID %lu\n",
865                          *n_groups, uid);
866           return TRUE;
867         }
868     }
869   else
870     return TRUE; /* successfully got 0 groups */
871 }
872
873 dbus_bool_t
874 bus_connection_is_in_unix_group (DBusConnection *connection,
875                                  unsigned long   gid)
876 {
877   int i;
878   unsigned long *group_ids;
879   int n_group_ids;
880
881   if (!bus_connection_get_unix_groups (connection, &group_ids, &n_group_ids,
882                                        NULL))
883     return FALSE;
884
885   i = 0;
886   while (i < n_group_ids)
887     {
888       if (group_ids[i] == gid)
889         {
890           dbus_free (group_ids);
891           return TRUE;
892         }
893       ++i;
894     }
895
896   dbus_free (group_ids);
897   return FALSE;
898 }
899
900 const char *
901 bus_connection_get_loginfo (DBusConnection        *connection)
902 {
903   BusConnectionData *d;
904     
905   d = BUS_CONNECTION_DATA (connection);
906
907   if (!bus_connection_is_active (connection))
908     return "inactive";
909   return d->cached_loginfo_string;  
910 }
911
912 BusClientPolicy*
913 bus_connection_get_policy (DBusConnection *connection)
914 {
915   BusConnectionData *d;
916     
917   d = BUS_CONNECTION_DATA (connection);
918
919   _dbus_assert (d != NULL);
920   _dbus_assert (d->policy != NULL);
921   
922   return d->policy;
923 }
924
925 static dbus_bool_t
926 foreach_active (BusConnections               *connections,
927                 BusConnectionForeachFunction  function,
928                 void                         *data)
929 {
930   DBusList *link;
931   
932   link = _dbus_list_get_first_link (&connections->completed);
933   while (link != NULL)
934     {
935       DBusConnection *connection = link->data;
936       DBusList *next = _dbus_list_get_next_link (&connections->completed, link);
937
938       if (!(* function) (connection, data))
939         return FALSE;
940       
941       link = next;
942     }
943
944   return TRUE;
945 }
946
947 static dbus_bool_t
948 foreach_inactive (BusConnections               *connections,
949                   BusConnectionForeachFunction  function,
950                   void                         *data)
951 {
952   DBusList *link;
953   
954   link = _dbus_list_get_first_link (&connections->incomplete);
955   while (link != NULL)
956     {
957       DBusConnection *connection = link->data;
958       DBusList *next = _dbus_list_get_next_link (&connections->incomplete, link);
959
960       if (!(* function) (connection, data))
961         return FALSE;
962       
963       link = next;
964     }
965
966   return TRUE;
967 }
968
969 /**
970  * Calls function on each active connection; if the function returns
971  * #FALSE, stops iterating. Active connections are authenticated
972  * and have sent a Hello message.
973  *
974  * @param connections the connections object
975  * @param function the function
976  * @param data data to pass to it as a second arg
977  */
978 void
979 bus_connections_foreach_active (BusConnections               *connections,
980                                 BusConnectionForeachFunction  function,
981                                 void                         *data)
982 {
983   foreach_active (connections, function, data);
984 }
985
986 /**
987  * Calls function on each connection; if the function returns
988  * #FALSE, stops iterating.
989  *
990  * @param connections the connections object
991  * @param function the function
992  * @param data data to pass to it as a second arg
993  */
994 void
995 bus_connections_foreach (BusConnections               *connections,
996                          BusConnectionForeachFunction  function,
997                          void                         *data)
998 {
999   if (!foreach_active (connections, function, data))
1000     return;
1001
1002   foreach_inactive (connections, function, data);
1003 }
1004
1005 DBusConnection*
1006 bus_connections_find_conn_by_name(BusConnections *connections, const char* name)
1007 {
1008     DBusList *link;
1009
1010     link = _dbus_list_get_first_link (&connections->completed);
1011     while (link != NULL)
1012       {
1013         DBusConnection *connection = link->data;
1014         DBusList *next = _dbus_list_get_next_link (&connections->completed, link);
1015
1016         if (!strcmp(bus_connection_get_name(connection), name))
1017           return connection;
1018
1019         link = next;
1020       }
1021
1022     return NULL;
1023 }
1024
1025 BusContext*
1026 bus_connections_get_context (BusConnections *connections)
1027 {
1028   return connections->context;
1029 }
1030
1031 /*
1032  * This is used to avoid covering the same connection twice when
1033  * traversing connections. Note that it assumes we will
1034  * bus_connection_mark_stamp() each connection at least once per
1035  * INT_MAX increments of the global stamp, or wraparound would break
1036  * things.
1037  */
1038 void
1039 bus_connections_increment_stamp (BusConnections *connections)
1040 {
1041   connections->stamp += 1;
1042 }
1043
1044 /* Mark connection with current stamp, return TRUE if it
1045  * didn't already have that stamp
1046  */
1047 dbus_bool_t
1048 bus_connection_mark_stamp (DBusConnection *connection)
1049 {
1050   BusConnectionData *d;
1051   
1052   d = BUS_CONNECTION_DATA (connection);
1053   
1054   _dbus_assert (d != NULL);
1055
1056   if (d->stamp == d->connections->stamp)
1057     return FALSE;
1058   else
1059     {
1060       d->stamp = d->connections->stamp;
1061       return TRUE;
1062     }
1063 }
1064
1065 BusContext*
1066 bus_connection_get_context (DBusConnection *connection)
1067 {
1068   BusConnectionData *d;
1069
1070   d = BUS_CONNECTION_DATA (connection);
1071
1072   _dbus_assert (d != NULL);
1073
1074   return d->connections->context;
1075 }
1076
1077 BusConnections*
1078 bus_connection_get_connections (DBusConnection *connection)
1079 {
1080   BusConnectionData *d;
1081     
1082   d = BUS_CONNECTION_DATA (connection);
1083
1084   _dbus_assert (d != NULL);
1085
1086   return d->connections;
1087 }
1088
1089 BusRegistry*
1090 bus_connection_get_registry (DBusConnection *connection)
1091 {
1092   BusConnectionData *d;
1093
1094   d = BUS_CONNECTION_DATA (connection);
1095
1096   _dbus_assert (d != NULL);
1097
1098   return bus_context_get_registry (d->connections->context);
1099 }
1100
1101 BusActivation*
1102 bus_connection_get_activation (DBusConnection *connection)
1103 {
1104   BusConnectionData *d;
1105
1106   d = BUS_CONNECTION_DATA (connection);
1107
1108   _dbus_assert (d != NULL);
1109
1110   return bus_context_get_activation (d->connections->context);
1111 }
1112
1113 BusMatchmaker*
1114 bus_connection_get_matchmaker (DBusConnection *connection)
1115 {
1116   BusConnectionData *d;
1117
1118   d = BUS_CONNECTION_DATA (connection);
1119
1120   _dbus_assert (d != NULL);
1121
1122   return bus_context_get_matchmaker (d->connections->context);
1123 }
1124
1125 BusSELinuxID*
1126 bus_connection_get_selinux_id (DBusConnection *connection)
1127 {
1128   BusConnectionData *d;
1129
1130   d = BUS_CONNECTION_DATA (connection);
1131
1132   _dbus_assert (d != NULL);
1133
1134   return d->selinux_id;
1135 }
1136
1137 /**
1138  * Checks whether the connection is registered with the message bus.
1139  *
1140  * @param connection the connection
1141  * @returns #TRUE if we're an active message bus participant
1142  */
1143 dbus_bool_t
1144 bus_connection_is_active (DBusConnection *connection)
1145 {
1146   BusConnectionData *d;
1147
1148   d = BUS_CONNECTION_DATA (connection);
1149   
1150   return d != NULL && d->name != NULL;
1151 }
1152
1153 dbus_bool_t
1154 bus_connection_preallocate_oom_error (DBusConnection *connection)
1155 {
1156   DBusMessage *message;
1157   DBusPreallocatedSend *preallocated;
1158   BusConnectionData *d;
1159
1160   d = BUS_CONNECTION_DATA (connection);  
1161
1162   _dbus_assert (d != NULL);
1163
1164   if (d->oom_preallocated != NULL)
1165     return TRUE;
1166   
1167   preallocated = dbus_connection_preallocate_send (connection);
1168   if (preallocated == NULL)
1169     return FALSE;
1170
1171   message = dbus_message_new (DBUS_MESSAGE_TYPE_ERROR);
1172
1173   if (message == NULL)
1174     {
1175       dbus_connection_free_preallocated_send (connection, preallocated);
1176       return FALSE;
1177     }
1178
1179   /* d->name may be NULL, but that is OK */
1180   if (!dbus_message_set_error_name (message, DBUS_ERROR_NO_MEMORY) ||
1181       !dbus_message_set_destination (message, d->name) ||
1182       !dbus_message_set_sender (message,
1183                                 DBUS_SERVICE_DBUS))
1184     {
1185       dbus_connection_free_preallocated_send (connection, preallocated);
1186       dbus_message_unref (message);
1187       return FALSE;
1188     }
1189   
1190   /* set reply serial to placeholder value just so space is already allocated
1191    * for it.
1192    */
1193   if (!dbus_message_set_reply_serial (message, 14))
1194     {
1195       dbus_connection_free_preallocated_send (connection, preallocated);
1196       dbus_message_unref (message);
1197       return FALSE;
1198     }
1199
1200   d->oom_message = message;
1201   d->oom_preallocated = preallocated;
1202   
1203   return TRUE;
1204 }
1205
1206 void
1207 bus_connection_send_oom_error (DBusConnection *connection,
1208                                DBusMessage    *in_reply_to)
1209 {
1210   BusConnectionData *d;
1211
1212   d = BUS_CONNECTION_DATA (connection);  
1213
1214   _dbus_assert (d != NULL);  
1215   _dbus_assert (d->oom_message != NULL);
1216
1217   /* should always succeed since we set it to a placeholder earlier */
1218   if (!dbus_message_set_reply_serial (d->oom_message,
1219                                       dbus_message_get_serial (in_reply_to)))
1220     _dbus_assert_not_reached ("Failed to set reply serial for preallocated oom message");
1221
1222   _dbus_assert (dbus_message_get_sender (d->oom_message) != NULL);
1223   
1224   dbus_connection_send_preallocated (connection, d->oom_preallocated,
1225                                      d->oom_message, NULL);
1226
1227   dbus_message_unref (d->oom_message);
1228   d->oom_message = NULL;
1229   d->oom_preallocated = NULL;
1230 }
1231
1232 #ifdef DBUS_ENABLE_STATS
1233 static void
1234 update_peak (int *peak,
1235              int n)
1236 {
1237   if (*peak < n)
1238     *peak = n;
1239 }
1240 #endif
1241
1242 void
1243 bus_connection_add_match_rule_link (DBusConnection *connection,
1244                                     DBusList       *link)
1245 {
1246   BusConnectionData *d;
1247
1248   d = BUS_CONNECTION_DATA (connection);
1249   _dbus_assert (d != NULL);
1250
1251   _dbus_list_append_link (&d->match_rules, link);
1252
1253   d->n_match_rules += 1;
1254
1255 #ifdef DBUS_ENABLE_STATS
1256   update_peak (&d->peak_match_rules, d->n_match_rules);
1257   update_peak (&d->connections->peak_match_rules_per_conn, d->n_match_rules);
1258
1259   d->connections->total_match_rules += 1;
1260   update_peak (&d->connections->peak_match_rules,
1261                d->connections->total_match_rules);
1262 #endif
1263 }
1264
1265 dbus_bool_t
1266 bus_connection_add_match_rule (DBusConnection *connection,
1267                                BusMatchRule   *rule)
1268 {
1269     DBusList *link;
1270
1271   link = _dbus_list_alloc_link (rule);
1272
1273   if (link == NULL)
1274     return FALSE;
1275
1276   bus_connection_add_match_rule_link (connection, link);
1277
1278   return TRUE;
1279 }
1280
1281 void
1282 bus_connection_remove_match_rule (DBusConnection *connection,
1283                                   BusMatchRule   *rule)
1284 {
1285   BusConnectionData *d;
1286
1287   d = BUS_CONNECTION_DATA (connection);
1288   _dbus_assert (d != NULL);
1289
1290   _dbus_list_remove_last (&d->match_rules, rule);
1291
1292   d->n_match_rules -= 1;
1293   _dbus_assert (d->n_match_rules >= 0);
1294
1295 #ifdef DBUS_ENABLE_STATS
1296   d->connections->total_match_rules -= 1;
1297 #endif
1298 }
1299
1300 int
1301 bus_connection_get_n_match_rules (DBusConnection *connection)
1302 {
1303   BusConnectionData *d;
1304
1305   d = BUS_CONNECTION_DATA (connection);
1306   _dbus_assert (d != NULL);
1307   
1308   return d->n_match_rules;
1309 }
1310
1311 void
1312 bus_connection_add_owned_service_link (DBusConnection *connection,
1313                                        DBusList       *link)
1314 {
1315   BusConnectionData *d;
1316
1317   d = BUS_CONNECTION_DATA (connection);
1318   _dbus_assert (d != NULL);
1319
1320   _dbus_list_append_link (&d->services_owned, link);
1321
1322   d->n_services_owned += 1;
1323
1324 #ifdef DBUS_ENABLE_STATS
1325   update_peak (&d->peak_bus_names, d->n_services_owned);
1326   update_peak (&d->connections->peak_bus_names_per_conn,
1327                d->n_services_owned);
1328
1329   d->connections->total_bus_names += 1;
1330   update_peak (&d->connections->peak_bus_names,
1331                d->connections->total_bus_names);
1332 #endif
1333 }
1334
1335 dbus_bool_t
1336 bus_connection_add_owned_service (DBusConnection *connection,
1337                                   BusService     *service)
1338 {
1339   DBusList *link;
1340
1341   link = _dbus_list_alloc_link (service);
1342
1343   if (link == NULL)
1344     return FALSE;
1345
1346   bus_connection_add_owned_service_link (connection, link);
1347
1348   return TRUE;
1349 }
1350
1351 void
1352 bus_connection_remove_owned_service (DBusConnection *connection,
1353                                      BusService     *service)
1354 {
1355   BusConnectionData *d;
1356
1357   d = BUS_CONNECTION_DATA (connection);
1358   _dbus_assert (d != NULL);
1359
1360   _dbus_list_remove_last (&d->services_owned, service);
1361
1362   d->n_services_owned -= 1;
1363   _dbus_assert (d->n_services_owned >= 0);
1364
1365 #ifdef DBUS_ENABLE_STATS
1366   d->connections->total_bus_names -= 1;
1367 #endif
1368 }
1369
1370 int
1371 bus_connection_get_n_services_owned (DBusConnection *connection)
1372 {
1373   BusConnectionData *d;
1374
1375   d = BUS_CONNECTION_DATA (connection);
1376   _dbus_assert (d != NULL);
1377   
1378   return d->n_services_owned;
1379 }
1380
1381 DBusList**
1382 bus_connection_get_services_owned (DBusConnection *connection)
1383 {
1384     BusConnectionData *d;
1385     d = BUS_CONNECTION_DATA (connection);
1386     _dbus_assert (d != NULL);
1387
1388     return &d->services_owned;
1389 }
1390
1391 dbus_bool_t
1392 bus_connection_complete (DBusConnection   *connection,
1393                          const DBusString *name,
1394                          DBusError        *error)
1395 {
1396   BusConnectionData *d;
1397   unsigned long uid;
1398   
1399   d = BUS_CONNECTION_DATA (connection);
1400   _dbus_assert (d != NULL);
1401   _dbus_assert (d->name == NULL);
1402   _dbus_assert (d->policy == NULL);
1403
1404   _dbus_assert (!bus_connection_is_active (connection));
1405   
1406   if (!_dbus_string_copy_data (name, &d->name))
1407     {
1408       BUS_SET_OOM (error);
1409       return FALSE;
1410     }
1411
1412   _dbus_assert (d->name != NULL);
1413   
1414   _dbus_verbose ("Name %s assigned to %p\n", d->name, connection);
1415
1416   d->policy = bus_context_create_client_policy (d->connections->context,
1417                                                 connection,
1418                                                 error);
1419
1420   /* we may have a NULL policy on OOM or error getting list of
1421    * groups for a user. In the latter case we don't handle it so
1422    * well currently, as it will just keep failing over and over.
1423    */
1424
1425   if (d->policy == NULL)
1426     {
1427       _dbus_verbose ("Failed to create security policy for connection %p\n",
1428                      connection);
1429       _DBUS_ASSERT_ERROR_IS_SET (error);
1430       dbus_free (d->name);
1431       d->name = NULL;
1432       return FALSE;
1433     }
1434   
1435   if (dbus_connection_get_unix_user (connection, &uid))
1436     {
1437       if (!adjust_connections_for_uid (d->connections,
1438                                        uid, 1))
1439         goto fail;
1440     }
1441
1442   /* Create and cache a string which holds information about the 
1443    * peer process; used for logging purposes.
1444    */
1445   if (!cache_peer_loginfo_string (d, connection))
1446     goto fail;
1447
1448   /* Now the connection is active, move it between lists */
1449   _dbus_list_unlink (&d->connections->incomplete,
1450                      d->link_in_connection_list);
1451   d->connections->n_incomplete -= 1;
1452   _dbus_list_append_link (&d->connections->completed,
1453                           d->link_in_connection_list);
1454   d->connections->n_completed += 1;
1455
1456   _dbus_assert (d->connections->n_incomplete >= 0);
1457   _dbus_assert (d->connections->n_completed > 0);
1458
1459   /* See if we can remove the timeout */
1460   bus_connections_expire_incomplete (d->connections);
1461
1462   _dbus_assert (bus_connection_is_active (connection));
1463   
1464   return TRUE;
1465 fail:
1466   BUS_SET_OOM (error);
1467   dbus_free (d->name);
1468   d->name = NULL;
1469   if (d->policy)
1470     bus_client_policy_unref (d->policy);
1471   d->policy = NULL;
1472   return FALSE;
1473 }
1474
1475 const char *
1476 bus_connection_get_name (DBusConnection *connection)
1477 {
1478   BusConnectionData *d;
1479   
1480   d = BUS_CONNECTION_DATA (connection);
1481   _dbus_assert (d != NULL);
1482   
1483   return d->name;
1484 }
1485
1486 /**
1487  * Check whether completing the passed-in connection would
1488  * exceed limits, and if so set error and return #FALSE
1489  */
1490 dbus_bool_t
1491 bus_connections_check_limits (BusConnections  *connections,
1492                               DBusConnection  *requesting_completion,
1493                               DBusError       *error)
1494 {
1495   unsigned long uid;
1496
1497   if (connections->n_completed >=
1498       bus_context_get_max_completed_connections (connections->context))
1499     {
1500       dbus_set_error (error, DBUS_ERROR_LIMITS_EXCEEDED,
1501                       "The maximum number of active connections has been reached");
1502       return FALSE;
1503     }
1504   
1505   if (dbus_connection_get_unix_user (requesting_completion, &uid))
1506     {
1507       if (get_connections_for_uid (connections, uid) >=
1508           bus_context_get_max_connections_per_user (connections->context))
1509         {
1510           dbus_set_error (error, DBUS_ERROR_LIMITS_EXCEEDED,
1511                           "The maximum number of active connections for UID %lu has been reached",
1512                           uid);
1513           return FALSE;
1514         }
1515     }
1516   
1517   return TRUE;
1518 }
1519
1520 static void
1521 bus_pending_reply_free (BusPendingReply *pending)
1522 {
1523   _dbus_verbose ("Freeing pending reply %p, replier %p receiver %p serial %u\n",
1524                  pending,
1525                  pending->will_send_reply,
1526                  pending->will_get_reply,
1527                  pending->reply_serial);
1528
1529   dbus_free (pending);
1530 }
1531
1532 static dbus_bool_t
1533 bus_pending_reply_send_no_reply (BusConnections  *connections,
1534                                  BusTransaction  *transaction,
1535                                  BusPendingReply *pending)
1536 {
1537   DBusMessage *message;
1538   DBusMessageIter iter;
1539   dbus_bool_t retval;
1540   const char *errmsg;
1541
1542   retval = FALSE;
1543   
1544   message = dbus_message_new (DBUS_MESSAGE_TYPE_ERROR);
1545   if (message == NULL)
1546     return FALSE;
1547   
1548   dbus_message_set_no_reply (message, TRUE);
1549   
1550   if (!dbus_message_set_reply_serial (message,
1551                                       pending->reply_serial))
1552     goto out;
1553
1554   if (!dbus_message_set_error_name (message,
1555                                     DBUS_ERROR_NO_REPLY))
1556     goto out;
1557
1558   errmsg = "Message did not receive a reply (timeout by message bus)";
1559   dbus_message_iter_init_append (message, &iter);
1560   if (!dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, &errmsg))
1561     goto out;
1562     
1563   if (!bus_transaction_send_from_driver (transaction, pending->will_get_reply,
1564                                          message))
1565     goto out;
1566
1567   retval = TRUE;
1568
1569  out:
1570   dbus_message_unref (message);
1571   return retval;
1572 }
1573
1574 static dbus_bool_t
1575 bus_pending_reply_expired (BusExpireList *list,
1576                            DBusList      *link,
1577                            void          *data)
1578 {
1579   BusPendingReply *pending = link->data;
1580   BusConnections *connections = data;
1581   BusTransaction *transaction;
1582   
1583   /* No reply is forthcoming. So nuke it if we can. If not,
1584    * leave it in the list to try expiring again later when we
1585    * get more memory.
1586    */
1587
1588   _dbus_verbose ("Expiring pending reply %p, replier %p receiver %p serial %u\n",
1589                  pending,
1590                  pending->will_send_reply,
1591                  pending->will_get_reply,
1592                  pending->reply_serial);
1593   
1594   transaction = bus_transaction_new (connections->context);
1595   if (transaction == NULL)
1596     return FALSE;
1597   
1598   if (!bus_pending_reply_send_no_reply (connections,
1599                                         transaction,
1600                                         pending))
1601     {
1602       bus_transaction_cancel_and_free (transaction);
1603       return FALSE;
1604     }
1605
1606   bus_expire_list_remove_link (connections->pending_replies, link);
1607
1608   bus_pending_reply_free (pending);
1609   bus_transaction_execute_and_free (transaction);
1610
1611   return TRUE;
1612 }
1613
1614 static void
1615 bus_connection_drop_pending_replies (BusConnections  *connections,
1616                                      DBusConnection  *connection)
1617 {
1618   /* The DBusConnection is almost 100% finalized here, so you can't
1619    * do anything with it except check for pointer equality
1620    */
1621   DBusList *link;
1622
1623   _dbus_verbose ("Dropping pending replies that involve connection %p\n",
1624                  connection);
1625   
1626   link = bus_expire_list_get_first_link (connections->pending_replies);
1627   while (link != NULL)
1628     {
1629       DBusList *next;
1630       BusPendingReply *pending;
1631
1632       next = bus_expire_list_get_next_link (connections->pending_replies,
1633                                             link);
1634       pending = link->data;
1635
1636       if (pending->will_get_reply == connection)
1637         {
1638           /* We don't need to track this pending reply anymore */
1639
1640           _dbus_verbose ("Dropping pending reply %p, replier %p receiver %p serial %u\n",
1641                          pending,
1642                          pending->will_send_reply,
1643                          pending->will_get_reply,
1644                          pending->reply_serial);
1645           
1646           bus_expire_list_remove_link (connections->pending_replies,
1647                                        link);
1648           bus_pending_reply_free (pending);
1649         }
1650       else if (pending->will_send_reply == connection)
1651         {
1652           /* The reply isn't going to be sent, so set things
1653            * up so it will be expired right away
1654            */
1655           _dbus_verbose ("Will expire pending reply %p, replier %p receiver %p serial %u\n",
1656                          pending,
1657                          pending->will_send_reply,
1658                          pending->will_get_reply,
1659                          pending->reply_serial);
1660           
1661           pending->will_send_reply = NULL;
1662           pending->expire_item.added_tv_sec = 0;
1663           pending->expire_item.added_tv_usec = 0;
1664
1665           bus_expire_list_recheck_immediately (connections->pending_replies);
1666         }
1667       
1668       link = next;
1669     }
1670 }
1671
1672
1673 typedef struct
1674 {
1675   BusPendingReply *pending;
1676   BusConnections  *connections;
1677 } CancelPendingReplyData;
1678
1679 static void
1680 cancel_pending_reply (void *data)
1681 {
1682   CancelPendingReplyData *d = data;
1683
1684   _dbus_verbose ("d = %p\n", d);
1685   
1686   if (!bus_expire_list_remove (d->connections->pending_replies,
1687                                &d->pending->expire_item))
1688     _dbus_assert_not_reached ("pending reply did not exist to be cancelled");
1689
1690   bus_pending_reply_free (d->pending); /* since it's been cancelled */
1691 }
1692
1693 static void
1694 cancel_pending_reply_data_free (void *data)
1695 {
1696   CancelPendingReplyData *d = data;
1697
1698   _dbus_verbose ("d = %p\n", d);
1699   
1700   /* d->pending should be either freed or still
1701    * in the list of pending replies (owned by someone
1702    * else)
1703    */
1704   
1705   dbus_free (d);
1706 }
1707
1708 /*
1709  * Record that a reply is allowed; return TRUE on success.
1710  */
1711 dbus_bool_t
1712 bus_connections_expect_reply (BusConnections  *connections,
1713                               BusTransaction  *transaction,
1714                               DBusConnection  *will_get_reply,
1715                               DBusConnection  *will_send_reply,
1716                               DBusMessage     *reply_to_this,
1717                               DBusError       *error)
1718 {
1719   BusPendingReply *pending;
1720   dbus_uint32_t reply_serial;
1721   DBusList *link;
1722   CancelPendingReplyData *cprd;
1723   int count;
1724
1725   _dbus_assert (will_get_reply != NULL);
1726   _dbus_assert (will_send_reply != NULL);
1727   _dbus_assert (reply_to_this != NULL);
1728   
1729   if (dbus_message_get_no_reply (reply_to_this))
1730     return TRUE; /* we won't allow a reply, since client doesn't care for one. */
1731   
1732   reply_serial = dbus_message_get_serial (reply_to_this);
1733
1734   link = bus_expire_list_get_first_link (connections->pending_replies);
1735   count = 0;
1736   while (link != NULL)
1737     {
1738       pending = link->data;
1739
1740       if (pending->reply_serial == reply_serial &&
1741           pending->will_get_reply == will_get_reply &&
1742           pending->will_send_reply == will_send_reply)
1743         {
1744           dbus_set_error (error, DBUS_ERROR_ACCESS_DENIED,
1745                           "Message has the same reply serial as a currently-outstanding existing method call");
1746           return FALSE;
1747         }
1748       
1749       link = bus_expire_list_get_next_link (connections->pending_replies,
1750                                             link);
1751       if (pending->will_get_reply == will_get_reply)
1752         ++count;
1753     }
1754   
1755   if (count >=
1756       bus_context_get_max_replies_per_connection (connections->context))
1757     {
1758       dbus_set_error (error, DBUS_ERROR_LIMITS_EXCEEDED,
1759                       "The maximum number of pending replies per connection has been reached");
1760       return FALSE;
1761     }
1762
1763   pending = dbus_new0 (BusPendingReply, 1);
1764   if (pending == NULL)
1765     {
1766       BUS_SET_OOM (error);
1767       return FALSE;
1768     }
1769
1770 #ifdef DBUS_ENABLE_VERBOSE_MODE
1771   /* so we can see a not-yet-added pending reply */
1772   pending->expire_item.added_tv_sec = 1;
1773   pending->expire_item.added_tv_usec = 1;
1774 #endif
1775
1776   pending->will_get_reply = will_get_reply;
1777   pending->will_send_reply = will_send_reply;
1778   pending->reply_serial = reply_serial;
1779   
1780   cprd = dbus_new0 (CancelPendingReplyData, 1);
1781   if (cprd == NULL)
1782     {
1783       BUS_SET_OOM (error);
1784       bus_pending_reply_free (pending);
1785       return FALSE;
1786     }
1787   
1788   if (!bus_expire_list_add (connections->pending_replies,
1789                             &pending->expire_item))
1790     {
1791       BUS_SET_OOM (error);
1792       dbus_free (cprd);
1793       bus_pending_reply_free (pending);
1794       return FALSE;
1795     }
1796
1797   if (!bus_transaction_add_cancel_hook (transaction,
1798                                         cancel_pending_reply,
1799                                         cprd,
1800                                         cancel_pending_reply_data_free))
1801     {
1802       BUS_SET_OOM (error);
1803       bus_expire_list_remove (connections->pending_replies, &pending->expire_item);
1804       dbus_free (cprd);
1805       bus_pending_reply_free (pending);
1806       return FALSE;
1807     }
1808                                         
1809   cprd->pending = pending;
1810   cprd->connections = connections;
1811   
1812   _dbus_get_monotonic_time (&pending->expire_item.added_tv_sec,
1813                             &pending->expire_item.added_tv_usec);
1814
1815   _dbus_verbose ("Added pending reply %p, replier %p receiver %p serial %u\n",
1816                  pending,
1817                  pending->will_send_reply,
1818                  pending->will_get_reply,
1819                  pending->reply_serial);
1820   
1821   return TRUE;
1822 }
1823
1824 typedef struct
1825 {
1826   DBusList        *link;
1827   BusConnections  *connections;
1828 } CheckPendingReplyData;
1829
1830 static void
1831 cancel_check_pending_reply (void *data)
1832 {
1833   CheckPendingReplyData *d = data;
1834
1835   _dbus_verbose ("d = %p\n",d);
1836
1837   bus_expire_list_add_link (d->connections->pending_replies,
1838                             d->link);
1839   d->link = NULL;
1840 }
1841
1842 static void
1843 check_pending_reply_data_free (void *data)
1844 {
1845   CheckPendingReplyData *d = data;
1846
1847   _dbus_verbose ("d = %p\n",d);
1848   
1849   if (d->link != NULL)
1850     {
1851       BusPendingReply *pending = d->link->data;
1852       
1853       _dbus_assert (!bus_expire_list_contains_item (d->connections->pending_replies,
1854                                                     &pending->expire_item));
1855       
1856       bus_pending_reply_free (pending);
1857       _dbus_list_free_link (d->link);
1858     }
1859   
1860   dbus_free (d);
1861 }
1862
1863 /*
1864  * Check whether a reply is allowed, remove BusPendingReply
1865  * if so, return TRUE if so.
1866  */
1867 dbus_bool_t
1868 bus_connections_check_reply (BusConnections *connections,
1869                              BusTransaction *transaction,
1870                              DBusConnection *sending_reply,
1871                              DBusConnection *receiving_reply,
1872                              DBusMessage    *reply,
1873                              DBusError      *error)
1874 {
1875   CheckPendingReplyData *cprd;
1876   DBusList *link;
1877   dbus_uint32_t reply_serial;
1878   
1879   _dbus_assert (sending_reply != NULL);
1880   _dbus_assert (receiving_reply != NULL);
1881
1882   reply_serial = dbus_message_get_reply_serial (reply);
1883
1884   link = bus_expire_list_get_first_link (connections->pending_replies);
1885   while (link != NULL)
1886     {
1887       BusPendingReply *pending = link->data;
1888
1889       if (pending->reply_serial == reply_serial &&
1890           pending->will_get_reply == receiving_reply &&
1891           pending->will_send_reply == sending_reply)
1892         {
1893           _dbus_verbose ("Found pending reply with serial %u\n", reply_serial);
1894           break;
1895         }
1896       
1897       link = bus_expire_list_get_next_link (connections->pending_replies,
1898                                             link);
1899     }
1900
1901   if (link == NULL)
1902     {
1903       _dbus_verbose ("No pending reply expected\n");
1904
1905       return FALSE;
1906     }
1907
1908   cprd = dbus_new0 (CheckPendingReplyData, 1);
1909   if (cprd == NULL)
1910     {
1911       BUS_SET_OOM (error);
1912       return FALSE;
1913     }
1914   
1915   if (!bus_transaction_add_cancel_hook (transaction,
1916                                         cancel_check_pending_reply,
1917                                         cprd,
1918                                         check_pending_reply_data_free))
1919     {
1920       BUS_SET_OOM (error);
1921       dbus_free (cprd);
1922       return FALSE;
1923     }
1924
1925   cprd->link = link;
1926   cprd->connections = connections;
1927   
1928   bus_expire_list_unlink (connections->pending_replies,
1929                           link);
1930   
1931   _dbus_assert (!bus_expire_list_contains_item (connections->pending_replies, link->data));
1932
1933   return TRUE;
1934 }
1935
1936 /*
1937  * Transactions
1938  *
1939  * Note that this is fairly fragile; in particular, don't try to use
1940  * one transaction across any main loop iterations.
1941  */
1942
1943 typedef struct
1944 {
1945   BusTransaction *transaction;
1946   DBusMessage    *message;
1947   DBusPreallocatedSend *preallocated;
1948 } MessageToSend;
1949
1950 typedef struct
1951 {
1952   BusTransactionCancelFunction cancel_function;
1953   DBusFreeFunction free_data_function;
1954   void *data;
1955 } CancelHook;
1956
1957 struct BusTransaction
1958 {
1959   DBusList *connections;
1960   BusContext *context;
1961   DBusList *cancel_hooks;
1962 };
1963
1964 static void
1965 message_to_send_free (DBusConnection *connection,
1966                       MessageToSend  *to_send)
1967 {
1968   if (to_send->message)
1969     dbus_message_unref (to_send->message);
1970
1971   if (to_send->preallocated)
1972     dbus_connection_free_preallocated_send (connection, to_send->preallocated);
1973
1974   dbus_free (to_send);
1975 }
1976
1977 static void
1978 cancel_hook_cancel (void *element,
1979                     void *data)
1980 {
1981   CancelHook *ch = element;
1982
1983   _dbus_verbose ("Running transaction cancel hook\n");
1984   
1985   if (ch->cancel_function)
1986     (* ch->cancel_function) (ch->data);  
1987 }
1988
1989 static void
1990 cancel_hook_free (void *element,
1991                   void *data)
1992 {
1993   CancelHook *ch = element;
1994
1995   if (ch->free_data_function)
1996     (* ch->free_data_function) (ch->data);
1997
1998   dbus_free (ch);
1999 }
2000
2001 static void
2002 free_cancel_hooks (BusTransaction *transaction)
2003 {
2004   _dbus_list_foreach (&transaction->cancel_hooks,
2005                       cancel_hook_free, NULL);
2006   
2007   _dbus_list_clear (&transaction->cancel_hooks);
2008 }
2009
2010 BusTransaction*
2011 bus_transaction_new (BusContext *context)
2012 {
2013   BusTransaction *transaction;
2014
2015   transaction = dbus_new0 (BusTransaction, 1);
2016   if (transaction == NULL)
2017     return NULL;
2018
2019   transaction->context = context;
2020   
2021   return transaction;
2022 }
2023
2024 BusContext*
2025 bus_transaction_get_context (BusTransaction  *transaction)
2026 {
2027   return transaction->context;
2028 }
2029
2030 BusConnections*
2031 bus_transaction_get_connections (BusTransaction  *transaction)
2032 {
2033   return bus_context_get_connections (transaction->context);
2034 }
2035
2036 dbus_bool_t
2037 bus_transaction_send_from_driver (BusTransaction *transaction,
2038                                   DBusConnection *connection,
2039                                   DBusMessage    *message)
2040 {
2041   /* We have to set the sender to the driver, and have
2042    * to check security policy since it was not done in
2043    * dispatch.c
2044    */
2045   _dbus_verbose ("Sending %s %s %s from driver\n",
2046                  dbus_message_get_interface (message) ?
2047                  dbus_message_get_interface (message) : "(no interface)",
2048                  dbus_message_get_member (message) ?
2049                  dbus_message_get_member (message) : "(no member)",
2050                  dbus_message_get_error_name (message) ?
2051                  dbus_message_get_error_name (message) : "(no error name)");
2052                  
2053   if (!dbus_message_set_sender (message, DBUS_SERVICE_DBUS))
2054     return FALSE;
2055
2056   if(!bus_context_is_kdbus(bus_transaction_get_context (transaction))) /* we can't set destination on the basis of connection when on kdbus*/
2057     if (bus_connection_is_active (connection))
2058     {
2059       if (!dbus_message_set_destination (message,
2060                                          bus_connection_get_name (connection)))
2061         return FALSE;
2062     }
2063   
2064   /* bus driver never wants a reply */
2065   dbus_message_set_no_reply (message, TRUE);
2066   
2067   /* If security policy doesn't allow the message, we silently
2068    * eat it; the driver doesn't care about getting a reply.
2069    */
2070   if (!bus_context_check_security_policy (bus_transaction_get_context (transaction),
2071                                           transaction,
2072                                           NULL, connection, connection, message, NULL))
2073     return TRUE;
2074
2075   return bus_transaction_send (transaction, connection, message);
2076 }
2077
2078 dbus_bool_t
2079 bus_transaction_send (BusTransaction *transaction,
2080                       DBusConnection *connection,
2081                       DBusMessage    *message)
2082 {
2083   MessageToSend *to_send;
2084   BusConnectionData *d;
2085   DBusList *link;
2086
2087   _dbus_verbose ("  trying to add %s interface=%s member=%s error=%s to transaction%s\n",
2088                  dbus_message_get_type (message) == DBUS_MESSAGE_TYPE_ERROR ? "error" :
2089                  dbus_message_get_reply_serial (message) != 0 ? "reply" :
2090                  "message",
2091                  dbus_message_get_interface (message) ?
2092                  dbus_message_get_interface (message) : "(unset)",
2093                  dbus_message_get_member (message) ?
2094                  dbus_message_get_member (message) : "(unset)",
2095                  dbus_message_get_error_name (message) ?
2096                  dbus_message_get_error_name (message) : "(unset)",
2097                  dbus_connection_get_is_connected (connection) ?
2098                  "" : " (disconnected)");
2099
2100   _dbus_assert (dbus_message_get_sender (message) != NULL);
2101   
2102   if (!dbus_connection_get_is_connected (connection))
2103     return TRUE; /* silently ignore disconnected connections */
2104   
2105   d = BUS_CONNECTION_DATA (connection);
2106   _dbus_assert (d != NULL);
2107   
2108   to_send = dbus_new (MessageToSend, 1);
2109   if (to_send == NULL)
2110     {
2111       return FALSE;
2112     }
2113
2114   to_send->preallocated = dbus_connection_preallocate_send (connection);
2115   if (to_send->preallocated == NULL)
2116     {
2117       dbus_free (to_send);
2118       return FALSE;
2119     }  
2120   
2121   dbus_message_ref (message);
2122   to_send->message = message;
2123   to_send->transaction = transaction;
2124
2125   _dbus_verbose ("about to prepend message\n");
2126   
2127   if (!_dbus_list_prepend (&d->transaction_messages, to_send))
2128     {
2129       message_to_send_free (connection, to_send);
2130       return FALSE;
2131     }
2132
2133   _dbus_verbose ("prepended message\n");
2134   
2135   /* See if we already had this connection in the list
2136    * for this transaction. If we have a pending message,
2137    * then we should already be in transaction->connections
2138    */
2139   link = _dbus_list_get_first_link (&d->transaction_messages);
2140   _dbus_assert (link->data == to_send);
2141   link = _dbus_list_get_next_link (&d->transaction_messages, link);
2142   while (link != NULL)
2143     {
2144       MessageToSend *m = link->data;
2145       DBusList *next = _dbus_list_get_next_link (&d->transaction_messages, link);
2146       
2147       if (m->transaction == transaction)
2148         break;
2149         
2150       link = next;
2151     }
2152
2153   if (link == NULL)
2154     {
2155       if (!_dbus_list_prepend (&transaction->connections, connection))
2156         {
2157           _dbus_list_remove (&d->transaction_messages, to_send);
2158           message_to_send_free (connection, to_send);
2159           return FALSE;
2160         }
2161     }
2162
2163   return TRUE;
2164 }
2165
2166 static void
2167 connection_cancel_transaction (DBusConnection *connection,
2168                                BusTransaction *transaction)
2169 {
2170   DBusList *link;
2171   BusConnectionData *d;
2172   
2173   d = BUS_CONNECTION_DATA (connection);
2174   _dbus_assert (d != NULL);
2175   
2176   link = _dbus_list_get_first_link (&d->transaction_messages);
2177   while (link != NULL)
2178     {
2179       MessageToSend *m = link->data;
2180       DBusList *next = _dbus_list_get_next_link (&d->transaction_messages, link);
2181       
2182       if (m->transaction == transaction)
2183         {
2184           _dbus_list_remove_link (&d->transaction_messages,
2185                                   link);
2186           
2187           message_to_send_free (connection, m);
2188         }
2189         
2190       link = next;
2191     }
2192 }
2193
2194 void
2195 bus_transaction_cancel_and_free (BusTransaction *transaction)
2196 {
2197   DBusConnection *connection;
2198
2199   _dbus_verbose ("TRANSACTION: cancelled\n");
2200   
2201   while ((connection = _dbus_list_pop_first (&transaction->connections)))
2202     connection_cancel_transaction (connection, transaction);
2203
2204   _dbus_assert (transaction->connections == NULL);
2205
2206   _dbus_list_foreach (&transaction->cancel_hooks,
2207                       cancel_hook_cancel, NULL);
2208
2209   free_cancel_hooks (transaction);
2210   
2211   dbus_free (transaction);
2212 }
2213
2214 static void
2215 connection_execute_transaction (DBusConnection *connection,
2216                                 BusTransaction *transaction)
2217 {
2218   DBusList *link;
2219   BusConnectionData *d;
2220   
2221   d = BUS_CONNECTION_DATA (connection);
2222   _dbus_assert (d != NULL);
2223
2224   /* Send the queue in order (FIFO) */
2225   link = _dbus_list_get_last_link (&d->transaction_messages);
2226   while (link != NULL)
2227     {
2228       MessageToSend *m = link->data;
2229       DBusList *prev = _dbus_list_get_prev_link (&d->transaction_messages, link);
2230       
2231       if (m->transaction == transaction)
2232         {
2233           _dbus_list_remove_link (&d->transaction_messages,
2234                                   link);
2235
2236           _dbus_assert (dbus_message_get_sender (m->message) != NULL);
2237           
2238           dbus_connection_send_preallocated (connection,
2239                                              m->preallocated,
2240                                              m->message,
2241                                              NULL);
2242
2243           m->preallocated = NULL; /* so we don't double-free it */
2244           
2245           message_to_send_free (connection, m);
2246         }
2247         
2248       link = prev;
2249     }
2250 }
2251
2252 void
2253 bus_transaction_execute_and_free (BusTransaction *transaction)
2254 {
2255   /* For each connection in transaction->connections
2256    * send the messages
2257    */
2258   DBusConnection *connection;
2259
2260   _dbus_verbose ("TRANSACTION: executing\n");
2261   
2262   while ((connection = _dbus_list_pop_first (&transaction->connections)))
2263     connection_execute_transaction (connection, transaction);
2264
2265   _dbus_assert (transaction->connections == NULL);
2266
2267   free_cancel_hooks (transaction);
2268   
2269   dbus_free (transaction);
2270 }
2271
2272 void
2273 bus_transaction_free (BusTransaction *transaction)
2274 {
2275           free_cancel_hooks (transaction);
2276           dbus_free (transaction);
2277 }
2278
2279 static void
2280 bus_connection_remove_transactions (DBusConnection *connection)
2281 {
2282   MessageToSend *to_send;
2283   BusConnectionData *d;
2284   
2285   d = BUS_CONNECTION_DATA (connection);
2286   _dbus_assert (d != NULL);
2287   
2288   while ((to_send = _dbus_list_get_first (&d->transaction_messages)))
2289     {
2290       /* only has an effect for the first MessageToSend listing this transaction */
2291       _dbus_list_remove (&to_send->transaction->connections,
2292                          connection);
2293
2294       _dbus_list_remove (&d->transaction_messages, to_send);
2295       message_to_send_free (connection, to_send);
2296     }
2297 }
2298
2299 /**
2300  * Converts the DBusError to a message reply
2301  */
2302 dbus_bool_t
2303 bus_transaction_send_error_reply (BusTransaction  *transaction,
2304                                   DBusConnection  *connection,
2305                                   const DBusError *error,
2306                                   DBusMessage     *in_reply_to)
2307 {
2308   DBusMessage *reply;
2309   
2310   _dbus_assert (error != NULL);
2311   _DBUS_ASSERT_ERROR_IS_SET (error);
2312   
2313   _dbus_verbose ("Sending error reply %s \"%s\"\n",
2314                  error->name, error->message);
2315
2316   reply = dbus_message_new_error (in_reply_to,
2317                                   error->name,
2318                                   error->message);
2319   if (reply == NULL)
2320     return FALSE;
2321
2322   if (!bus_transaction_send_from_driver (transaction, connection, reply))
2323     {
2324       dbus_message_unref (reply);
2325       return FALSE;
2326     }
2327
2328   dbus_message_unref (reply);
2329   
2330   return TRUE;
2331 }
2332
2333 dbus_bool_t
2334 bus_transaction_add_cancel_hook (BusTransaction               *transaction,
2335                                  BusTransactionCancelFunction  cancel_function,
2336                                  void                         *data,
2337                                  DBusFreeFunction              free_data_function)
2338 {
2339   CancelHook *ch;
2340
2341   ch = dbus_new (CancelHook, 1);
2342   if (ch == NULL)
2343     return FALSE;
2344
2345   _dbus_verbose ("     adding cancel hook function = %p data = %p\n",
2346                  cancel_function, data);
2347   
2348   ch->cancel_function = cancel_function;
2349   ch->data = data;
2350   ch->free_data_function = free_data_function;
2351
2352   /* It's important that the hooks get run in reverse order that they
2353    * were added
2354    */
2355   if (!_dbus_list_prepend (&transaction->cancel_hooks, ch))
2356     {
2357       dbus_free (ch);
2358       return FALSE;
2359     }
2360
2361   return TRUE;
2362 }
2363
2364 #ifdef DBUS_ENABLE_STATS
2365 int
2366 bus_connections_get_n_active (BusConnections *connections)
2367 {
2368   return connections->n_completed;
2369 }
2370
2371 int
2372 bus_connections_get_n_incomplete (BusConnections *connections)
2373 {
2374   return connections->n_incomplete;
2375 }
2376
2377 int
2378 bus_connections_get_total_match_rules (BusConnections *connections)
2379 {
2380   return connections->total_match_rules;
2381 }
2382
2383 int
2384 bus_connections_get_peak_match_rules (BusConnections *connections)
2385 {
2386   return connections->peak_match_rules;
2387 }
2388
2389 int
2390 bus_connections_get_peak_match_rules_per_conn (BusConnections *connections)
2391 {
2392   return connections->peak_match_rules_per_conn;
2393 }
2394
2395 int
2396 bus_connections_get_total_bus_names (BusConnections *connections)
2397 {
2398   return connections->total_bus_names;
2399 }
2400
2401 int
2402 bus_connections_get_peak_bus_names (BusConnections *connections)
2403 {
2404   return connections->peak_bus_names;
2405 }
2406
2407 int
2408 bus_connections_get_peak_bus_names_per_conn (BusConnections *connections)
2409 {
2410   return connections->peak_bus_names_per_conn;
2411 }
2412
2413 int
2414 bus_connection_get_peak_match_rules (DBusConnection *connection)
2415 {
2416   BusConnectionData *d;
2417
2418   d = BUS_CONNECTION_DATA (connection);
2419   return d->peak_match_rules;
2420 }
2421
2422 int
2423 bus_connection_get_peak_bus_names (DBusConnection *connection)
2424 {
2425   BusConnectionData *d;
2426
2427   d = BUS_CONNECTION_DATA (connection);
2428   return d->peak_bus_names;
2429 }
2430 #endif /* DBUS_ENABLE_STATS */