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>
25 /*struct and type below copied from dbus_transport_socket.c
26 * needed for _dbus_transport_new_for_socket_kdbus and kdbus_vtable(?)
27 * todo maybe DBusTransportSocket and _dbus_transport_new_for_socket_kdbus not needed here -
28 * maybe only static const DBusTransportVTable implementation will be enough
32 * Opaque object representing a socket file descriptor transport.
34 typedef struct DBusTransportSocket DBusTransportSocket;
37 * Implementation details of DBusTransportSocket. All members are private.
39 struct DBusTransportSocket
41 DBusTransport base; /**< Parent instance */
42 int fd; /**< File descriptor. */
43 DBusWatch *read_watch; /**< Watch for readability. */
44 DBusWatch *write_watch; /**< Watch for writability. */
46 int max_bytes_read_per_iteration; /**< To avoid blocking too long. */
47 int max_bytes_written_per_iteration; /**< To avoid blocking too long. */
49 int message_bytes_written; /**< Number of bytes of current
50 * outgoing message that have
53 DBusString encoded_outgoing; /**< Encoded version of current
56 DBusString encoded_incoming; /**< Encoded version of current
61 //prototypes of local functions, needed for compiler
62 int _dbus_connect_kdbus (const char *path, DBusError *error);
63 DBusTransport* _dbus_transport_new_for_kdbus (const char *path, DBusError *error);
64 DBusTransport* _dbus_transport_new_for_socket_kdbus (int fd, const DBusString *server_guid, const DBusString *address);
66 /* Functions from dbus_transport_socket - to be modified or reused
70 free_watches (DBusTransport *transport)
72 DBusTransportSocket *socket_transport = (DBusTransportSocket*) transport;
74 _dbus_verbose ("start\n");
76 if (socket_transport->read_watch)
78 if (transport->connection)
79 _dbus_connection_remove_watch_unlocked (transport->connection,
80 socket_transport->read_watch);
81 _dbus_watch_invalidate (socket_transport->read_watch);
82 _dbus_watch_unref (socket_transport->read_watch);
83 socket_transport->read_watch = NULL;
86 if (socket_transport->write_watch)
88 if (transport->connection)
89 _dbus_connection_remove_watch_unlocked (transport->connection,
90 socket_transport->write_watch);
91 _dbus_watch_invalidate (socket_transport->write_watch);
92 _dbus_watch_unref (socket_transport->write_watch);
93 socket_transport->write_watch = NULL;
96 _dbus_verbose ("end\n");
100 socket_finalize (DBusTransport *transport)
102 DBusTransportSocket *socket_transport = (DBusTransportSocket*) transport;
104 _dbus_verbose ("\n");
106 free_watches (transport);
108 _dbus_string_free (&socket_transport->encoded_outgoing);
109 _dbus_string_free (&socket_transport->encoded_incoming);
111 _dbus_transport_finalize_base (transport);
113 _dbus_assert (socket_transport->read_watch == NULL);
114 _dbus_assert (socket_transport->write_watch == NULL);
116 dbus_free (transport);
120 check_write_watch (DBusTransport *transport)
122 DBusTransportSocket *socket_transport = (DBusTransportSocket*) transport;
125 if (transport->connection == NULL)
128 if (transport->disconnected)
130 _dbus_assert (socket_transport->write_watch == NULL);
134 _dbus_transport_ref (transport);
136 if (_dbus_transport_get_is_authenticated (transport))
137 needed = _dbus_connection_has_messages_to_send_unlocked (transport->connection);
140 if (transport->send_credentials_pending)
144 DBusAuthState auth_state;
146 auth_state = _dbus_auth_do_work (transport->auth);
148 /* If we need memory we install the write watch just in case,
149 * if there's no need for it, it will get de-installed
150 * next time we try reading.
152 if (auth_state == DBUS_AUTH_STATE_HAVE_BYTES_TO_SEND ||
153 auth_state == DBUS_AUTH_STATE_WAITING_FOR_MEMORY)
160 _dbus_verbose ("check_write_watch(): needed = %d on connection %p watch %p fd = %d outgoing messages exist %d\n",
161 needed, transport->connection, socket_transport->write_watch,
162 socket_transport->fd,
163 _dbus_connection_has_messages_to_send_unlocked (transport->connection));
165 _dbus_connection_toggle_watch_unlocked (transport->connection,
166 socket_transport->write_watch,
169 _dbus_transport_unref (transport);
173 check_read_watch (DBusTransport *transport)
175 DBusTransportSocket *socket_transport = (DBusTransportSocket*) transport;
176 dbus_bool_t need_read_watch;
178 _dbus_verbose ("fd = %d\n",socket_transport->fd);
180 if (transport->connection == NULL)
183 if (transport->disconnected)
185 _dbus_assert (socket_transport->read_watch == NULL);
189 _dbus_transport_ref (transport);
191 if (_dbus_transport_get_is_authenticated (transport))
193 (_dbus_counter_get_size_value (transport->live_messages) < transport->max_live_messages_size) &&
194 (_dbus_counter_get_unix_fd_value (transport->live_messages) < transport->max_live_messages_unix_fds);
197 if (transport->receive_credentials_pending)
198 need_read_watch = TRUE;
201 /* The reason to disable need_read_watch when not WAITING_FOR_INPUT
202 * is to avoid spinning on the file descriptor when we're waiting
203 * to write or for some other part of the auth process
205 DBusAuthState auth_state;
207 auth_state = _dbus_auth_do_work (transport->auth);
209 /* If we need memory we install the read watch just in case,
210 * if there's no need for it, it will get de-installed
211 * next time we try reading. If we're authenticated we
212 * install it since we normally have it installed while
215 if (auth_state == DBUS_AUTH_STATE_WAITING_FOR_INPUT ||
216 auth_state == DBUS_AUTH_STATE_WAITING_FOR_MEMORY ||
217 auth_state == DBUS_AUTH_STATE_AUTHENTICATED)
218 need_read_watch = TRUE;
220 need_read_watch = FALSE;
224 _dbus_verbose (" setting read watch enabled = %d\n", need_read_watch);
225 _dbus_connection_toggle_watch_unlocked (transport->connection,
226 socket_transport->read_watch,
229 _dbus_transport_unref (transport);
233 do_io_error (DBusTransport *transport)
235 _dbus_transport_ref (transport);
236 _dbus_transport_disconnect (transport);
237 _dbus_transport_unref (transport);
240 /* return value is whether we successfully read any new data. */
242 read_data_into_auth (DBusTransport *transport,
245 DBusTransportSocket *socket_transport = (DBusTransportSocket*) transport;
251 _dbus_auth_get_buffer (transport->auth, &buffer);
253 bytes_read = _dbus_read_socket (socket_transport->fd,
254 buffer, socket_transport->max_bytes_read_per_iteration);
256 _dbus_auth_return_buffer (transport->auth, buffer,
257 bytes_read > 0 ? bytes_read : 0);
261 _dbus_verbose (" read %d bytes in auth phase\n", bytes_read);
265 else if (bytes_read < 0)
267 /* EINTR already handled for us */
269 if (_dbus_get_is_errno_enomem ())
273 else if (_dbus_get_is_errno_eagain_or_ewouldblock ())
274 ; /* do nothing, just return FALSE below */
277 _dbus_verbose ("Error reading from remote app: %s\n",
278 _dbus_strerror_from_errno ());
279 do_io_error (transport);
286 _dbus_assert (bytes_read == 0);
288 _dbus_verbose ("Disconnected from remote app\n");
289 do_io_error (transport);
295 /* Return value is whether we successfully wrote any bytes */
297 write_data_from_auth (DBusTransport *transport)
299 DBusTransportSocket *socket_transport = (DBusTransportSocket*) transport;
301 const DBusString *buffer;
303 if (!_dbus_auth_get_bytes_to_send (transport->auth,
307 bytes_written = _dbus_write_socket (socket_transport->fd,
309 0, _dbus_string_get_length (buffer));
311 if (bytes_written > 0)
313 _dbus_auth_bytes_sent (transport->auth, bytes_written);
316 else if (bytes_written < 0)
318 /* EINTR already handled for us */
320 if (_dbus_get_is_errno_eagain_or_ewouldblock ())
324 _dbus_verbose ("Error writing to remote app: %s\n",
325 _dbus_strerror_from_errno ());
326 do_io_error (transport);
335 exchange_credentials (DBusTransport *transport,
336 dbus_bool_t do_reading,
337 dbus_bool_t do_writing)
339 DBusTransportSocket *socket_transport = (DBusTransportSocket*) transport;
340 DBusError error = DBUS_ERROR_INIT;
342 _dbus_verbose ("exchange_credentials: do_reading = %d, do_writing = %d\n",
343 do_reading, do_writing);
345 if (do_writing && transport->send_credentials_pending)
347 if (_dbus_send_credentials_socket (socket_transport->fd,
350 transport->send_credentials_pending = FALSE;
354 _dbus_verbose ("Failed to write credentials: %s\n", error.message);
355 dbus_error_free (&error);
356 do_io_error (transport);
360 if (do_reading && transport->receive_credentials_pending)
362 /* FIXME this can fail due to IO error _or_ OOM, broken
363 * (somewhat tricky to fix since the OOM error can be set after
364 * we already read the credentials byte, so basically we need to
365 * separate reading the byte and storing it in the
366 * transport->credentials). Does not really matter for now
367 * because storing in credentials never actually fails on unix.
369 if (_dbus_read_credentials_socket (socket_transport->fd,
370 transport->credentials,
373 transport->receive_credentials_pending = FALSE;
377 _dbus_verbose ("Failed to read credentials %s\n", error.message);
378 dbus_error_free (&error);
379 do_io_error (transport);
383 if (!(transport->send_credentials_pending ||
384 transport->receive_credentials_pending))
386 if (!_dbus_auth_set_credentials (transport->auth,
387 transport->credentials))
395 do_authentication (DBusTransport *transport,
396 dbus_bool_t do_reading,
397 dbus_bool_t do_writing,
398 dbus_bool_t *auth_completed)
401 dbus_bool_t orig_auth_state;
405 orig_auth_state = _dbus_transport_get_is_authenticated (transport);
407 /* This is essential to avoid the check_write_watch() at the end,
408 * we don't want to add a write watch in do_iteration before
409 * we try writing and get EAGAIN
414 *auth_completed = FALSE;
418 _dbus_transport_ref (transport);
420 while (!_dbus_transport_get_is_authenticated (transport) &&
421 _dbus_transport_get_is_connected (transport))
423 if (!exchange_credentials (transport, do_reading, do_writing))
430 if (transport->send_credentials_pending ||
431 transport->receive_credentials_pending)
433 _dbus_verbose ("send_credentials_pending = %d receive_credentials_pending = %d\n",
434 transport->send_credentials_pending,
435 transport->receive_credentials_pending);
439 #define TRANSPORT_SIDE(t) ((t)->is_server ? "server" : "client")
440 switch (_dbus_auth_do_work (transport->auth))
442 case DBUS_AUTH_STATE_WAITING_FOR_INPUT:
443 _dbus_verbose (" %s auth state: waiting for input\n",
444 TRANSPORT_SIDE (transport));
445 if (!do_reading || !read_data_into_auth (transport, &oom))
449 case DBUS_AUTH_STATE_WAITING_FOR_MEMORY:
450 _dbus_verbose (" %s auth state: waiting for memory\n",
451 TRANSPORT_SIDE (transport));
456 case DBUS_AUTH_STATE_HAVE_BYTES_TO_SEND:
457 _dbus_verbose (" %s auth state: bytes to send\n",
458 TRANSPORT_SIDE (transport));
459 if (!do_writing || !write_data_from_auth (transport))
463 case DBUS_AUTH_STATE_NEED_DISCONNECT:
464 _dbus_verbose (" %s auth state: need to disconnect\n",
465 TRANSPORT_SIDE (transport));
466 do_io_error (transport);
469 case DBUS_AUTH_STATE_AUTHENTICATED:
470 _dbus_verbose (" %s auth state: authenticated\n",
471 TRANSPORT_SIDE (transport));
478 *auth_completed = (orig_auth_state != _dbus_transport_get_is_authenticated (transport));
480 check_read_watch (transport);
481 check_write_watch (transport);
482 _dbus_transport_unref (transport);
490 /* returns false on oom */
492 do_writing (DBusTransport *transport)
495 DBusTransportSocket *socket_transport = (DBusTransportSocket*) transport;
498 /* No messages without authentication! */
499 if (!_dbus_transport_get_is_authenticated (transport))
501 _dbus_verbose ("Not authenticated, not writing anything\n");
505 if (transport->disconnected)
507 _dbus_verbose ("Not connected, not writing anything\n");
512 _dbus_verbose ("do_writing(), have_messages = %d, fd = %d\n",
513 _dbus_connection_has_messages_to_send_unlocked (transport->connection),
514 socket_transport->fd);
520 while (!transport->disconnected &&
521 _dbus_connection_has_messages_to_send_unlocked (transport->connection))
524 DBusMessage *message;
525 const DBusString *header;
526 const DBusString *body;
527 int header_len, body_len;
528 int total_bytes_to_write;
530 if (total > socket_transport->max_bytes_written_per_iteration)
532 _dbus_verbose ("%d bytes exceeds %d bytes written per iteration, returning\n",
533 total, socket_transport->max_bytes_written_per_iteration);
537 message = _dbus_connection_get_message_to_send (transport->connection);
538 _dbus_assert (message != NULL);
539 dbus_message_lock (message);
542 _dbus_verbose ("writing message %p\n", message);
545 _dbus_message_get_network_data (message,
548 header_len = _dbus_string_get_length (header);
549 body_len = _dbus_string_get_length (body);
551 if (_dbus_auth_needs_encoding (transport->auth))
553 /* Does fd passing even make sense with encoded data? */
554 _dbus_assert(!DBUS_TRANSPORT_CAN_SEND_UNIX_FD(transport));
556 if (_dbus_string_get_length (&socket_transport->encoded_outgoing) == 0)
558 if (!_dbus_auth_encode_data (transport->auth,
559 header, &socket_transport->encoded_outgoing))
565 if (!_dbus_auth_encode_data (transport->auth,
566 body, &socket_transport->encoded_outgoing))
568 _dbus_string_set_length (&socket_transport->encoded_outgoing, 0);
574 total_bytes_to_write = _dbus_string_get_length (&socket_transport->encoded_outgoing);
577 _dbus_verbose ("encoded message is %d bytes\n",
578 total_bytes_to_write);
582 _dbus_write_socket (socket_transport->fd,
583 &socket_transport->encoded_outgoing,
584 socket_transport->message_bytes_written,
585 total_bytes_to_write - socket_transport->message_bytes_written);
589 total_bytes_to_write = header_len + body_len;
592 _dbus_verbose ("message is %d bytes\n",
593 total_bytes_to_write);
596 #ifdef HAVE_UNIX_FD_PASSING
597 if (socket_transport->message_bytes_written <= 0 && DBUS_TRANSPORT_CAN_SEND_UNIX_FD(transport))
599 /* Send the fds along with the first byte of the message */
603 _dbus_message_get_unix_fds(message, &unix_fds, &n);
606 _dbus_write_socket_with_unix_fds_two (socket_transport->fd,
608 socket_transport->message_bytes_written,
609 header_len - socket_transport->message_bytes_written,
615 if (bytes_written > 0 && n > 0)
616 _dbus_verbose("Wrote %i unix fds\n", n);
621 if (socket_transport->message_bytes_written < header_len)
624 _dbus_write_socket_two (socket_transport->fd,
626 socket_transport->message_bytes_written,
627 header_len - socket_transport->message_bytes_written,
634 _dbus_write_socket (socket_transport->fd,
636 (socket_transport->message_bytes_written - header_len),
638 (socket_transport->message_bytes_written - header_len));
643 if (bytes_written < 0)
645 /* EINTR already handled for us */
647 /* For some discussion of why we also ignore EPIPE here, see
648 * http://lists.freedesktop.org/archives/dbus/2008-March/009526.html
651 if (_dbus_get_is_errno_eagain_or_ewouldblock () || _dbus_get_is_errno_epipe ())
655 _dbus_verbose ("Error writing to remote app: %s\n",
656 _dbus_strerror_from_errno ());
657 do_io_error (transport);
663 _dbus_verbose (" wrote %d bytes of %d\n", bytes_written,
664 total_bytes_to_write);
666 total += bytes_written;
667 socket_transport->message_bytes_written += bytes_written;
669 _dbus_assert (socket_transport->message_bytes_written <=
670 total_bytes_to_write);
672 if (socket_transport->message_bytes_written == total_bytes_to_write)
674 socket_transport->message_bytes_written = 0;
675 _dbus_string_set_length (&socket_transport->encoded_outgoing, 0);
676 _dbus_string_compact (&socket_transport->encoded_outgoing, 2048);
678 _dbus_connection_message_sent_unlocked (transport->connection,
691 /* returns false on out-of-memory */
693 do_reading (DBusTransport *transport)
695 DBusTransportSocket *socket_transport = (DBusTransportSocket*) transport;
701 _dbus_verbose ("fd = %d\n",socket_transport->fd);
703 /* No messages without authentication! */
704 if (!_dbus_transport_get_is_authenticated (transport))
713 /* See if we've exceeded max messages and need to disable reading */
714 check_read_watch (transport);
716 if (total > socket_transport->max_bytes_read_per_iteration)
718 _dbus_verbose ("%d bytes exceeds %d bytes read per iteration, returning\n",
719 total, socket_transport->max_bytes_read_per_iteration);
723 _dbus_assert (socket_transport->read_watch != NULL ||
724 transport->disconnected);
726 if (transport->disconnected)
729 if (!dbus_watch_get_enabled (socket_transport->read_watch))
732 if (_dbus_auth_needs_decoding (transport->auth))
734 /* Does fd passing even make sense with encoded data? */
735 _dbus_assert(!DBUS_TRANSPORT_CAN_SEND_UNIX_FD(transport));
737 if (_dbus_string_get_length (&socket_transport->encoded_incoming) > 0)
738 bytes_read = _dbus_string_get_length (&socket_transport->encoded_incoming);
740 bytes_read = _dbus_read_socket (socket_transport->fd,
741 &socket_transport->encoded_incoming,
742 socket_transport->max_bytes_read_per_iteration);
744 _dbus_assert (_dbus_string_get_length (&socket_transport->encoded_incoming) ==
751 _dbus_message_loader_get_buffer (transport->loader,
754 orig_len = _dbus_string_get_length (buffer);
756 if (!_dbus_auth_decode_data (transport->auth,
757 &socket_transport->encoded_incoming,
760 _dbus_verbose ("Out of memory decoding incoming data\n");
761 _dbus_message_loader_return_buffer (transport->loader,
763 _dbus_string_get_length (buffer) - orig_len);
769 _dbus_message_loader_return_buffer (transport->loader,
771 _dbus_string_get_length (buffer) - orig_len);
773 _dbus_string_set_length (&socket_transport->encoded_incoming, 0);
774 _dbus_string_compact (&socket_transport->encoded_incoming, 2048);
779 _dbus_message_loader_get_buffer (transport->loader,
782 #ifdef HAVE_UNIX_FD_PASSING
783 if (DBUS_TRANSPORT_CAN_SEND_UNIX_FD(transport))
787 if (!_dbus_message_loader_get_unix_fds(transport->loader, &fds, &n_fds))
789 _dbus_verbose ("Out of memory reading file descriptors\n");
790 _dbus_message_loader_return_buffer (transport->loader, buffer, 0);
795 bytes_read = _dbus_read_socket_with_unix_fds(socket_transport->fd,
797 socket_transport->max_bytes_read_per_iteration,
800 if (bytes_read >= 0 && n_fds > 0)
801 _dbus_verbose("Read %i unix fds\n", n_fds);
803 _dbus_message_loader_return_unix_fds(transport->loader, fds, bytes_read < 0 ? 0 : n_fds);
808 bytes_read = _dbus_read_socket (socket_transport->fd,
809 buffer, socket_transport->max_bytes_read_per_iteration);
812 _dbus_message_loader_return_buffer (transport->loader,
814 bytes_read < 0 ? 0 : bytes_read);
819 /* EINTR already handled for us */
821 if (_dbus_get_is_errno_enomem ())
823 _dbus_verbose ("Out of memory in read()/do_reading()\n");
827 else if (_dbus_get_is_errno_eagain_or_ewouldblock ())
831 _dbus_verbose ("Error reading from remote app: %s\n",
832 _dbus_strerror_from_errno ());
833 do_io_error (transport);
837 else if (bytes_read == 0)
839 _dbus_verbose ("Disconnected from remote app\n");
840 do_io_error (transport);
845 _dbus_verbose (" read %d bytes\n", bytes_read);
849 if (!_dbus_transport_queue_messages (transport))
852 _dbus_verbose (" out of memory when queueing messages we just read in the transport\n");
856 /* Try reading more data until we get EAGAIN and return, or
857 * exceed max bytes per iteration. If in blocking mode of
858 * course we'll block instead of returning.
871 unix_error_with_read_to_come (DBusTransport *itransport,
875 DBusTransportSocket *transport = (DBusTransportSocket *) itransport;
877 if (!(flags & DBUS_WATCH_HANGUP || flags & DBUS_WATCH_ERROR))
880 /* If we have a read watch enabled ...
881 we -might have data incoming ... => handle the HANGUP there */
882 if (watch != transport->read_watch &&
883 _dbus_watch_get_enabled (transport->read_watch))
890 socket_handle_watch (DBusTransport *transport,
894 DBusTransportSocket *socket_transport = (DBusTransportSocket*) transport;
896 _dbus_assert (watch == socket_transport->read_watch ||
897 watch == socket_transport->write_watch);
898 _dbus_assert (watch != NULL);
900 /* If we hit an error here on a write watch, don't disconnect the transport yet because data can
901 * still be in the buffer and do_reading may need several iteration to read
902 * it all (because of its max_bytes_read_per_iteration limit).
904 if (!(flags & DBUS_WATCH_READABLE) && unix_error_with_read_to_come (transport, watch, flags))
906 _dbus_verbose ("Hang up or error on watch\n");
907 _dbus_transport_disconnect (transport);
911 if (watch == socket_transport->read_watch &&
912 (flags & DBUS_WATCH_READABLE))
914 dbus_bool_t auth_finished;
916 _dbus_verbose ("handling read watch %p flags = %x\n",
919 if (!do_authentication (transport, TRUE, FALSE, &auth_finished))
922 /* We don't want to do a read immediately following
923 * a successful authentication. This is so we
924 * have a chance to propagate the authentication
925 * state further up. Specifically, we need to
926 * process any pending data from the auth object.
930 if (!do_reading (transport))
932 _dbus_verbose ("no memory to read\n");
938 _dbus_verbose ("Not reading anything since we just completed the authentication\n");
941 else if (watch == socket_transport->write_watch &&
942 (flags & DBUS_WATCH_WRITABLE))
945 _dbus_verbose ("handling write watch, have_outgoing_messages = %d\n",
946 _dbus_connection_has_messages_to_send_unlocked (transport->connection));
948 if (!do_authentication (transport, FALSE, TRUE, NULL))
951 if (!do_writing (transport))
953 _dbus_verbose ("no memory to write\n");
957 /* See if we still need the write watch */
958 check_write_watch (transport);
960 #ifdef DBUS_ENABLE_VERBOSE_MODE
963 if (watch == socket_transport->read_watch)
964 _dbus_verbose ("asked to handle read watch with non-read condition 0x%x\n",
966 else if (watch == socket_transport->write_watch)
967 _dbus_verbose ("asked to handle write watch with non-write condition 0x%x\n",
970 _dbus_verbose ("asked to handle watch %p on fd %d that we don't recognize\n",
971 watch, dbus_watch_get_socket (watch));
973 #endif /* DBUS_ENABLE_VERBOSE_MODE */
979 socket_disconnect (DBusTransport *transport)
981 DBusTransportSocket *socket_transport = (DBusTransportSocket*) transport;
983 _dbus_verbose ("\n");
985 free_watches (transport);
987 _dbus_close_socket (socket_transport->fd, NULL);
988 socket_transport->fd = -1;
992 socket_connection_set (DBusTransport *transport)
994 DBusTransportSocket *socket_transport = (DBusTransportSocket*) transport;
996 _dbus_watch_set_handler (socket_transport->write_watch,
997 _dbus_connection_handle_watch,
998 transport->connection, NULL);
1000 _dbus_watch_set_handler (socket_transport->read_watch,
1001 _dbus_connection_handle_watch,
1002 transport->connection, NULL);
1004 if (!_dbus_connection_add_watch_unlocked (transport->connection,
1005 socket_transport->write_watch))
1008 if (!_dbus_connection_add_watch_unlocked (transport->connection,
1009 socket_transport->read_watch))
1011 _dbus_connection_remove_watch_unlocked (transport->connection,
1012 socket_transport->write_watch);
1016 check_read_watch (transport);
1017 check_write_watch (transport);
1023 * @todo We need to have a way to wake up the select sleep if
1024 * a new iteration request comes in with a flag (read/write) that
1025 * we're not currently serving. Otherwise a call that just reads
1026 * could block a write call forever (if there are no incoming
1030 socket_do_iteration (DBusTransport *transport,
1032 int timeout_milliseconds)
1034 DBusTransportSocket *socket_transport = (DBusTransportSocket*) transport;
1039 _dbus_verbose (" iteration flags = %s%s timeout = %d read_watch = %p write_watch = %p fd = %d\n",
1040 flags & DBUS_ITERATION_DO_READING ? "read" : "",
1041 flags & DBUS_ITERATION_DO_WRITING ? "write" : "",
1042 timeout_milliseconds,
1043 socket_transport->read_watch,
1044 socket_transport->write_watch,
1045 socket_transport->fd);
1047 /* the passed in DO_READING/DO_WRITING flags indicate whether to
1048 * read/write messages, but regardless of those we may need to block
1049 * for reading/writing to do auth. But if we do reading for auth,
1050 * we don't want to read any messages yet if not given DO_READING.
1053 poll_fd.fd = socket_transport->fd;
1056 if (_dbus_transport_get_is_authenticated (transport))
1058 /* This is kind of a hack; if we have stuff to write, then try
1059 * to avoid the poll. This is probably about a 5% speedup on an
1060 * echo client/server.
1062 * If both reading and writing were requested, we want to avoid this
1063 * since it could have funky effects:
1064 * - both ends spinning waiting for the other one to read
1065 * data so they can finish writing
1066 * - prioritizing all writing ahead of reading
1068 if ((flags & DBUS_ITERATION_DO_WRITING) &&
1069 !(flags & (DBUS_ITERATION_DO_READING | DBUS_ITERATION_BLOCK)) &&
1070 !transport->disconnected &&
1071 _dbus_connection_has_messages_to_send_unlocked (transport->connection))
1073 do_writing (transport);
1075 if (transport->disconnected ||
1076 !_dbus_connection_has_messages_to_send_unlocked (transport->connection))
1080 /* If we get here, we decided to do the poll() after all */
1081 _dbus_assert (socket_transport->read_watch);
1082 if (flags & DBUS_ITERATION_DO_READING)
1083 poll_fd.events |= _DBUS_POLLIN;
1085 _dbus_assert (socket_transport->write_watch);
1086 if (flags & DBUS_ITERATION_DO_WRITING)
1087 poll_fd.events |= _DBUS_POLLOUT;
1091 DBusAuthState auth_state;
1093 auth_state = _dbus_auth_do_work (transport->auth);
1095 if (transport->receive_credentials_pending ||
1096 auth_state == DBUS_AUTH_STATE_WAITING_FOR_INPUT)
1097 poll_fd.events |= _DBUS_POLLIN;
1099 if (transport->send_credentials_pending ||
1100 auth_state == DBUS_AUTH_STATE_HAVE_BYTES_TO_SEND)
1101 poll_fd.events |= _DBUS_POLLOUT;
1106 if (flags & DBUS_ITERATION_BLOCK)
1107 poll_timeout = timeout_milliseconds;
1111 /* For blocking selects we drop the connection lock here
1112 * to avoid blocking out connection access during a potentially
1113 * indefinite blocking call. The io path is still protected
1114 * by the io_path_cond condvar, so we won't reenter this.
1116 if (flags & DBUS_ITERATION_BLOCK)
1118 _dbus_verbose ("unlock pre poll\n");
1119 _dbus_connection_unlock (transport->connection);
1123 poll_res = _dbus_poll (&poll_fd, 1, poll_timeout);
1125 if (poll_res < 0 && _dbus_get_is_errno_eintr ())
1128 if (flags & DBUS_ITERATION_BLOCK)
1130 _dbus_verbose ("lock post poll\n");
1131 _dbus_connection_lock (transport->connection);
1137 poll_fd.revents = 0; /* some concern that posix does not guarantee this;
1138 * valgrind flags it as an error. though it probably
1139 * is guaranteed on linux at least.
1142 if (poll_fd.revents & _DBUS_POLLERR)
1143 do_io_error (transport);
1146 dbus_bool_t need_read = (poll_fd.revents & _DBUS_POLLIN) > 0;
1147 dbus_bool_t need_write = (poll_fd.revents & _DBUS_POLLOUT) > 0;
1148 dbus_bool_t authentication_completed;
1150 _dbus_verbose ("in iteration, need_read=%d need_write=%d\n",
1151 need_read, need_write);
1152 do_authentication (transport, need_read, need_write,
1153 &authentication_completed);
1155 /* See comment in socket_handle_watch. */
1156 if (authentication_completed)
1159 if (need_read && (flags & DBUS_ITERATION_DO_READING))
1160 do_reading (transport);
1161 if (need_write && (flags & DBUS_ITERATION_DO_WRITING))
1162 do_writing (transport);
1167 _dbus_verbose ("Error from _dbus_poll(): %s\n",
1168 _dbus_strerror_from_errno ());
1174 /* We need to install the write watch only if we did not
1175 * successfully write everything. Note we need to be careful that we
1176 * don't call check_write_watch *before* do_writing, since it's
1177 * inefficient to add the write watch, and we can avoid it most of
1178 * the time since we can write immediately.
1180 * However, we MUST always call check_write_watch(); DBusConnection code
1181 * relies on the fact that running an iteration will notice that
1182 * messages are pending.
1184 check_write_watch (transport);
1186 _dbus_verbose (" ... leaving do_iteration()\n");
1190 socket_live_messages_changed (DBusTransport *transport)
1192 /* See if we should look for incoming messages again */
1193 check_read_watch (transport);
1198 socket_get_socket_fd (DBusTransport *transport,
1201 DBusTransportSocket *socket_transport = (DBusTransportSocket*) transport;
1203 *fd_p = socket_transport->fd;
1208 static const DBusTransportVTable kdbus_vtable = {
1210 socket_handle_watch,
1212 socket_connection_set,
1213 socket_do_iteration,
1214 socket_live_messages_changed,
1215 socket_get_socket_fd
1219 * Creates a new transport for the given kdbus file descriptor. The file
1220 * descriptor must be nonblocking (use _dbus_set_fd_nonblocking() to
1223 * @param fd the file descriptor.
1224 * @param server_guid non-#NULL if this transport is on the server side of a connection
1225 * @param address the transport's address
1226 * @returns the new transport, or #NULL if no memory.
1229 _dbus_transport_new_for_socket_kdbus (int fd,
1230 const DBusString *server_guid,
1231 const DBusString *address)
1233 DBusTransportSocket *socket_transport;
1235 socket_transport = dbus_new0 (DBusTransportSocket, 1);
1236 if (socket_transport == NULL)
1239 if (!_dbus_string_init (&socket_transport->encoded_outgoing))
1242 if (!_dbus_string_init (&socket_transport->encoded_incoming))
1245 socket_transport->write_watch = _dbus_watch_new (fd,
1246 DBUS_WATCH_WRITABLE,
1249 if (socket_transport->write_watch == NULL)
1252 socket_transport->read_watch = _dbus_watch_new (fd,
1253 DBUS_WATCH_READABLE,
1256 if (socket_transport->read_watch == NULL)
1259 if (!_dbus_transport_init_base (&socket_transport->base,
1261 server_guid, address))
1264 #ifdef HAVE_UNIX_FD_PASSING
1265 _dbus_auth_set_unix_fd_possible(socket_transport->base.auth, _dbus_socket_can_pass_unix_fd(fd));
1268 socket_transport->fd = fd;
1269 socket_transport->message_bytes_written = 0;
1271 /* These values should probably be tunable or something. */
1272 socket_transport->max_bytes_read_per_iteration = 2048;
1273 socket_transport->max_bytes_written_per_iteration = 2048;
1275 return (DBusTransport*) socket_transport;
1278 _dbus_watch_invalidate (socket_transport->read_watch);
1279 _dbus_watch_unref (socket_transport->read_watch);
1281 _dbus_watch_invalidate (socket_transport->write_watch);
1282 _dbus_watch_unref (socket_transport->write_watch);
1284 _dbus_string_free (&socket_transport->encoded_incoming);
1286 _dbus_string_free (&socket_transport->encoded_outgoing);
1288 dbus_free (socket_transport);
1294 * Creates a connection to the kdbus bus
1296 * This will set FD_CLOEXEC for the socket returned.
1298 * @param path the path to UNIX domain socket
1299 * @param error return location for error code
1300 * @returns connection file descriptor or -1 on error
1302 int _dbus_connect_kdbus (const char *path, DBusError *error)
1306 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
1307 _dbus_verbose ("connecting to kdbus bus %s\n", path);
1309 fd = open(path, O_RDWR|O_CLOEXEC|O_NONBLOCK); //[RP] | O_NONBLOCK added here, in dbus added separately in section commented out below
1312 dbus_set_error(error, _dbus_error_from_errno (errno), "Failed to open file descriptor: %s", _dbus_strerror (errno));
1313 _DBUS_ASSERT_ERROR_IS_SET(error);
1314 return -1; //[RP] not needed here if commented block below is removed
1317 /*if (!_dbus_set_fd_nonblocking (fd, error))
1319 _DBUS_ASSERT_ERROR_IS_SET (error);
1320 _dbus_close (fd, NULL);
1329 * Creates a new transport for kdbus.
1330 * This creates a client-side of a transport.
1332 * @param path the path to the domain socket.
1333 * @param error address where an error can be returned.
1334 * @returns a new transport, or #NULL on failure.
1336 DBusTransport* _dbus_transport_new_for_kdbus (const char *path, DBusError *error)
1339 DBusTransport *transport;
1342 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
1344 if (!_dbus_string_init (&address))
1346 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
1352 if ((!_dbus_string_append (&address, "kdbus:path=")) || (!_dbus_string_append (&address, path)))
1354 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
1358 fd = _dbus_connect_kdbus (path, error);
1359 // fd = _dbus_connect_unix_socket (path, error);
1362 _DBUS_ASSERT_ERROR_IS_SET (error);
1366 _dbus_verbose ("Successfully connected to kdbus bus %s\n", path);
1368 transport = _dbus_transport_new_for_socket_kdbus (fd, NULL, &address); //todo
1369 if (transport == NULL)
1371 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
1375 _dbus_string_free (&address);
1380 _dbus_close_socket (fd, NULL);
1382 _dbus_string_free (&address);
1388 * Opens kdbus transport.
1390 * @param entry the address entry to try opening
1391 * @param transport_p return location for the opened transport
1392 * @param error error to be set
1393 * @returns result of the attempt
1395 DBusTransportOpenResult _dbus_transport_open_kdbus(DBusAddressEntry *entry,
1396 DBusTransport **transport_p,
1401 method = dbus_address_entry_get_method (entry);
1402 _dbus_assert (method != NULL);
1404 if (strcmp (method, "kdbus") == 0)
1406 const char *path = dbus_address_entry_get_value (entry, "path");
1410 _dbus_set_bad_address (error, "kdbus", "path", NULL);
1411 return DBUS_TRANSPORT_OPEN_BAD_ADDRESS;
1414 *transport_p = _dbus_transport_new_for_kdbus (path, error);
1416 if (*transport_p == NULL)
1418 _DBUS_ASSERT_ERROR_IS_SET (error);
1419 return DBUS_TRANSPORT_OPEN_DID_NOT_CONNECT;
1423 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
1424 return DBUS_TRANSPORT_OPEN_OK;
1429 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
1430 return DBUS_TRANSPORT_OPEN_NOT_HANDLED;
1434 dbus_bool_t bus_register_kdbus(char** unique_name, DBusConnection *connection, DBusError *error)
1436 dbus_bool_t retval = TRUE;
1438 struct kdbus_cmd_hello hello;
1441 memset(&hello, 0, sizeof(hello));
1442 hello.conn_flags = KDBUS_HELLO_ACCEPT_FD |
1443 KDBUS_HELLO_ATTACH_COMM |
1444 KDBUS_HELLO_ATTACH_EXE |
1445 KDBUS_HELLO_ATTACH_CMDLINE |
1446 KDBUS_HELLO_ATTACH_CAPS |
1447 KDBUS_HELLO_ATTACH_CGROUP |
1448 KDBUS_HELLO_ATTACH_SECLABEL |
1449 KDBUS_HELLO_ATTACH_AUDIT;
1450 hello.size = sizeof(struct kdbus_cmd_hello);
1451 hello.pool_size = (16 * 1024LU * 1024LU); //todo was: #define POOL_SIZE
1453 if(!dbus_connection_get_socket(connection, &fd))
1455 dbus_set_error (error, "failed to get fd for connection", NULL);
1458 if (ioctl(fd, KDBUS_CMD_HELLO, &hello))
1460 dbus_set_error(error,_dbus_error_from_errno (errno), "Failed to send hello: %s", _dbus_strerror (errno));
1464 _dbus_verbose("-- Our peer ID is: %llu\n", (unsigned long long)hello.id); //todo [RP] can be removed after development
1465 *unique_name = _dbus_strdup(name);
1466 sprintf(name, "%llx", (unsigned long long)hello.id);
1467 if (*unique_name == NULL)
1469 _DBUS_SET_OOM (error);