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 _dbus_verbose ("do writing destination: %s\n", name); //todo can be removed at the end
126 dst_id = KDBUS_DST_ID_WELL_KNOWN_NAME;
127 if((name[0] == ':') && (name[1] == '1') && (name[2] == '.')) //if name starts with :1. it is a unique name and should be send as number
129 dst_id = strtoll(&name[3], NULL, 10);
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 if (dst_id == KDBUS_DST_ID_BROADCAST)
151 size += KDBUS_PART_HEADER_SIZE + 64;
154 size += KDBUS_ITEM_SIZE(strlen(name) + 1);
159 _dbus_verbose("Error allocating memory for: %s,%s\n", _dbus_strerror (errno), _dbus_error_from_errno (errno));
163 memset(msg, 0, size);
165 msg->src_id = strtoll(dbus_bus_get_unique_name(transport->connection), NULL , 10);
166 msg->dst_id = name ? 0 : dst_id;
167 msg->cookie = dbus_message_get_serial(message);
168 msg->payload_type = KDBUS_PAYLOAD_DBUS1;
174 item->type = KDBUS_MSG_DST_NAME;
175 item->size = KDBUS_PART_HEADER_SIZE + strlen(name) + 1;
176 strcpy(item->str, name);
177 item = KDBUS_PART_NEXT(item);
180 item->type = KDBUS_MSG_PAYLOAD_VEC;
181 item->size = KDBUS_PART_HEADER_SIZE + sizeof(struct kdbus_vec);
182 item->vec.address = (unsigned long) _dbus_string_get_const_data(header);
183 item->vec.size = ret_size;
187 item = KDBUS_PART_NEXT(item);
188 item->type = KDBUS_MSG_PAYLOAD_VEC;
189 item->size = KDBUS_PART_HEADER_SIZE + sizeof(struct kdbus_vec);
190 item->vec.address = (unsigned long) _dbus_string_get_const_data(body);
191 item->vec.size = body_size;
192 ret_size += body_size;
195 /* fprintf (stderr, "\nbody:\n");
196 for(i=0; i < item->vec.size; i++)
198 fprintf (stderr, "%02x", _dbus_string_get_byte(body,i));
200 fprintf (stderr, "\nitem->vec.size: %llu, i: %lu\n", item->vec.size, i);*/
202 if (dst_id == KDBUS_DST_ID_BROADCAST)
204 item = KDBUS_PART_NEXT(item);
205 item->type = KDBUS_MSG_BLOOM;
206 item->size = KDBUS_PART_HEADER_SIZE + 64;
210 if (ioctl(fd, KDBUS_CMD_MSG_SEND, msg))
214 if(errno == ENXIO) //when recipient is not available on the bus
216 DBusMessage *errMessage = NULL;
218 errMessage = generate_local_error_message(msg->cookie, "org.freedesktop.DBus.Error.ServiceUnknown", NULL);
219 if(errMessage == NULL)
221 dbus_message_set_reply_serial(errMessage, dbus_message_get_reply_serial(message));
222 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 _dbus_verbose ("do writing encoded message destination: %s\n", name); //todo can be removed at the end
248 dst_id = KDBUS_DST_ID_WELL_KNOWN_NAME;
249 if((name[0] == ':') && (name[1] == '1') && (name[2] == '.'))
251 dst_id = strtoll(&name[2], NULL, 10);
256 size = sizeof(struct kdbus_msg);
257 size += KDBUS_ITEM_SIZE(sizeof(struct kdbus_vec));
259 if (dst_id == KDBUS_DST_ID_BROADCAST)
260 size += KDBUS_PART_HEADER_SIZE + 64;
263 size += KDBUS_ITEM_SIZE(strlen(name) + 1);
268 _dbus_verbose("Error allocating memory for: %s,%s\n", _dbus_strerror (errno), _dbus_error_from_errno (errno));
272 memset(msg, 0, size);
274 msg->src_id = strtoll(dbus_bus_get_unique_name(socket_transport->base.connection), NULL , 10);
275 _dbus_verbose("sending encoded msg, src_id=%llu\n", msg->src_id);
276 msg->dst_id = name ? 0 : dst_id;
277 msg->cookie = dbus_message_get_serial(message);
278 msg->payload_type = KDBUS_PAYLOAD_DBUS1;
284 item->type = KDBUS_MSG_DST_NAME;
285 item->size = KDBUS_PART_HEADER_SIZE + strlen(name) + 1;
286 strcpy(item->str, name);
287 item = KDBUS_PART_NEXT(item);
290 item->type = KDBUS_MSG_PAYLOAD_VEC;
291 item->size = KDBUS_PART_HEADER_SIZE + sizeof(struct kdbus_vec);
292 item->vec.address = (unsigned long) &socket_transport->encoded_outgoing;
293 item->vec.size = _dbus_string_get_length (&socket_transport->encoded_outgoing);
294 item = KDBUS_PART_NEXT(item);
296 if (dst_id == KDBUS_DST_ID_BROADCAST)
298 item->type = KDBUS_MSG_BLOOM;
299 item->size = KDBUS_PART_HEADER_SIZE + 64;
303 if (ioctl(socket_transport->fd, KDBUS_CMD_MSG_SEND, msg))
307 if(errno == ENXIO) //when recipient is not available on the bus
309 DBusMessage *errMessage = NULL;
311 errMessage = generate_local_error_message(msg->cookie, "org.freedesktop.DBus.Error.ServiceUnknown", NULL);
312 if(errMessage == NULL)
314 dbus_message_set_reply_serial(errMessage, dbus_message_get_reply_serial(message));
315 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 char *msg_id(uint64_t id, char *buf);
331 char *msg_id(uint64_t id, char *buf)
337 sprintf(buf, "%llu", (unsigned long long)id);
341 struct kdbus_enum_table {
345 #define _STRINGIFY(x) #x
346 #define STRINGIFY(x) _STRINGIFY(x)
347 #define ELEMENTSOF(x) (sizeof(x)/sizeof((x)[0]))
348 #define TABLE(what) static struct kdbus_enum_table kdbus_table_##what[]
349 #define ENUM(_id) { .id=_id, .name=STRINGIFY(_id) }
350 #define LOOKUP(what) \
351 const char *enum_##what(long long id) { \
353 for (i = 0; i < ELEMENTSOF(kdbus_table_##what); i++) \
354 if (id == kdbus_table_##what[i].id) \
355 return kdbus_table_##what[i].name; \
358 const char *enum_MSG(long long id);
360 ENUM(_KDBUS_MSG_NULL),
361 ENUM(KDBUS_MSG_PAYLOAD_VEC),
362 ENUM(KDBUS_MSG_PAYLOAD_OFF),
363 ENUM(KDBUS_MSG_PAYLOAD_MEMFD),
365 ENUM(KDBUS_MSG_BLOOM),
366 ENUM(KDBUS_MSG_DST_NAME),
367 ENUM(KDBUS_MSG_SRC_CREDS),
368 ENUM(KDBUS_MSG_SRC_PID_COMM),
369 ENUM(KDBUS_MSG_SRC_TID_COMM),
370 ENUM(KDBUS_MSG_SRC_EXE),
371 ENUM(KDBUS_MSG_SRC_CMDLINE),
372 ENUM(KDBUS_MSG_SRC_CGROUP),
373 ENUM(KDBUS_MSG_SRC_CAPS),
374 ENUM(KDBUS_MSG_SRC_SECLABEL),
375 ENUM(KDBUS_MSG_SRC_AUDIT),
376 ENUM(KDBUS_MSG_SRC_NAMES),
377 ENUM(KDBUS_MSG_TIMESTAMP),
378 ENUM(KDBUS_MSG_NAME_ADD),
379 ENUM(KDBUS_MSG_NAME_REMOVE),
380 ENUM(KDBUS_MSG_NAME_CHANGE),
381 ENUM(KDBUS_MSG_ID_ADD),
382 ENUM(KDBUS_MSG_ID_REMOVE),
383 ENUM(KDBUS_MSG_REPLY_TIMEOUT),
384 ENUM(KDBUS_MSG_REPLY_DEAD),
387 const char *enum_PAYLOAD(long long id);
389 ENUM(KDBUS_PAYLOAD_KERNEL),
390 ENUM(KDBUS_PAYLOAD_DBUS1),
391 ENUM(KDBUS_PAYLOAD_GVARIANT),
395 static int kdbus_decode_msg(const struct kdbus_msg* msg, char *data, void* mmap_ptr)
397 const struct kdbus_item *item = msg->items;
398 char buf[32]; //todo to be removed after development
400 DBusMessage *message = NULL;
401 DBusMessageIter args;
402 char* pStringMallocked = NULL;
403 const char* dbus = "org.freedesktop.DBus";
404 const char* emptyString = "";
405 const DBusString *header;
406 const DBusString *body;
408 const char* pString = NULL;
412 _dbus_verbose("MESSAGE: %s (%llu bytes) flags=0x%llx, %s → %s, cookie=%llu, timeout=%llu\n",
413 enum_PAYLOAD(msg->payload_type), (unsigned long long) msg->size,
414 (unsigned long long) msg->flags,
415 msg_id(msg->src_id, buf), msg_id(msg->dst_id, buf),
416 (unsigned long long) msg->cookie, (unsigned long long) msg->timeout_ns);
418 KDBUS_PART_FOREACH(item, msg, items)
420 if (item->size <= KDBUS_PART_HEADER_SIZE)
422 _dbus_verbose(" +%s (%llu bytes) invalid data record\n", enum_MSG(item->type), item->size);
423 break; //todo to be discovered and rewritten
428 case KDBUS_MSG_PAYLOAD_OFF:
432 if (item->vec.offset == ~0ULL)
433 s = "[padding bytes]";
438 s = (char *)mmap_ptr + item->vec.offset;
439 /* fprintf(stderr,"\nmmap: %lu", (uint64_t)mmap_ptr);
440 fprintf (stderr, "\nheader: %llu\n", item->vec.size);
441 for(i=0; i < item->vec.size; i++)
443 fprintf (stderr, "%02x", (int)s[i]);
445 fprintf (stderr, "\nret size: %llu, i: %lu\n", item->vec.size, i);*/
447 memcpy(data, s, item->vec.size);
448 data += item->vec.size;
449 ret_size += item->vec.size;
452 _dbus_verbose(" +%s (%llu bytes) off=%llu size=%llu '%s'\n",
453 enum_MSG(item->type), item->size,
454 (unsigned long long)item->vec.offset,
455 (unsigned long long)item->vec.size, s);
459 case KDBUS_MSG_PAYLOAD_MEMFD:
464 buf = mmap(NULL, item->memfd.size, PROT_READ, MAP_SHARED, item->memfd.fd, 0);
465 if (buf == MAP_FAILED) {
466 _dbus_verbose("mmap() fd=%i failed:%m", item->memfd.fd);
470 if (ioctl(item->memfd.fd, KDBUS_CMD_MEMFD_SIZE_GET, &size) < 0) {
471 _dbus_verbose("KDBUS_CMD_MEMFD_SIZE_GET failed: %m\n");
475 _dbus_verbose(" +%s (%llu bytes) fd=%i size=%llu filesize=%llu '%s'\n",
476 enum_MSG(item->type), item->size, item->memfd.fd,
477 (unsigned long long)item->memfd.size, (unsigned long long)size, buf);
481 case KDBUS_MSG_SRC_CREDS:
482 _dbus_verbose(" +%s (%llu bytes) uid=%lld, gid=%lld, pid=%lld, tid=%lld, starttime=%lld\n",
483 enum_MSG(item->type), item->size,
484 item->creds.uid, item->creds.gid,
485 item->creds.pid, item->creds.tid,
486 item->creds.starttime);
489 case KDBUS_MSG_SRC_PID_COMM:
490 case KDBUS_MSG_SRC_TID_COMM:
491 case KDBUS_MSG_SRC_EXE:
492 case KDBUS_MSG_SRC_CGROUP:
493 case KDBUS_MSG_SRC_SECLABEL:
494 case KDBUS_MSG_DST_NAME:
495 _dbus_verbose(" +%s (%llu bytes) '%s' (%zu)\n",
496 enum_MSG(item->type), item->size, item->str, strlen(item->str));
499 case KDBUS_MSG_SRC_CMDLINE:
500 case KDBUS_MSG_SRC_NAMES: {
501 size_t size = item->size - KDBUS_PART_HEADER_SIZE;
502 const char *str = item->str;
505 _dbus_verbose(" +%s (%llu bytes) ", enum_MSG(item->type), item->size);
507 _dbus_verbose("'%s' ", str);
508 size -= strlen(str) + 1;
509 str += strlen(str) + 1;
513 _dbus_verbose("(%d string%s)\n", count, (count == 1) ? "" : "s");
517 case KDBUS_MSG_SRC_AUDIT:
518 _dbus_verbose(" +%s (%llu bytes) loginuid=%llu sessionid=%llu\n",
519 enum_MSG(item->type), item->size,
520 (unsigned long long)item->data64[0],
521 (unsigned long long)item->data64[1]);
524 case KDBUS_MSG_SRC_CAPS: {
529 _dbus_verbose(" +%s (%llu bytes) len=%llu bytes)\n",
530 enum_MSG(item->type), item->size,
531 (unsigned long long)item->size - KDBUS_PART_HEADER_SIZE);
534 n = (item->size - KDBUS_PART_HEADER_SIZE) / 4 / sizeof(uint32_t);
536 _dbus_verbose(" CapInh=");
537 for (i = 0; i < n; i++)
538 _dbus_verbose("%08x", cap[(0 * n) + (n - i - 1)]);
540 _dbus_verbose(" CapPrm=");
541 for (i = 0; i < n; i++)
542 _dbus_verbose("%08x", cap[(1 * n) + (n - i - 1)]);
544 _dbus_verbose(" CapEff=");
545 for (i = 0; i < n; i++)
546 _dbus_verbose("%08x", cap[(2 * n) + (n - i - 1)]);
548 _dbus_verbose(" CapInh=");
549 for (i = 0; i < n; i++)
550 _dbus_verbose("%08x", cap[(3 * n) + (n - i - 1)]);
555 case KDBUS_MSG_TIMESTAMP:
556 _dbus_verbose(" +%s (%llu bytes) realtime=%lluns monotonic=%lluns\n",
557 enum_MSG(item->type), item->size,
558 (unsigned long long)item->timestamp.realtime_ns,
559 (unsigned long long)item->timestamp.monotonic_ns);
562 case KDBUS_MSG_REPLY_TIMEOUT:
563 _dbus_verbose(" +%s (%llu bytes) cookie=%llu\n",
564 enum_MSG(item->type), item->size, msg->cookie_reply);
566 message = generate_local_error_message(msg->cookie_reply, "org.freedesktop.DBus.Error.NoReply", NULL);
573 dbus_message_lock (message);
574 _dbus_message_get_network_data (message, &header, &body);
575 size = _dbus_string_get_length(header);
576 memcpy(data, _dbus_string_get_const_data(header), size);
579 size = _dbus_string_get_length(body);
580 memcpy(data, _dbus_string_get_const_data(body), size);
585 case KDBUS_MSG_NAME_ADD:
586 _dbus_verbose(" +%s (%llu bytes) '%s', old id=%lld, new id=%lld, flags=0x%llx\n",
587 enum_MSG(item->type), (unsigned long long) item->size,
588 item->name_change.name, item->name_change.old_id,
589 item->name_change.new_id, item->name_change.flags);
591 pStringMallocked = malloc (sizeof(item->name_change.new_id)*2.5 + 4);
594 strcpy(pStringMallocked,":1.");
595 sprintf(&pStringMallocked[3],"%llu",item->name_change.new_id);
596 _dbus_verbose ("Name added for id: %s\n", pStringMallocked); //todo to be removed
601 message = dbus_message_new_signal("/org/freedesktop/DBus", // object name of the signal
602 dbus, // interface name of the signal
603 "NameOwnerChanged"); // name of the signal
610 pString = item->name_change.name;
611 _dbus_verbose ("Name added: %s\n", pString);
612 dbus_message_iter_init_append(message, &args);
613 if (!dbus_message_iter_append_basic(&args, DBUS_TYPE_STRING,&pString))
618 if (!dbus_message_iter_append_basic(&args, DBUS_TYPE_STRING, &emptyString))
623 if (!dbus_message_iter_append_basic(&args, DBUS_TYPE_STRING, &pStringMallocked))
629 dbus_message_set_sender(message, dbus);
630 dbus_message_set_serial(message, 1);
632 dbus_message_lock (message);
633 _dbus_message_get_network_data (message, &header, &body);
634 size = _dbus_string_get_length(header);
635 memcpy(data, _dbus_string_get_const_data(header), size);
638 size = _dbus_string_get_length(body);
639 memcpy(data, _dbus_string_get_const_data(body), size);
644 case KDBUS_MSG_NAME_REMOVE:
645 _dbus_verbose(" +%s (%llu bytes) '%s', old id=%lld, new id=%lld, flags=0x%llx\n",
646 enum_MSG(item->type), (unsigned long long) item->size,
647 item->name_change.name, item->name_change.old_id,
648 item->name_change.new_id, item->name_change.flags);
650 pStringMallocked = malloc (sizeof(item->name_change.old_id)*2.5 + 4);
653 strcpy(pStringMallocked,":1.");
654 sprintf(&pStringMallocked[3],"%llu",item->name_change.old_id);
655 _dbus_verbose ("Name removed for id: %s\n", pStringMallocked); //todo to be removed
660 message = dbus_message_new_signal("/org/freedesktop/DBus", // object name of the signal
661 dbus, // interface name of the signal
662 "NameOwnerChanged"); // name of the signal
669 pString = item->name_change.name;
670 _dbus_verbose ("Name removed: %s\n", pString);
671 dbus_message_iter_init_append(message, &args);
672 if (!dbus_message_iter_append_basic(&args, DBUS_TYPE_STRING,&pString))
677 if (!dbus_message_iter_append_basic(&args, DBUS_TYPE_STRING, &pStringMallocked))
682 if (!dbus_message_iter_append_basic(&args, DBUS_TYPE_STRING, &emptyString))
688 dbus_message_set_sender(message, dbus);
689 dbus_message_set_serial(message, 1);
691 dbus_message_lock (message);
692 _dbus_message_get_network_data (message, &header, &body);
693 size = _dbus_string_get_length(header);
694 memcpy(data, _dbus_string_get_const_data(header), size);
697 size = _dbus_string_get_length(body);
698 memcpy(data, _dbus_string_get_const_data(body), size);
703 case KDBUS_MSG_NAME_CHANGE:
704 _dbus_verbose(" +%s (%llu bytes) '%s', old id=%lld, new id=%lld, flags=0x%llx\n",
705 enum_MSG(item->type), (unsigned long long) item->size,
706 item->name_change.name, item->name_change.old_id,
707 item->name_change.new_id, item->name_change.flags);
709 pStringMallocked = malloc (sizeof(item->name_change.new_id)*2.5 + 4);
712 strcpy(pStringMallocked,":1.");
713 sprintf(&pStringMallocked[3],"%llu",item->name_change.old_id);
714 _dbus_verbose ("Old id: %s\n", pStringMallocked); //todo to be removed
719 message = dbus_message_new_signal("/org/freedesktop/DBus", // object name of the signal
720 dbus, // interface name of the signal
721 "NameOwnerChanged"); // name of the signal
728 pString = item->name_change.name;
729 _dbus_verbose ("Name changed: %s\n", pString);
730 dbus_message_iter_init_append(message, &args);
731 if (!dbus_message_iter_append_basic(&args, DBUS_TYPE_STRING,&pString))
736 if (!dbus_message_iter_append_basic(&args, DBUS_TYPE_STRING, &pStringMallocked))
741 sprintf(&pStringMallocked[3],"%llu",item->name_change.new_id);
742 _dbus_verbose ("New id: %s\n", pStringMallocked); //todo to be removed
743 if (!dbus_message_iter_append_basic(&args, DBUS_TYPE_STRING, &pStringMallocked))
749 dbus_message_set_sender(message, dbus);
750 dbus_message_set_serial(message, 1);
752 dbus_message_lock (message);
753 _dbus_message_get_network_data (message, &header, &body);
754 size = _dbus_string_get_length(header);
755 memcpy(data, _dbus_string_get_const_data(header), size);
758 size = _dbus_string_get_length(body);
759 memcpy(data, _dbus_string_get_const_data(body), size);
764 case KDBUS_MSG_ID_ADD:
765 _dbus_verbose(" +%s (%llu bytes) id=%llu flags=%llu\n",
766 enum_MSG(item->type), (unsigned long long) item->size,
767 (unsigned long long) item->id_change.id,
768 (unsigned long long) item->id_change.flags);
770 pStringMallocked = malloc (sizeof(item->id_change.id)*2.5 + 4);
773 strcpy(pStringMallocked,":1.");
774 sprintf(&pStringMallocked[3],"%llu",item->id_change.id);
775 _dbus_verbose ("Id added: %s\n", pStringMallocked); //todo to be removed
780 message = dbus_message_new_signal("/org/freedesktop/DBus", // object name of the signal
781 dbus, // interface name of the signal
782 "NameOwnerChanged"); // name of the signal
789 dbus_message_iter_init_append(message, &args);
790 if (!dbus_message_iter_append_basic(&args, DBUS_TYPE_STRING, &pStringMallocked))
795 if (!dbus_message_iter_append_basic(&args, DBUS_TYPE_STRING, &emptyString))
800 if (!dbus_message_iter_append_basic(&args, DBUS_TYPE_STRING, &pStringMallocked))
806 dbus_message_set_sender(message, dbus);
807 dbus_message_set_serial(message, 1);
809 dbus_message_lock (message);
810 _dbus_message_get_network_data (message, &header, &body);
811 size = _dbus_string_get_length(header);
812 memcpy(data, _dbus_string_get_const_data(header), size);
815 size = _dbus_string_get_length(body);
816 memcpy(data, _dbus_string_get_const_data(body), size);
821 case KDBUS_MSG_ID_REMOVE:
822 _dbus_verbose(" +%s (%llu bytes) id=%llu flags=%llu\n",
823 enum_MSG(item->type), (unsigned long long) item->size,
824 (unsigned long long) item->id_change.id,
825 (unsigned long long) item->id_change.flags);
827 pStringMallocked = malloc (sizeof(item->id_change.id)*2.5 + 4);
830 strcpy(pStringMallocked,":1.");
831 sprintf(&pStringMallocked[3],"%llu",item->id_change.id);
832 _dbus_verbose ("Id removed: %s\n", pStringMallocked); //todo to be removed
837 message = dbus_message_new_signal("/org/freedesktop/DBus", // object name of the signal
838 dbus, // interface name of the signal
839 "NameOwnerChanged"); // name of the signal
846 dbus_message_iter_init_append(message, &args);
847 if (!dbus_message_iter_append_basic(&args, DBUS_TYPE_STRING, &pStringMallocked))
852 if (!dbus_message_iter_append_basic(&args, DBUS_TYPE_STRING, &pStringMallocked))
857 if (!dbus_message_iter_append_basic(&args, DBUS_TYPE_STRING, &emptyString))
863 dbus_message_set_sender(message, dbus);
864 dbus_message_set_serial(message, 1);
866 dbus_message_lock (message);
867 _dbus_message_get_network_data (message, &header, &body);
868 size = _dbus_string_get_length(header);
869 memcpy(data, _dbus_string_get_const_data(header), size);
872 size = _dbus_string_get_length(body);
873 memcpy(data, _dbus_string_get_const_data(body), size);
879 _dbus_verbose(" +%s (%llu bytes)\n", enum_MSG(item->type), item->size);
884 if ((char *)item - ((char *)msg + msg->size) >= 8)
885 _dbus_verbose("invalid padding at end of message\n");
889 dbus_message_unref(message);
891 free((void*)pStringMallocked);
895 static int kdbus_read_message(DBusTransportSocket *socket_transport, DBusString *buffer)
899 struct kdbus_msg *msg;
904 _dbus_assert (socket_transport->max_bytes_read_per_iteration >= 0);
905 start = _dbus_string_get_length (buffer);
906 if (!_dbus_string_lengthen (buffer, socket_transport->max_bytes_read_per_iteration))
911 data = _dbus_string_get_data_len (buffer, start, socket_transport->max_bytes_read_per_iteration);
914 ret = ioctl(socket_transport->fd, KDBUS_CMD_MSG_RECV, &offset);
919 _dbus_verbose("kdbus error receiving message: %d (%m)\n", ret);
920 _dbus_string_set_length (buffer, start);
924 msg = (struct kdbus_msg *)((char*)socket_transport->kdbus_mmap_ptr + offset);
926 ret_size = kdbus_decode_msg(msg, data, socket_transport->kdbus_mmap_ptr);
928 _dbus_string_set_length (buffer, start + ret_size);
931 ret = ioctl(socket_transport->fd, KDBUS_CMD_MSG_RELEASE, &offset);
936 _dbus_verbose("kdbus error freeing message: %d (%m)\n", ret);
944 free_watches (DBusTransport *transport)
946 DBusTransportSocket *socket_transport = (DBusTransportSocket*) transport;
948 _dbus_verbose ("start\n");
950 if (socket_transport->read_watch)
952 if (transport->connection)
953 _dbus_connection_remove_watch_unlocked (transport->connection,
954 socket_transport->read_watch);
955 _dbus_watch_invalidate (socket_transport->read_watch);
956 _dbus_watch_unref (socket_transport->read_watch);
957 socket_transport->read_watch = NULL;
960 if (socket_transport->write_watch)
962 if (transport->connection)
963 _dbus_connection_remove_watch_unlocked (transport->connection,
964 socket_transport->write_watch);
965 _dbus_watch_invalidate (socket_transport->write_watch);
966 _dbus_watch_unref (socket_transport->write_watch);
967 socket_transport->write_watch = NULL;
970 _dbus_verbose ("end\n");
974 socket_finalize (DBusTransport *transport)
976 DBusTransportSocket *socket_transport = (DBusTransportSocket*) transport;
978 _dbus_verbose ("\n");
980 free_watches (transport);
982 _dbus_string_free (&socket_transport->encoded_outgoing);
983 _dbus_string_free (&socket_transport->encoded_incoming);
985 _dbus_transport_finalize_base (transport);
987 _dbus_assert (socket_transport->read_watch == NULL);
988 _dbus_assert (socket_transport->write_watch == NULL);
990 dbus_free (transport);
994 check_write_watch (DBusTransport *transport)
996 DBusTransportSocket *socket_transport = (DBusTransportSocket*) transport;
999 if (transport->connection == NULL)
1002 if (transport->disconnected)
1004 _dbus_assert (socket_transport->write_watch == NULL);
1008 _dbus_transport_ref (transport);
1010 if (_dbus_transport_get_is_authenticated (transport))
1011 needed = _dbus_connection_has_messages_to_send_unlocked (transport->connection);
1014 if (transport->send_credentials_pending)
1018 DBusAuthState auth_state;
1020 auth_state = _dbus_auth_do_work (transport->auth);
1022 /* If we need memory we install the write watch just in case,
1023 * if there's no need for it, it will get de-installed
1024 * next time we try reading.
1026 if (auth_state == DBUS_AUTH_STATE_HAVE_BYTES_TO_SEND ||
1027 auth_state == DBUS_AUTH_STATE_WAITING_FOR_MEMORY)
1034 _dbus_verbose ("check_write_watch(): needed = %d on connection %p watch %p fd = %d outgoing messages exist %d\n",
1035 needed, transport->connection, socket_transport->write_watch,
1036 socket_transport->fd,
1037 _dbus_connection_has_messages_to_send_unlocked (transport->connection));
1039 _dbus_connection_toggle_watch_unlocked (transport->connection,
1040 socket_transport->write_watch,
1043 _dbus_transport_unref (transport);
1047 check_read_watch (DBusTransport *transport)
1049 DBusTransportSocket *socket_transport = (DBusTransportSocket*) transport;
1050 dbus_bool_t need_read_watch;
1052 _dbus_verbose ("fd = %d\n",socket_transport->fd);
1054 if (transport->connection == NULL)
1057 if (transport->disconnected)
1059 _dbus_assert (socket_transport->read_watch == NULL);
1063 _dbus_transport_ref (transport);
1065 if (_dbus_transport_get_is_authenticated (transport))
1067 (_dbus_counter_get_size_value (transport->live_messages) < transport->max_live_messages_size) &&
1068 (_dbus_counter_get_unix_fd_value (transport->live_messages) < transport->max_live_messages_unix_fds);
1071 if (transport->receive_credentials_pending)
1072 need_read_watch = TRUE;
1075 /* The reason to disable need_read_watch when not WAITING_FOR_INPUT
1076 * is to avoid spinning on the file descriptor when we're waiting
1077 * to write or for some other part of the auth process
1079 DBusAuthState auth_state;
1081 auth_state = _dbus_auth_do_work (transport->auth);
1083 /* If we need memory we install the read watch just in case,
1084 * if there's no need for it, it will get de-installed
1085 * next time we try reading. If we're authenticated we
1086 * install it since we normally have it installed while
1089 if (auth_state == DBUS_AUTH_STATE_WAITING_FOR_INPUT ||
1090 auth_state == DBUS_AUTH_STATE_WAITING_FOR_MEMORY ||
1091 auth_state == DBUS_AUTH_STATE_AUTHENTICATED)
1092 need_read_watch = TRUE;
1094 need_read_watch = FALSE;
1098 _dbus_verbose (" setting read watch enabled = %d\n", need_read_watch);
1099 _dbus_connection_toggle_watch_unlocked (transport->connection,
1100 socket_transport->read_watch,
1103 _dbus_transport_unref (transport);
1107 do_io_error (DBusTransport *transport)
1109 _dbus_transport_ref (transport);
1110 _dbus_transport_disconnect (transport);
1111 _dbus_transport_unref (transport);
1114 /* return value is whether we successfully read any new data. */
1116 read_data_into_auth (DBusTransport *transport,
1119 DBusTransportSocket *socket_transport = (DBusTransportSocket*) transport;
1125 _dbus_auth_get_buffer (transport->auth, &buffer);
1127 bytes_read = _dbus_read_socket (socket_transport->fd,
1128 buffer, socket_transport->max_bytes_read_per_iteration);
1130 _dbus_auth_return_buffer (transport->auth, buffer,
1131 bytes_read > 0 ? bytes_read : 0);
1135 _dbus_verbose (" read %d bytes in auth phase\n", bytes_read);
1139 else if (bytes_read < 0)
1141 /* EINTR already handled for us */
1143 if (_dbus_get_is_errno_enomem ())
1147 else if (_dbus_get_is_errno_eagain_or_ewouldblock ())
1148 ; /* do nothing, just return FALSE below */
1151 _dbus_verbose ("Error reading from remote app: %s\n",
1152 _dbus_strerror_from_errno ());
1153 do_io_error (transport);
1160 _dbus_assert (bytes_read == 0);
1162 _dbus_verbose ("Disconnected from remote app\n");
1163 do_io_error (transport);
1169 /* Return value is whether we successfully wrote any bytes */
1171 write_data_from_auth (DBusTransport *transport)
1173 DBusTransportSocket *socket_transport = (DBusTransportSocket*) transport;
1175 const DBusString *buffer;
1177 if (!_dbus_auth_get_bytes_to_send (transport->auth,
1181 bytes_written = _dbus_write_socket (socket_transport->fd,
1183 0, _dbus_string_get_length (buffer));
1185 if (bytes_written > 0)
1187 _dbus_auth_bytes_sent (transport->auth, bytes_written);
1190 else if (bytes_written < 0)
1192 /* EINTR already handled for us */
1194 if (_dbus_get_is_errno_eagain_or_ewouldblock ())
1198 _dbus_verbose ("Error writing to remote app: %s\n",
1199 _dbus_strerror_from_errno ());
1200 do_io_error (transport);
1209 exchange_credentials (DBusTransport *transport,
1210 dbus_bool_t do_reading,
1211 dbus_bool_t do_writing)
1213 DBusTransportSocket *socket_transport = (DBusTransportSocket*) transport;
1214 DBusError error = DBUS_ERROR_INIT;
1216 _dbus_verbose ("exchange_credentials: do_reading = %d, do_writing = %d\n",
1217 do_reading, do_writing);
1219 if (do_writing && transport->send_credentials_pending)
1221 if (_dbus_send_credentials_socket (socket_transport->fd,
1224 transport->send_credentials_pending = FALSE;
1228 _dbus_verbose ("Failed to write credentials: %s\n", error.message);
1229 dbus_error_free (&error);
1230 do_io_error (transport);
1234 if (do_reading && transport->receive_credentials_pending)
1236 /* FIXME this can fail due to IO error _or_ OOM, broken
1237 * (somewhat tricky to fix since the OOM error can be set after
1238 * we already read the credentials byte, so basically we need to
1239 * separate reading the byte and storing it in the
1240 * transport->credentials). Does not really matter for now
1241 * because storing in credentials never actually fails on unix.
1243 if (_dbus_read_credentials_socket (socket_transport->fd,
1244 transport->credentials,
1247 transport->receive_credentials_pending = FALSE;
1251 _dbus_verbose ("Failed to read credentials %s\n", error.message);
1252 dbus_error_free (&error);
1253 do_io_error (transport);
1257 if (!(transport->send_credentials_pending ||
1258 transport->receive_credentials_pending))
1260 if (!_dbus_auth_set_credentials (transport->auth,
1261 transport->credentials))
1269 do_authentication (DBusTransport *transport,
1270 dbus_bool_t do_reading,
1271 dbus_bool_t do_writing,
1272 dbus_bool_t *auth_completed)
1275 dbus_bool_t orig_auth_state;
1279 orig_auth_state = _dbus_transport_get_is_authenticated (transport);
1281 /* This is essential to avoid the check_write_watch() at the end,
1282 * we don't want to add a write watch in do_iteration before
1283 * we try writing and get EAGAIN
1285 if (orig_auth_state)
1288 *auth_completed = FALSE;
1292 _dbus_transport_ref (transport);
1294 while (!_dbus_transport_get_is_authenticated (transport) &&
1295 _dbus_transport_get_is_connected (transport))
1297 if (!exchange_credentials (transport, do_reading, do_writing))
1304 if (transport->send_credentials_pending ||
1305 transport->receive_credentials_pending)
1307 _dbus_verbose ("send_credentials_pending = %d receive_credentials_pending = %d\n",
1308 transport->send_credentials_pending,
1309 transport->receive_credentials_pending);
1313 #define TRANSPORT_SIDE(t) ((t)->is_server ? "server" : "client")
1314 switch (_dbus_auth_do_work (transport->auth))
1316 case DBUS_AUTH_STATE_WAITING_FOR_INPUT:
1317 _dbus_verbose (" %s auth state: waiting for input\n",
1318 TRANSPORT_SIDE (transport));
1319 if (!do_reading || !read_data_into_auth (transport, &oom))
1323 case DBUS_AUTH_STATE_WAITING_FOR_MEMORY:
1324 _dbus_verbose (" %s auth state: waiting for memory\n",
1325 TRANSPORT_SIDE (transport));
1330 case DBUS_AUTH_STATE_HAVE_BYTES_TO_SEND:
1331 _dbus_verbose (" %s auth state: bytes to send\n",
1332 TRANSPORT_SIDE (transport));
1333 if (!do_writing || !write_data_from_auth (transport))
1337 case DBUS_AUTH_STATE_NEED_DISCONNECT:
1338 _dbus_verbose (" %s auth state: need to disconnect\n",
1339 TRANSPORT_SIDE (transport));
1340 do_io_error (transport);
1343 case DBUS_AUTH_STATE_AUTHENTICATED:
1344 _dbus_verbose (" %s auth state: authenticated\n",
1345 TRANSPORT_SIDE (transport));
1352 *auth_completed = (orig_auth_state != _dbus_transport_get_is_authenticated (transport));
1354 check_read_watch (transport);
1355 check_write_watch (transport);
1356 _dbus_transport_unref (transport);
1364 /* returns false on oom */
1366 do_writing (DBusTransport *transport)
1369 DBusTransportSocket *socket_transport = (DBusTransportSocket*) transport;
1372 /* No messages without authentication! */
1373 if (!_dbus_transport_get_is_authenticated (transport))
1375 _dbus_verbose ("Not authenticated, not writing anything\n");
1379 if (transport->disconnected)
1381 _dbus_verbose ("Not connected, not writing anything\n");
1386 _dbus_verbose ("do_writing(), have_messages = %d, fd = %d\n",
1387 _dbus_connection_has_messages_to_send_unlocked (transport->connection),
1388 socket_transport->fd);
1394 while (!transport->disconnected && _dbus_connection_has_messages_to_send_unlocked (transport->connection))
1397 DBusMessage *message;
1398 const DBusString *header;
1399 const DBusString *body;
1400 int total_bytes_to_write;
1403 if (total > socket_transport->max_bytes_written_per_iteration)
1405 _dbus_verbose ("%d bytes exceeds %d bytes written per iteration, returning\n",
1406 total, socket_transport->max_bytes_written_per_iteration);
1410 message = _dbus_connection_get_message_to_send (transport->connection);
1411 _dbus_assert (message != NULL);
1412 dbus_message_lock (message);
1413 _dbus_message_get_network_data (message, &header, &body);
1415 if (_dbus_auth_needs_encoding (transport->auth))
1417 // Does fd passing even make sense with encoded data?
1418 _dbus_assert(!DBUS_TRANSPORT_CAN_SEND_UNIX_FD(transport));
1420 if (_dbus_string_get_length (&socket_transport->encoded_outgoing) == 0)
1422 if (!_dbus_auth_encode_data (transport->auth,
1423 header, &socket_transport->encoded_outgoing))
1429 if (!_dbus_auth_encode_data (transport->auth,
1430 body, &socket_transport->encoded_outgoing))
1432 _dbus_string_set_length (&socket_transport->encoded_outgoing, 0);
1438 total_bytes_to_write = _dbus_string_get_length (&socket_transport->encoded_outgoing);
1439 bytes_written = kdbus_write_msg_encoded(message, socket_transport);
1443 total_bytes_to_write = _dbus_string_get_length(header) + _dbus_string_get_length(body);
1444 bytes_written = kdbus_write_msg(transport, message, socket_transport->fd);
1447 if (bytes_written < 0)
1449 /* EINTR already handled for us */
1451 /* For some discussion of why we also ignore EPIPE here, see
1452 * http://lists.freedesktop.org/archives/dbus/2008-March/009526.html
1455 if (_dbus_get_is_errno_eagain_or_ewouldblock () || _dbus_get_is_errno_epipe ())
1459 _dbus_verbose ("Error writing to remote app: %s\n",
1460 _dbus_strerror_from_errno ());
1461 do_io_error (transport);
1467 _dbus_verbose (" wrote %d bytes of %d\n", bytes_written,
1468 total_bytes_to_write);
1470 total += bytes_written;
1471 socket_transport->message_bytes_written += bytes_written;
1473 _dbus_assert (socket_transport->message_bytes_written <=
1474 total_bytes_to_write);
1476 if (socket_transport->message_bytes_written == total_bytes_to_write)
1478 socket_transport->message_bytes_written = 0;
1479 _dbus_string_set_length (&socket_transport->encoded_outgoing, 0);
1480 _dbus_string_compact (&socket_transport->encoded_outgoing, 2048);
1482 _dbus_connection_message_sent_unlocked (transport->connection,
1495 /* returns false on out-of-memory */
1497 do_reading (DBusTransport *transport)
1499 DBusTransportSocket *socket_transport = (DBusTransportSocket*) transport;
1505 _dbus_verbose ("fd = %d\n",socket_transport->fd);
1507 /* No messages without authentication! */
1508 if (!_dbus_transport_get_is_authenticated (transport))
1517 /* See if we've exceeded max messages and need to disable reading */
1518 check_read_watch (transport);
1520 if (total > socket_transport->max_bytes_read_per_iteration)
1522 _dbus_verbose ("%d bytes exceeds %d bytes read per iteration, returning\n",
1523 total, socket_transport->max_bytes_read_per_iteration);
1527 _dbus_assert (socket_transport->read_watch != NULL ||
1528 transport->disconnected);
1530 if (transport->disconnected)
1533 if (!dbus_watch_get_enabled (socket_transport->read_watch))
1536 if (_dbus_auth_needs_decoding (transport->auth))
1538 /* Does fd passing even make sense with encoded data? */
1539 /* _dbus_assert(!DBUS_TRANSPORT_CAN_SEND_UNIX_FD(transport));
1541 if (_dbus_string_get_length (&socket_transport->encoded_incoming) > 0)
1542 bytes_read = _dbus_string_get_length (&socket_transport->encoded_incoming);
1544 bytes_read = _dbus_read_socket (socket_transport->fd,
1545 &socket_transport->encoded_incoming,
1546 socket_transport->max_bytes_read_per_iteration);*/
1548 bytes_read = kdbus_read_message(socket_transport, &socket_transport->encoded_incoming);
1550 _dbus_assert (_dbus_string_get_length (&socket_transport->encoded_incoming) ==
1557 _dbus_message_loader_get_buffer (transport->loader,
1560 orig_len = _dbus_string_get_length (buffer);
1562 if (!_dbus_auth_decode_data (transport->auth,
1563 &socket_transport->encoded_incoming,
1566 _dbus_verbose ("Out of memory decoding incoming data\n");
1567 _dbus_message_loader_return_buffer (transport->loader,
1569 _dbus_string_get_length (buffer) - orig_len);
1575 _dbus_message_loader_return_buffer (transport->loader,
1577 _dbus_string_get_length (buffer) - orig_len);
1579 _dbus_string_set_length (&socket_transport->encoded_incoming, 0);
1580 _dbus_string_compact (&socket_transport->encoded_incoming, 2048);
1585 _dbus_message_loader_get_buffer (transport->loader,
1588 bytes_read = kdbus_read_message(socket_transport, buffer);
1590 _dbus_message_loader_return_buffer (transport->loader,
1592 bytes_read < 0 ? 0 : bytes_read);
1597 /* EINTR already handled for us */
1599 if (_dbus_get_is_errno_enomem ())
1601 _dbus_verbose ("Out of memory in read()/do_reading()\n");
1605 else if (_dbus_get_is_errno_eagain_or_ewouldblock ())
1609 _dbus_verbose ("Error reading from remote app: %s\n",
1610 _dbus_strerror_from_errno ());
1611 do_io_error (transport);
1615 else if (bytes_read == 0)
1617 _dbus_verbose ("Disconnected from remote app\n");
1618 do_io_error (transport);
1623 _dbus_verbose (" read %d bytes\n", bytes_read);
1625 total += bytes_read;
1627 if (!_dbus_transport_queue_messages (transport))
1630 _dbus_verbose (" out of memory when queueing messages we just read in the transport\n");
1634 /* Try reading more data until we get EAGAIN and return, or
1635 * exceed max bytes per iteration. If in blocking mode of
1636 * course we'll block instead of returning.
1649 unix_error_with_read_to_come (DBusTransport *itransport,
1653 DBusTransportSocket *transport = (DBusTransportSocket *) itransport;
1655 if (!(flags & DBUS_WATCH_HANGUP || flags & DBUS_WATCH_ERROR))
1658 /* If we have a read watch enabled ...
1659 we -might have data incoming ... => handle the HANGUP there */
1660 if (watch != transport->read_watch &&
1661 _dbus_watch_get_enabled (transport->read_watch))
1668 socket_handle_watch (DBusTransport *transport,
1672 DBusTransportSocket *socket_transport = (DBusTransportSocket*) transport;
1674 _dbus_assert (watch == socket_transport->read_watch ||
1675 watch == socket_transport->write_watch);
1676 _dbus_assert (watch != NULL);
1678 /* If we hit an error here on a write watch, don't disconnect the transport yet because data can
1679 * still be in the buffer and do_reading may need several iteration to read
1680 * it all (because of its max_bytes_read_per_iteration limit).
1682 if (!(flags & DBUS_WATCH_READABLE) && unix_error_with_read_to_come (transport, watch, flags))
1684 _dbus_verbose ("Hang up or error on watch\n");
1685 _dbus_transport_disconnect (transport);
1689 if (watch == socket_transport->read_watch &&
1690 (flags & DBUS_WATCH_READABLE))
1692 dbus_bool_t auth_finished;
1694 _dbus_verbose ("handling read watch %p flags = %x\n",
1697 if (!do_authentication (transport, TRUE, FALSE, &auth_finished))
1700 /* We don't want to do a read immediately following
1701 * a successful authentication. This is so we
1702 * have a chance to propagate the authentication
1703 * state further up. Specifically, we need to
1704 * process any pending data from the auth object.
1708 if (!do_reading (transport))
1710 _dbus_verbose ("no memory to read\n");
1716 _dbus_verbose ("Not reading anything since we just completed the authentication\n");
1719 else if (watch == socket_transport->write_watch &&
1720 (flags & DBUS_WATCH_WRITABLE))
1723 _dbus_verbose ("handling write watch, have_outgoing_messages = %d\n",
1724 _dbus_connection_has_messages_to_send_unlocked (transport->connection));
1726 if (!do_authentication (transport, FALSE, TRUE, NULL))
1729 if (!do_writing (transport))
1731 _dbus_verbose ("no memory to write\n");
1735 /* See if we still need the write watch */
1736 check_write_watch (transport);
1738 #ifdef DBUS_ENABLE_VERBOSE_MODE
1741 if (watch == socket_transport->read_watch)
1742 _dbus_verbose ("asked to handle read watch with non-read condition 0x%x\n",
1744 else if (watch == socket_transport->write_watch)
1745 _dbus_verbose ("asked to handle write watch with non-write condition 0x%x\n",
1748 _dbus_verbose ("asked to handle watch %p on fd %d that we don't recognize\n",
1749 watch, dbus_watch_get_socket (watch));
1751 #endif /* DBUS_ENABLE_VERBOSE_MODE */
1757 socket_disconnect (DBusTransport *transport)
1759 DBusTransportSocket *socket_transport = (DBusTransportSocket*) transport;
1761 _dbus_verbose ("\n");
1763 free_watches (transport);
1765 _dbus_close_socket (socket_transport->fd, NULL);
1766 socket_transport->fd = -1;
1770 socket_connection_set (DBusTransport *transport)
1772 DBusTransportSocket *socket_transport = (DBusTransportSocket*) transport;
1774 _dbus_watch_set_handler (socket_transport->write_watch,
1775 _dbus_connection_handle_watch,
1776 transport->connection, NULL);
1778 _dbus_watch_set_handler (socket_transport->read_watch,
1779 _dbus_connection_handle_watch,
1780 transport->connection, NULL);
1782 if (!_dbus_connection_add_watch_unlocked (transport->connection,
1783 socket_transport->write_watch))
1786 if (!_dbus_connection_add_watch_unlocked (transport->connection,
1787 socket_transport->read_watch))
1789 _dbus_connection_remove_watch_unlocked (transport->connection,
1790 socket_transport->write_watch);
1794 check_read_watch (transport);
1795 check_write_watch (transport);
1801 * @todo We need to have a way to wake up the select sleep if
1802 * a new iteration request comes in with a flag (read/write) that
1803 * we're not currently serving. Otherwise a call that just reads
1804 * could block a write call forever (if there are no incoming
1808 kdbus_do_iteration (DBusTransport *transport,
1810 int timeout_milliseconds)
1812 DBusTransportSocket *socket_transport = (DBusTransportSocket*) transport;
1817 _dbus_verbose (" iteration flags = %s%s timeout = %d read_watch = %p write_watch = %p fd = %d\n",
1818 flags & DBUS_ITERATION_DO_READING ? "read" : "",
1819 flags & DBUS_ITERATION_DO_WRITING ? "write" : "",
1820 timeout_milliseconds,
1821 socket_transport->read_watch,
1822 socket_transport->write_watch,
1823 socket_transport->fd);
1825 /* the passed in DO_READING/DO_WRITING flags indicate whether to
1826 * read/write messages, but regardless of those we may need to block
1827 * for reading/writing to do auth. But if we do reading for auth,
1828 * we don't want to read any messages yet if not given DO_READING.
1831 poll_fd.fd = socket_transport->fd;
1834 if (_dbus_transport_get_is_authenticated (transport))
1836 /* This is kind of a hack; if we have stuff to write, then try
1837 * to avoid the poll. This is probably about a 5% speedup on an
1838 * echo client/server.
1840 * If both reading and writing were requested, we want to avoid this
1841 * since it could have funky effects:
1842 * - both ends spinning waiting for the other one to read
1843 * data so they can finish writing
1844 * - prioritizing all writing ahead of reading
1846 if ((flags & DBUS_ITERATION_DO_WRITING) &&
1847 !(flags & (DBUS_ITERATION_DO_READING | DBUS_ITERATION_BLOCK)) &&
1848 !transport->disconnected &&
1849 _dbus_connection_has_messages_to_send_unlocked (transport->connection))
1851 do_writing (transport);
1853 if (transport->disconnected ||
1854 !_dbus_connection_has_messages_to_send_unlocked (transport->connection))
1858 /* If we get here, we decided to do the poll() after all */
1859 _dbus_assert (socket_transport->read_watch);
1860 if (flags & DBUS_ITERATION_DO_READING)
1861 poll_fd.events |= _DBUS_POLLIN;
1863 _dbus_assert (socket_transport->write_watch);
1864 if (flags & DBUS_ITERATION_DO_WRITING)
1865 poll_fd.events |= _DBUS_POLLOUT;
1869 DBusAuthState auth_state;
1871 auth_state = _dbus_auth_do_work (transport->auth);
1873 if (transport->receive_credentials_pending ||
1874 auth_state == DBUS_AUTH_STATE_WAITING_FOR_INPUT)
1875 poll_fd.events |= _DBUS_POLLIN;
1877 if (transport->send_credentials_pending ||
1878 auth_state == DBUS_AUTH_STATE_HAVE_BYTES_TO_SEND)
1879 poll_fd.events |= _DBUS_POLLOUT;
1884 if (flags & DBUS_ITERATION_BLOCK)
1885 poll_timeout = timeout_milliseconds;
1889 /* For blocking selects we drop the connection lock here
1890 * to avoid blocking out connection access during a potentially
1891 * indefinite blocking call. The io path is still protected
1892 * by the io_path_cond condvar, so we won't reenter this.
1894 if (flags & DBUS_ITERATION_BLOCK)
1896 _dbus_verbose ("unlock pre poll\n");
1897 _dbus_connection_unlock (transport->connection);
1899 _dbus_verbose ("poll_fd.events: %x, timeout: %d\n", poll_fd.events, poll_timeout);
1901 poll_res = _dbus_poll (&poll_fd, 1, poll_timeout);
1903 if (poll_res < 0 && _dbus_get_is_errno_eintr ())
1905 _dbus_verbose ("Error from _dbus_poll(): %s\n",
1906 _dbus_strerror_from_errno ());
1909 _dbus_verbose ("poll_fd.revents: %x\n", poll_fd.revents);
1911 if (flags & DBUS_ITERATION_BLOCK)
1913 _dbus_verbose ("lock post poll\n");
1914 _dbus_connection_lock (transport->connection);
1920 poll_fd.revents = 0; /* some concern that posix does not guarantee this;
1921 * valgrind flags it as an error. though it probably
1922 * is guaranteed on linux at least.
1925 if (poll_fd.revents & _DBUS_POLLERR)
1926 do_io_error (transport);
1929 dbus_bool_t need_read = (poll_fd.revents & _DBUS_POLLIN) > 0;
1930 dbus_bool_t need_write = (poll_fd.revents & _DBUS_POLLOUT) > 0;
1931 dbus_bool_t authentication_completed;
1933 _dbus_verbose ("in iteration, need_read=%d need_write=%d\n",
1934 need_read, need_write);
1935 do_authentication (transport, need_read, need_write,
1936 &authentication_completed);
1938 /* See comment in socket_handle_watch. */
1939 if (authentication_completed)
1942 if (need_read && (flags & DBUS_ITERATION_DO_READING))
1943 do_reading (transport);
1944 if (need_write && (flags & DBUS_ITERATION_DO_WRITING))
1945 do_writing (transport);
1950 _dbus_verbose ("Error from _dbus_poll(): %s\n",
1951 _dbus_strerror_from_errno ());
1957 /* We need to install the write watch only if we did not
1958 * successfully write everything. Note we need to be careful that we
1959 * don't call check_write_watch *before* do_writing, since it's
1960 * inefficient to add the write watch, and we can avoid it most of
1961 * the time since we can write immediately.
1963 * However, we MUST always call check_write_watch(); DBusConnection code
1964 * relies on the fact that running an iteration will notice that
1965 * messages are pending.
1967 check_write_watch (transport);
1969 _dbus_verbose (" ... leaving do_iteration()\n");
1973 socket_live_messages_changed (DBusTransport *transport)
1975 /* See if we should look for incoming messages again */
1976 check_read_watch (transport);
1979 static const DBusTransportVTable kdbus_vtable = {
1981 socket_handle_watch,
1983 socket_connection_set,
1985 socket_live_messages_changed,
1986 socket_get_socket_fd
1990 * Creates a new transport for the given kdbus file descriptor. The file
1991 * descriptor must be nonblocking (use _dbus_set_fd_nonblocking() to
1994 * @param fd the file descriptor.
1995 * @param server_guid non-#NULL if this transport is on the server side of a connection
1996 * @param address the transport's address
1997 * @returns the new transport, or #NULL if no memory.
1999 static DBusTransport*
2000 _dbus_transport_new_for_socket_kdbus (int fd,
2001 const DBusString *server_guid,
2002 const DBusString *address)
2004 DBusTransportSocket *socket_transport;
2006 socket_transport = dbus_new0 (DBusTransportSocket, 1);
2007 if (socket_transport == NULL)
2010 if (!_dbus_string_init (&socket_transport->encoded_outgoing))
2013 if (!_dbus_string_init (&socket_transport->encoded_incoming))
2016 socket_transport->write_watch = _dbus_watch_new (fd,
2017 DBUS_WATCH_WRITABLE,
2020 if (socket_transport->write_watch == NULL)
2023 socket_transport->read_watch = _dbus_watch_new (fd,
2024 DBUS_WATCH_READABLE,
2027 if (socket_transport->read_watch == NULL)
2030 if (!_dbus_transport_init_base (&socket_transport->base,
2032 server_guid, address))
2035 #ifdef HAVE_UNIX_FD_PASSING
2036 _dbus_auth_set_unix_fd_possible(socket_transport->base.auth, _dbus_socket_can_pass_unix_fd(fd));
2039 socket_transport->fd = fd;
2040 socket_transport->message_bytes_written = 0;
2042 /* These values should probably be tunable or something. */
2043 socket_transport->max_bytes_read_per_iteration = POOL_SIZE;
2044 socket_transport->max_bytes_written_per_iteration = 2048;
2046 socket_transport->kdbus_mmap_ptr = NULL;
2048 return (DBusTransport*) socket_transport;
2051 _dbus_watch_invalidate (socket_transport->read_watch);
2052 _dbus_watch_unref (socket_transport->read_watch);
2054 _dbus_watch_invalidate (socket_transport->write_watch);
2055 _dbus_watch_unref (socket_transport->write_watch);
2057 _dbus_string_free (&socket_transport->encoded_incoming);
2059 _dbus_string_free (&socket_transport->encoded_outgoing);
2061 dbus_free (socket_transport);
2067 * Creates a connection to the kdbus bus
2069 * This will set FD_CLOEXEC for the socket returned.
2071 * @param path the path to UNIX domain socket
2072 * @param error return location for error code
2073 * @returns connection file descriptor or -1 on error
2075 static int _dbus_connect_kdbus (const char *path, DBusError *error)
2079 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
2080 _dbus_verbose ("connecting to kdbus bus %s\n", path);
2082 fd = open(path, O_RDWR|O_CLOEXEC|O_NONBLOCK); //[RP] | O_NONBLOCK added here, in dbus added separately in section commented out below
2085 dbus_set_error(error, _dbus_error_from_errno (errno), "Failed to open file descriptor: %s", _dbus_strerror (errno));
2086 _DBUS_ASSERT_ERROR_IS_SET(error);
2087 return -1; //[RP] not needed here if commented block below is removed
2090 /*if (!_dbus_set_fd_nonblocking (fd, error))
2092 _DBUS_ASSERT_ERROR_IS_SET (error);
2093 _dbus_close (fd, NULL);
2100 static dbus_bool_t kdbus_mmap(DBusTransport* transport)
2102 DBusTransportSocket *socket_transport = (DBusTransportSocket*) transport;
2104 socket_transport->kdbus_mmap_ptr = mmap(NULL, POOL_SIZE, PROT_READ, MAP_SHARED, socket_transport->fd, 0);
2105 if (socket_transport->kdbus_mmap_ptr == MAP_FAILED)
2112 * Creates a new transport for kdbus.
2113 * This creates a client-side of a transport.
2115 * @param path the path to the domain socket.
2116 * @param error address where an error can be returned.
2117 * @returns a new transport, or #NULL on failure.
2119 static DBusTransport* _dbus_transport_new_for_kdbus (const char *path, DBusError *error)
2122 DBusTransport *transport;
2125 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
2127 if (!_dbus_string_init (&address))
2129 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
2135 if ((!_dbus_string_append (&address, "kdbus:path=")) || (!_dbus_string_append (&address, path)))
2137 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
2141 fd = _dbus_connect_kdbus (path, error);
2144 _DBUS_ASSERT_ERROR_IS_SET (error);
2148 _dbus_verbose ("Successfully connected to kdbus bus %s\n", path);
2150 transport = _dbus_transport_new_for_socket_kdbus (fd, NULL, &address);
2151 if (transport == NULL)
2153 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
2157 _dbus_string_free (&address);
2162 _dbus_close_socket (fd, NULL);
2164 _dbus_string_free (&address);
2170 * Opens kdbus transport.
2172 * @param entry the address entry to try opening
2173 * @param transport_p return location for the opened transport
2174 * @param error error to be set
2175 * @returns result of the attempt
2177 DBusTransportOpenResult _dbus_transport_open_kdbus(DBusAddressEntry *entry,
2178 DBusTransport **transport_p,
2183 method = dbus_address_entry_get_method (entry);
2184 _dbus_assert (method != NULL);
2186 if (strcmp (method, "kdbus") == 0)
2188 const char *path = dbus_address_entry_get_value (entry, "path");
2192 _dbus_set_bad_address (error, "kdbus", "path", NULL);
2193 return DBUS_TRANSPORT_OPEN_BAD_ADDRESS;
2196 *transport_p = _dbus_transport_new_for_kdbus (path, error);
2198 if (*transport_p == NULL)
2200 _DBUS_ASSERT_ERROR_IS_SET (error);
2201 return DBUS_TRANSPORT_OPEN_DID_NOT_CONNECT;
2205 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
2206 return DBUS_TRANSPORT_OPEN_OK;
2211 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
2212 return DBUS_TRANSPORT_OPEN_NOT_HANDLED;
2216 static struct kdbus_policy *make_policy_name(const char *name)
2218 struct kdbus_policy *p;
2221 size = offsetof(struct kdbus_policy, name) + strlen(name) + 1;
2227 p->type = KDBUS_POLICY_NAME;
2228 strcpy(p->name, name);
2233 static struct kdbus_policy *make_policy_access(__u64 type, __u64 bits, __u64 id)
2235 struct kdbus_policy *p;
2236 __u64 size = sizeof(*p);
2244 p->type = KDBUS_POLICY_ACCESS;
2245 p->access.type = type;
2246 p->access.bits = bits;
2252 static void append_policy(struct kdbus_cmd_policy *cmd_policy, struct kdbus_policy *policy, __u64 max_size)
2254 struct kdbus_policy *dst = (struct kdbus_policy *) ((char *) cmd_policy + cmd_policy->size);
2256 if (cmd_policy->size + policy->size > max_size)
2259 memcpy(dst, policy, policy->size);
2260 cmd_policy->size += KDBUS_ALIGN8(policy->size);
2264 dbus_bool_t bus_register_policy_kdbus(const char* name, DBusConnection *connection, DBusError *error)
2266 struct kdbus_cmd_policy *cmd_policy;
2267 struct kdbus_policy *policy;
2271 if(!dbus_connection_get_socket(connection, &fd))
2273 dbus_set_error (error, "Failed to get fd for registering policy", NULL);
2277 cmd_policy = (struct kdbus_cmd_policy *) alloca(size);
2278 memset(cmd_policy, 0, size);
2280 policy = (struct kdbus_policy *) cmd_policy->policies;
2281 cmd_policy->size = offsetof(struct kdbus_cmd_policy, policies);
2283 policy = make_policy_name(name); //todo to be verified or changed when meaning will be known
2284 append_policy(cmd_policy, policy, size);
2286 policy = make_policy_access(KDBUS_POLICY_ACCESS_USER, KDBUS_POLICY_OWN, getuid());
2287 append_policy(cmd_policy, policy, size);
2289 policy = make_policy_access(KDBUS_POLICY_ACCESS_WORLD, KDBUS_POLICY_RECV, 0);
2290 append_policy(cmd_policy, policy, size);
2292 policy = make_policy_access(KDBUS_POLICY_ACCESS_WORLD, KDBUS_POLICY_SEND, 0);
2293 append_policy(cmd_policy, policy, size);
2295 if (ioctl(fd, KDBUS_CMD_EP_POLICY_SET, cmd_policy) < 0)
2297 dbus_set_error(error,_dbus_error_from_errno (errno), "Error setting EP policy: %s", _dbus_strerror (errno));
2301 _dbus_verbose("Policy %s set correctly\n", name);
2305 dbus_bool_t bus_register_kdbus(char* name, DBusConnection *connection, DBusError *error)
2307 struct kdbus_cmd_hello hello;
2310 memset(&hello, 0, sizeof(hello));
2311 hello.conn_flags = KDBUS_HELLO_ACCEPT_FD |
2312 KDBUS_HELLO_ATTACH_COMM |
2313 KDBUS_HELLO_ATTACH_EXE |
2314 KDBUS_HELLO_ATTACH_CMDLINE |
2315 KDBUS_HELLO_ATTACH_CAPS |
2316 KDBUS_HELLO_ATTACH_CGROUP |
2317 KDBUS_HELLO_ATTACH_SECLABEL |
2318 KDBUS_HELLO_ATTACH_AUDIT;
2319 hello.size = sizeof(struct kdbus_cmd_hello);
2320 hello.pool_size = POOL_SIZE;
2322 if(!dbus_connection_get_socket(connection, &fd))
2324 dbus_set_error (error, "failed to get fd for bus registration", NULL);
2327 if (ioctl(fd, KDBUS_CMD_HELLO, &hello))
2329 dbus_set_error(error,_dbus_error_from_errno (errno), "Failed to send hello: %s", _dbus_strerror (errno));
2333 _dbus_verbose("-- Our peer ID is: %llu\n", (unsigned long long)hello.id);
2334 sprintf(name, "%llu", (unsigned long long)hello.id);
2336 if(!kdbus_mmap(dbus_connection_get_transport(connection)))
2338 dbus_set_error(error,_dbus_error_from_errno (errno), "Error when mmap: %s", _dbus_strerror (errno));
2345 uint64_t bus_request_name_kdbus(DBusConnection *connection, const char *name, const uint64_t flags, DBusError *error)
2347 struct kdbus_cmd_name *cmd_name;
2349 uint64_t size = sizeof(*cmd_name) + strlen(name) + 1;
2350 uint64_t flags_kdbus = 0;
2352 cmd_name = alloca(size);
2354 memset(cmd_name, 0, size);
2355 strcpy(cmd_name->name, name);
2356 cmd_name->size = size;
2358 if(flags & DBUS_NAME_FLAG_ALLOW_REPLACEMENT)
2359 flags_kdbus |= KDBUS_NAME_ALLOW_REPLACEMENT;
2360 if(!(flags & DBUS_NAME_FLAG_DO_NOT_QUEUE))
2361 flags_kdbus |= KDBUS_NAME_QUEUE;
2362 if(flags & DBUS_NAME_FLAG_REPLACE_EXISTING)
2363 flags_kdbus |= KDBUS_NAME_REPLACE_EXISTING;
2365 cmd_name->conn_flags = flags_kdbus;
2367 if(!dbus_connection_get_socket(connection, &fd))
2369 dbus_set_error (error, "failed to get fd for name request", NULL);
2373 _dbus_verbose("Request name - flags sent: 0x%llx !!!!!!!!!\n", cmd_name->conn_flags);
2375 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
2376 if (ioctl(fd, KDBUS_CMD_NAME_ACQUIRE, cmd_name))
2378 dbus_set_error(error,_dbus_error_from_errno (errno), "error acquiring name: %s", _dbus_strerror (errno));
2380 return DBUS_REQUEST_NAME_REPLY_EXISTS;
2384 _dbus_verbose("Request name - received flag: 0x%llx !!!!!!!!!\n", cmd_name->conn_flags);
2386 if(cmd_name->conn_flags & KDBUS_NAME_IN_QUEUE)
2387 return DBUS_REQUEST_NAME_REPLY_IN_QUEUE;
2389 return DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER;
2390 //todo now 1 codes are never returned - DBUS_REQUEST_NAME_REPLY_ALREADY_OWNER
2394 * Checks if the connection's transport is kdbus on the basis of its address
2396 * @param pointer to the connection
2397 * @returns TRUE if kdbus transport, otherwise FALSE
2399 dbus_bool_t dbus_transport_is_kdbus(DBusConnection *connection)
2401 const char* address = _dbus_connection_get_address(connection);
2403 if(address == strstr(address, "kdbus:path="))
2409 void dbus_bus_add_match_kdbus (DBusConnection *connection, const char *rule, DBusError *error)
2411 struct kdbus_cmd_match cmd_match;
2414 memset(&cmd_match, 0, sizeof(cmd_match));
2416 if(!dbus_connection_get_socket(connection, &fd))
2418 dbus_set_error (error, "failed to get fd for add match", NULL);
2422 cmd_match.size = sizeof(cmd_match);
2424 //todo add matching rules from *rule when it will be docuemnted in kdbus
2427 cmd_match.src_id = KDBUS_MATCH_SRC_ID_ANY;
2429 if (ioctl(fd, KDBUS_CMD_MATCH_ADD, &cmd_match))
2430 dbus_set_error(error,_dbus_error_from_errno (errno), "error adding match: %s", _dbus_strerror (errno));
2432 _dbus_verbose("Finished adding match bus rule %s\n", rule);