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