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