2 * dbus-transport-kdbus.c
4 * Transport layer using kdbus
6 * Created on: Jun 20, 2013
12 #include "dbus-transport.h"
13 #include "dbus-transport-kdbus.h"
14 #include <dbus/dbus-transport-protected.h>
15 #include "dbus-connection-internal.h"
17 #include "dbus-watch.h"
18 #include "dbus-errors.h"
20 #include <linux/types.h>
24 #include <sys/ioctl.h>
31 #define KDBUS_ALIGN8(l) (((l) + 7) & ~7)
32 #define KDBUS_PART_HEADER_SIZE offsetof(struct kdbus_item, data)
33 #define KDBUS_ITEM_SIZE(s) KDBUS_ALIGN8((s) + KDBUS_PART_HEADER_SIZE)
35 #define KDBUS_PART_NEXT(part) \
36 (typeof(part))(((uint8_t *)part) + KDBUS_ALIGN8((part)->size))
37 #define KDBUS_PART_FOREACH(part, head, first) \
38 for (part = (head)->first; \
39 (uint8_t *)(part) < (uint8_t *)(head) + (head)->size; \
40 part = KDBUS_PART_NEXT(part))
41 #define POOL_SIZE (16 * 1024LU * 1024LU) //todo pool size to be decided
44 * Opaque object representing a socket file descriptor transport.
46 typedef struct DBusTransportSocket DBusTransportSocket;
49 * Implementation details of DBusTransportSocket. All members are private.
51 struct DBusTransportSocket
53 DBusTransport base; /**< Parent instance */
54 int fd; /**< File descriptor. */
55 DBusWatch *read_watch; /**< Watch for readability. */
56 DBusWatch *write_watch; /**< Watch for writability. */
58 int max_bytes_read_per_iteration; /**< To avoid blocking too long. */
59 int max_bytes_written_per_iteration; /**< To avoid blocking too long. */
61 int message_bytes_written; /**< Number of bytes of current
62 * outgoing message that have
65 DBusString encoded_outgoing; /**< Encoded version of current
68 DBusString encoded_incoming; /**< Encoded version of current
77 socket_get_socket_fd (DBusTransport *transport,
80 DBusTransportSocket *socket_transport = (DBusTransportSocket*) transport;
82 *fd_p = socket_transport->fd;
88 * Adds locally generated message to received messages queue
91 static dbus_bool_t add_message_to_received(DBusMessage *message, DBusTransport *transport)
93 DBusList *message_link;
95 message_link = _dbus_list_alloc_link (message);
96 if (message_link == NULL)
98 /* it's OK to unref this, nothing that could have attached a callback
100 dbus_message_unref (message);
104 _dbus_connection_queue_synthesized_message_link(transport->connection, message_link);
109 static int kdbus_write_msg(DBusTransport *transport, DBusMessage *message, int fd)
111 struct kdbus_msg *msg;
112 struct kdbus_item *item;
115 uint64_t dst_id = KDBUS_DST_ID_BROADCAST;
116 const DBusString *header;
117 const DBusString *body;
123 if((name = dbus_message_get_destination(message)))
125 if((name[0] == ':') && (name[1] == '1') && (name[2] == '.')) //if name starts with :1. it is a unique name and should be send as number
127 dst_id = strtoll(&name[3], NULL, 10);
131 dst_id = KDBUS_DST_ID_WELL_KNOWN_NAME;
134 _dbus_message_get_network_data (message, &header, &body);
135 ret_size = _dbus_string_get_length(header);
136 body_size = _dbus_string_get_length(body);
138 /* fprintf (stderr, "\nheader:\n");
139 for(i=0; i < ret_size; i++)
141 fprintf (stderr, "%02x", _dbus_string_get_byte(header,i));
143 fprintf (stderr, "\nret size: %lu, i: %lu\n", ret_size, i);*/
145 size = sizeof(struct kdbus_msg);
146 size += KDBUS_ITEM_SIZE(sizeof(struct kdbus_vec));
147 if(body_size) //body can be empty
148 size += KDBUS_ITEM_SIZE(sizeof(struct kdbus_vec));
150 size += KDBUS_ITEM_SIZE(strlen(name) + 1);
151 else if (dst_id == KDBUS_DST_ID_BROADCAST)
152 size += KDBUS_PART_HEADER_SIZE + 64;
157 _dbus_verbose("Error allocating memory for: %s,%s\n", _dbus_strerror (errno), _dbus_error_from_errno (errno));
161 memset(msg, 0, size);
163 msg->src_id = strtoll(dbus_bus_get_unique_name(transport->connection), NULL , 10);
164 msg->dst_id = name ? 0 : dst_id;
165 msg->cookie = dbus_message_get_serial(message);
166 msg->payload_type = KDBUS_PAYLOAD_DBUS1;
172 item->type = KDBUS_MSG_DST_NAME;
173 item->size = KDBUS_PART_HEADER_SIZE + strlen(name) + 1;
174 strcpy(item->str, name);
175 item = KDBUS_PART_NEXT(item);
178 item->type = KDBUS_MSG_PAYLOAD_VEC;
179 item->size = KDBUS_PART_HEADER_SIZE + sizeof(struct kdbus_vec);
180 item->vec.address = (unsigned long) _dbus_string_get_const_data(header);
181 item->vec.size = ret_size;
185 item = KDBUS_PART_NEXT(item);
186 item->type = KDBUS_MSG_PAYLOAD_VEC;
187 item->size = KDBUS_PART_HEADER_SIZE + sizeof(struct kdbus_vec);
188 item->vec.address = (unsigned long) _dbus_string_get_const_data(body);
189 item->vec.size = body_size;
190 ret_size += body_size;
193 /* fprintf (stderr, "\nbody:\n");
194 for(i=0; i < item->vec.size; i++)
196 fprintf (stderr, "%02x", _dbus_string_get_byte(body,i));
198 fprintf (stderr, "\nitem->vec.size: %llu, i: %lu\n", item->vec.size, i);*/
200 if (dst_id == KDBUS_DST_ID_BROADCAST)
202 item = KDBUS_PART_NEXT(item);
203 item->type = KDBUS_MSG_BLOOM;
204 item->size = KDBUS_PART_HEADER_SIZE + 64;
208 if (ioctl(fd, KDBUS_CMD_MSG_SEND, msg))
212 if(errno == ENXIO) //when recipient is not available on the bus
214 DBusMessage *errMessage;
216 errMessage = generate_local_error_message(msg->cookie, "org.freedesktop.DBus.Error.ServiceUnknown", NULL);
217 if(errMessage == NULL)
222 dbus_message_set_reply_serial(errMessage, dbus_message_get_reply_serial(message));
223 if (!add_message_to_received(errMessage, transport))
227 _dbus_verbose("kdbus error sending message: err %d (%m)\n", errno);
236 static int kdbus_write_msg_encoded(DBusMessage *message, DBusTransportSocket *socket_transport)
238 struct kdbus_msg *msg;
239 struct kdbus_item *item;
242 uint64_t dst_id = KDBUS_DST_ID_BROADCAST;
245 if((name = dbus_message_get_destination(message)))
247 if((name[0] == ':') && (name[1] == '1') && (name[2] == '.'))
249 dst_id = strtoll(&name[2], NULL, 10);
253 dst_id = KDBUS_DST_ID_WELL_KNOWN_NAME;
256 size = sizeof(struct kdbus_msg);
257 size += KDBUS_ITEM_SIZE(sizeof(struct kdbus_vec));
259 size += KDBUS_ITEM_SIZE(strlen(name) + 1);
260 else if (dst_id == KDBUS_DST_ID_BROADCAST)
261 size += KDBUS_PART_HEADER_SIZE + 64;
266 _dbus_verbose("Error allocating memory for: %s,%s\n", _dbus_strerror (errno), _dbus_error_from_errno (errno));
270 memset(msg, 0, size);
272 msg->src_id = strtoll(dbus_bus_get_unique_name(socket_transport->base.connection), NULL , 10);
273 _dbus_verbose("sending encoded msg, src_id=%llu\n", msg->src_id);
274 msg->dst_id = name ? 0 : dst_id;
275 msg->cookie = dbus_message_get_serial(message);
276 msg->payload_type = KDBUS_PAYLOAD_DBUS1;
282 item->type = KDBUS_MSG_DST_NAME;
283 item->size = KDBUS_PART_HEADER_SIZE + strlen(name) + 1;
284 strcpy(item->str, name);
285 item = KDBUS_PART_NEXT(item);
288 item->type = KDBUS_MSG_PAYLOAD_VEC;
289 item->size = KDBUS_PART_HEADER_SIZE + sizeof(struct kdbus_vec);
290 item->vec.address = (unsigned long) &socket_transport->encoded_outgoing;
291 item->vec.size = _dbus_string_get_length (&socket_transport->encoded_outgoing);
293 if (dst_id == KDBUS_DST_ID_BROADCAST)
295 item = KDBUS_PART_NEXT(item);
296 item->type = KDBUS_MSG_BLOOM;
297 item->size = KDBUS_PART_HEADER_SIZE + 64;
301 if (ioctl(socket_transport->fd, KDBUS_CMD_MSG_SEND, msg))
305 if(errno == ENXIO) //when recipient is not available on the bus
307 DBusMessage *errMessage = NULL;
309 errMessage = generate_local_error_message(msg->cookie, "org.freedesktop.DBus.Error.ServiceUnknown", NULL);
310 if(errMessage == NULL)
315 dbus_message_set_reply_serial(errMessage, dbus_message_get_reply_serial(message));
316 if (!add_message_to_received(errMessage, &socket_transport->base))
320 _dbus_verbose("error sending encoded message: err %d (%m)\n", errno);
329 //todo functions from kdbus-utli.c for printing messages - maybe to remove at the end
330 static char *msg_id(uint64_t id, char *buf)
336 sprintf(buf, "%llu", (unsigned long long)id);
340 struct kdbus_enum_table {
344 #define _STRINGIFY(x) #x
345 #define STRINGIFY(x) _STRINGIFY(x)
346 #define ELEMENTSOF(x) (sizeof(x)/sizeof((x)[0]))
347 #define TABLE(what) static struct kdbus_enum_table kdbus_table_##what[]
348 #define ENUM(_id) { .id=_id, .name=STRINGIFY(_id) }
349 #define LOOKUP(what) \
350 const char *enum_##what(long long id) { \
352 for (i = 0; i < ELEMENTSOF(kdbus_table_##what); i++) \
353 if (id == kdbus_table_##what[i].id) \
354 return kdbus_table_##what[i].name; \
357 const char *enum_MSG(long long id);
359 ENUM(_KDBUS_MSG_NULL),
360 ENUM(KDBUS_MSG_PAYLOAD_VEC),
361 ENUM(KDBUS_MSG_PAYLOAD_OFF),
362 ENUM(KDBUS_MSG_PAYLOAD_MEMFD),
364 ENUM(KDBUS_MSG_BLOOM),
365 ENUM(KDBUS_MSG_DST_NAME),
366 ENUM(KDBUS_MSG_SRC_CREDS),
367 ENUM(KDBUS_MSG_SRC_PID_COMM),
368 ENUM(KDBUS_MSG_SRC_TID_COMM),
369 ENUM(KDBUS_MSG_SRC_EXE),
370 ENUM(KDBUS_MSG_SRC_CMDLINE),
371 ENUM(KDBUS_MSG_SRC_CGROUP),
372 ENUM(KDBUS_MSG_SRC_CAPS),
373 ENUM(KDBUS_MSG_SRC_SECLABEL),
374 ENUM(KDBUS_MSG_SRC_AUDIT),
375 ENUM(KDBUS_MSG_SRC_NAMES),
376 ENUM(KDBUS_MSG_TIMESTAMP),
377 ENUM(KDBUS_MSG_NAME_ADD),
378 ENUM(KDBUS_MSG_NAME_REMOVE),
379 ENUM(KDBUS_MSG_NAME_CHANGE),
380 ENUM(KDBUS_MSG_ID_ADD),
381 ENUM(KDBUS_MSG_ID_REMOVE),
382 ENUM(KDBUS_MSG_REPLY_TIMEOUT),
383 ENUM(KDBUS_MSG_REPLY_DEAD),
386 const char *enum_PAYLOAD(long long id);
388 ENUM(KDBUS_PAYLOAD_KERNEL),
389 ENUM(KDBUS_PAYLOAD_DBUS1),
390 ENUM(KDBUS_PAYLOAD_GVARIANT),
394 static int put_message_into_data(DBusMessage *message, char* data)
397 const DBusString *header;
398 const DBusString *body;
401 dbus_message_lock (message);
402 _dbus_message_get_network_data (message, &header, &body);
403 ret_size = _dbus_string_get_length(header);
404 memcpy(data, _dbus_string_get_const_data(header), ret_size);
406 size = _dbus_string_get_length(body);
407 memcpy(data, _dbus_string_get_const_data(body), size);
413 static int kdbus_decode_msg(const struct kdbus_msg* msg, char *data, void* mmap_ptr)
415 const struct kdbus_item *item = msg->items;
416 char buf[32]; //todo to be removed after development
418 DBusMessage *message = NULL;
419 DBusMessageIter args;
420 char* pStringMallocked = NULL;
421 const char* dbus = "org.freedesktop.DBus";
422 const char* emptyString = "";
424 const char* pString = NULL;
426 _dbus_verbose("MESSAGE: %s (%llu bytes) flags=0x%llx, %s → %s, cookie=%llu, timeout=%llu\n",
427 enum_PAYLOAD(msg->payload_type), (unsigned long long) msg->size,
428 (unsigned long long) msg->flags,
429 msg_id(msg->src_id, buf), msg_id(msg->dst_id, buf),
430 (unsigned long long) msg->cookie, (unsigned long long) msg->timeout_ns);
432 KDBUS_PART_FOREACH(item, msg, items)
434 if (item->size <= KDBUS_PART_HEADER_SIZE)
436 _dbus_verbose(" +%s (%llu bytes) invalid data record\n", enum_MSG(item->type), item->size);
437 break; //todo to be discovered and rewritten
442 case KDBUS_MSG_PAYLOAD_OFF:
443 memcpy(data, (char *)mmap_ptr + item->vec.offset, item->vec.size);
444 data += item->vec.size;
445 ret_size += item->vec.size;
447 _dbus_verbose(" +%s (%llu bytes) off=%llu size=%llu\n",
448 enum_MSG(item->type), item->size,
449 (unsigned long long)item->vec.offset,
450 (unsigned long long)item->vec.size);
453 case KDBUS_MSG_PAYLOAD_MEMFD: //todo
458 buf = mmap(NULL, item->memfd.size, PROT_READ, MAP_SHARED, item->memfd.fd, 0);
459 if (buf == MAP_FAILED) {
460 _dbus_verbose("mmap() fd=%i failed:%m", item->memfd.fd);
464 if (ioctl(item->memfd.fd, KDBUS_CMD_MEMFD_SIZE_GET, &size) < 0) {
465 _dbus_verbose("KDBUS_CMD_MEMFD_SIZE_GET failed: %m\n");
469 _dbus_verbose(" +%s (%llu bytes) fd=%i size=%llu filesize=%llu '%s'\n",
470 enum_MSG(item->type), item->size, item->memfd.fd,
471 (unsigned long long)item->memfd.size, (unsigned long long)size, buf);
473 memcpy(data, buf, size);
479 /* case KDBUS_MSG_SRC_CREDS:
480 _dbus_verbose(" +%s (%llu bytes) uid=%lld, gid=%lld, pid=%lld, tid=%lld, starttime=%lld\n",
481 enum_MSG(item->type), item->size,
482 item->creds.uid, item->creds.gid,
483 item->creds.pid, item->creds.tid,
484 item->creds.starttime);
487 case KDBUS_MSG_SRC_PID_COMM:
488 case KDBUS_MSG_SRC_TID_COMM:
489 case KDBUS_MSG_SRC_EXE:
490 case KDBUS_MSG_SRC_CGROUP:
491 case KDBUS_MSG_SRC_SECLABEL:
492 case KDBUS_MSG_DST_NAME:
493 _dbus_verbose(" +%s (%llu bytes) '%s' (%zu)\n",
494 enum_MSG(item->type), item->size, item->str, strlen(item->str));
497 case KDBUS_MSG_SRC_CMDLINE:
498 case KDBUS_MSG_SRC_NAMES: {
499 size_t size = item->size - KDBUS_PART_HEADER_SIZE;
500 const char *str = item->str;
503 _dbus_verbose(" +%s (%llu bytes) ", enum_MSG(item->type), item->size);
505 _dbus_verbose("'%s' ", str);
506 size -= strlen(str) + 1;
507 str += strlen(str) + 1;
511 _dbus_verbose("(%d string%s)\n", count, (count == 1) ? "" : "s");
515 case KDBUS_MSG_SRC_AUDIT:
516 _dbus_verbose(" +%s (%llu bytes) loginuid=%llu sessionid=%llu\n",
517 enum_MSG(item->type), item->size,
518 (unsigned long long)item->data64[0],
519 (unsigned long long)item->data64[1]);
522 case KDBUS_MSG_SRC_CAPS: {
527 _dbus_verbose(" +%s (%llu bytes) len=%llu bytes)\n",
528 enum_MSG(item->type), item->size,
529 (unsigned long long)item->size - KDBUS_PART_HEADER_SIZE);
532 n = (item->size - KDBUS_PART_HEADER_SIZE) / 4 / sizeof(uint32_t);
534 _dbus_verbose(" CapInh=");
535 for (i = 0; i < n; i++)
536 _dbus_verbose("%08x", cap[(0 * n) + (n - i - 1)]);
538 _dbus_verbose(" CapPrm=");
539 for (i = 0; i < n; i++)
540 _dbus_verbose("%08x", cap[(1 * n) + (n - i - 1)]);
542 _dbus_verbose(" CapEff=");
543 for (i = 0; i < n; i++)
544 _dbus_verbose("%08x", cap[(2 * n) + (n - i - 1)]);
546 _dbus_verbose(" CapInh=");
547 for (i = 0; i < n; i++)
548 _dbus_verbose("%08x", cap[(3 * n) + (n - i - 1)]);
553 case KDBUS_MSG_TIMESTAMP:
554 _dbus_verbose(" +%s (%llu bytes) realtime=%lluns monotonic=%lluns\n",
555 enum_MSG(item->type), item->size,
556 (unsigned long long)item->timestamp.realtime_ns,
557 (unsigned long long)item->timestamp.monotonic_ns);
560 case KDBUS_MSG_REPLY_TIMEOUT:
561 _dbus_verbose(" +%s (%llu bytes) cookie=%llu\n",
562 enum_MSG(item->type), item->size, msg->cookie_reply);
564 message = generate_local_error_message(msg->cookie_reply, "org.freedesktop.DBus.Error.NoReply", NULL);
571 ret_size = put_message_into_data(message, data);
574 case KDBUS_MSG_NAME_ADD:
575 _dbus_verbose(" +%s (%llu bytes) '%s', old id=%lld, new id=%lld, flags=0x%llx\n",
576 enum_MSG(item->type), (unsigned long long) item->size,
577 item->name_change.name, item->name_change.old_id,
578 item->name_change.new_id, item->name_change.flags);
580 pStringMallocked = malloc (sizeof(item->name_change.new_id)*2.5 + 4);
583 strcpy(pStringMallocked,":1.");
584 sprintf(&pStringMallocked[3],"%llu",item->name_change.new_id);
589 message = dbus_message_new_signal("/org/freedesktop/DBus", // object name of the signal
590 dbus, // interface name of the signal
591 "NameOwnerChanged"); // name of the signal
598 pString = item->name_change.name;
599 _dbus_verbose ("Name added: %s\n", pString);
600 dbus_message_iter_init_append(message, &args);
601 if (!dbus_message_iter_append_basic(&args, DBUS_TYPE_STRING,&pString))
606 if (!dbus_message_iter_append_basic(&args, DBUS_TYPE_STRING, &emptyString))
611 if (!dbus_message_iter_append_basic(&args, DBUS_TYPE_STRING, &pStringMallocked))
617 dbus_message_set_sender(message, dbus);
618 dbus_message_set_serial(message, 1);
620 ret_size = put_message_into_data(message, data);
623 case KDBUS_MSG_NAME_REMOVE:
624 _dbus_verbose(" +%s (%llu bytes) '%s', old id=%lld, new id=%lld, flags=0x%llx\n",
625 enum_MSG(item->type), (unsigned long long) item->size,
626 item->name_change.name, item->name_change.old_id,
627 item->name_change.new_id, item->name_change.flags);
629 pStringMallocked = malloc (sizeof(item->name_change.old_id)*2.5 + 4);
632 strcpy(pStringMallocked,":1.");
633 sprintf(&pStringMallocked[3],"%llu",item->name_change.old_id);
638 message = dbus_message_new_signal("/org/freedesktop/DBus", // object name of the signal
639 dbus, // interface name of the signal
640 "NameOwnerChanged"); // name of the signal
647 pString = item->name_change.name;
648 _dbus_verbose ("Name removed: %s\n", pString);
649 dbus_message_iter_init_append(message, &args);
650 if (!dbus_message_iter_append_basic(&args, DBUS_TYPE_STRING,&pString))
655 if (!dbus_message_iter_append_basic(&args, DBUS_TYPE_STRING, &pStringMallocked))
660 if (!dbus_message_iter_append_basic(&args, DBUS_TYPE_STRING, &emptyString))
666 dbus_message_set_sender(message, dbus);
667 dbus_message_set_serial(message, 1);
669 ret_size = put_message_into_data(message, data);
672 case KDBUS_MSG_NAME_CHANGE:
673 _dbus_verbose(" +%s (%llu bytes) '%s', old id=%lld, new id=%lld, flags=0x%llx\n",
674 enum_MSG(item->type), (unsigned long long) item->size,
675 item->name_change.name, item->name_change.old_id,
676 item->name_change.new_id, item->name_change.flags);
678 pStringMallocked = malloc (sizeof(item->name_change.new_id)*2.5 + 4);
681 strcpy(pStringMallocked,":1.");
682 sprintf(&pStringMallocked[3],"%llu",item->name_change.old_id);
687 message = dbus_message_new_signal("/org/freedesktop/DBus", // object name of the signal
688 dbus, // interface name of the signal
689 "NameOwnerChanged"); // name of the signal
696 pString = item->name_change.name;
697 _dbus_verbose ("Name changed: %s\n", pString);
698 dbus_message_iter_init_append(message, &args);
699 if (!dbus_message_iter_append_basic(&args, DBUS_TYPE_STRING,&pString))
704 if (!dbus_message_iter_append_basic(&args, DBUS_TYPE_STRING, &pStringMallocked))
709 sprintf(&pStringMallocked[3],"%llu",item->name_change.new_id);
710 _dbus_verbose ("New id: %s\n", pStringMallocked); //todo to be removed
711 if (!dbus_message_iter_append_basic(&args, DBUS_TYPE_STRING, &pStringMallocked))
717 dbus_message_set_sender(message, dbus);
718 dbus_message_set_serial(message, 1);
720 ret_size = put_message_into_data(message, data);
723 case KDBUS_MSG_ID_ADD:
724 _dbus_verbose(" +%s (%llu bytes) id=%llu flags=%llu\n",
725 enum_MSG(item->type), (unsigned long long) item->size,
726 (unsigned long long) item->id_change.id,
727 (unsigned long long) item->id_change.flags);
729 pStringMallocked = malloc (sizeof(item->id_change.id)*2.5 + 4);
732 strcpy(pStringMallocked,":1.");
733 sprintf(&pStringMallocked[3],"%llu",item->id_change.id);
738 message = dbus_message_new_signal("/org/freedesktop/DBus", // object name of the signal
739 dbus, // interface name of the signal
740 "NameOwnerChanged"); // name of the signal
747 dbus_message_iter_init_append(message, &args);
748 if (!dbus_message_iter_append_basic(&args, DBUS_TYPE_STRING, &pStringMallocked))
753 if (!dbus_message_iter_append_basic(&args, DBUS_TYPE_STRING, &emptyString))
758 if (!dbus_message_iter_append_basic(&args, DBUS_TYPE_STRING, &pStringMallocked))
764 dbus_message_set_sender(message, dbus);
765 dbus_message_set_serial(message, 1);
767 ret_size = put_message_into_data(message, data);
770 case KDBUS_MSG_ID_REMOVE:
771 _dbus_verbose(" +%s (%llu bytes) id=%llu flags=%llu\n",
772 enum_MSG(item->type), (unsigned long long) item->size,
773 (unsigned long long) item->id_change.id,
774 (unsigned long long) item->id_change.flags);
776 pStringMallocked = malloc (sizeof(item->id_change.id)*2.5 + 4);
779 strcpy(pStringMallocked,":1.");
780 sprintf(&pStringMallocked[3],"%llu",item->id_change.id);
785 message = dbus_message_new_signal("/org/freedesktop/DBus", // object name of the signal
786 dbus, // interface name of the signal
787 "NameOwnerChanged"); // name of the signal
794 dbus_message_iter_init_append(message, &args);
795 if (!dbus_message_iter_append_basic(&args, DBUS_TYPE_STRING, &pStringMallocked))
800 if (!dbus_message_iter_append_basic(&args, DBUS_TYPE_STRING, &pStringMallocked))
805 if (!dbus_message_iter_append_basic(&args, DBUS_TYPE_STRING, &emptyString))
811 dbus_message_set_sender(message, dbus);
812 dbus_message_set_serial(message, 1);
814 ret_size = put_message_into_data(message, data);
818 _dbus_verbose(" +%s (%llu bytes)\n", enum_MSG(item->type), item->size);
823 /*if ((char *)item - ((char *)msg + msg->size) >= 8)
824 _dbus_verbose("invalid padding at end of message\n");*/
828 dbus_message_unref(message);
830 free((void*)pStringMallocked);
834 static int kdbus_read_message(DBusTransportSocket *socket_transport, DBusString *buffer)
838 struct kdbus_msg *msg;
842 _dbus_assert (socket_transport->max_bytes_read_per_iteration >= 0);
843 // start = _dbus_string_get_length (buffer);
844 // _dbus_verbose("read start: %d !!!!!!!!!!!!!!! \n", start);
845 if (!_dbus_string_lengthen (buffer, socket_transport->max_bytes_read_per_iteration))
850 data = _dbus_string_get_data_len (buffer, /*start*/0, socket_transport->max_bytes_read_per_iteration);
853 if (ioctl(socket_transport->fd, KDBUS_CMD_MSG_RECV, &offset) < 0)
857 _dbus_verbose("kdbus error receiving message: %d (%m)\n", errno);
858 _dbus_string_set_length (buffer, /*start*/0);
862 msg = (struct kdbus_msg *)((char*)socket_transport->kdbus_mmap_ptr + offset);
864 ret_size = kdbus_decode_msg(msg, data, socket_transport->kdbus_mmap_ptr);
865 _dbus_string_set_length (buffer, /*start +*/ ret_size);
868 if (ioctl(socket_transport->fd, KDBUS_CMD_MSG_RELEASE, &offset) < 0)
872 _dbus_verbose("kdbus error freeing message: %d (%m)\n", errno);
880 free_watches (DBusTransport *transport)
882 DBusTransportSocket *socket_transport = (DBusTransportSocket*) transport;
884 _dbus_verbose ("start\n");
886 if (socket_transport->read_watch)
888 if (transport->connection)
889 _dbus_connection_remove_watch_unlocked (transport->connection,
890 socket_transport->read_watch);
891 _dbus_watch_invalidate (socket_transport->read_watch);
892 _dbus_watch_unref (socket_transport->read_watch);
893 socket_transport->read_watch = NULL;
896 if (socket_transport->write_watch)
898 if (transport->connection)
899 _dbus_connection_remove_watch_unlocked (transport->connection,
900 socket_transport->write_watch);
901 _dbus_watch_invalidate (socket_transport->write_watch);
902 _dbus_watch_unref (socket_transport->write_watch);
903 socket_transport->write_watch = NULL;
906 _dbus_verbose ("end\n");
910 socket_finalize (DBusTransport *transport)
912 DBusTransportSocket *socket_transport = (DBusTransportSocket*) transport;
914 _dbus_verbose ("\n");
916 free_watches (transport);
918 _dbus_string_free (&socket_transport->encoded_outgoing);
919 _dbus_string_free (&socket_transport->encoded_incoming);
921 _dbus_transport_finalize_base (transport);
923 _dbus_assert (socket_transport->read_watch == NULL);
924 _dbus_assert (socket_transport->write_watch == NULL);
926 dbus_free (transport);
930 check_write_watch (DBusTransport *transport)
932 DBusTransportSocket *socket_transport = (DBusTransportSocket*) transport;
935 if (transport->connection == NULL)
938 if (transport->disconnected)
940 _dbus_assert (socket_transport->write_watch == NULL);
944 _dbus_transport_ref (transport);
946 if (_dbus_transport_get_is_authenticated (transport))
947 needed = _dbus_connection_has_messages_to_send_unlocked (transport->connection);
950 if (transport->send_credentials_pending)
954 DBusAuthState auth_state;
956 auth_state = _dbus_auth_do_work (transport->auth);
958 /* If we need memory we install the write watch just in case,
959 * if there's no need for it, it will get de-installed
960 * next time we try reading.
962 if (auth_state == DBUS_AUTH_STATE_HAVE_BYTES_TO_SEND ||
963 auth_state == DBUS_AUTH_STATE_WAITING_FOR_MEMORY)
970 _dbus_verbose ("check_write_watch(): needed = %d on connection %p watch %p fd = %d outgoing messages exist %d\n",
971 needed, transport->connection, socket_transport->write_watch,
972 socket_transport->fd,
973 _dbus_connection_has_messages_to_send_unlocked (transport->connection));
975 _dbus_connection_toggle_watch_unlocked (transport->connection,
976 socket_transport->write_watch,
979 _dbus_transport_unref (transport);
983 check_read_watch (DBusTransport *transport)
985 DBusTransportSocket *socket_transport = (DBusTransportSocket*) transport;
986 dbus_bool_t need_read_watch;
988 _dbus_verbose ("fd = %d\n",socket_transport->fd);
990 if (transport->connection == NULL)
993 if (transport->disconnected)
995 _dbus_assert (socket_transport->read_watch == NULL);
999 _dbus_transport_ref (transport);
1001 if (_dbus_transport_get_is_authenticated (transport))
1003 (_dbus_counter_get_size_value (transport->live_messages) < transport->max_live_messages_size) &&
1004 (_dbus_counter_get_unix_fd_value (transport->live_messages) < transport->max_live_messages_unix_fds);
1007 if (transport->receive_credentials_pending)
1008 need_read_watch = TRUE;
1011 /* The reason to disable need_read_watch when not WAITING_FOR_INPUT
1012 * is to avoid spinning on the file descriptor when we're waiting
1013 * to write or for some other part of the auth process
1015 DBusAuthState auth_state;
1017 auth_state = _dbus_auth_do_work (transport->auth);
1019 /* If we need memory we install the read watch just in case,
1020 * if there's no need for it, it will get de-installed
1021 * next time we try reading. If we're authenticated we
1022 * install it since we normally have it installed while
1025 if (auth_state == DBUS_AUTH_STATE_WAITING_FOR_INPUT ||
1026 auth_state == DBUS_AUTH_STATE_WAITING_FOR_MEMORY ||
1027 auth_state == DBUS_AUTH_STATE_AUTHENTICATED)
1028 need_read_watch = TRUE;
1030 need_read_watch = FALSE;
1034 _dbus_verbose (" setting read watch enabled = %d\n", need_read_watch);
1035 _dbus_connection_toggle_watch_unlocked (transport->connection,
1036 socket_transport->read_watch,
1039 _dbus_transport_unref (transport);
1043 do_io_error (DBusTransport *transport)
1045 _dbus_transport_ref (transport);
1046 _dbus_transport_disconnect (transport);
1047 _dbus_transport_unref (transport);
1050 /* return value is whether we successfully read any new data. */
1052 read_data_into_auth (DBusTransport *transport,
1055 DBusTransportSocket *socket_transport = (DBusTransportSocket*) transport;
1061 _dbus_auth_get_buffer (transport->auth, &buffer);
1063 bytes_read = kdbus_read_message(socket_transport, buffer);
1065 _dbus_auth_return_buffer (transport->auth, buffer,
1066 bytes_read > 0 ? bytes_read : 0);
1070 _dbus_verbose (" read %d bytes in auth phase\n", bytes_read);
1073 else if (bytes_read < 0)
1075 /* EINTR already handled for us */
1077 if (_dbus_get_is_errno_enomem ())
1081 else if (_dbus_get_is_errno_eagain_or_ewouldblock ())
1082 ; /* do nothing, just return FALSE below */
1085 _dbus_verbose ("Error reading from remote app: %s\n",
1086 _dbus_strerror_from_errno ());
1087 do_io_error (transport);
1094 _dbus_assert (bytes_read == 0);
1096 _dbus_verbose ("Disconnected from remote app\n");
1097 do_io_error (transport);
1103 /* Return value is whether we successfully wrote any bytes */
1105 write_data_from_auth (DBusTransport *transport) //todo change to kdbus
1107 DBusTransportSocket *socket_transport = (DBusTransportSocket*) transport;
1109 const DBusString *buffer;
1111 if (!_dbus_auth_get_bytes_to_send (transport->auth,
1115 bytes_written = _dbus_write_socket (socket_transport->fd,
1117 0, _dbus_string_get_length (buffer));
1119 if (bytes_written > 0)
1121 _dbus_auth_bytes_sent (transport->auth, bytes_written);
1124 else if (bytes_written < 0)
1126 /* EINTR already handled for us */
1128 if (_dbus_get_is_errno_eagain_or_ewouldblock ())
1132 _dbus_verbose ("Error writing to remote app: %s\n",
1133 _dbus_strerror_from_errno ());
1134 do_io_error (transport);
1143 exchange_credentials (DBusTransport *transport,
1144 dbus_bool_t do_reading,
1145 dbus_bool_t do_writing)
1147 DBusTransportSocket *socket_transport = (DBusTransportSocket*) transport;
1148 DBusError error = DBUS_ERROR_INIT;
1150 _dbus_verbose ("exchange_credentials: do_reading = %d, do_writing = %d\n",
1151 do_reading, do_writing);
1153 if (do_writing && transport->send_credentials_pending)
1155 if (_dbus_send_credentials_socket (socket_transport->fd,
1158 transport->send_credentials_pending = FALSE;
1162 _dbus_verbose ("Failed to write credentials: %s\n", error.message);
1163 dbus_error_free (&error);
1164 do_io_error (transport);
1168 if (do_reading && transport->receive_credentials_pending)
1170 /* FIXME this can fail due to IO error _or_ OOM, broken
1171 * (somewhat tricky to fix since the OOM error can be set after
1172 * we already read the credentials byte, so basically we need to
1173 * separate reading the byte and storing it in the
1174 * transport->credentials). Does not really matter for now
1175 * because storing in credentials never actually fails on unix.
1177 if (_dbus_read_credentials_socket (socket_transport->fd,
1178 transport->credentials,
1181 transport->receive_credentials_pending = FALSE;
1185 _dbus_verbose ("Failed to read credentials %s\n", error.message);
1186 dbus_error_free (&error);
1187 do_io_error (transport);
1191 if (!(transport->send_credentials_pending ||
1192 transport->receive_credentials_pending))
1194 if (!_dbus_auth_set_credentials (transport->auth,
1195 transport->credentials))
1203 do_authentication (DBusTransport *transport,
1204 dbus_bool_t do_reading,
1205 dbus_bool_t do_writing,
1206 dbus_bool_t *auth_completed)
1209 dbus_bool_t orig_auth_state;
1213 orig_auth_state = _dbus_transport_get_is_authenticated (transport);
1215 /* This is essential to avoid the check_write_watch() at the end,
1216 * we don't want to add a write watch in do_iteration before
1217 * we try writing and get EAGAIN
1219 if (orig_auth_state)
1222 *auth_completed = FALSE;
1226 _dbus_transport_ref (transport);
1228 while (!_dbus_transport_get_is_authenticated (transport) &&
1229 _dbus_transport_get_is_connected (transport))
1231 if (!exchange_credentials (transport, do_reading, do_writing))
1238 if (transport->send_credentials_pending ||
1239 transport->receive_credentials_pending)
1241 _dbus_verbose ("send_credentials_pending = %d receive_credentials_pending = %d\n",
1242 transport->send_credentials_pending,
1243 transport->receive_credentials_pending);
1247 #define TRANSPORT_SIDE(t) ((t)->is_server ? "server" : "client")
1248 switch (_dbus_auth_do_work (transport->auth))
1250 case DBUS_AUTH_STATE_WAITING_FOR_INPUT:
1251 _dbus_verbose (" %s auth state: waiting for input\n",
1252 TRANSPORT_SIDE (transport));
1253 if (!do_reading || !read_data_into_auth (transport, &oom))
1257 case DBUS_AUTH_STATE_WAITING_FOR_MEMORY:
1258 _dbus_verbose (" %s auth state: waiting for memory\n",
1259 TRANSPORT_SIDE (transport));
1264 case DBUS_AUTH_STATE_HAVE_BYTES_TO_SEND:
1265 _dbus_verbose (" %s auth state: bytes to send\n",
1266 TRANSPORT_SIDE (transport));
1267 if (!do_writing || !write_data_from_auth (transport))
1271 case DBUS_AUTH_STATE_NEED_DISCONNECT:
1272 _dbus_verbose (" %s auth state: need to disconnect\n",
1273 TRANSPORT_SIDE (transport));
1274 do_io_error (transport);
1277 case DBUS_AUTH_STATE_AUTHENTICATED:
1278 _dbus_verbose (" %s auth state: authenticated\n",
1279 TRANSPORT_SIDE (transport));
1286 *auth_completed = (orig_auth_state != _dbus_transport_get_is_authenticated (transport));
1288 check_read_watch (transport);
1289 check_write_watch (transport);
1290 _dbus_transport_unref (transport);
1298 /* returns false on oom */
1300 do_writing (DBusTransport *transport)
1303 DBusTransportSocket *socket_transport = (DBusTransportSocket*) transport;
1306 /* No messages without authentication! */
1307 if (!_dbus_transport_get_is_authenticated (transport))
1309 _dbus_verbose ("Not authenticated, not writing anything\n");
1313 if (transport->disconnected)
1315 _dbus_verbose ("Not connected, not writing anything\n");
1320 _dbus_verbose ("do_writing(), have_messages = %d, fd = %d\n",
1321 _dbus_connection_has_messages_to_send_unlocked (transport->connection),
1322 socket_transport->fd);
1328 while (!transport->disconnected && _dbus_connection_has_messages_to_send_unlocked (transport->connection))
1331 DBusMessage *message;
1332 const DBusString *header;
1333 const DBusString *body;
1334 int total_bytes_to_write;
1337 if (total > socket_transport->max_bytes_written_per_iteration)
1339 _dbus_verbose ("%d bytes exceeds %d bytes written per iteration, returning\n",
1340 total, socket_transport->max_bytes_written_per_iteration);
1344 message = _dbus_connection_get_message_to_send (transport->connection);
1345 _dbus_assert (message != NULL);
1346 dbus_message_lock (message);
1347 _dbus_message_get_network_data (message, &header, &body);
1349 if (_dbus_auth_needs_encoding (transport->auth))
1351 // Does fd passing even make sense with encoded data?
1352 _dbus_assert(!DBUS_TRANSPORT_CAN_SEND_UNIX_FD(transport));
1354 if (_dbus_string_get_length (&socket_transport->encoded_outgoing) == 0)
1356 if (!_dbus_auth_encode_data (transport->auth,
1357 header, &socket_transport->encoded_outgoing))
1363 if (!_dbus_auth_encode_data (transport->auth,
1364 body, &socket_transport->encoded_outgoing))
1366 _dbus_string_set_length (&socket_transport->encoded_outgoing, 0);
1372 total_bytes_to_write = _dbus_string_get_length (&socket_transport->encoded_outgoing);
1373 bytes_written = kdbus_write_msg_encoded(message, socket_transport);
1377 total_bytes_to_write = _dbus_string_get_length(header) + _dbus_string_get_length(body);
1378 bytes_written = kdbus_write_msg(transport, message, socket_transport->fd);
1381 if (bytes_written < 0)
1383 /* EINTR already handled for us */
1385 /* For some discussion of why we also ignore EPIPE here, see
1386 * http://lists.freedesktop.org/archives/dbus/2008-March/009526.html
1389 if (_dbus_get_is_errno_eagain_or_ewouldblock () || _dbus_get_is_errno_epipe ())
1393 _dbus_verbose ("Error writing to remote app: %s\n",
1394 _dbus_strerror_from_errno ());
1395 do_io_error (transport);
1401 _dbus_verbose (" wrote %d bytes of %d\n", bytes_written,
1402 total_bytes_to_write);
1404 total += bytes_written;
1405 socket_transport->message_bytes_written += bytes_written;
1407 _dbus_assert (socket_transport->message_bytes_written <=
1408 total_bytes_to_write);
1410 if (socket_transport->message_bytes_written == total_bytes_to_write)
1412 socket_transport->message_bytes_written = 0;
1413 _dbus_string_set_length (&socket_transport->encoded_outgoing, 0);
1414 _dbus_string_compact (&socket_transport->encoded_outgoing, 2048);
1416 _dbus_connection_message_sent_unlocked (transport->connection,
1429 /* returns false on out-of-memory */
1431 do_reading (DBusTransport *transport)
1433 DBusTransportSocket *socket_transport = (DBusTransportSocket*) transport;
1439 _dbus_verbose ("fd = %d\n",socket_transport->fd);
1441 /* No messages without authentication! */
1442 if (!_dbus_transport_get_is_authenticated (transport))
1451 /* See if we've exceeded max messages and need to disable reading */
1452 check_read_watch (transport);
1454 if (total > socket_transport->max_bytes_read_per_iteration)
1456 _dbus_verbose ("%d bytes exceeds %d bytes read per iteration, returning\n",
1457 total, socket_transport->max_bytes_read_per_iteration);
1461 _dbus_assert (socket_transport->read_watch != NULL ||
1462 transport->disconnected);
1464 if (transport->disconnected)
1467 if (!dbus_watch_get_enabled (socket_transport->read_watch))
1470 if (_dbus_auth_needs_decoding (transport->auth))
1472 /* Does fd passing even make sense with encoded data? */
1473 /* _dbus_assert(!DBUS_TRANSPORT_CAN_SEND_UNIX_FD(transport));
1475 if (_dbus_string_get_length (&socket_transport->encoded_incoming) > 0)
1476 bytes_read = _dbus_string_get_length (&socket_transport->encoded_incoming);
1478 bytes_read = _dbus_read_socket (socket_transport->fd,
1479 &socket_transport->encoded_incoming,
1480 socket_transport->max_bytes_read_per_iteration);*/
1482 bytes_read = kdbus_read_message(socket_transport, &socket_transport->encoded_incoming);
1484 _dbus_assert (_dbus_string_get_length (&socket_transport->encoded_incoming) ==
1491 _dbus_message_loader_get_buffer (transport->loader,
1494 orig_len = _dbus_string_get_length (buffer);
1496 if (!_dbus_auth_decode_data (transport->auth,
1497 &socket_transport->encoded_incoming,
1500 _dbus_verbose ("Out of memory decoding incoming data\n");
1501 _dbus_message_loader_return_buffer (transport->loader,
1503 _dbus_string_get_length (buffer) - orig_len);
1509 _dbus_message_loader_return_buffer (transport->loader,
1511 _dbus_string_get_length (buffer) - orig_len);
1513 _dbus_string_set_length (&socket_transport->encoded_incoming, 0);
1514 _dbus_string_compact (&socket_transport->encoded_incoming, 2048);
1519 _dbus_message_loader_get_buffer (transport->loader,
1522 bytes_read = kdbus_read_message(socket_transport, buffer);
1524 _dbus_message_loader_return_buffer (transport->loader,
1526 bytes_read < 0 ? 0 : bytes_read);
1531 /* EINTR already handled for us */
1533 if (_dbus_get_is_errno_enomem ())
1535 _dbus_verbose ("Out of memory in read()/do_reading()\n");
1539 else if (_dbus_get_is_errno_eagain_or_ewouldblock ())
1543 _dbus_verbose ("Error reading from remote app: %s\n",
1544 _dbus_strerror_from_errno ());
1545 do_io_error (transport);
1549 else if (bytes_read == 0)
1551 _dbus_verbose ("Disconnected from remote app\n");
1552 do_io_error (transport);
1557 _dbus_verbose (" read %d bytes\n", bytes_read);
1559 total += bytes_read;
1561 if (!_dbus_transport_queue_messages (transport))
1564 _dbus_verbose (" out of memory when queueing messages we just read in the transport\n");
1568 /* Try reading more data until we get EAGAIN and return, or
1569 * exceed max bytes per iteration. If in blocking mode of
1570 * course we'll block instead of returning.
1583 unix_error_with_read_to_come (DBusTransport *itransport,
1587 DBusTransportSocket *transport = (DBusTransportSocket *) itransport;
1589 if (!(flags & DBUS_WATCH_HANGUP || flags & DBUS_WATCH_ERROR))
1592 /* If we have a read watch enabled ...
1593 we -might have data incoming ... => handle the HANGUP there */
1594 if (watch != transport->read_watch &&
1595 _dbus_watch_get_enabled (transport->read_watch))
1602 socket_handle_watch (DBusTransport *transport,
1606 DBusTransportSocket *socket_transport = (DBusTransportSocket*) transport;
1608 _dbus_assert (watch == socket_transport->read_watch ||
1609 watch == socket_transport->write_watch);
1610 _dbus_assert (watch != NULL);
1612 /* If we hit an error here on a write watch, don't disconnect the transport yet because data can
1613 * still be in the buffer and do_reading may need several iteration to read
1614 * it all (because of its max_bytes_read_per_iteration limit).
1616 if (!(flags & DBUS_WATCH_READABLE) && unix_error_with_read_to_come (transport, watch, flags))
1618 _dbus_verbose ("Hang up or error on watch\n");
1619 _dbus_transport_disconnect (transport);
1623 if (watch == socket_transport->read_watch &&
1624 (flags & DBUS_WATCH_READABLE))
1626 dbus_bool_t auth_finished;
1628 _dbus_verbose ("handling read watch %p flags = %x\n",
1631 if (!do_authentication (transport, TRUE, FALSE, &auth_finished))
1634 /* We don't want to do a read immediately following
1635 * a successful authentication. This is so we
1636 * have a chance to propagate the authentication
1637 * state further up. Specifically, we need to
1638 * process any pending data from the auth object.
1642 if (!do_reading (transport))
1644 _dbus_verbose ("no memory to read\n");
1650 _dbus_verbose ("Not reading anything since we just completed the authentication\n");
1653 else if (watch == socket_transport->write_watch &&
1654 (flags & DBUS_WATCH_WRITABLE))
1657 _dbus_verbose ("handling write watch, have_outgoing_messages = %d\n",
1658 _dbus_connection_has_messages_to_send_unlocked (transport->connection));
1660 if (!do_authentication (transport, FALSE, TRUE, NULL))
1663 if (!do_writing (transport))
1665 _dbus_verbose ("no memory to write\n");
1669 /* See if we still need the write watch */
1670 check_write_watch (transport);
1672 #ifdef DBUS_ENABLE_VERBOSE_MODE
1675 if (watch == socket_transport->read_watch)
1676 _dbus_verbose ("asked to handle read watch with non-read condition 0x%x\n",
1678 else if (watch == socket_transport->write_watch)
1679 _dbus_verbose ("asked to handle write watch with non-write condition 0x%x\n",
1682 _dbus_verbose ("asked to handle watch %p on fd %d that we don't recognize\n",
1683 watch, dbus_watch_get_socket (watch));
1685 #endif /* DBUS_ENABLE_VERBOSE_MODE */
1691 socket_disconnect (DBusTransport *transport)
1693 DBusTransportSocket *socket_transport = (DBusTransportSocket*) transport;
1695 _dbus_verbose ("\n");
1697 free_watches (transport);
1699 _dbus_close_socket (socket_transport->fd, NULL);
1700 socket_transport->fd = -1;
1704 socket_connection_set (DBusTransport *transport)
1706 DBusTransportSocket *socket_transport = (DBusTransportSocket*) transport;
1708 _dbus_watch_set_handler (socket_transport->write_watch,
1709 _dbus_connection_handle_watch,
1710 transport->connection, NULL);
1712 _dbus_watch_set_handler (socket_transport->read_watch,
1713 _dbus_connection_handle_watch,
1714 transport->connection, NULL);
1716 if (!_dbus_connection_add_watch_unlocked (transport->connection,
1717 socket_transport->write_watch))
1720 if (!_dbus_connection_add_watch_unlocked (transport->connection,
1721 socket_transport->read_watch))
1723 _dbus_connection_remove_watch_unlocked (transport->connection,
1724 socket_transport->write_watch);
1728 check_read_watch (transport);
1729 check_write_watch (transport);
1735 * @todo We need to have a way to wake up the select sleep if
1736 * a new iteration request comes in with a flag (read/write) that
1737 * we're not currently serving. Otherwise a call that just reads
1738 * could block a write call forever (if there are no incoming
1742 kdbus_do_iteration (DBusTransport *transport,
1744 int timeout_milliseconds)
1746 DBusTransportSocket *socket_transport = (DBusTransportSocket*) transport;
1751 _dbus_verbose (" iteration flags = %s%s timeout = %d read_watch = %p write_watch = %p fd = %d\n",
1752 flags & DBUS_ITERATION_DO_READING ? "read" : "",
1753 flags & DBUS_ITERATION_DO_WRITING ? "write" : "",
1754 timeout_milliseconds,
1755 socket_transport->read_watch,
1756 socket_transport->write_watch,
1757 socket_transport->fd);
1759 /* the passed in DO_READING/DO_WRITING flags indicate whether to
1760 * read/write messages, but regardless of those we may need to block
1761 * for reading/writing to do auth. But if we do reading for auth,
1762 * we don't want to read any messages yet if not given DO_READING.
1765 poll_fd.fd = socket_transport->fd;
1768 if (_dbus_transport_get_is_authenticated (transport))
1770 /* This is kind of a hack; if we have stuff to write, then try
1771 * to avoid the poll. This is probably about a 5% speedup on an
1772 * echo client/server.
1774 * If both reading and writing were requested, we want to avoid this
1775 * since it could have funky effects:
1776 * - both ends spinning waiting for the other one to read
1777 * data so they can finish writing
1778 * - prioritizing all writing ahead of reading
1780 if ((flags & DBUS_ITERATION_DO_WRITING) &&
1781 !(flags & (DBUS_ITERATION_DO_READING | DBUS_ITERATION_BLOCK)) &&
1782 !transport->disconnected &&
1783 _dbus_connection_has_messages_to_send_unlocked (transport->connection))
1785 do_writing (transport);
1787 if (transport->disconnected ||
1788 !_dbus_connection_has_messages_to_send_unlocked (transport->connection))
1792 /* If we get here, we decided to do the poll() after all */
1793 _dbus_assert (socket_transport->read_watch);
1794 if (flags & DBUS_ITERATION_DO_READING)
1795 poll_fd.events |= _DBUS_POLLIN;
1797 _dbus_assert (socket_transport->write_watch);
1798 if (flags & DBUS_ITERATION_DO_WRITING)
1799 poll_fd.events |= _DBUS_POLLOUT;
1803 DBusAuthState auth_state;
1805 auth_state = _dbus_auth_do_work (transport->auth);
1807 if (transport->receive_credentials_pending ||
1808 auth_state == DBUS_AUTH_STATE_WAITING_FOR_INPUT)
1809 poll_fd.events |= _DBUS_POLLIN;
1811 if (transport->send_credentials_pending ||
1812 auth_state == DBUS_AUTH_STATE_HAVE_BYTES_TO_SEND)
1813 poll_fd.events |= _DBUS_POLLOUT;
1818 if (flags & DBUS_ITERATION_BLOCK)
1819 poll_timeout = timeout_milliseconds;
1823 /* For blocking selects we drop the connection lock here
1824 * to avoid blocking out connection access during a potentially
1825 * indefinite blocking call. The io path is still protected
1826 * by the io_path_cond condvar, so we won't reenter this.
1828 if (flags & DBUS_ITERATION_BLOCK)
1830 _dbus_verbose ("unlock pre poll\n");
1831 _dbus_connection_unlock (transport->connection);
1835 poll_res = _dbus_poll (&poll_fd, 1, poll_timeout);
1837 if (poll_res < 0 && _dbus_get_is_errno_eintr ())
1839 _dbus_verbose ("Error from _dbus_poll(): %s\n",
1840 _dbus_strerror_from_errno ());
1844 if (flags & DBUS_ITERATION_BLOCK)
1846 _dbus_verbose ("lock post poll\n");
1847 _dbus_connection_lock (transport->connection);
1853 poll_fd.revents = 0; /* some concern that posix does not guarantee this;
1854 * valgrind flags it as an error. though it probably
1855 * is guaranteed on linux at least.
1858 if (poll_fd.revents & _DBUS_POLLERR)
1859 do_io_error (transport);
1862 dbus_bool_t need_read = (poll_fd.revents & _DBUS_POLLIN) > 0;
1863 dbus_bool_t need_write = (poll_fd.revents & _DBUS_POLLOUT) > 0;
1864 dbus_bool_t authentication_completed;
1866 _dbus_verbose ("in iteration, need_read=%d need_write=%d\n",
1867 need_read, need_write);
1868 do_authentication (transport, need_read, need_write,
1869 &authentication_completed);
1871 /* See comment in socket_handle_watch. */
1872 if (authentication_completed)
1875 if (need_read && (flags & DBUS_ITERATION_DO_READING))
1876 do_reading (transport);
1877 if (need_write && (flags & DBUS_ITERATION_DO_WRITING))
1878 do_writing (transport);
1883 _dbus_verbose ("Error from _dbus_poll(): %s\n",
1884 _dbus_strerror_from_errno ());
1890 /* We need to install the write watch only if we did not
1891 * successfully write everything. Note we need to be careful that we
1892 * don't call check_write_watch *before* do_writing, since it's
1893 * inefficient to add the write watch, and we can avoid it most of
1894 * the time since we can write immediately.
1896 * However, we MUST always call check_write_watch(); DBusConnection code
1897 * relies on the fact that running an iteration will notice that
1898 * messages are pending.
1900 check_write_watch (transport);
1902 _dbus_verbose (" ... leaving do_iteration()\n");
1906 socket_live_messages_changed (DBusTransport *transport)
1908 /* See if we should look for incoming messages again */
1909 check_read_watch (transport);
1912 static const DBusTransportVTable kdbus_vtable = {
1914 socket_handle_watch,
1916 socket_connection_set,
1918 socket_live_messages_changed,
1919 socket_get_socket_fd
1923 * Creates a new transport for the given kdbus file descriptor. The file
1924 * descriptor must be nonblocking (use _dbus_set_fd_nonblocking() to
1927 * @param fd the file descriptor.
1928 * @param server_guid non-#NULL if this transport is on the server side of a connection
1929 * @param address the transport's address
1930 * @returns the new transport, or #NULL if no memory.
1932 static DBusTransport*
1933 _dbus_transport_new_for_socket_kdbus (int fd,
1934 const DBusString *server_guid,
1935 const DBusString *address)
1937 DBusTransportSocket *socket_transport;
1939 socket_transport = dbus_new0 (DBusTransportSocket, 1);
1940 if (socket_transport == NULL)
1943 if (!_dbus_string_init (&socket_transport->encoded_outgoing))
1946 if (!_dbus_string_init (&socket_transport->encoded_incoming))
1949 socket_transport->write_watch = _dbus_watch_new (fd,
1950 DBUS_WATCH_WRITABLE,
1953 if (socket_transport->write_watch == NULL)
1956 socket_transport->read_watch = _dbus_watch_new (fd,
1957 DBUS_WATCH_READABLE,
1960 if (socket_transport->read_watch == NULL)
1963 if (!_dbus_transport_init_base (&socket_transport->base,
1965 server_guid, address))
1968 #ifdef HAVE_UNIX_FD_PASSING
1969 _dbus_auth_set_unix_fd_possible(socket_transport->base.auth, _dbus_socket_can_pass_unix_fd(fd));
1972 socket_transport->fd = fd;
1973 socket_transport->message_bytes_written = 0;
1975 /* These values should probably be tunable or something. */
1976 socket_transport->max_bytes_read_per_iteration = POOL_SIZE;
1977 socket_transport->max_bytes_written_per_iteration = 2048;
1979 socket_transport->kdbus_mmap_ptr = NULL;
1981 return (DBusTransport*) socket_transport;
1984 _dbus_watch_invalidate (socket_transport->read_watch);
1985 _dbus_watch_unref (socket_transport->read_watch);
1987 _dbus_watch_invalidate (socket_transport->write_watch);
1988 _dbus_watch_unref (socket_transport->write_watch);
1990 _dbus_string_free (&socket_transport->encoded_incoming);
1992 _dbus_string_free (&socket_transport->encoded_outgoing);
1994 dbus_free (socket_transport);
2000 * Creates a connection to the kdbus bus
2002 * This will set FD_CLOEXEC for the socket returned.
2004 * @param path the path to UNIX domain socket
2005 * @param error return location for error code
2006 * @returns connection file descriptor or -1 on error
2008 static int _dbus_connect_kdbus (const char *path, DBusError *error)
2012 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
2013 _dbus_verbose ("connecting to kdbus bus %s\n", path);
2015 fd = open(path, O_RDWR|O_CLOEXEC|O_NONBLOCK); //[RP] | O_NONBLOCK added here, in dbus added separately in section commented out below
2018 dbus_set_error(error, _dbus_error_from_errno (errno), "Failed to open file descriptor: %s", _dbus_strerror (errno));
2019 _DBUS_ASSERT_ERROR_IS_SET(error);
2020 return -1; //[RP] not needed here if commented block below is removed
2023 /*if (!_dbus_set_fd_nonblocking (fd, error))
2025 _DBUS_ASSERT_ERROR_IS_SET (error);
2026 _dbus_close (fd, NULL);
2033 static dbus_bool_t kdbus_mmap(DBusTransport* transport)
2035 DBusTransportSocket *socket_transport = (DBusTransportSocket*) transport;
2037 socket_transport->kdbus_mmap_ptr = mmap(NULL, POOL_SIZE, PROT_READ, MAP_SHARED, socket_transport->fd, 0);
2038 if (socket_transport->kdbus_mmap_ptr == MAP_FAILED)
2045 * Creates a new transport for kdbus.
2046 * This creates a client-side of a transport.
2048 * @param path the path to the domain socket.
2049 * @param error address where an error can be returned.
2050 * @returns a new transport, or #NULL on failure.
2052 static DBusTransport* _dbus_transport_new_for_kdbus (const char *path, DBusError *error)
2055 DBusTransport *transport;
2058 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
2060 if (!_dbus_string_init (&address))
2062 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
2068 if ((!_dbus_string_append (&address, "kdbus:path=")) || (!_dbus_string_append (&address, path)))
2070 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
2074 fd = _dbus_connect_kdbus (path, error);
2077 _DBUS_ASSERT_ERROR_IS_SET (error);
2081 _dbus_verbose ("Successfully connected to kdbus bus %s\n", path);
2083 transport = _dbus_transport_new_for_socket_kdbus (fd, NULL, &address);
2084 if (transport == NULL)
2086 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
2090 _dbus_string_free (&address);
2095 _dbus_close_socket (fd, NULL);
2097 _dbus_string_free (&address);
2103 * Opens kdbus transport.
2105 * @param entry the address entry to try opening
2106 * @param transport_p return location for the opened transport
2107 * @param error error to be set
2108 * @returns result of the attempt
2110 DBusTransportOpenResult _dbus_transport_open_kdbus(DBusAddressEntry *entry,
2111 DBusTransport **transport_p,
2116 method = dbus_address_entry_get_method (entry);
2117 _dbus_assert (method != NULL);
2119 if (strcmp (method, "kdbus") == 0)
2121 const char *path = dbus_address_entry_get_value (entry, "path");
2125 _dbus_set_bad_address (error, "kdbus", "path", NULL);
2126 return DBUS_TRANSPORT_OPEN_BAD_ADDRESS;
2129 *transport_p = _dbus_transport_new_for_kdbus (path, error);
2131 if (*transport_p == NULL)
2133 _DBUS_ASSERT_ERROR_IS_SET (error);
2134 return DBUS_TRANSPORT_OPEN_DID_NOT_CONNECT;
2138 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
2139 return DBUS_TRANSPORT_OPEN_OK;
2144 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
2145 return DBUS_TRANSPORT_OPEN_NOT_HANDLED;
2149 static struct kdbus_policy *make_policy_name(const char *name)
2151 struct kdbus_policy *p;
2154 size = offsetof(struct kdbus_policy, name) + strlen(name) + 1;
2160 p->type = KDBUS_POLICY_NAME;
2161 strcpy(p->name, name);
2166 static struct kdbus_policy *make_policy_access(__u64 type, __u64 bits, __u64 id)
2168 struct kdbus_policy *p;
2169 __u64 size = sizeof(*p);
2177 p->type = KDBUS_POLICY_ACCESS;
2178 p->access.type = type;
2179 p->access.bits = bits;
2185 static void append_policy(struct kdbus_cmd_policy *cmd_policy, struct kdbus_policy *policy, __u64 max_size)
2187 struct kdbus_policy *dst = (struct kdbus_policy *) ((char *) cmd_policy + cmd_policy->size);
2189 if (cmd_policy->size + policy->size > max_size)
2192 memcpy(dst, policy, policy->size);
2193 cmd_policy->size += KDBUS_ALIGN8(policy->size);
2197 dbus_bool_t bus_register_policy_kdbus(const char* name, DBusConnection *connection, DBusError *error)
2199 struct kdbus_cmd_policy *cmd_policy;
2200 struct kdbus_policy *policy;
2204 if(!dbus_connection_get_socket(connection, &fd))
2206 dbus_set_error (error, "Failed to get fd for registering policy", NULL);
2210 cmd_policy = (struct kdbus_cmd_policy *) alloca(size);
2211 memset(cmd_policy, 0, size);
2213 policy = (struct kdbus_policy *) cmd_policy->policies;
2214 cmd_policy->size = offsetof(struct kdbus_cmd_policy, policies);
2216 policy = make_policy_name(name); //todo to be verified or changed when meaning will be known
2217 append_policy(cmd_policy, policy, size);
2219 policy = make_policy_access(KDBUS_POLICY_ACCESS_USER, KDBUS_POLICY_OWN, getuid());
2220 append_policy(cmd_policy, policy, size);
2222 policy = make_policy_access(KDBUS_POLICY_ACCESS_WORLD, KDBUS_POLICY_RECV, 0);
2223 append_policy(cmd_policy, policy, size);
2225 policy = make_policy_access(KDBUS_POLICY_ACCESS_WORLD, KDBUS_POLICY_SEND, 0);
2226 append_policy(cmd_policy, policy, size);
2228 if (ioctl(fd, KDBUS_CMD_EP_POLICY_SET, cmd_policy) < 0)
2230 dbus_set_error(error,_dbus_error_from_errno (errno), "Error setting EP policy: %s", _dbus_strerror (errno));
2234 _dbus_verbose("Policy %s set correctly\n", name);
2238 dbus_bool_t bus_register_kdbus(char* name, DBusConnection *connection, DBusError *error)
2240 struct kdbus_cmd_hello hello;
2243 memset(&hello, 0, sizeof(hello));
2244 hello.conn_flags = KDBUS_HELLO_ACCEPT_FD |
2245 KDBUS_HELLO_ATTACH_COMM |
2246 KDBUS_HELLO_ATTACH_EXE |
2247 KDBUS_HELLO_ATTACH_CMDLINE |
2248 KDBUS_HELLO_ATTACH_CAPS |
2249 KDBUS_HELLO_ATTACH_CGROUP |
2250 KDBUS_HELLO_ATTACH_SECLABEL |
2251 KDBUS_HELLO_ATTACH_AUDIT;
2252 hello.size = sizeof(struct kdbus_cmd_hello);
2253 hello.pool_size = POOL_SIZE;
2255 if(!dbus_connection_get_socket(connection, &fd))
2257 dbus_set_error (error, "failed to get fd for bus registration", NULL);
2260 if (ioctl(fd, KDBUS_CMD_HELLO, &hello))
2262 dbus_set_error(error,_dbus_error_from_errno (errno), "Failed to send hello: %s", _dbus_strerror (errno));
2266 _dbus_verbose("-- Our peer ID is: %llu\n", (unsigned long long)hello.id);
2267 sprintf(name, "%llu", (unsigned long long)hello.id);
2269 if(!kdbus_mmap(dbus_connection_get_transport(connection)))
2271 dbus_set_error(error,_dbus_error_from_errno (errno), "Error when mmap: %s", _dbus_strerror (errno));
2278 uint64_t bus_request_name_kdbus(DBusConnection *connection, const char *name, const uint64_t flags, DBusError *error)
2280 struct kdbus_cmd_name *cmd_name;
2282 uint64_t size = sizeof(*cmd_name) + strlen(name) + 1;
2283 uint64_t flags_kdbus = 0;
2285 cmd_name = alloca(size);
2287 memset(cmd_name, 0, size);
2288 strcpy(cmd_name->name, name);
2289 cmd_name->size = size;
2291 if(flags & DBUS_NAME_FLAG_ALLOW_REPLACEMENT)
2292 flags_kdbus |= KDBUS_NAME_ALLOW_REPLACEMENT;
2293 if(!(flags & DBUS_NAME_FLAG_DO_NOT_QUEUE))
2294 flags_kdbus |= KDBUS_NAME_QUEUE;
2295 if(flags & DBUS_NAME_FLAG_REPLACE_EXISTING)
2296 flags_kdbus |= KDBUS_NAME_REPLACE_EXISTING;
2298 cmd_name->conn_flags = flags_kdbus;
2300 if(!dbus_connection_get_socket(connection, &fd))
2302 dbus_set_error (error, "failed to get fd for name request", NULL);
2306 _dbus_verbose("Request name - flags sent: 0x%llx !!!!!!!!!\n", cmd_name->conn_flags);
2308 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
2309 if (ioctl(fd, KDBUS_CMD_NAME_ACQUIRE, cmd_name))
2311 dbus_set_error(error,_dbus_error_from_errno (errno), "error acquiring name: %s", _dbus_strerror (errno));
2313 return DBUS_REQUEST_NAME_REPLY_EXISTS;
2317 _dbus_verbose("Request name - received flag: 0x%llx !!!!!!!!!\n", cmd_name->conn_flags);
2319 if(cmd_name->conn_flags & KDBUS_NAME_IN_QUEUE)
2320 return DBUS_REQUEST_NAME_REPLY_IN_QUEUE;
2322 return DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER;
2323 //todo now 1 code is never returned - DBUS_REQUEST_NAME_REPLY_ALREADY_OWNER
2327 * Checks if the connection's transport is kdbus on the basis of its address
2329 * @param pointer to the connection
2330 * @returns TRUE if kdbus transport, otherwise FALSE
2332 dbus_bool_t dbus_transport_is_kdbus(DBusConnection *connection)
2334 const char* address = _dbus_connection_get_address(connection);
2336 if(address == strstr(address, "kdbus:path="))
2342 void dbus_bus_add_match_kdbus (DBusConnection *connection, const char *rule, DBusError *error)
2344 struct kdbus_cmd_match cmd_match;
2347 memset(&cmd_match, 0, sizeof(cmd_match));
2349 if(!dbus_connection_get_socket(connection, &fd))
2351 dbus_set_error (error, "failed to get fd for add match", NULL);
2355 cmd_match.size = sizeof(cmd_match);
2357 //todo add matching rules from *rule when it will be docuemnted in kdbus
2360 cmd_match.src_id = KDBUS_MATCH_SRC_ID_ANY;
2362 if (ioctl(fd, KDBUS_CMD_MATCH_ADD, &cmd_match))
2363 dbus_set_error(error,_dbus_error_from_errno (errno), "error adding match: %s", _dbus_strerror (errno));
2365 _dbus_verbose("Finished adding match bus rule %s\n", rule);