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"
22 #include <sys/ioctl.h>
29 #define KDBUS_ALIGN8(l) (((l) + 7) & ~7)
32 /*struct and type below copied from dbus_transport_socket.c
33 * needed for _dbus_transport_new_for_socket_kdbus and kdbus_vtable(?)
34 * todo maybe DBusTransportSocket and _dbus_transport_new_for_socket_kdbus not needed here -
35 * maybe only static const DBusTransportVTable implementation will be enough
39 * Opaque object representing a socket file descriptor transport.
41 typedef struct DBusTransportSocket DBusTransportSocket;
44 * Implementation details of DBusTransportSocket. All members are private.
46 struct DBusTransportSocket
48 DBusTransport base; /**< Parent instance */
49 int fd; /**< File descriptor. */
50 DBusWatch *read_watch; /**< Watch for readability. */
51 DBusWatch *write_watch; /**< Watch for writability. */
53 int max_bytes_read_per_iteration; /**< To avoid blocking too long. */
54 int max_bytes_written_per_iteration; /**< To avoid blocking too long. */
56 int message_bytes_written; /**< Number of bytes of current
57 * outgoing message that have
60 DBusString encoded_outgoing; /**< Encoded version of current
63 DBusString encoded_incoming; /**< Encoded version of current
70 //prototypes of local functions, needed for compiler
71 int _dbus_connect_kdbus (const char *path, DBusError *error);
72 DBusTransport* _dbus_transport_new_for_kdbus (const char *path, DBusError *error);
73 DBusTransport* _dbus_transport_new_for_socket_kdbus (int fd, const DBusString *server_guid, const DBusString *address);
74 struct kdbus_policy *make_policy_name(const char *name);
75 struct kdbus_policy *make_policy_access(__u64 type, __u64 bits, __u64 id);
76 void append_policy(struct kdbus_cmd_policy *cmd_policy, struct kdbus_policy *policy, __u64 max_size);
78 /* Functions from dbus_transport_socket - to be modified or reused
82 free_watches (DBusTransport *transport)
84 DBusTransportSocket *socket_transport = (DBusTransportSocket*) transport;
86 _dbus_verbose ("start\n");
88 if (socket_transport->read_watch)
90 if (transport->connection)
91 _dbus_connection_remove_watch_unlocked (transport->connection,
92 socket_transport->read_watch);
93 _dbus_watch_invalidate (socket_transport->read_watch);
94 _dbus_watch_unref (socket_transport->read_watch);
95 socket_transport->read_watch = NULL;
98 if (socket_transport->write_watch)
100 if (transport->connection)
101 _dbus_connection_remove_watch_unlocked (transport->connection,
102 socket_transport->write_watch);
103 _dbus_watch_invalidate (socket_transport->write_watch);
104 _dbus_watch_unref (socket_transport->write_watch);
105 socket_transport->write_watch = NULL;
108 _dbus_verbose ("end\n");
112 socket_finalize (DBusTransport *transport)
114 DBusTransportSocket *socket_transport = (DBusTransportSocket*) transport;
116 _dbus_verbose ("\n");
118 free_watches (transport);
120 _dbus_string_free (&socket_transport->encoded_outgoing);
121 _dbus_string_free (&socket_transport->encoded_incoming);
123 _dbus_transport_finalize_base (transport);
125 _dbus_assert (socket_transport->read_watch == NULL);
126 _dbus_assert (socket_transport->write_watch == NULL);
128 dbus_free (transport);
132 check_write_watch (DBusTransport *transport)
134 DBusTransportSocket *socket_transport = (DBusTransportSocket*) transport;
137 if (transport->connection == NULL)
140 if (transport->disconnected)
142 _dbus_assert (socket_transport->write_watch == NULL);
146 _dbus_transport_ref (transport);
148 if (_dbus_transport_get_is_authenticated (transport))
149 needed = _dbus_connection_has_messages_to_send_unlocked (transport->connection);
152 if (transport->send_credentials_pending)
156 DBusAuthState auth_state;
158 auth_state = _dbus_auth_do_work (transport->auth);
160 /* If we need memory we install the write watch just in case,
161 * if there's no need for it, it will get de-installed
162 * next time we try reading.
164 if (auth_state == DBUS_AUTH_STATE_HAVE_BYTES_TO_SEND ||
165 auth_state == DBUS_AUTH_STATE_WAITING_FOR_MEMORY)
172 _dbus_verbose ("check_write_watch(): needed = %d on connection %p watch %p fd = %d outgoing messages exist %d\n",
173 needed, transport->connection, socket_transport->write_watch,
174 socket_transport->fd,
175 _dbus_connection_has_messages_to_send_unlocked (transport->connection));
177 _dbus_connection_toggle_watch_unlocked (transport->connection,
178 socket_transport->write_watch,
181 _dbus_transport_unref (transport);
185 check_read_watch (DBusTransport *transport)
187 DBusTransportSocket *socket_transport = (DBusTransportSocket*) transport;
188 dbus_bool_t need_read_watch;
190 _dbus_verbose ("fd = %d\n",socket_transport->fd);
192 if (transport->connection == NULL)
195 if (transport->disconnected)
197 _dbus_assert (socket_transport->read_watch == NULL);
201 _dbus_transport_ref (transport);
203 if (_dbus_transport_get_is_authenticated (transport))
205 (_dbus_counter_get_size_value (transport->live_messages) < transport->max_live_messages_size) &&
206 (_dbus_counter_get_unix_fd_value (transport->live_messages) < transport->max_live_messages_unix_fds);
209 if (transport->receive_credentials_pending)
210 need_read_watch = TRUE;
213 /* The reason to disable need_read_watch when not WAITING_FOR_INPUT
214 * is to avoid spinning on the file descriptor when we're waiting
215 * to write or for some other part of the auth process
217 DBusAuthState auth_state;
219 auth_state = _dbus_auth_do_work (transport->auth);
221 /* If we need memory we install the read watch just in case,
222 * if there's no need for it, it will get de-installed
223 * next time we try reading. If we're authenticated we
224 * install it since we normally have it installed while
227 if (auth_state == DBUS_AUTH_STATE_WAITING_FOR_INPUT ||
228 auth_state == DBUS_AUTH_STATE_WAITING_FOR_MEMORY ||
229 auth_state == DBUS_AUTH_STATE_AUTHENTICATED)
230 need_read_watch = TRUE;
232 need_read_watch = FALSE;
236 _dbus_verbose (" setting read watch enabled = %d\n", need_read_watch);
237 _dbus_connection_toggle_watch_unlocked (transport->connection,
238 socket_transport->read_watch,
241 _dbus_transport_unref (transport);
245 do_io_error (DBusTransport *transport)
247 _dbus_transport_ref (transport);
248 _dbus_transport_disconnect (transport);
249 _dbus_transport_unref (transport);
252 /* return value is whether we successfully read any new data. */
254 read_data_into_auth (DBusTransport *transport,
257 DBusTransportSocket *socket_transport = (DBusTransportSocket*) transport;
263 _dbus_auth_get_buffer (transport->auth, &buffer);
265 bytes_read = _dbus_read_socket (socket_transport->fd,
266 buffer, socket_transport->max_bytes_read_per_iteration);
268 _dbus_auth_return_buffer (transport->auth, buffer,
269 bytes_read > 0 ? bytes_read : 0);
273 _dbus_verbose (" read %d bytes in auth phase\n", bytes_read);
277 else if (bytes_read < 0)
279 /* EINTR already handled for us */
281 if (_dbus_get_is_errno_enomem ())
285 else if (_dbus_get_is_errno_eagain_or_ewouldblock ())
286 ; /* do nothing, just return FALSE below */
289 _dbus_verbose ("Error reading from remote app: %s\n",
290 _dbus_strerror_from_errno ());
291 do_io_error (transport);
298 _dbus_assert (bytes_read == 0);
300 _dbus_verbose ("Disconnected from remote app\n");
301 do_io_error (transport);
307 /* Return value is whether we successfully wrote any bytes */
309 write_data_from_auth (DBusTransport *transport)
311 DBusTransportSocket *socket_transport = (DBusTransportSocket*) transport;
313 const DBusString *buffer;
315 if (!_dbus_auth_get_bytes_to_send (transport->auth,
319 bytes_written = _dbus_write_socket (socket_transport->fd,
321 0, _dbus_string_get_length (buffer));
323 if (bytes_written > 0)
325 _dbus_auth_bytes_sent (transport->auth, bytes_written);
328 else if (bytes_written < 0)
330 /* EINTR already handled for us */
332 if (_dbus_get_is_errno_eagain_or_ewouldblock ())
336 _dbus_verbose ("Error writing to remote app: %s\n",
337 _dbus_strerror_from_errno ());
338 do_io_error (transport);
347 exchange_credentials (DBusTransport *transport,
348 dbus_bool_t do_reading,
349 dbus_bool_t do_writing)
351 DBusTransportSocket *socket_transport = (DBusTransportSocket*) transport;
352 DBusError error = DBUS_ERROR_INIT;
354 _dbus_verbose ("exchange_credentials: do_reading = %d, do_writing = %d\n",
355 do_reading, do_writing);
357 if (do_writing && transport->send_credentials_pending)
359 if (_dbus_send_credentials_socket (socket_transport->fd,
362 transport->send_credentials_pending = FALSE;
366 _dbus_verbose ("Failed to write credentials: %s\n", error.message);
367 dbus_error_free (&error);
368 do_io_error (transport);
372 if (do_reading && transport->receive_credentials_pending)
374 /* FIXME this can fail due to IO error _or_ OOM, broken
375 * (somewhat tricky to fix since the OOM error can be set after
376 * we already read the credentials byte, so basically we need to
377 * separate reading the byte and storing it in the
378 * transport->credentials). Does not really matter for now
379 * because storing in credentials never actually fails on unix.
381 if (_dbus_read_credentials_socket (socket_transport->fd,
382 transport->credentials,
385 transport->receive_credentials_pending = FALSE;
389 _dbus_verbose ("Failed to read credentials %s\n", error.message);
390 dbus_error_free (&error);
391 do_io_error (transport);
395 if (!(transport->send_credentials_pending ||
396 transport->receive_credentials_pending))
398 if (!_dbus_auth_set_credentials (transport->auth,
399 transport->credentials))
407 do_authentication (DBusTransport *transport,
408 dbus_bool_t do_reading,
409 dbus_bool_t do_writing,
410 dbus_bool_t *auth_completed)
413 dbus_bool_t orig_auth_state;
417 orig_auth_state = _dbus_transport_get_is_authenticated (transport);
419 /* This is essential to avoid the check_write_watch() at the end,
420 * we don't want to add a write watch in do_iteration before
421 * we try writing and get EAGAIN
426 *auth_completed = FALSE;
430 _dbus_transport_ref (transport);
432 while (!_dbus_transport_get_is_authenticated (transport) &&
433 _dbus_transport_get_is_connected (transport))
435 if (!exchange_credentials (transport, do_reading, do_writing))
442 if (transport->send_credentials_pending ||
443 transport->receive_credentials_pending)
445 _dbus_verbose ("send_credentials_pending = %d receive_credentials_pending = %d\n",
446 transport->send_credentials_pending,
447 transport->receive_credentials_pending);
451 #define TRANSPORT_SIDE(t) ((t)->is_server ? "server" : "client")
452 switch (_dbus_auth_do_work (transport->auth))
454 case DBUS_AUTH_STATE_WAITING_FOR_INPUT:
455 _dbus_verbose (" %s auth state: waiting for input\n",
456 TRANSPORT_SIDE (transport));
457 if (!do_reading || !read_data_into_auth (transport, &oom))
461 case DBUS_AUTH_STATE_WAITING_FOR_MEMORY:
462 _dbus_verbose (" %s auth state: waiting for memory\n",
463 TRANSPORT_SIDE (transport));
468 case DBUS_AUTH_STATE_HAVE_BYTES_TO_SEND:
469 _dbus_verbose (" %s auth state: bytes to send\n",
470 TRANSPORT_SIDE (transport));
471 if (!do_writing || !write_data_from_auth (transport))
475 case DBUS_AUTH_STATE_NEED_DISCONNECT:
476 _dbus_verbose (" %s auth state: need to disconnect\n",
477 TRANSPORT_SIDE (transport));
478 do_io_error (transport);
481 case DBUS_AUTH_STATE_AUTHENTICATED:
482 _dbus_verbose (" %s auth state: authenticated\n",
483 TRANSPORT_SIDE (transport));
490 *auth_completed = (orig_auth_state != _dbus_transport_get_is_authenticated (transport));
492 check_read_watch (transport);
493 check_write_watch (transport);
494 _dbus_transport_unref (transport);
502 /* returns false on oom */
504 do_writing (DBusTransport *transport)
507 DBusTransportSocket *socket_transport = (DBusTransportSocket*) transport;
510 /* No messages without authentication! */
511 if (!_dbus_transport_get_is_authenticated (transport))
513 _dbus_verbose ("Not authenticated, not writing anything\n");
517 if (transport->disconnected)
519 _dbus_verbose ("Not connected, not writing anything\n");
524 _dbus_verbose ("do_writing(), have_messages = %d, fd = %d\n",
525 _dbus_connection_has_messages_to_send_unlocked (transport->connection),
526 socket_transport->fd);
532 while (!transport->disconnected &&
533 _dbus_connection_has_messages_to_send_unlocked (transport->connection))
536 DBusMessage *message;
537 const DBusString *header;
538 const DBusString *body;
539 int header_len, body_len;
540 int total_bytes_to_write;
542 if (total > socket_transport->max_bytes_written_per_iteration)
544 _dbus_verbose ("%d bytes exceeds %d bytes written per iteration, returning\n",
545 total, socket_transport->max_bytes_written_per_iteration);
549 message = _dbus_connection_get_message_to_send (transport->connection);
550 _dbus_assert (message != NULL);
551 dbus_message_lock (message);
554 _dbus_verbose ("writing message %p\n", message);
557 _dbus_message_get_network_data (message,
560 header_len = _dbus_string_get_length (header);
561 body_len = _dbus_string_get_length (body);
563 if (_dbus_auth_needs_encoding (transport->auth))
565 /* Does fd passing even make sense with encoded data? */
566 _dbus_assert(!DBUS_TRANSPORT_CAN_SEND_UNIX_FD(transport));
568 if (_dbus_string_get_length (&socket_transport->encoded_outgoing) == 0)
570 if (!_dbus_auth_encode_data (transport->auth,
571 header, &socket_transport->encoded_outgoing))
577 if (!_dbus_auth_encode_data (transport->auth,
578 body, &socket_transport->encoded_outgoing))
580 _dbus_string_set_length (&socket_transport->encoded_outgoing, 0);
586 total_bytes_to_write = _dbus_string_get_length (&socket_transport->encoded_outgoing);
589 _dbus_verbose ("encoded message is %d bytes\n",
590 total_bytes_to_write);
594 _dbus_write_socket (socket_transport->fd,
595 &socket_transport->encoded_outgoing,
596 socket_transport->message_bytes_written,
597 total_bytes_to_write - socket_transport->message_bytes_written);
601 total_bytes_to_write = header_len + body_len;
604 _dbus_verbose ("message is %d bytes\n",
605 total_bytes_to_write);
608 #ifdef HAVE_UNIX_FD_PASSING
609 if (socket_transport->message_bytes_written <= 0 && DBUS_TRANSPORT_CAN_SEND_UNIX_FD(transport))
611 /* Send the fds along with the first byte of the message */
615 _dbus_message_get_unix_fds(message, &unix_fds, &n);
618 _dbus_write_socket_with_unix_fds_two (socket_transport->fd,
620 socket_transport->message_bytes_written,
621 header_len - socket_transport->message_bytes_written,
627 if (bytes_written > 0 && n > 0)
628 _dbus_verbose("Wrote %i unix fds\n", n);
633 if (socket_transport->message_bytes_written < header_len)
636 _dbus_write_socket_two (socket_transport->fd,
638 socket_transport->message_bytes_written,
639 header_len - socket_transport->message_bytes_written,
646 _dbus_write_socket (socket_transport->fd,
648 (socket_transport->message_bytes_written - header_len),
650 (socket_transport->message_bytes_written - header_len));
655 if (bytes_written < 0)
657 /* EINTR already handled for us */
659 /* For some discussion of why we also ignore EPIPE here, see
660 * http://lists.freedesktop.org/archives/dbus/2008-March/009526.html
663 if (_dbus_get_is_errno_eagain_or_ewouldblock () || _dbus_get_is_errno_epipe ())
667 _dbus_verbose ("Error writing to remote app: %s\n",
668 _dbus_strerror_from_errno ());
669 do_io_error (transport);
675 _dbus_verbose (" wrote %d bytes of %d\n", bytes_written,
676 total_bytes_to_write);
678 total += bytes_written;
679 socket_transport->message_bytes_written += bytes_written;
681 _dbus_assert (socket_transport->message_bytes_written <=
682 total_bytes_to_write);
684 if (socket_transport->message_bytes_written == total_bytes_to_write)
686 socket_transport->message_bytes_written = 0;
687 _dbus_string_set_length (&socket_transport->encoded_outgoing, 0);
688 _dbus_string_compact (&socket_transport->encoded_outgoing, 2048);
690 _dbus_connection_message_sent_unlocked (transport->connection,
703 /* returns false on out-of-memory */
705 do_reading (DBusTransport *transport)
707 DBusTransportSocket *socket_transport = (DBusTransportSocket*) transport;
713 _dbus_verbose ("fd = %d\n",socket_transport->fd);
715 /* No messages without authentication! */
716 if (!_dbus_transport_get_is_authenticated (transport))
725 /* See if we've exceeded max messages and need to disable reading */
726 check_read_watch (transport);
728 if (total > socket_transport->max_bytes_read_per_iteration)
730 _dbus_verbose ("%d bytes exceeds %d bytes read per iteration, returning\n",
731 total, socket_transport->max_bytes_read_per_iteration);
735 _dbus_assert (socket_transport->read_watch != NULL ||
736 transport->disconnected);
738 if (transport->disconnected)
741 if (!dbus_watch_get_enabled (socket_transport->read_watch))
744 if (_dbus_auth_needs_decoding (transport->auth))
746 /* Does fd passing even make sense with encoded data? */
747 _dbus_assert(!DBUS_TRANSPORT_CAN_SEND_UNIX_FD(transport));
749 if (_dbus_string_get_length (&socket_transport->encoded_incoming) > 0)
750 bytes_read = _dbus_string_get_length (&socket_transport->encoded_incoming);
752 bytes_read = _dbus_read_socket (socket_transport->fd,
753 &socket_transport->encoded_incoming,
754 socket_transport->max_bytes_read_per_iteration);
756 _dbus_assert (_dbus_string_get_length (&socket_transport->encoded_incoming) ==
763 _dbus_message_loader_get_buffer (transport->loader,
766 orig_len = _dbus_string_get_length (buffer);
768 if (!_dbus_auth_decode_data (transport->auth,
769 &socket_transport->encoded_incoming,
772 _dbus_verbose ("Out of memory decoding incoming data\n");
773 _dbus_message_loader_return_buffer (transport->loader,
775 _dbus_string_get_length (buffer) - orig_len);
781 _dbus_message_loader_return_buffer (transport->loader,
783 _dbus_string_get_length (buffer) - orig_len);
785 _dbus_string_set_length (&socket_transport->encoded_incoming, 0);
786 _dbus_string_compact (&socket_transport->encoded_incoming, 2048);
791 _dbus_message_loader_get_buffer (transport->loader,
794 #ifdef HAVE_UNIX_FD_PASSING
795 if (DBUS_TRANSPORT_CAN_SEND_UNIX_FD(transport))
799 if (!_dbus_message_loader_get_unix_fds(transport->loader, &fds, &n_fds))
801 _dbus_verbose ("Out of memory reading file descriptors\n");
802 _dbus_message_loader_return_buffer (transport->loader, buffer, 0);
807 bytes_read = _dbus_read_socket_with_unix_fds(socket_transport->fd,
809 socket_transport->max_bytes_read_per_iteration,
812 if (bytes_read >= 0 && n_fds > 0)
813 _dbus_verbose("Read %i unix fds\n", n_fds);
815 _dbus_message_loader_return_unix_fds(transport->loader, fds, bytes_read < 0 ? 0 : n_fds);
820 bytes_read = _dbus_read_socket (socket_transport->fd,
821 buffer, socket_transport->max_bytes_read_per_iteration);
824 _dbus_message_loader_return_buffer (transport->loader,
826 bytes_read < 0 ? 0 : bytes_read);
831 /* EINTR already handled for us */
833 if (_dbus_get_is_errno_enomem ())
835 _dbus_verbose ("Out of memory in read()/do_reading()\n");
839 else if (_dbus_get_is_errno_eagain_or_ewouldblock ())
843 _dbus_verbose ("Error reading from remote app: %s\n",
844 _dbus_strerror_from_errno ());
845 do_io_error (transport);
849 else if (bytes_read == 0)
851 _dbus_verbose ("Disconnected from remote app\n");
852 do_io_error (transport);
857 _dbus_verbose (" read %d bytes\n", bytes_read);
861 if (!_dbus_transport_queue_messages (transport))
864 _dbus_verbose (" out of memory when queueing messages we just read in the transport\n");
868 /* Try reading more data until we get EAGAIN and return, or
869 * exceed max bytes per iteration. If in blocking mode of
870 * course we'll block instead of returning.
883 unix_error_with_read_to_come (DBusTransport *itransport,
887 DBusTransportSocket *transport = (DBusTransportSocket *) itransport;
889 if (!(flags & DBUS_WATCH_HANGUP || flags & DBUS_WATCH_ERROR))
892 /* If we have a read watch enabled ...
893 we -might have data incoming ... => handle the HANGUP there */
894 if (watch != transport->read_watch &&
895 _dbus_watch_get_enabled (transport->read_watch))
902 socket_handle_watch (DBusTransport *transport,
906 DBusTransportSocket *socket_transport = (DBusTransportSocket*) transport;
908 _dbus_assert (watch == socket_transport->read_watch ||
909 watch == socket_transport->write_watch);
910 _dbus_assert (watch != NULL);
912 /* If we hit an error here on a write watch, don't disconnect the transport yet because data can
913 * still be in the buffer and do_reading may need several iteration to read
914 * it all (because of its max_bytes_read_per_iteration limit).
916 if (!(flags & DBUS_WATCH_READABLE) && unix_error_with_read_to_come (transport, watch, flags))
918 _dbus_verbose ("Hang up or error on watch\n");
919 _dbus_transport_disconnect (transport);
923 if (watch == socket_transport->read_watch &&
924 (flags & DBUS_WATCH_READABLE))
926 dbus_bool_t auth_finished;
928 _dbus_verbose ("handling read watch %p flags = %x\n",
931 if (!do_authentication (transport, TRUE, FALSE, &auth_finished))
934 /* We don't want to do a read immediately following
935 * a successful authentication. This is so we
936 * have a chance to propagate the authentication
937 * state further up. Specifically, we need to
938 * process any pending data from the auth object.
942 if (!do_reading (transport))
944 _dbus_verbose ("no memory to read\n");
950 _dbus_verbose ("Not reading anything since we just completed the authentication\n");
953 else if (watch == socket_transport->write_watch &&
954 (flags & DBUS_WATCH_WRITABLE))
957 _dbus_verbose ("handling write watch, have_outgoing_messages = %d\n",
958 _dbus_connection_has_messages_to_send_unlocked (transport->connection));
960 if (!do_authentication (transport, FALSE, TRUE, NULL))
963 if (!do_writing (transport))
965 _dbus_verbose ("no memory to write\n");
969 /* See if we still need the write watch */
970 check_write_watch (transport);
972 #ifdef DBUS_ENABLE_VERBOSE_MODE
975 if (watch == socket_transport->read_watch)
976 _dbus_verbose ("asked to handle read watch with non-read condition 0x%x\n",
978 else if (watch == socket_transport->write_watch)
979 _dbus_verbose ("asked to handle write watch with non-write condition 0x%x\n",
982 _dbus_verbose ("asked to handle watch %p on fd %d that we don't recognize\n",
983 watch, dbus_watch_get_socket (watch));
985 #endif /* DBUS_ENABLE_VERBOSE_MODE */
991 socket_disconnect (DBusTransport *transport)
993 DBusTransportSocket *socket_transport = (DBusTransportSocket*) transport;
995 _dbus_verbose ("\n");
997 free_watches (transport);
999 _dbus_close_socket (socket_transport->fd, NULL);
1000 socket_transport->fd = -1;
1004 socket_connection_set (DBusTransport *transport)
1006 DBusTransportSocket *socket_transport = (DBusTransportSocket*) transport;
1008 _dbus_watch_set_handler (socket_transport->write_watch,
1009 _dbus_connection_handle_watch,
1010 transport->connection, NULL);
1012 _dbus_watch_set_handler (socket_transport->read_watch,
1013 _dbus_connection_handle_watch,
1014 transport->connection, NULL);
1016 if (!_dbus_connection_add_watch_unlocked (transport->connection,
1017 socket_transport->write_watch))
1020 if (!_dbus_connection_add_watch_unlocked (transport->connection,
1021 socket_transport->read_watch))
1023 _dbus_connection_remove_watch_unlocked (transport->connection,
1024 socket_transport->write_watch);
1028 check_read_watch (transport);
1029 check_write_watch (transport);
1035 * @todo We need to have a way to wake up the select sleep if
1036 * a new iteration request comes in with a flag (read/write) that
1037 * we're not currently serving. Otherwise a call that just reads
1038 * could block a write call forever (if there are no incoming
1042 socket_do_iteration (DBusTransport *transport,
1044 int timeout_milliseconds)
1046 DBusTransportSocket *socket_transport = (DBusTransportSocket*) transport;
1051 _dbus_verbose (" iteration flags = %s%s timeout = %d read_watch = %p write_watch = %p fd = %d\n",
1052 flags & DBUS_ITERATION_DO_READING ? "read" : "",
1053 flags & DBUS_ITERATION_DO_WRITING ? "write" : "",
1054 timeout_milliseconds,
1055 socket_transport->read_watch,
1056 socket_transport->write_watch,
1057 socket_transport->fd);
1059 /* the passed in DO_READING/DO_WRITING flags indicate whether to
1060 * read/write messages, but regardless of those we may need to block
1061 * for reading/writing to do auth. But if we do reading for auth,
1062 * we don't want to read any messages yet if not given DO_READING.
1065 poll_fd.fd = socket_transport->fd;
1068 if (_dbus_transport_get_is_authenticated (transport))
1070 /* This is kind of a hack; if we have stuff to write, then try
1071 * to avoid the poll. This is probably about a 5% speedup on an
1072 * echo client/server.
1074 * If both reading and writing were requested, we want to avoid this
1075 * since it could have funky effects:
1076 * - both ends spinning waiting for the other one to read
1077 * data so they can finish writing
1078 * - prioritizing all writing ahead of reading
1080 if ((flags & DBUS_ITERATION_DO_WRITING) &&
1081 !(flags & (DBUS_ITERATION_DO_READING | DBUS_ITERATION_BLOCK)) &&
1082 !transport->disconnected &&
1083 _dbus_connection_has_messages_to_send_unlocked (transport->connection))
1085 do_writing (transport);
1087 if (transport->disconnected ||
1088 !_dbus_connection_has_messages_to_send_unlocked (transport->connection))
1092 /* If we get here, we decided to do the poll() after all */
1093 _dbus_assert (socket_transport->read_watch);
1094 if (flags & DBUS_ITERATION_DO_READING)
1095 poll_fd.events |= _DBUS_POLLIN;
1097 _dbus_assert (socket_transport->write_watch);
1098 if (flags & DBUS_ITERATION_DO_WRITING)
1099 poll_fd.events |= _DBUS_POLLOUT;
1103 DBusAuthState auth_state;
1105 auth_state = _dbus_auth_do_work (transport->auth);
1107 if (transport->receive_credentials_pending ||
1108 auth_state == DBUS_AUTH_STATE_WAITING_FOR_INPUT)
1109 poll_fd.events |= _DBUS_POLLIN;
1111 if (transport->send_credentials_pending ||
1112 auth_state == DBUS_AUTH_STATE_HAVE_BYTES_TO_SEND)
1113 poll_fd.events |= _DBUS_POLLOUT;
1118 if (flags & DBUS_ITERATION_BLOCK)
1119 poll_timeout = timeout_milliseconds;
1123 /* For blocking selects we drop the connection lock here
1124 * to avoid blocking out connection access during a potentially
1125 * indefinite blocking call. The io path is still protected
1126 * by the io_path_cond condvar, so we won't reenter this.
1128 if (flags & DBUS_ITERATION_BLOCK)
1130 _dbus_verbose ("unlock pre poll\n");
1131 _dbus_connection_unlock (transport->connection);
1135 poll_res = _dbus_poll (&poll_fd, 1, poll_timeout);
1137 if (poll_res < 0 && _dbus_get_is_errno_eintr ())
1140 if (flags & DBUS_ITERATION_BLOCK)
1142 _dbus_verbose ("lock post poll\n");
1143 _dbus_connection_lock (transport->connection);
1149 poll_fd.revents = 0; /* some concern that posix does not guarantee this;
1150 * valgrind flags it as an error. though it probably
1151 * is guaranteed on linux at least.
1154 if (poll_fd.revents & _DBUS_POLLERR)
1155 do_io_error (transport);
1158 dbus_bool_t need_read = (poll_fd.revents & _DBUS_POLLIN) > 0;
1159 dbus_bool_t need_write = (poll_fd.revents & _DBUS_POLLOUT) > 0;
1160 dbus_bool_t authentication_completed;
1162 _dbus_verbose ("in iteration, need_read=%d need_write=%d\n",
1163 need_read, need_write);
1164 do_authentication (transport, need_read, need_write,
1165 &authentication_completed);
1167 /* See comment in socket_handle_watch. */
1168 if (authentication_completed)
1171 if (need_read && (flags & DBUS_ITERATION_DO_READING))
1172 do_reading (transport);
1173 if (need_write && (flags & DBUS_ITERATION_DO_WRITING))
1174 do_writing (transport);
1179 _dbus_verbose ("Error from _dbus_poll(): %s\n",
1180 _dbus_strerror_from_errno ());
1186 /* We need to install the write watch only if we did not
1187 * successfully write everything. Note we need to be careful that we
1188 * don't call check_write_watch *before* do_writing, since it's
1189 * inefficient to add the write watch, and we can avoid it most of
1190 * the time since we can write immediately.
1192 * However, we MUST always call check_write_watch(); DBusConnection code
1193 * relies on the fact that running an iteration will notice that
1194 * messages are pending.
1196 check_write_watch (transport);
1198 _dbus_verbose (" ... leaving do_iteration()\n");
1202 socket_live_messages_changed (DBusTransport *transport)
1204 /* See if we should look for incoming messages again */
1205 check_read_watch (transport);
1210 socket_get_socket_fd (DBusTransport *transport,
1213 DBusTransportSocket *socket_transport = (DBusTransportSocket*) transport;
1215 *fd_p = socket_transport->fd;
1220 static const DBusTransportVTable kdbus_vtable = {
1222 socket_handle_watch,
1224 socket_connection_set,
1225 socket_do_iteration,
1226 socket_live_messages_changed,
1227 socket_get_socket_fd
1231 * Creates a new transport for the given kdbus file descriptor. The file
1232 * descriptor must be nonblocking (use _dbus_set_fd_nonblocking() to
1235 * @param fd the file descriptor.
1236 * @param server_guid non-#NULL if this transport is on the server side of a connection
1237 * @param address the transport's address
1238 * @returns the new transport, or #NULL if no memory.
1241 _dbus_transport_new_for_socket_kdbus (int fd,
1242 const DBusString *server_guid,
1243 const DBusString *address)
1245 DBusTransportSocket *socket_transport;
1247 socket_transport = dbus_new0 (DBusTransportSocket, 1);
1248 if (socket_transport == NULL)
1251 if (!_dbus_string_init (&socket_transport->encoded_outgoing))
1254 if (!_dbus_string_init (&socket_transport->encoded_incoming))
1257 socket_transport->write_watch = _dbus_watch_new (fd,
1258 DBUS_WATCH_WRITABLE,
1261 if (socket_transport->write_watch == NULL)
1264 socket_transport->read_watch = _dbus_watch_new (fd,
1265 DBUS_WATCH_READABLE,
1268 if (socket_transport->read_watch == NULL)
1271 if (!_dbus_transport_init_base (&socket_transport->base,
1273 server_guid, address))
1276 #ifdef HAVE_UNIX_FD_PASSING
1277 _dbus_auth_set_unix_fd_possible(socket_transport->base.auth, _dbus_socket_can_pass_unix_fd(fd));
1280 socket_transport->fd = fd;
1281 socket_transport->message_bytes_written = 0;
1283 /* These values should probably be tunable or something. */
1284 socket_transport->max_bytes_read_per_iteration = 2048;
1285 socket_transport->max_bytes_written_per_iteration = 2048;
1287 return (DBusTransport*) socket_transport;
1290 _dbus_watch_invalidate (socket_transport->read_watch);
1291 _dbus_watch_unref (socket_transport->read_watch);
1293 _dbus_watch_invalidate (socket_transport->write_watch);
1294 _dbus_watch_unref (socket_transport->write_watch);
1296 _dbus_string_free (&socket_transport->encoded_incoming);
1298 _dbus_string_free (&socket_transport->encoded_outgoing);
1300 dbus_free (socket_transport);
1306 * Creates a connection to the kdbus bus
1308 * This will set FD_CLOEXEC for the socket returned.
1310 * @param path the path to UNIX domain socket
1311 * @param error return location for error code
1312 * @returns connection file descriptor or -1 on error
1314 int _dbus_connect_kdbus (const char *path, DBusError *error)
1318 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
1319 _dbus_verbose ("connecting to kdbus bus %s\n", path);
1321 fd = open(path, O_RDWR|O_CLOEXEC|O_NONBLOCK); //[RP] | O_NONBLOCK added here, in dbus added separately in section commented out below
1324 dbus_set_error(error, _dbus_error_from_errno (errno), "Failed to open file descriptor: %s", _dbus_strerror (errno));
1325 _DBUS_ASSERT_ERROR_IS_SET(error);
1326 return -1; //[RP] not needed here if commented block below is removed
1329 /*if (!_dbus_set_fd_nonblocking (fd, error))
1331 _DBUS_ASSERT_ERROR_IS_SET (error);
1332 _dbus_close (fd, NULL);
1341 * Creates a new transport for kdbus.
1342 * This creates a client-side of a transport.
1344 * @param path the path to the domain socket.
1345 * @param error address where an error can be returned.
1346 * @returns a new transport, or #NULL on failure.
1348 DBusTransport* _dbus_transport_new_for_kdbus (const char *path, DBusError *error)
1351 DBusTransport *transport;
1354 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
1356 if (!_dbus_string_init (&address))
1358 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
1364 if ((!_dbus_string_append (&address, "kdbus:path=")) || (!_dbus_string_append (&address, path)))
1366 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
1370 fd = _dbus_connect_kdbus (path, error);
1371 // fd = _dbus_connect_unix_socket (path, error);
1374 _DBUS_ASSERT_ERROR_IS_SET (error);
1378 _dbus_verbose ("Successfully connected to kdbus bus %s\n", path);
1380 transport = _dbus_transport_new_for_socket_kdbus (fd, NULL, &address); //todo
1381 if (transport == NULL)
1383 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
1387 _dbus_string_free (&address);
1392 _dbus_close_socket (fd, NULL);
1394 _dbus_string_free (&address);
1400 * Opens kdbus transport.
1402 * @param entry the address entry to try opening
1403 * @param transport_p return location for the opened transport
1404 * @param error error to be set
1405 * @returns result of the attempt
1407 DBusTransportOpenResult _dbus_transport_open_kdbus(DBusAddressEntry *entry,
1408 DBusTransport **transport_p,
1413 method = dbus_address_entry_get_method (entry);
1414 _dbus_assert (method != NULL);
1416 if (strcmp (method, "kdbus") == 0)
1418 const char *path = dbus_address_entry_get_value (entry, "path");
1422 _dbus_set_bad_address (error, "kdbus", "path", NULL);
1423 return DBUS_TRANSPORT_OPEN_BAD_ADDRESS;
1426 *transport_p = _dbus_transport_new_for_kdbus (path, error);
1428 if (*transport_p == NULL)
1430 _DBUS_ASSERT_ERROR_IS_SET (error);
1431 return DBUS_TRANSPORT_OPEN_DID_NOT_CONNECT;
1435 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
1436 return DBUS_TRANSPORT_OPEN_OK;
1441 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
1442 return DBUS_TRANSPORT_OPEN_NOT_HANDLED;
1446 struct kdbus_policy *make_policy_name(const char *name)
1448 struct kdbus_policy *p;
1451 size = offsetof(struct kdbus_policy, name) + strlen(name) + 1;
1457 p->type = KDBUS_POLICY_NAME;
1458 strcpy(p->name, name);
1463 struct kdbus_policy *make_policy_access(__u64 type, __u64 bits, __u64 id)
1465 struct kdbus_policy *p;
1466 __u64 size = sizeof(*p);
1474 p->type = KDBUS_POLICY_ACCESS;
1475 p->access.type = type;
1476 p->access.bits = bits;
1482 void append_policy(struct kdbus_cmd_policy *cmd_policy, struct kdbus_policy *policy, __u64 max_size)
1484 struct kdbus_policy *dst = (struct kdbus_policy *) ((char *) cmd_policy + cmd_policy->size);
1486 if (cmd_policy->size + policy->size > max_size)
1489 memcpy(dst, policy, policy->size);
1490 cmd_policy->size += KDBUS_ALIGN8(policy->size);
1494 dbus_bool_t bus_register_kdbus_policy(const char* name, DBusConnection *connection, DBusError *error)
1496 struct kdbus_cmd_policy *cmd_policy;
1497 struct kdbus_policy *policy;
1501 if(!dbus_connection_get_socket(connection, &fd))
1503 dbus_set_error (error, "Failed to get fd for registering policy", NULL);
1507 cmd_policy = (struct kdbus_cmd_policy *) alloca(size);
1508 memset(cmd_policy, 0, size);
1510 policy = (struct kdbus_policy *) cmd_policy->policies;
1511 cmd_policy->size = offsetof(struct kdbus_cmd_policy, policies);
1513 policy = make_policy_name(name); //todo to be verified or changed when meaning will be known
1514 append_policy(cmd_policy, policy, size);
1516 policy = make_policy_access(KDBUS_POLICY_ACCESS_USER, KDBUS_POLICY_OWN, getuid());
1517 append_policy(cmd_policy, policy, size);
1519 policy = make_policy_access(KDBUS_POLICY_ACCESS_WORLD, KDBUS_POLICY_RECV, 0);
1520 append_policy(cmd_policy, policy, size);
1522 policy = make_policy_access(KDBUS_POLICY_ACCESS_WORLD, KDBUS_POLICY_SEND, 0);
1523 append_policy(cmd_policy, policy, size);
1525 if (ioctl(fd, KDBUS_CMD_EP_POLICY_SET, cmd_policy) < 0)
1527 dbus_set_error(error,_dbus_error_from_errno (errno), "Error setting EP policy: %s", _dbus_strerror (errno));
1531 _dbus_verbose("Policy %s set correctly\n", name);
1535 dbus_bool_t bus_register_kdbus(char** unique_name, DBusConnection *connection, DBusError *error)
1538 struct kdbus_cmd_hello hello;
1541 memset(&hello, 0, sizeof(hello));
1542 hello.conn_flags = KDBUS_HELLO_ACCEPT_FD |
1543 KDBUS_HELLO_ATTACH_COMM |
1544 KDBUS_HELLO_ATTACH_EXE |
1545 KDBUS_HELLO_ATTACH_CMDLINE |
1546 KDBUS_HELLO_ATTACH_CAPS |
1547 KDBUS_HELLO_ATTACH_CGROUP |
1548 KDBUS_HELLO_ATTACH_SECLABEL |
1549 KDBUS_HELLO_ATTACH_AUDIT;
1550 hello.size = sizeof(struct kdbus_cmd_hello);
1551 hello.pool_size = (16 * 1024LU * 1024LU); //todo was: #define POOL_SIZE
1553 if(!dbus_connection_get_socket(connection, &fd))
1555 dbus_set_error (error, "failed to get fd for bus registration", NULL);
1558 if (ioctl(fd, KDBUS_CMD_HELLO, &hello))
1560 dbus_set_error(error,_dbus_error_from_errno (errno), "Failed to send hello: %s", _dbus_strerror (errno));
1564 _dbus_verbose("-- Our peer ID is: %llu\n", (unsigned long long)hello.id);
1565 sprintf(name, "%llx", (unsigned long long)hello.id);
1566 *unique_name = _dbus_strdup(name);
1567 if (*unique_name == NULL)
1569 _DBUS_SET_OOM (error);
1576 uint64_t bus_request_name_kdbus(DBusConnection *connection, const char *name, const uint64_t flags, DBusError *error)
1578 struct kdbus_cmd_name *cmd_name;
1580 uint64_t size = sizeof(*cmd_name) + strlen(name) + 1;
1581 uint64_t flags_kdbus = 0;
1583 cmd_name = alloca(size);
1585 memset(cmd_name, 0, size);
1586 strcpy(cmd_name->name, name);
1587 cmd_name->size = size;
1589 if(flags & DBUS_NAME_FLAG_ALLOW_REPLACEMENT)
1590 flags_kdbus |= KDBUS_NAME_ALLOW_REPLACEMENT;
1591 if(!(flags & DBUS_NAME_FLAG_DO_NOT_QUEUE))
1592 flags_kdbus |= KDBUS_NAME_QUEUE;
1593 if(flags & DBUS_NAME_FLAG_REPLACE_EXISTING)
1594 flags_kdbus |= KDBUS_NAME_REPLACE_EXISTING;
1596 cmd_name->conn_flags = flags_kdbus;
1598 if(!dbus_connection_get_socket(connection, &fd))
1600 dbus_set_error (error, "failed to get fd for name request", NULL);
1604 _dbus_verbose("Request name - flags sent: 0x%llx !!!!!!!!!\n", cmd_name->conn_flags);
1606 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
1607 if (ioctl(fd, KDBUS_CMD_NAME_ACQUIRE, cmd_name))
1609 dbus_set_error(error,_dbus_error_from_errno (errno), "error acquiring name: %s", _dbus_strerror (errno));
1611 return DBUS_REQUEST_NAME_REPLY_EXISTS;
1615 _dbus_verbose("Request name - received flag: 0x%llx !!!!!!!!!\n", cmd_name->conn_flags);
1617 if(cmd_name->conn_flags & KDBUS_NAME_IN_QUEUE)
1618 return DBUS_REQUEST_NAME_REPLY_IN_QUEUE;
1620 return DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER;
1621 //todo now 1 codes are never returned - DBUS_REQUEST_NAME_REPLY_ALREADY_OWNER
1625 * Checks if the connection's transport is kdbus on the basis of its address
1627 * @param pointer to the connection
1628 * @returns TRUE if kdbus transport, otherwise FALSE
1630 dbus_bool_t dbus_transport_is_kdbus(DBusConnection *connection)
1632 const char* address = _dbus_connection_get_address(connection);
1634 if(address == strstr(address, "kdbus:path="))
1640 void dbus_bus_add_match_kdbus (DBusConnection *connection, const char *rule, DBusError *error)
1642 struct kdbus_cmd_match cmd_match;
1645 memset(&cmd_match, 0, sizeof(cmd_match));
1647 if(!dbus_connection_get_socket(connection, &fd))
1649 dbus_set_error (error, "failed to get fd for add match", NULL);
1653 cmd_match.size = sizeof(cmd_match);
1655 //todo add matching rules from *rule when it will be docuemnted in kdbus
1658 cmd_match.src_id = KDBUS_MATCH_SRC_ID_ANY;
1660 if (ioctl(fd, KDBUS_CMD_MATCH_ADD, &cmd_match))
1661 dbus_set_error(error,_dbus_error_from_errno (errno), "error adding match: %s", _dbus_strerror (errno));
1663 _dbus_verbose("Finished adding match bus rule %s !!!!!!!!!\n", rule);