chiark / gitweb /
sd-bus: log about bus state changes
[elogind.git] / src / libelogind / sd-bus / bus-internal.h
1 /* SPDX-License-Identifier: LGPL-2.1+ */
2 #pragma once
3
4 /***
5   This file is part of systemd.
6
7   Copyright 2013 Lennart Poettering
8
9   systemd is free software; you can redistribute it and/or modify it
10   under the terms of the GNU Lesser General Public License as published by
11   the Free Software Foundation; either version 2.1 of the License, or
12   (at your option) any later version.
13
14   systemd is distributed in the hope that it will be useful, but
15   WITHOUT ANY WARRANTY; without even the implied warranty of
16   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17   Lesser General Public License for more details.
18
19   You should have received a copy of the GNU Lesser General Public License
20   along with systemd; If not, see <http://www.gnu.org/licenses/>.
21 ***/
22
23 #include <pthread.h>
24 #include <sys/socket.h>
25
26 #include "sd-bus.h"
27
28 #include "bus-error.h"
29 #include "bus-kernel.h"
30 #include "bus-match.h"
31 #include "def.h"
32 #include "hashmap.h"
33 #include "list.h"
34 #include "prioq.h"
35 #include "refcnt.h"
36 #include "socket-util.h"
37 #include "util.h"
38
39 struct reply_callback {
40         sd_bus_message_handler_t callback;
41         usec_t timeout_usec; /* this is a relative timeout until we reach the BUS_HELLO state, and an absolute one right after */
42         uint64_t cookie;
43         unsigned prioq_idx;
44 };
45
46 struct filter_callback {
47         sd_bus_message_handler_t callback;
48
49         unsigned last_iteration;
50
51         LIST_FIELDS(struct filter_callback, callbacks);
52 };
53
54 struct match_callback {
55         sd_bus_message_handler_t callback;
56         sd_bus_message_handler_t install_callback;
57
58         sd_bus_slot *install_slot; /* The AddMatch() call */
59
60         unsigned last_iteration;
61
62         char *match_string;
63
64         struct bus_match_node *match_node;
65 };
66
67 struct node {
68         char *path;
69         struct node *parent;
70         LIST_HEAD(struct node, child);
71         LIST_FIELDS(struct node, siblings);
72
73         LIST_HEAD(struct node_callback, callbacks);
74         LIST_HEAD(struct node_vtable, vtables);
75         LIST_HEAD(struct node_enumerator, enumerators);
76         LIST_HEAD(struct node_object_manager, object_managers);
77 };
78
79 struct node_callback {
80         struct node *node;
81
82         bool is_fallback;
83         sd_bus_message_handler_t callback;
84
85         unsigned last_iteration;
86
87         LIST_FIELDS(struct node_callback, callbacks);
88 };
89
90 struct node_enumerator {
91         struct node *node;
92
93         sd_bus_node_enumerator_t callback;
94
95         unsigned last_iteration;
96
97         LIST_FIELDS(struct node_enumerator, enumerators);
98 };
99
100 struct node_object_manager {
101         struct node *node;
102
103         LIST_FIELDS(struct node_object_manager, object_managers);
104 };
105
106 struct node_vtable {
107         struct node *node;
108
109         char *interface;
110         bool is_fallback;
111         const sd_bus_vtable *vtable;
112         sd_bus_object_find_t find;
113
114         unsigned last_iteration;
115
116         LIST_FIELDS(struct node_vtable, vtables);
117 };
118
119 struct vtable_member {
120         const char *path;
121         const char *interface;
122         const char *member;
123         struct node_vtable *parent;
124         unsigned last_iteration;
125         const sd_bus_vtable *vtable;
126 };
127
128 typedef enum BusSlotType {
129         BUS_REPLY_CALLBACK,
130         BUS_FILTER_CALLBACK,
131         BUS_MATCH_CALLBACK,
132         BUS_NODE_CALLBACK,
133         BUS_NODE_ENUMERATOR,
134         BUS_NODE_VTABLE,
135         BUS_NODE_OBJECT_MANAGER,
136         _BUS_SLOT_INVALID = -1,
137 } BusSlotType;
138
139 struct sd_bus_slot {
140         unsigned n_ref;
141         sd_bus *bus;
142         void *userdata;
143         BusSlotType type:5;
144         bool floating:1;
145         bool match_added:1;
146         char *description;
147
148         LIST_FIELDS(sd_bus_slot, slots);
149
150         union {
151                 struct reply_callback reply_callback;
152                 struct filter_callback filter_callback;
153                 struct match_callback match_callback;
154                 struct node_callback node_callback;
155                 struct node_enumerator node_enumerator;
156                 struct node_object_manager node_object_manager;
157                 struct node_vtable node_vtable;
158         };
159 };
160
161 enum bus_state {
162         BUS_UNSET,
163         BUS_WATCH_BIND,      /* waiting for the socket to appear via inotify */
164         BUS_OPENING,         /* the kernel's connect() is still not ready */
165         BUS_AUTHENTICATING,  /* we are currently in the "SASL" authorization phase of dbus */
166         BUS_HELLO,           /* we are waiting for the Hello() response */
167         BUS_RUNNING,
168         BUS_CLOSING,
169         BUS_CLOSED,
170         _BUS_STATE_MAX,
171 };
172
173 static inline bool BUS_IS_OPEN(enum bus_state state) {
174         return state > BUS_UNSET && state < BUS_CLOSING;
175 }
176
177 enum bus_auth {
178         _BUS_AUTH_INVALID,
179         BUS_AUTH_EXTERNAL,
180         BUS_AUTH_ANONYMOUS
181 };
182
183 struct sd_bus {
184         /* We use atomic ref counting here since sd_bus_message
185            objects retain references to their originating sd_bus but
186            we want to allow them to be processed in a different
187            thread. We won't provide full thread safety, but only the
188            bare minimum that makes it possible to use sd_bus and
189            sd_bus_message objects independently and on different
190            threads as long as each object is used only once at the
191            same time. */
192         RefCount n_ref;
193
194         enum bus_state state;
195         int input_fd, output_fd;
196         int inotify_fd;
197         int message_version;
198         int message_endian;
199
200         bool can_fds:1;
201         bool bus_client:1;
202         bool ucred_valid:1;
203         bool is_server:1;
204         bool anonymous_auth:1;
205         bool prefer_readv:1;
206         bool prefer_writev:1;
207         bool match_callbacks_modified:1;
208         bool filter_callbacks_modified:1;
209         bool nodes_modified:1;
210         bool trusted:1;
211         bool manual_peer_interface:1;
212         bool is_system:1;
213         bool is_user:1;
214         bool allow_interactive_authorization:1;
215         bool exit_on_disconnect:1;
216         bool exited:1;
217         bool exit_triggered:1;
218         bool is_local:1;
219         bool watch_bind:1;
220         bool is_monitor:1;
221         bool accept_fd:1;
222         bool attach_timestamp:1;
223         bool connected_signal:1;
224
225         int use_memfd;
226
227         void *rbuffer;
228         size_t rbuffer_size;
229
230         sd_bus_message **rqueue;
231         unsigned rqueue_size;
232         size_t rqueue_allocated;
233
234         sd_bus_message **wqueue;
235         unsigned wqueue_size;
236         size_t windex;
237         size_t wqueue_allocated;
238
239         uint64_t cookie;
240
241         char *unique_name;
242         uint64_t unique_id;
243
244         struct bus_match_node match_callbacks;
245         Prioq *reply_callbacks_prioq;
246         OrderedHashmap *reply_callbacks;
247         LIST_HEAD(struct filter_callback, filter_callbacks);
248
249         Hashmap *nodes;
250         Hashmap *vtable_methods;
251         Hashmap *vtable_properties;
252
253         union sockaddr_union sockaddr;
254         socklen_t sockaddr_size;
255
256         char *machine;
257         pid_t nspid;
258
259         sd_id128_t server_id;
260
261         char *address;
262         unsigned address_index;
263
264         int last_connect_error;
265
266         enum bus_auth auth;
267         size_t auth_rbegin;
268         struct iovec auth_iovec[3];
269         unsigned auth_index;
270         char *auth_buffer;
271         usec_t auth_timeout;
272
273         struct ucred ucred;
274         char *label;
275         gid_t *groups;
276         size_t n_groups;
277
278         uint64_t creds_mask;
279
280         int *fds;
281         unsigned n_fds;
282
283         char *exec_path;
284         char **exec_argv;
285
286         unsigned iteration_counter;
287
288         /* We do locking around the memfd cache, since we want to
289          * allow people to process a sd_bus_message in a different
290          * thread then it was generated on and free it there. Since
291          * adding something to the memfd cache might happen when a
292          * message is released, we hence need to protect this bit with
293          * a mutex. */
294         pthread_mutex_t memfd_cache_mutex;
295         struct memfd_cache memfd_cache[MEMFD_CACHE_MAX];
296         unsigned n_memfd_cache;
297
298         pid_t original_pid;
299
300         sd_event_source *input_io_event_source;
301         sd_event_source *output_io_event_source;
302         sd_event_source *time_event_source;
303         sd_event_source *quit_event_source;
304         sd_event_source *inotify_event_source;
305         sd_event *event;
306         int event_priority;
307
308         sd_bus_message *current_message;
309         sd_bus_slot *current_slot;
310         sd_bus_message_handler_t current_handler;
311         void *current_userdata;
312
313         sd_bus **default_bus_ptr;
314         pid_t tid;
315
316         char *cgroup_root;
317
318         char *description;
319
320         sd_bus_track *track_queue;
321
322         LIST_HEAD(sd_bus_slot, slots);
323         LIST_HEAD(sd_bus_track, tracks);
324
325         int *inotify_watches;
326         size_t n_inotify_watches;
327 };
328
329 /* For method calls we time-out at 25s, like in the D-Bus reference implementation */
330 #define BUS_DEFAULT_TIMEOUT ((usec_t) (25 * USEC_PER_SEC))
331
332 /* For the authentication phase we grant 90s, to provide extra room during boot, when RNGs and such are not filled up
333  * with enough entropy yet and might delay the boot */
334 #define BUS_AUTH_TIMEOUT ((usec_t) DEFAULT_TIMEOUT_USEC)
335
336 #define BUS_WQUEUE_MAX (192*1024)
337 #define BUS_RQUEUE_MAX (192*1024)
338
339 #define BUS_MESSAGE_SIZE_MAX (64*1024*1024)
340 #define BUS_AUTH_SIZE_MAX (64*1024)
341
342 #define BUS_CONTAINER_DEPTH 128
343
344 /* Defined by the specification as maximum size of an array in
345  * bytes */
346 #define BUS_ARRAY_MAX_SIZE 67108864
347
348 #define BUS_FDS_MAX 1024
349
350 #define BUS_EXEC_ARGV_MAX 256
351
352 bool interface_name_is_valid(const char *p) _pure_;
353 bool service_name_is_valid(const char *p) _pure_;
354 #if 0 /// UNNEEDED by elogind
355 char* service_name_startswith(const char *a, const char *b);
356 #endif // 0
357 bool member_name_is_valid(const char *p) _pure_;
358 bool object_path_is_valid(const char *p) _pure_;
359 char *object_path_startswith(const char *a, const char *b) _pure_;
360
361 bool namespace_complex_pattern(const char *pattern, const char *value) _pure_;
362 bool path_complex_pattern(const char *pattern, const char *value) _pure_;
363
364 bool namespace_simple_pattern(const char *pattern, const char *value) _pure_;
365 bool path_simple_pattern(const char *pattern, const char *value) _pure_;
366
367 int bus_message_type_from_string(const char *s, uint8_t *u) _pure_;
368 const char *bus_message_type_to_string(uint8_t u) _pure_;
369
370 #define error_name_is_valid interface_name_is_valid
371
372 int bus_ensure_running(sd_bus *bus);
373 int bus_start_running(sd_bus *bus);
374 int bus_next_address(sd_bus *bus);
375
376 int bus_seal_synthetic_message(sd_bus *b, sd_bus_message *m);
377
378 int bus_rqueue_make_room(sd_bus *bus);
379
380 bool bus_pid_changed(sd_bus *bus);
381
382 char *bus_address_escape(const char *v);
383
384 int bus_attach_io_events(sd_bus *b);
385 int bus_attach_inotify_event(sd_bus *b);
386
387 void bus_close_inotify_fd(sd_bus *b);
388 void bus_close_io_fds(sd_bus *b);
389
390 #define OBJECT_PATH_FOREACH_PREFIX(prefix, path)                        \
391         for (char *_slash = ({ strcpy((prefix), (path)); streq((prefix), "/") ? NULL : strrchr((prefix), '/'); }) ; \
392              _slash && !(_slash[(_slash) == (prefix)] = 0);             \
393              _slash = streq((prefix), "/") ? NULL : strrchr((prefix), '/'))
394
395 /* If we are invoking callbacks of a bus object, ensure unreffing the
396  * bus from the callback doesn't destroy the object we are working
397  * on */
398 #define BUS_DONT_DESTROY(bus) \
399         _cleanup_(sd_bus_unrefp) _unused_ sd_bus *_dont_destroy_##bus = sd_bus_ref(bus)
400
401 int bus_set_address_system(sd_bus *bus);
402 #if 0 /// UNNEEDED by elogind
403 int bus_set_address_user(sd_bus *bus);
404 #endif // 0
405 int bus_set_address_system_remote(sd_bus *b, const char *host);
406 int bus_set_address_system_machine(sd_bus *b, const char *machine);
407
408 #if 0 /// UNNEEDED by elogind
409 #endif // 0
410 int bus_get_root_path(sd_bus *bus);
411
412 int bus_maybe_reply_error(sd_bus_message *m, int r, sd_bus_error *error);
413
414 #define bus_assert_return(expr, r, error)                               \
415         do {                                                            \
416                 if (!assert_log(expr, #expr))                           \
417                         return sd_bus_error_set_errno(error, r);        \
418         } while (false)
419
420 void bus_enter_closing(sd_bus *bus);
421
422 void bus_set_state(sd_bus *bus, enum bus_state state);