chiark / gitweb /
b862cb9443b60cde358d2b7d91faab032ee22585
[elogind.git] / src / libsystemd-bus / bus-message.h
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 <stdbool.h>
25 #include <byteswap.h>
26 #include <sys/socket.h>
27
28 #include "macro.h"
29 #include "sd-bus.h"
30 #include "kdbus.h"
31 #include "time-util.h"
32 #include "bus-creds.h"
33 #include "bus-protocol.h"
34
35 struct bus_container {
36         char enclosing;
37
38         unsigned index, saved_index;
39
40         char *signature;
41
42         uint32_t *array_size;
43         size_t before, begin;
44
45         size_t *offsets;
46         size_t n_offsets, n_allocated;
47
48         bool need_offsets;
49 };
50
51 struct bus_header {
52         uint8_t endian;
53         uint8_t type;
54         uint8_t flags;
55         uint8_t version;
56         uint32_t body_size;
57         uint32_t serial;
58         uint32_t fields_size;
59 } _packed_;
60
61 struct bus_body_part {
62         struct bus_body_part *next;
63         void *data;
64         size_t size;
65         size_t mapped;
66         int memfd;
67         bool free_this:1;
68         bool munmap_this:1;
69         bool sealed:1;
70         bool is_zero:1;
71 };
72
73 struct sd_bus_message {
74         unsigned n_ref;
75
76         sd_bus *bus;
77
78         uint32_t reply_serial;
79
80         const char *path;
81         const char *interface;
82         const char *member;
83         const char *destination;
84         const char *sender;
85
86         sd_bus_error error;
87
88         sd_bus_creds creds;
89
90         usec_t monotonic;
91         usec_t realtime;
92
93         bool sealed:1;
94         bool dont_send:1;
95         bool allow_fds:1;
96         bool free_header:1;
97         bool free_kdbus:1;
98         bool free_fds:1;
99         bool release_kdbus:1;
100         bool poisoned:1;
101         bool is_gvariant:1;
102
103         struct bus_header *header;
104         struct bus_body_part body;
105         struct bus_body_part *body_end;
106         unsigned n_body_parts;
107
108         size_t rindex;
109         struct bus_body_part *cached_rindex_part;
110         size_t cached_rindex_part_begin;
111
112         uint32_t n_fds;
113         int *fds;
114
115         struct bus_container root_container, *containers;
116         unsigned n_containers;
117
118         struct iovec *iovec;
119         struct iovec iovec_fixed[2];
120         unsigned n_iovec;
121
122         struct kdbus_msg *kdbus;
123
124         char *peeked_signature;
125
126         /* If set replies to this message must carry the signature
127          * specified here to successfully seal. This is initialized
128          * from the vtable data */
129         const char *enforced_reply_signature;
130
131         usec_t timeout;
132
133         char sender_buffer[3 + DECIMAL_STR_MAX(uint64_t) + 1];
134         char destination_buffer[3 + DECIMAL_STR_MAX(uint64_t) + 1];
135
136         size_t header_offsets[_BUS_MESSAGE_HEADER_MAX];
137         unsigned n_header_offsets;
138 };
139
140 #define BUS_MESSAGE_NEED_BSWAP(m) ((m)->header->endian != BUS_NATIVE_ENDIAN)
141
142 static inline uint16_t BUS_MESSAGE_BSWAP16(sd_bus_message *m, uint16_t u) {
143         return BUS_MESSAGE_NEED_BSWAP(m) ? bswap_16(u) : u;
144 }
145
146 static inline uint32_t BUS_MESSAGE_BSWAP32(sd_bus_message *m, uint32_t u) {
147         return BUS_MESSAGE_NEED_BSWAP(m) ? bswap_32(u) : u;
148 }
149
150 static inline uint64_t BUS_MESSAGE_BSWAP64(sd_bus_message *m, uint64_t u) {
151         return BUS_MESSAGE_NEED_BSWAP(m) ? bswap_64(u) : u;
152 }
153
154 static inline uint32_t BUS_MESSAGE_SERIAL(sd_bus_message *m) {
155         return BUS_MESSAGE_BSWAP32(m, m->header->serial);
156 }
157
158 static inline uint32_t BUS_MESSAGE_BODY_SIZE(sd_bus_message *m) {
159         return BUS_MESSAGE_BSWAP32(m, m->header->body_size);
160 }
161
162 static inline uint32_t BUS_MESSAGE_FIELDS_SIZE(sd_bus_message *m) {
163         return BUS_MESSAGE_BSWAP32(m, m->header->fields_size);
164 }
165
166 static inline uint32_t BUS_MESSAGE_SIZE(sd_bus_message *m) {
167         return
168                 sizeof(struct bus_header) +
169                 ALIGN8(BUS_MESSAGE_FIELDS_SIZE(m)) +
170                 BUS_MESSAGE_BODY_SIZE(m);
171 }
172
173 static inline uint32_t BUS_MESSAGE_BODY_BEGIN(sd_bus_message *m) {
174         return
175                 sizeof(struct bus_header) +
176                 ALIGN8(BUS_MESSAGE_FIELDS_SIZE(m));
177 }
178
179 static inline void* BUS_MESSAGE_FIELDS(sd_bus_message *m) {
180         return (uint8_t*) m->header + sizeof(struct bus_header);
181 }
182
183 int bus_message_seal(sd_bus_message *m, uint64_t serial);
184 int bus_message_get_blob(sd_bus_message *m, void **buffer, size_t *sz);
185 int bus_message_read_strv_extend(sd_bus_message *m, char ***l);
186
187 int bus_message_from_header(
188                 sd_bus *bus,
189                 void *header,
190                 size_t length,
191                 int *fds,
192                 unsigned n_fds,
193                 const struct ucred *ucred,
194                 const char *label,
195                 size_t extra,
196                 sd_bus_message **ret);
197
198 int bus_message_from_malloc(
199                 sd_bus *bus,
200                 void *buffer,
201                 size_t length,
202                 int *fds,
203                 unsigned n_fds,
204                 const struct ucred *ucred,
205                 const char *label,
206                 sd_bus_message **ret);
207
208 const char* bus_message_get_arg(sd_bus_message *m, unsigned i);
209
210 int bus_message_append_ap(sd_bus_message *m, const char *types, va_list ap);
211
212 int bus_message_parse_fields(sd_bus_message *m);
213
214 bool bus_header_is_complete(struct bus_header *h, size_t size);
215 int bus_header_message_size(struct bus_header *h, size_t *sum);
216
217 struct bus_body_part *message_append_part(sd_bus_message *m);
218
219 #define MESSAGE_FOREACH_PART(part, i, m) \
220         for ((i) = 0, (part) = &(m)->body; (i) < (m)->n_body_parts; (i)++, (part) = (part)->next)
221
222 int bus_body_part_map(struct bus_body_part *part);
223 void bus_body_part_unmap(struct bus_body_part *part);
224
225 int bus_message_to_errno(sd_bus_message *m);
226
227 int bus_message_new_synthetic_error(sd_bus *bus, uint64_t serial, const sd_bus_error *e, sd_bus_message **m);