diff options
-rw-r--r-- | meta-ivi/recipes-core-ivi/dbus/dbus/dbus_1.6-add-afbus-support.patch | 3201 | ||||
-rw-r--r-- | meta-ivi/recipes-core-ivi/dbus/dbus_%.bbappend | 4 |
2 files changed, 0 insertions, 3205 deletions
diff --git a/meta-ivi/recipes-core-ivi/dbus/dbus/dbus_1.6-add-afbus-support.patch b/meta-ivi/recipes-core-ivi/dbus/dbus/dbus_1.6-add-afbus-support.patch deleted file mode 100644 index 2e91507..0000000 --- a/meta-ivi/recipes-core-ivi/dbus/dbus/dbus_1.6-add-afbus-support.patch +++ /dev/null @@ -1,3201 +0,0 @@ -diff --git a/bus/Makefile.am b/bus/Makefile.am -index 6cbc09a..cf3a962 100644 ---- a/bus/Makefile.am -+++ b/bus/Makefile.am -@@ -63,6 +63,15 @@ endif - endif - endif - -+if HAVE_AFBUS -+AFBUS_SOURCE = \ -+ driver-afbus.c \ -+ driver-afbus.h \ -+ $(NULL) -+else -+AFBUS_SOURCE = -+endif -+ - BUS_SOURCES= \ - activation.c \ - activation.h \ -@@ -83,6 +92,7 @@ BUS_SOURCES= \ - dispatch.h \ - driver.c \ - driver.h \ -+ $(AFBUS_SOURCE) \ - expirelist.c \ - expirelist.h \ - policy.c \ -diff --git a/bus/bus.c b/bus/bus.c -index e80e708..5038958 100644 ---- a/bus/bus.c -+++ b/bus/bus.c -@@ -52,11 +52,20 @@ struct BusContext - char *type; - char *servicehelper; - char *address; -+ -+ /* if we are in AF_BUS compat mode, contains the AF_BUS address */ -+ char *main_address; -+ - char *pidfile; - char *user; - char *log_prefix; - DBusLoop *loop; - DBusList *servers; -+ -+ /* One of the servers may be a AF_BUS server. We can have at most only one -+ * AF_BUS server. */ -+ DBusServer *main_afbus_server; -+ - BusConnections *connections; - BusActivation *activation; - BusRegistry *registry; -@@ -207,6 +216,29 @@ free_server_data (void *data) - dbus_free (bd); - } - -+static void -+shutdown_server (BusContext *context, -+ DBusServer *server) -+{ -+ if (server == NULL || -+ !dbus_server_get_is_connected (server)) -+ return; -+ -+ if (!dbus_server_set_watch_functions (server, -+ NULL, NULL, NULL, -+ context, -+ NULL)) -+ _dbus_assert_not_reached ("setting watch functions to NULL failed"); -+ -+ if (!dbus_server_set_timeout_functions (server, -+ NULL, NULL, NULL, -+ context, -+ NULL)) -+ _dbus_assert_not_reached ("setting timeout functions to NULL failed"); -+ -+ dbus_server_disconnect (server); -+} -+ - static dbus_bool_t - setup_server (BusContext *context, - DBusServer *server, -@@ -275,6 +307,7 @@ process_config_first_time_only (BusContext *context, - DBusString log_prefix; - DBusList *link; - DBusList **addresses; -+ DBusList **addresses_if_possible; - const char *user, *pidfile; - char **auth_mechanisms; - DBusList **auth_mechanisms_list; -@@ -448,6 +481,7 @@ process_config_first_time_only (BusContext *context, - while (link != NULL) - { - DBusServer *server; -+ dbus_bool_t is_afbus; - - server = dbus_server_listen (link->data, error); - if (server == NULL) -@@ -455,17 +489,78 @@ process_config_first_time_only (BusContext *context, - _DBUS_ASSERT_ERROR_IS_SET (error); - goto failed; - } -- else if (!setup_server (context, server, auth_mechanisms, error)) -+ is_afbus = dbus_server_is_afbus (server); -+ -+ /* Only accept one AF_BUS server */ -+ if (is_afbus && context->main_afbus_server != NULL) - { -+ dbus_server_disconnect (server); -+ dbus_server_unref (server); -+ dbus_set_error (error, -+ DBUS_ERROR_MULTIPLE_AFBUS, -+ "Cannot listen on multiple AF_BUS address"); -+ goto failed; -+ } -+ -+ if (!setup_server (context, server, auth_mechanisms, error)) -+ { -+ shutdown_server (context, server); -+ dbus_server_unref (server); - _DBUS_ASSERT_ERROR_IS_SET (error); - goto failed; - } -+ if (is_afbus) -+ context->main_afbus_server = server; - - if (!_dbus_list_append (&context->servers, server)) - goto oom; - - link = _dbus_list_get_next_link (addresses, link); - } -+ -+ addresses_if_possible = -+ bus_config_parser_get_addresses_if_possible (parser); -+ -+ link = _dbus_list_get_first_link (addresses_if_possible); -+ while (link != NULL) -+ { -+ DBusServer *server; -+ dbus_bool_t is_afbus; -+ -+ server = dbus_server_listen (link->data, NULL); -+ if (server == NULL) -+ { -+ link = _dbus_list_get_next_link (addresses_if_possible, link); -+ continue; -+ } -+ is_afbus = dbus_server_is_afbus (server); -+ -+ /* Only accept one AF_BUS server */ -+ if (is_afbus && context->main_afbus_server != NULL) -+ { -+ dbus_server_disconnect (server); -+ dbus_server_unref (server); -+ -+ link = _dbus_list_get_next_link (addresses_if_possible, link); -+ continue; -+ } -+ -+ if (!setup_server (context, server, auth_mechanisms, NULL)) -+ { -+ shutdown_server (context, server); -+ dbus_server_unref (server); -+ -+ link = _dbus_list_get_next_link (addresses_if_possible, link); -+ continue; -+ } -+ if (is_afbus) -+ context->main_afbus_server = server; -+ -+ if (!_dbus_list_append (&context->servers, server)) -+ goto oom; -+ -+ link = _dbus_list_get_next_link (addresses_if_possible, link); -+ } - } - - context->fork = bus_config_parser_get_fork (parser); -@@ -499,6 +594,7 @@ process_config_every_time (BusContext *context, - DBusError *error) - { - DBusString full_address; -+ DBusString main_address; - DBusList *link; - DBusList **dirs; - char *addr; -@@ -518,6 +614,12 @@ process_config_every_time (BusContext *context, - return FALSE; - } - -+ if (!_dbus_string_init (&main_address)) -+ { -+ BUS_SET_OOM (error); -+ return FALSE; -+ } -+ - /* get our limits and timeout lengths */ - bus_config_parser_get_limits (parser, &context->limits); - -@@ -554,6 +656,18 @@ process_config_every_time (BusContext *context, - goto failed; - } - -+ if (dbus_server_is_afbus (link->data)) -+ { -+ /* There must be at most one AF_BUS server */ -+ _dbus_assert (_dbus_string_get_length (&main_address) == 0); -+ -+ if (!_dbus_string_append (&main_address, addr)) -+ { -+ BUS_SET_OOM (error); -+ goto failed; -+ } -+ } -+ - dbus_free (addr); - addr = NULL; - -@@ -561,7 +675,10 @@ process_config_every_time (BusContext *context, - } - - if (is_reload) -- dbus_free (context->address); -+ { -+ dbus_free (context->address); -+ dbus_free (context->main_address); -+ } - - if (!_dbus_string_copy_data (&full_address, &context->address)) - { -@@ -569,6 +686,12 @@ process_config_every_time (BusContext *context, - goto failed; - } - -+ if (!_dbus_string_copy_data (&main_address, &context->main_address)) -+ { -+ BUS_SET_OOM (error); -+ goto failed; -+ } -+ - /* get the service directories */ - dirs = bus_config_parser_get_service_dirs (parser); - -@@ -609,6 +732,7 @@ process_config_every_time (BusContext *context, - - failed: - _dbus_string_free (&full_address); -+ _dbus_string_free (&main_address); - - if (addr) - dbus_free (addr); -@@ -990,29 +1114,6 @@ bus_context_reload_config (BusContext *context, - return ret; - } - --static void --shutdown_server (BusContext *context, -- DBusServer *server) --{ -- if (server == NULL || -- !dbus_server_get_is_connected (server)) -- return; -- -- if (!dbus_server_set_watch_functions (server, -- NULL, NULL, NULL, -- context, -- NULL)) -- _dbus_assert_not_reached ("setting watch functions to NULL failed"); -- -- if (!dbus_server_set_timeout_functions (server, -- NULL, NULL, NULL, -- context, -- NULL)) -- _dbus_assert_not_reached ("setting timeout functions to NULL failed"); -- -- dbus_server_disconnect (server); --} -- - void - bus_context_shutdown (BusContext *context) - { -@@ -1099,6 +1200,7 @@ bus_context_unref (BusContext *context) - dbus_free (context->log_prefix); - dbus_free (context->type); - dbus_free (context->address); -+ dbus_free (context->main_address); - dbus_free (context->user); - dbus_free (context->servicehelper); - -@@ -1134,6 +1236,12 @@ bus_context_get_address (BusContext *context) - } - - const char* -+bus_context_get_main_address (BusContext *context) -+{ -+ return context->main_address; -+} -+ -+const char* - bus_context_get_servicehelper (BusContext *context) - { - return context->servicehelper; -diff --git a/bus/bus.h b/bus/bus.h -index 3597884..f2a55f2 100644 ---- a/bus/bus.h -+++ b/bus/bus.h -@@ -88,6 +88,7 @@ dbus_bool_t bus_context_get_id (BusContext - DBusString *uuid); - const char* bus_context_get_type (BusContext *context); - const char* bus_context_get_address (BusContext *context); -+const char* bus_context_get_main_address (BusContext *context); - const char* bus_context_get_servicehelper (BusContext *context); - dbus_bool_t bus_context_get_systemd_activation (BusContext *context); - BusRegistry* bus_context_get_registry (BusContext *context); -diff --git a/bus/config-parser-common.c b/bus/config-parser-common.c -index c522ff4..8747835 100644 ---- a/bus/config-parser-common.c -+++ b/bus/config-parser-common.c -@@ -63,6 +63,10 @@ bus_config_parser_element_name_to_type (const char *name) - { - return ELEMENT_LISTEN; - } -+ else if (strcmp (name, "listen_if_possible") == 0) -+ { -+ return ELEMENT_LISTEN_IF_POSSIBLE; -+ } - else if (strcmp (name, "auth") == 0) - { - return ELEMENT_AUTH; -@@ -145,6 +149,8 @@ bus_config_parser_element_type_to_name (ElementType type) - return "user"; - case ELEMENT_LISTEN: - return "listen"; -+ case ELEMENT_LISTEN_IF_POSSIBLE: -+ return "listen_if_possible"; - case ELEMENT_AUTH: - return "auth"; - case ELEMENT_POLICY: -diff --git a/bus/config-parser-common.h b/bus/config-parser-common.h -index 186bf4c..6ea509c 100644 ---- a/bus/config-parser-common.h -+++ b/bus/config-parser-common.h -@@ -31,6 +31,7 @@ typedef enum - ELEMENT_INCLUDE, - ELEMENT_USER, - ELEMENT_LISTEN, -+ ELEMENT_LISTEN_IF_POSSIBLE, - ELEMENT_AUTH, - ELEMENT_POLICY, - ELEMENT_LIMIT, -diff --git a/bus/config-parser.c b/bus/config-parser.c -index 07e8fbb..fffc0e1 100644 ---- a/bus/config-parser.c -+++ b/bus/config-parser.c -@@ -96,6 +96,8 @@ struct BusConfigParser - - DBusList *listen_on; /**< List of addresses to listen to */ - -+ DBusList *listen_on_if_possible; /**< List of addresses to listen to, but continue on failure */ -+ - DBusList *mechanisms; /**< Auth mechanisms */ - - DBusList *service_dirs; /**< Directories to look for session services in */ -@@ -327,6 +329,9 @@ merge_included (BusConfigParser *parser, - while ((link = _dbus_list_pop_first_link (&included->listen_on))) - _dbus_list_append_link (&parser->listen_on, link); - -+ while ((link = _dbus_list_pop_first_link (&included->listen_on_if_possible))) -+ _dbus_list_append_link (&parser->listen_on_if_possible, link); -+ - while ((link = _dbus_list_pop_first_link (&included->mechanisms))) - _dbus_list_append_link (&parser->mechanisms, link); - -@@ -497,6 +502,12 @@ bus_config_parser_unref (BusConfigParser *parser) - - _dbus_list_clear (&parser->listen_on); - -+ _dbus_list_foreach (&parser->listen_on_if_possible, -+ (DBusForeachFunction) dbus_free, -+ NULL); -+ -+ _dbus_list_clear (&parser->listen_on_if_possible); -+ - _dbus_list_foreach (&parser->service_dirs, - (DBusForeachFunction) dbus_free, - NULL); -@@ -774,6 +785,19 @@ start_busconfig_child (BusConfigParser *parser, - - return TRUE; - } -+ else if (element_type == ELEMENT_LISTEN_IF_POSSIBLE) -+ { -+ if (!check_no_attributes (parser, "listen_if_possible", attribute_names, attribute_values, error)) -+ return FALSE; -+ -+ if (push_element (parser, ELEMENT_LISTEN_IF_POSSIBLE) == NULL) -+ { -+ BUS_SET_OOM (error); -+ return FALSE; -+ } -+ -+ return TRUE; -+ } - else if (element_type == ELEMENT_AUTH) - { - if (!check_no_attributes (parser, "auth", attribute_names, attribute_values, error)) -@@ -2018,6 +2042,7 @@ bus_config_parser_end_element (BusConfigParser *parser, - case ELEMENT_USER: - case ELEMENT_CONFIGTYPE: - case ELEMENT_LISTEN: -+ case ELEMENT_LISTEN_IF_POSSIBLE: - case ELEMENT_PIDFILE: - case ELEMENT_AUTH: - case ELEMENT_SERVICEDIR: -@@ -2518,6 +2543,24 @@ bus_config_parser_content (BusConfigParser *parser, - } - break; - -+ case ELEMENT_LISTEN_IF_POSSIBLE: -+ { -+ char *s; -+ -+ e->had_content = TRUE; -+ -+ if (!_dbus_string_copy_data (content, &s)) -+ goto nomem; -+ -+ if (!_dbus_list_append (&parser->listen_on_if_possible, -+ s)) -+ { -+ dbus_free (s); -+ goto nomem; -+ } -+ } -+ break; -+ - case ELEMENT_AUTH: - { - char *s; -@@ -2646,6 +2689,12 @@ bus_config_parser_get_addresses (BusConfigParser *parser) - } - - DBusList** -+bus_config_parser_get_addresses_if_possible (BusConfigParser *parser) -+{ -+ return &parser->listen_on_if_possible; -+} -+ -+DBusList** - bus_config_parser_get_mechanisms (BusConfigParser *parser) - { - return &parser->mechanisms; -@@ -3123,6 +3172,9 @@ config_parsers_equal (const BusConfigParser *a, - if (!lists_of_c_strings_equal (a->listen_on, b->listen_on)) - return FALSE; - -+ if (!lists_of_c_strings_equal (a->listen_on_if_possible, b->listen_on_if_possible)) -+ return FALSE; -+ - if (!lists_of_c_strings_equal (a->mechanisms, b->mechanisms)) - return FALSE; - -diff --git a/bus/config-parser.h b/bus/config-parser.h -index ba5bf74..f8a3c07 100644 ---- a/bus/config-parser.h -+++ b/bus/config-parser.h -@@ -61,6 +61,7 @@ dbus_bool_t bus_config_parser_finished (BusConfigParser *parser, - const char* bus_config_parser_get_user (BusConfigParser *parser); - const char* bus_config_parser_get_type (BusConfigParser *parser); - DBusList** bus_config_parser_get_addresses (BusConfigParser *parser); -+DBusList** bus_config_parser_get_addresses_if_possible (BusConfigParser *parser); - DBusList** bus_config_parser_get_mechanisms (BusConfigParser *parser); - dbus_bool_t bus_config_parser_get_fork (BusConfigParser *parser); - dbus_bool_t bus_config_parser_get_allow_anonymous (BusConfigParser *parser); -diff --git a/bus/connection.c b/bus/connection.c -index d69758c..2d68c84 100644 ---- a/bus/connection.c -+++ b/bus/connection.c -@@ -30,9 +30,16 @@ - #include "signals.h" - #include "expirelist.h" - #include "selinux.h" -+#include "driver-afbus.h" - #include <dbus/dbus-list.h> - #include <dbus/dbus-hash.h> - #include <dbus/dbus-timeout.h> -+#ifdef HAVE_AFBUS -+#include <dbus/dbus-transport-afbus.h> -+#endif -+ -+#include <sys/types.h> /* See NOTES */ -+#include <sys/socket.h> - - /* Trim executed commands to this length; we want to keep logs readable */ - #define MAX_LOG_COMMAND_LEN 50 -@@ -94,6 +101,13 @@ typedef struct - char *cached_loginfo_string; - BusSELinuxID *selinux_id; - -+ dbus_bool_t peer_address_set; -+ struct sockaddr_storage peer_address; -+ socklen_t peer_addrlen; -+ DBusConnection *proxy_connection; /**< If this is a compat connection, -+ proxy_connection is the proxy -+ connection to AF_BUS */ -+ - long connection_tv_sec; /**< Time when we connected (seconds component) */ - long connection_tv_usec; /**< Time when we connected (microsec component) */ - int stamp; /**< connections->stamp last time we were traversed */ -@@ -184,12 +198,33 @@ adjust_connections_for_uid (BusConnections *connections, - } - } - -+static DBusHandlerResult -+proxy_connection_message_filter (DBusConnection *connection, -+ DBusMessage *message, -+ void *user_data) -+{ -+ DBusConnection *source_connection = user_data; -+ -+ if (dbus_message_get_destination (message) == NULL && -+ dbus_message_is_signal (message, -+ DBUS_INTERFACE_LOCAL, -+ "Disconnected")) -+ { -+ dbus_connection_close (source_connection); -+ return DBUS_HANDLER_RESULT_HANDLED; -+ } -+ -+ dbus_connection_send (source_connection, message, NULL); -+ return DBUS_HANDLER_RESULT_HANDLED; -+} -+ - void - bus_connection_disconnected (DBusConnection *connection) - { - BusConnectionData *d; - BusService *service; - BusMatchmaker *matchmaker; -+ DBusError error; - - d = BUS_CONNECTION_DATA (connection); - _dbus_assert (d != NULL); -@@ -197,6 +232,20 @@ bus_connection_disconnected (DBusConnection *connection) - _dbus_verbose ("%s disconnected, dropping all service ownership and releasing\n", - d->name ? d->name : "(inactive)"); - -+ if (d->proxy_connection) -+ { -+ dbus_connection_remove_filter (d->proxy_connection, -+ proxy_connection_message_filter, connection); -+ dbus_connection_close (d->proxy_connection); -+ dbus_connection_unref (d->proxy_connection); -+ d->proxy_connection = NULL; -+ } -+ -+ dbus_error_init (&error); -+ -+ if (!bus_driver_afbus_disconnected(connection, &error)) -+ dbus_error_free (&error); -+ - /* Delete our match rules */ - if (d->n_match_rules > 0) - { -@@ -309,6 +358,18 @@ bus_connection_disconnected (DBusConnection *connection) - dbus_connection_unref (connection); - } - -+DBusConnection * -+bus_connection_get_proxy_connection (DBusConnection *connection) -+{ -+ BusConnectionData *d; -+ -+ d = BUS_CONNECTION_DATA (connection); -+ -+ _dbus_assert (d != NULL); -+ -+ return d->proxy_connection; -+} -+ - static dbus_bool_t - add_connection_watch (DBusWatch *watch, - void *data) -@@ -588,6 +649,52 @@ oom: - return FALSE; - } - -+#ifdef HAVE_AFBUS -+static dbus_bool_t -+bus_connections_setup_proxy_connection (BusConnections *connections, -+ DBusConnection *connection, -+ const char *main_address) -+{ -+ BusConnectionData *d = BUS_CONNECTION_DATA (connection); -+ DBusError error; -+ dbus_bool_t retval = FALSE; -+ -+ dbus_error_init (&error); -+ -+ d->proxy_connection -+ = dbus_connection_open_private (main_address, &error); -+ if (dbus_error_is_set (&error)) -+ { -+ dbus_error_free (&error); -+ goto out; -+ } -+ -+ dbus_connection_set_route_peer_messages (d->proxy_connection, TRUE); -+ -+ dbus_connection_set_dispatch_status_function (d->proxy_connection, -+ dispatch_status_function, -+ bus_context_get_loop (connections->context), NULL); -+ -+ if (!dbus_connection_add_filter(d->proxy_connection, -+ proxy_connection_message_filter, connection, NULL)) -+ goto out; -+ -+ -+ if (!dbus_connection_set_watch_functions (d->proxy_connection, -+ add_connection_watch, -+ remove_connection_watch, -+ toggle_connection_watch, -+ connection, -+ NULL)) -+ goto out; -+ -+ return TRUE; -+ -+out: -+ return retval; -+} -+#endif -+ - dbus_bool_t - bus_connections_setup_connection (BusConnections *connections, - DBusConnection *connection) -@@ -596,7 +703,6 @@ bus_connections_setup_connection (BusConnections *connections, - BusConnectionData *d; - dbus_bool_t retval; - DBusError error; -- - - d = dbus_new0 (BusConnectionData, 1); - -@@ -622,8 +728,32 @@ bus_connections_setup_connection (BusConnections *connections, - dbus_connection_set_route_peer_messages (connection, TRUE); - - retval = FALSE; -- - dbus_error_init (&error); -+ -+#ifdef HAVE_AFBUS -+ d->peer_addrlen = sizeof(d->peer_address); -+ d->peer_address_set = dbus_connection_get_peer_address (connection, -+ &d->peer_address, (long int *)&d->peer_addrlen); -+ -+ /* If this connection is not AF_BUS, and we have a AF_BUS -+ * server, we are in compat mode and we need to setup a -+ * new connection */ -+ if (d->peer_address_set && -+ ((struct sockaddr *)&d->peer_address)->sa_family != AF_BUS) -+ { -+ const char *main_address; -+ main_address = bus_context_get_main_address (connections->context); -+ if (main_address && main_address[0] != '\0') -+ { -+ if (!bus_connections_setup_proxy_connection (connections, connection, -+ main_address)) -+ { -+ goto out; -+ } -+ } -+ } -+#endif -+ - d->selinux_id = bus_selinux_init_connection_id (connection, - &error); - if (dbus_error_is_set (&error)) -@@ -2383,3 +2513,21 @@ bus_connection_get_peak_bus_names (DBusConnection *connection) - return d->peak_bus_names; - } - #endif /* DBUS_ENABLE_STATS */ -+ -+int -+bus_connection_get_peer_address (DBusConnection *connection, -+ struct sockaddr **peer_address, -+ socklen_t *peer_addrlen) -+{ -+ BusConnectionData *d; -+ -+ d = BUS_CONNECTION_DATA (connection); -+ -+ if (!d->peer_address_set) -+ return FALSE; -+ -+ *peer_address = (struct sockaddr *) &d->peer_address; -+ *peer_addrlen = d->peer_addrlen; -+ -+ return TRUE; -+} -diff --git a/bus/connection.h b/bus/connection.h -index c936021..95856f3 100644 ---- a/bus/connection.h -+++ b/bus/connection.h -@@ -24,6 +24,8 @@ - #ifndef BUS_CONNECTION_H - #define BUS_CONNECTION_H - -+#include <sys/types.h> -+#include <sys/socket.h> - #include <dbus/dbus.h> - #include <dbus/dbus-list.h> - #include "bus.h" -@@ -103,8 +105,9 @@ dbus_bool_t bus_connection_complete (DBusConnection *connection, - const DBusString *name, - DBusError *error); - --/* called by dispatch.c when the connection is dropped */ --void bus_connection_disconnected (DBusConnection *connection); -+/* called by dispatch.c */ -+void bus_connection_disconnected (DBusConnection *connection); -+DBusConnection *bus_connection_get_proxy_connection (DBusConnection *connection); - - dbus_bool_t bus_connection_is_in_unix_group (DBusConnection *connection, - unsigned long gid); -@@ -151,4 +154,9 @@ int bus_connections_get_peak_bus_names_per_conn (BusConnections *connections); - int bus_connection_get_peak_match_rules (DBusConnection *connection); - int bus_connection_get_peak_bus_names (DBusConnection *connection); - -+/* called by driver-afbus.c */ -+int bus_connection_get_peer_address (DBusConnection *connection, -+ struct sockaddr **peer_address, -+ socklen_t *peer_addrlen); -+ - #endif /* BUS_CONNECTION_H */ -diff --git a/bus/dispatch.c b/bus/dispatch.c -index 7a96f9d..4feae05 100644 ---- a/bus/dispatch.c -+++ b/bus/dispatch.c -@@ -27,6 +27,7 @@ - #include "dispatch.h" - #include "connection.h" - #include "driver.h" -+#include "driver-afbus.h" - #include "services.h" - #include "activation.h" - #include "utils.h" -@@ -129,6 +130,18 @@ bus_dispatch_matches (BusTransaction *transaction, - BUS_SET_OOM (error); - return FALSE; - } -+ -+ /* If using AF_BUS and the message came to the daemon, the client sending -+ * the message doesn't yet know the address for this service, so notify -+ * it of the address associated with the service. */ -+ if (!bus_driver_afbus_emit_forwarded (transaction, -+ sender, -+ addressed_recipient, -+ dbus_message_get_destination (message))) -+ { -+ _dbus_verbose ("bus_driver_afbus_emit_forwarded() failed\n"); -+ return FALSE; -+ } - } - - /* Now dispatch to others who look interested in this message */ -@@ -180,6 +193,7 @@ bus_dispatch (DBusConnection *connection, - BusContext *context; - DBusHandlerResult result; - DBusConnection *addressed_recipient; -+ DBusConnection *proxy_connection; - - result = DBUS_HANDLER_RESULT_HANDLED; - -@@ -241,6 +255,15 @@ bus_dispatch (DBusConnection *connection, - } - } - -+ /* Directly send the message to the proxy without analysing it */ -+ proxy_connection = bus_connection_get_proxy_connection (connection); -+ if (proxy_connection) -+ { -+ if (!dbus_connection_send (proxy_connection, message, NULL)) -+ BUS_SET_OOM (&error); -+ goto out; -+ } -+ - /* Create our transaction */ - transaction = bus_transaction_new (context); - if (transaction == NULL) -diff --git a/bus/driver-afbus.c b/bus/driver-afbus.c -new file mode 100644 -index 0000000..70edafb ---- /dev/null -+++ b/bus/driver-afbus.c -@@ -0,0 +1,345 @@ -+/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ -+/* driver.c Bus client, AF_BUS bits (driver) -+ * -+ * Copyright (C) 2012 Collabora Ltd -+ * -+ * Licensed under the Academic Free License version 2.1 -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License as published by -+ * the Free Software Foundation; either version 2 of the License, or -+ * (at your option) any later version. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this program; if not, write to the Free Software -+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -+ * -+ */ -+ -+#include <config.h> -+ -+#include "driver-afbus.h" -+ -+#include <unistd.h> -+#include <sys/types.h> -+#include <sys/socket.h> -+#include <asm/types.h> -+#include <errno.h> -+#include <linux/netlink.h> -+#include <linux/rtnetlink.h> -+#include <linux/connector.h> -+#include <dbus/dbus-transport-afbus.h> -+ -+#define CN_IDX_NFDBUS 0xA /* netfilter D-Bus */ -+#define CN_VAL_NFDBUS 0x1 -+ -+#define NFDBUS_CMD_ADDMATCH 0x01 -+#define NFDBUS_CMD_REMOVEMATCH 0x02 -+#define NFDBUS_CMD_REMOVEALLMATCH 0x03 -+ -+struct nfdbus_nl_cfg_req { -+ __u32 cmd; -+ __u32 len; -+ struct sockaddr_bus addr; -+ __u64 pad; -+ unsigned char data[0]; -+}; -+ -+struct nfdbus_nl_cfg_reply { -+ __u32 ret_code; -+}; -+ -+static int -+ensure_nl_sock(DBusError *error) -+{ -+ static int nlsock = 0; -+ -+ struct sockaddr_nl l_local; -+ int fd; -+ int ret; -+ -+ if (nlsock > 0) -+ return nlsock; -+ -+ fd = socket(PF_NETLINK, SOCK_DGRAM, NETLINK_CONNECTOR); -+ if (fd == -1) { -+ dbus_set_error (error, DBUS_ERROR_NETLINK, -+ "Couldn't use the netlink socket: %s", -+ strerror(errno)); -+ return -1; -+ } -+ -+ if (!_dbus_set_fd_nonblocking (fd, error)) -+ { -+ _dbus_close_socket (fd, NULL); -+ return -1; -+ } -+ -+ l_local.nl_family = AF_NETLINK; -+ l_local.nl_groups = 0; -+ l_local.nl_pid = 0; -+ ret = bind(fd, (struct sockaddr *)&l_local, sizeof(struct sockaddr_nl)); -+ if (ret == -1) { -+ close(fd); -+ dbus_set_error (error, DBUS_ERROR_NETLINK, -+ "Couldn't bind the netlink socket: %s", -+ strerror(errno)); -+ return -1; -+ } -+ -+ nlsock = fd; -+ return nlsock; -+} -+ -+static int netlink_send(int nlsock, struct cn_msg *msg, int seq) -+{ -+ struct nlmsghdr *nlh; -+ unsigned int size; -+ char buf[4096]; -+ struct cn_msg *m; -+ -+ size = NLMSG_SPACE(sizeof(struct cn_msg) + msg->len); -+ -+ nlh = (struct nlmsghdr *)buf; -+ nlh->nlmsg_seq = seq; -+ nlh->nlmsg_pid = getpid(); -+ nlh->nlmsg_type = NLMSG_DONE; -+ nlh->nlmsg_len = NLMSG_LENGTH(size - sizeof(*nlh)); -+ nlh->nlmsg_flags = 0; -+ -+ m = NLMSG_DATA(nlh); -+ memcpy(m, msg, sizeof(*m) + msg->len); -+ -+ return send(nlsock, nlh, size, 0); -+} -+ -+static dbus_bool_t -+bus_driver_afbus_upload_match_rule (DBusConnection *connection, -+ const char *rule, -+ int cmd, -+ DBusError *error) -+{ -+ static int seq; -+ -+ int nlsock; -+ int ret; -+ -+ char buf[sizeof(struct cn_msg) + sizeof(struct nfdbus_nl_cfg_req) + 1024]; -+ -+ struct cn_msg *data; -+ struct nlmsghdr *reply; -+ struct nfdbus_nl_cfg_req *req; -+ //struct nfdbus_nl_cfg_reply *req_reply; -+ -+ struct sockaddr_storage *address; -+ socklen_t addrlen = sizeof(address); -+ -+ if (!bus_connection_get_peer_address(connection, -+ (struct sockaddr **) &address, &addrlen)) -+ return TRUE; -+ -+ if (((struct sockaddr*)address)->sa_family != AF_BUS) -+ return TRUE; -+ -+ nlsock = ensure_nl_sock (error); -+ if (nlsock == -1) -+ return FALSE; -+ -+ memset(buf, 0, sizeof(buf)); -+ -+ data = (struct cn_msg *)buf; -+ -+ data->id.idx = CN_IDX_NFDBUS; -+ data->id.val = CN_VAL_NFDBUS; -+ data->seq = seq++; -+ data->ack = 0; -+ data->len = sizeof(struct nfdbus_nl_cfg_req) + strlen(rule) + 1; -+ req = (struct nfdbus_nl_cfg_req *) data->data; -+ -+ req->cmd = cmd; -+ req->len = strlen(rule) + 1; -+ req->addr = *(struct sockaddr_bus *)address; -+ strcpy((char *)req->data, rule); -+ -+ ret = netlink_send(nlsock, data, seq++); -+ if (ret <= 0) -+ { -+ } -+ -+ memset(buf, 0, sizeof(buf)); -+ ret = recv(nlsock, buf, sizeof(buf), 0); -+ if (ret <= 0) -+ { -+ } -+ -+ reply = (struct nlmsghdr *)buf; -+ if (reply->nlmsg_type != NLMSG_DONE) -+ { -+ } -+ -+ return TRUE; -+} -+ -+dbus_bool_t -+bus_driver_afbus_add_match_rule (DBusConnection *connection, -+ const char *rule, -+ DBusError *error) -+{ -+ if (bus_driver_afbus_upload_match_rule (connection, rule, NFDBUS_CMD_ADDMATCH, error)) -+ { -+ /* Check if the match rule is for eavesdropping, and set the socket -+ * to allow receiving all messages if so */ -+ if (strstr (rule, "eavesdrop=true")) -+ { -+ int fd; -+ -+ if (dbus_connection_get_socket (connection, &fd)) -+ { -+ if (setsockopt (fd, SOL_BUS, BUS_SET_EAVESDROP, NULL, 0) == 0) -+ return TRUE; -+ else -+ { -+ dbus_set_error (error, -+ _dbus_error_from_errno (errno), -+ "Failed to setsockopt on socket %d: %s", -+ fd, _dbus_strerror (errno)); -+ } -+ } -+ else -+ dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL); -+ } -+ else -+ return TRUE; -+ } -+ -+ return FALSE; -+} -+ -+dbus_bool_t -+bus_driver_afbus_remove_match_rule (DBusConnection *connection, -+ const char *rule, -+ DBusError *error) -+{ -+ return bus_driver_afbus_upload_match_rule (connection, rule, NFDBUS_CMD_REMOVEMATCH, error); -+} -+ -+dbus_bool_t -+bus_driver_afbus_append_unique_name (DBusConnection *connection, -+ DBusString *str) -+{ -+ struct sockaddr_bus address; -+ long len = sizeof(address); -+ -+ memset (&address, 0, sizeof (address)); -+ if (!dbus_connection_get_peer_address(connection, &address, &len) || -+ address.sbus_family != AF_BUS) -+ return FALSE; -+ -+ if (!_dbus_string_append (str, "AF-BUS.")) -+ return FALSE; -+ -+ if (!_dbus_string_append_uint (str, address.sbus_addr.s_addr)) -+ return FALSE; -+ -+ return TRUE; -+} -+ -+dbus_bool_t -+bus_driver_afbus_emit_forwarded (BusTransaction *transaction, -+ DBusConnection *connection, -+ DBusConnection *addressed_recipient, -+ const char *service_name) -+{ -+ struct sockaddr_bus address; -+ long len = sizeof (address); -+ DBusMessage *message; -+ dbus_bool_t result = FALSE; -+ -+ memset (&address, 0, sizeof (address)); -+ if (!dbus_connection_get_peer_address (addressed_recipient, &address, &len) || -+ address.sbus_family != AF_BUS) -+ { -+ /* Don't return an error if it is not a AF_BUS socket */ -+ return TRUE; -+ } -+ -+ /* Prepare the message to be sent */ -+ message = dbus_message_new_signal (DBUS_PATH_AFBUS, -+ DBUS_INTERFACE_AFBUS, -+ "Forwarded"); -+ if (message == NULL) -+ { -+ _dbus_verbose ("Could not allocate AF_BUS.Forwarded signal message\n"); -+ return FALSE; -+ } -+ -+ if (!dbus_message_set_sender (message, DBUS_SERVICE_DBUS)) -+ { -+ _dbus_verbose ("Could not set sender for AF_BUS.Forwarded signal message\n"); -+ goto out; -+ } -+ -+ if (!dbus_message_append_args (message, -+ DBUS_TYPE_STRING, &service_name, -+ DBUS_TYPE_UINT64, &address.sbus_addr.s_addr, -+ DBUS_TYPE_INVALID)) -+ { -+ _dbus_verbose ("Could not append arguments for AF_BUS.Forwarded signal message\n"); -+ goto out; -+ } -+ -+ if (bus_transaction_send (transaction, connection, message)) -+ result = TRUE; -+ else -+ _dbus_verbose ("Could not send AF_BUS.Forwarded signal message\n"); -+ -+ out: -+ dbus_message_unref (message); -+ -+ return result; -+} -+ -+dbus_bool_t -+bus_driver_afbus_assign_address (DBusConnection *connection) -+{ -+ struct sockaddr_bus address; -+ long len = sizeof (address); -+ int fd; -+ static dbus_uint64_t next_address = 0x1111000000000001ULL; -+ -+ memset (&address, 0, sizeof (address)); -+ if (!dbus_connection_get_peer_address (connection, &address, &len) || -+ ((struct sockaddr *) &address)->sa_family != AF_BUS) -+ { -+ /* Don't return an error if it is not a AF_BUS socket */ -+ return TRUE; -+ } -+ -+ if (!dbus_connection_get_unix_fd (connection, &fd)) -+ { -+ return FALSE; -+ } -+ -+ address.sbus_addr.s_addr = next_address; -+ if (setsockopt (fd, SOL_BUS, BUS_ADD_ADDR, &address, sizeof (address)) != 0) -+ { -+ return FALSE; -+ } -+ -+ next_address++; -+ -+ return TRUE; -+} -+ -+dbus_bool_t -+bus_driver_afbus_disconnected (DBusConnection *connection, -+ DBusError *error) -+{ -+ return bus_driver_afbus_upload_match_rule (connection, "", -+ NFDBUS_CMD_REMOVEALLMATCH, error); -+} -diff --git a/bus/driver-afbus.h b/bus/driver-afbus.h -new file mode 100644 -index 0000000..9c40111 ---- /dev/null -+++ b/bus/driver-afbus.h -@@ -0,0 +1,96 @@ -+/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ -+/* driver-afbus.h Bus client, AF_BUS bits (driver) -+ * -+ * Copyright (C) 2012 Collabora Ltd -+ * -+ * Licensed under the Academic Free License version 2.1 -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License as published by -+ * the Free Software Foundation; either version 2 of the License, or -+ * (at your option) any later version. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this program; if not, write to the Free Software -+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -+ * -+ */ -+ -+#ifndef BUS_DRIVER_AFBUS_H -+#define BUS_DRIVER_AFBUS_H -+ -+#include <config.h> -+#include <sys/socket.h> -+#include <dbus/dbus.h> -+#include "connection.h" -+ -+#if HAVE_AFBUS -+dbus_bool_t bus_driver_afbus_add_match_rule (DBusConnection *connection, -+ const char *rule, -+ DBusError *error); -+dbus_bool_t bus_driver_afbus_remove_match_rule (DBusConnection *connection, -+ const char *rule, -+ DBusError *error); -+dbus_bool_t bus_driver_afbus_append_unique_name (DBusConnection *connection, -+ DBusString *str); -+dbus_bool_t bus_driver_afbus_emit_forwarded (BusTransaction *transaction, -+ DBusConnection *connection, -+ DBusConnection *addressed_recipient, -+ const char *service_name); -+dbus_bool_t bus_driver_afbus_assign_address (DBusConnection *connection); -+dbus_bool_t bus_driver_afbus_disconnected (DBusConnection *connection, -+ DBusError *error); -+#else -+static inline -+dbus_bool_t bus_driver_afbus_add_match_rule (DBusConnection *connection, -+ const char *rule, -+ DBusError *error) -+{ -+ return TRUE; -+} -+ -+static inline -+dbus_bool_t bus_driver_afbus_remove_match_rule (DBusConnection *connection, -+ const char *rule, -+ DBusError *error) -+{ -+ return TRUE; -+} -+ -+static inline -+dbus_bool_t bus_driver_afbus_append_unique_name (DBusConnection *connection, -+ DBusString *str) -+{ -+ return TRUE; -+} -+ -+static inline -+dbus_bool_t bus_driver_afbus_emit_forwarded (BusTransaction *transaction, -+ DBusConnection *connection, -+ DBusConnection *addressed_recipient, -+ const char *service_name) -+{ -+ return TRUE; -+} -+ -+static inline -+dbus_bool_t bus_driver_afbus_assign_address (DBusConnection *connection) -+{ -+ return TRUE; -+} -+ -+static inline -+dbus_bool_t bus_driver_afbus_disconnected (DBusConnection *connection, -+ DBusError *error) -+{ -+ return TRUE; -+} -+ -+#endif -+ -+#endif /* BUS_DRIVER_AFBUS_H */ -diff --git a/bus/driver.c b/bus/driver.c -index 574e0f3..11767c8 100644 ---- a/bus/driver.c -+++ b/bus/driver.c -@@ -26,6 +26,7 @@ - #include "activation.h" - #include "connection.h" - #include "driver.h" -+#include "driver-afbus.h" - #include "dispatch.h" - #include "services.h" - #include "selinux.h" -@@ -182,8 +183,9 @@ bus_driver_send_service_acquired (DBusConnection *connection, - } - - static dbus_bool_t --create_unique_client_name (BusRegistry *registry, -- DBusString *str) -+create_unique_client_name (DBusConnection *connection, -+ BusRegistry *registry, -+ DBusString *str) - { - /* We never want to use the same unique client name twice, because - * we want to guarantee that if you send a message to a given unique -@@ -214,19 +216,23 @@ create_unique_client_name (BusRegistry *registry, - _dbus_assert (next_major_number > 0); - _dbus_assert (next_minor_number >= 0); - -- /* appname:MAJOR-MINOR */ -+ /* unique name: -+ * :[AF-BUS.BUS-ADDRESS.]MAJOR.MINOR */ - - if (!_dbus_string_append (str, ":")) - return FALSE; - -- if (!_dbus_string_append_int (str, next_major_number)) -- return FALSE; -+ if (!bus_driver_afbus_append_unique_name (connection, str)) -+ { -+ if (!_dbus_string_append_int (str, next_major_number)) -+ return FALSE; - -- if (!_dbus_string_append (str, ".")) -- return FALSE; -+ if (!_dbus_string_append (str, ".")) -+ return FALSE; - -- if (!_dbus_string_append_int (str, next_minor_number)) -- return FALSE; -+ if (!_dbus_string_append_int (str, next_minor_number)) -+ return FALSE; -+ } - - next_minor_number += 1; - -@@ -287,7 +293,7 @@ bus_driver_handle_hello (DBusConnection *connection, - - registry = bus_connection_get_registry (connection); - -- if (!create_unique_client_name (registry, &unique_name)) -+ if (!create_unique_client_name (connection, registry, &unique_name)) - { - BUS_SET_OOM (error); - goto out_0; -@@ -610,6 +616,13 @@ bus_driver_handle_acquire_service (DBusConnection *connection, - goto out; - } - -+ /* If using AF_BUS, assign an address to this peer */ -+ if (!bus_driver_afbus_assign_address (connection)) -+ { -+ BUS_SET_OOM (error); -+ goto out; -+ } -+ - retval = TRUE; - - out: -@@ -988,6 +1001,9 @@ bus_driver_handle_add_match (DBusConnection *connection, - if (rule == NULL) - goto failed; - -+ if (!bus_driver_afbus_add_match_rule (connection, text, error)) -+ goto failed; -+ - matchmaker = bus_connection_get_matchmaker (connection); - - if (!bus_matchmaker_add_rule (matchmaker, rule)) -@@ -1051,6 +1067,9 @@ bus_driver_handle_remove_match (DBusConnection *connection, - message, error)) - goto failed; - -+ if (!bus_driver_afbus_remove_match_rule (connection, text, error)) -+ goto failed; -+ - matchmaker = bus_connection_get_matchmaker (connection); - - if (!bus_matchmaker_remove_rule_by_value (matchmaker, rule, error)) -@@ -1779,6 +1798,13 @@ static InterfaceHandler interface_handlers[] = { - { DBUS_INTERFACE_INTROSPECTABLE, introspectable_message_handlers, NULL }, - #ifdef DBUS_ENABLE_STATS - { BUS_INTERFACE_STATS, stats_message_handlers, NULL }, -+#ifdef HAVE_AFBUS -+ { DBUS_INTERFACE_AFBUS, NULL, -+ " <signal name=\"AF_BUS.Forwarded\">\n" -+ " <arg type=\"s\"/>\n" -+ " <arg type=\"t\"/>\n" -+ " </signal>\n" }, -+#endif - #endif - { NULL, NULL, NULL } - }; -diff --git a/bus/session.conf.in b/bus/session.conf.in -index e121ff9..09a7ecf 100644 ---- a/bus/session.conf.in -+++ b/bus/session.conf.in -@@ -12,7 +12,8 @@ - the behavior of child processes. --> - <keep_umask/> - -- <listen>@DBUS_SESSION_BUS_DEFAULT_ADDRESS@</listen> -+ <listen_if_possible>afbus:tmpdir=/tmp</listen_if_possible> -+ <listen>unix:tmpdir=/tmp</listen> - - <standard_session_servicedirs /> - -diff --git a/bus/system.conf.in b/bus/system.conf.in -index 92f4cc4..515509f 100644 ---- a/bus/system.conf.in -+++ b/bus/system.conf.in -@@ -39,6 +39,7 @@ - means use abstract namespace, don't really create filesystem - file; only Linux supports this. Use path=/whatever on other - systems.) --> -+ <listen_if_possible>afbus:@DBUS_SYSTEM_SOCKET@.afbus</listen_if_possible> - <listen>@DBUS_SYSTEM_BUS_DEFAULT_ADDRESS@</listen> - - <policy context="default"> -diff --git a/configure.ac b/configure.ac -index 4f86e9d..51a48fd 100644 ---- a/configure.ac -+++ b/configure.ac -@@ -1509,6 +1509,20 @@ if test "x$with_systemdsystemunitdir" != xno; then - fi - AM_CONDITIONAL(HAVE_SYSTEMD, [test -n "$with_systemdsystemunitdir" -a "x$with_systemdsystemunitdir" != xno ]) - -+## Check for AF_DBUS -+AC_MSG_CHECKING([for AF_BUS socket family]) -+AC_COMPILE_IFELSE( -+ [AC_LANG_PROGRAM( -+ [[#include <sys/socket.h>]], -+ [[return socket (PF_BUS, SOCK_STREAM, 0);]])], -+ [have_afbus=yes], -+ [have_afbus=no]) -+AC_MSG_RESULT([$have_afbus]) -+if test "x$have_afbus" = "xyes"; then -+ AC_DEFINE(HAVE_AFBUS, 1, [Define if AF_BUS is available]) -+fi -+AM_CONDITIONAL(HAVE_AFBUS, test "x$have_afbus" = "xyes") -+ - ##### Set up location for system bus socket - if ! test -z "$with_system_socket"; then - DBUS_SYSTEM_SOCKET=$with_system_socket -@@ -1648,7 +1662,11 @@ AC_SUBST(TEST_SOCKET_DIR) - AC_DEFINE_UNQUOTED(DBUS_TEST_SOCKET_DIR, "$TEST_SOCKET_DIR", [Where to put test sockets]) - - if test "x$dbus_unix" = xyes; then -- TEST_LISTEN="unix:tmpdir=$TEST_SOCKET_DIR" -+ if test "x$have_afbus" = "xyes"; then -+ TEST_LISTEN="afbus:tmpdir=$TEST_SOCKET_DIR" -+ else -+ TEST_LISTEN="unix:tmpdir=$TEST_SOCKET_DIR" -+ fi - else - TEST_LISTEN="tcp:host=localhost" - fi -@@ -1668,6 +1686,8 @@ if test x$dbus_win = xyes; then - DBUS_SESSION_BUS_DEFAULT_ADDRESS="$with_dbus_session_bus_default_address" - elif test x$have_launchd = xyes; then - DBUS_SESSION_BUS_DEFAULT_ADDRESS="launchd:env=DBUS_LAUNCHD_SESSION_BUS_SOCKET" -+elif test x$have_afbus = xyes; then -+ DBUS_SESSION_BUS_DEFAULT_ADDRESS="afbus:tmpdir=$DBUS_SESSION_SOCKET_DIR" - else - DBUS_SESSION_BUS_DEFAULT_ADDRESS="unix:tmpdir=$DBUS_SESSION_SOCKET_DIR" - fi -diff --git a/dbus/Makefile.am b/dbus/Makefile.am -index bb5ccca..b925419 100644 ---- a/dbus/Makefile.am -+++ b/dbus/Makefile.am -@@ -87,6 +87,16 @@ else - launchd_source = - endif - -+if HAVE_AFBUS -+afbus_source = \ -+ dbus-server-afbus.c \ -+ dbus-server-afbus.h \ -+ dbus-transport-afbus.c \ -+ dbus-transport-afbus.h -+else -+afbus_source = -+endif -+ - DBUS_LIB_arch_sources = \ - dbus-uuidgen.c \ - dbus-uuidgen.h \ -@@ -95,6 +105,7 @@ DBUS_LIB_arch_sources = \ - - DBUS_SHARED_arch_sources = \ - $(launchd_source) \ -+ $(afbus_source) \ - dbus-file-unix.c \ - dbus-pipe-unix.c \ - dbus-sysdeps-unix.c \ -diff --git a/dbus/dbus-connection.c b/dbus/dbus-connection.c -index ee33b6c..5f3a459 100644 ---- a/dbus/dbus-connection.c -+++ b/dbus/dbus-connection.c -@@ -45,6 +45,8 @@ - #include "dbus-bus.h" - #include "dbus-marshal-basic.h" - -+#include <sys/socket.h> -+ - #ifdef DBUS_DISABLE_CHECKS - #define TOOK_LOCK_CHECK(connection) - #define RELEASING_LOCK_CHECK(connection) -@@ -2054,9 +2056,15 @@ _dbus_connection_send_preallocated_and_unlock (DBusConnection *connection, - dbus_uint32_t *client_serial) - { - DBusDispatchStatus status; -+ const char *sender; - - HAVE_LOCK_CHECK (connection); -- -+ -+ /* Set the sender field */ -+ sender = dbus_bus_get_unique_name (connection); -+ if (sender) -+ dbus_message_set_sender (message, sender); -+ - _dbus_connection_send_preallocated_unlocked_no_update (connection, - preallocated, - message, client_serial); -@@ -3359,6 +3367,7 @@ dbus_connection_send_with_reply (DBusConnection *connection, - DBusPendingCall *pending; - dbus_int32_t serial = -1; - DBusDispatchStatus status; -+ const char *sender; - - _dbus_return_val_if_fail (connection != NULL, FALSE); - _dbus_return_val_if_fail (message != NULL, FALSE); -@@ -3401,6 +3410,11 @@ dbus_connection_send_with_reply (DBusConnection *connection, - return FALSE; - } - -+ /* Set the sender field */ -+ sender = dbus_bus_get_unique_name (connection); -+ if (sender) -+ dbus_message_set_sender (message, sender); -+ - /* Assign a serial to the message */ - serial = dbus_message_get_serial (message); - if (serial == 0) -@@ -5439,6 +5453,27 @@ dbus_connection_set_route_peer_messages (DBusConnection *connection, - CONNECTION_UNLOCK (connection); - } - -+dbus_bool_t -+dbus_connection_get_peer_address (DBusConnection *connection, -+ void *addr, -+ long *len) -+{ -+ dbus_bool_t res; -+ int fd; -+ socklen_t _len = *len; -+ -+ _dbus_return_val_if_fail (connection != NULL, FALSE); -+ -+ res = _dbus_transport_get_socket_fd (connection->transport, &fd); -+ if (!res) -+ return res; -+ -+ res = getpeername(fd, (struct sockaddr *) addr, &_len) == 0; -+ if (res) -+ *len = _len; -+ return res; -+} -+ - /** - * Adds a message filter. Filters are handlers that are run on all - * incoming messages, prior to the objects registered with -diff --git a/dbus/dbus-connection.h b/dbus/dbus-connection.h -index fe4d04e..81fe9f1 100644 ---- a/dbus/dbus-connection.h -+++ b/dbus/dbus-connection.h -@@ -287,6 +287,10 @@ void dbus_connection_set_allow_anonymous (DBusConnection - DBUS_EXPORT - void dbus_connection_set_route_peer_messages (DBusConnection *connection, - dbus_bool_t value); -+DBUS_EXPORT -+dbus_bool_t dbus_connection_get_peer_address (DBusConnection *connection, -+ void *addr, -+ long *len); - - - /* Filters */ -diff --git a/dbus/dbus-protocol.h b/dbus/dbus-protocol.h -index 60605ab..71c2870 100644 ---- a/dbus/dbus-protocol.h -+++ b/dbus/dbus-protocol.h -@@ -458,6 +458,12 @@ extern "C" { - /** XML document type declaration of the introspection format version 1.0 */ - #define DBUS_INTROSPECT_1_0_XML_DOCTYPE_DECL_NODE "<!DOCTYPE node PUBLIC \"" DBUS_INTROSPECT_1_0_XML_PUBLIC_IDENTIFIER "\"\n\"" DBUS_INTROSPECT_1_0_XML_SYSTEM_IDENTIFIER "\">\n" - -+/* AF_BUS errors */ -+ -+/** Tried to use a netlink socket and it failed. */ -+#define DBUS_ERROR_NETLINK "org.freedesktop.DBus.Error.NetLink" -+#define DBUS_ERROR_MULTIPLE_AFBUS "org.freedesktop.DBus.Error.MultipleAFBUS" -+ - /** @} */ - - #ifdef __cplusplus -diff --git a/dbus/dbus-server-afbus.c b/dbus/dbus-server-afbus.c -new file mode 100644 -index 0000000..1d8e9bd ---- /dev/null -+++ b/dbus/dbus-server-afbus.c -@@ -0,0 +1,397 @@ -+/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ -+/* dbus-server-unix.c Server implementation for Unix network protocols. -+ * -+ * Copyright (C) 2012 Collabora Ltd -+ * -+ * Licensed under the Academic Free License version 2.1 -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License as published by -+ * the Free Software Foundation; either version 2 of the License, or -+ * (at your option) any later version. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this program; if not, write to the Free Software -+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -+ * -+ */ -+ -+#include <config.h> -+#include <errno.h> -+#include <sys/socket.h> -+#include "dbus-connection-internal.h" -+#include "dbus-server-afbus.h" -+#include "dbus-server-protected.h" -+#include "dbus-string.h" -+#include "dbus-sysdeps.h" -+#include "dbus-transport.h" -+#include "dbus-transport-afbus.h" -+ -+/** -+ * @defgroup DBusServerAfbus DBusServer implementation for AF_BUS sockets -+ * @ingroup DBusInternals -+ * @brief Implementation details of DBusServer for AF_BUS sockets -+ * -+ * @{ -+ */ -+/** -+ * Opaque object representing a AF_BUS-based server implementation. -+ */ -+typedef struct DBusServerAfbus DBusServerAfbus; -+ -+/** -+ * Implementation details of DBusServerAfbus. All members -+ * are private. -+ */ -+struct DBusServerAfbus -+{ -+ DBusServer base; /**< Parent class members. */ -+ int fd; /**< File descriptor. */ -+ DBusWatch *watch; /**< File descriptor watch. */ -+ DBusString address; /**< The server address */ -+}; -+ -+static void -+afbus_finalize (DBusServer *server) -+{ -+ DBusServerAfbus *afbus_server = (DBusServerAfbus *) server; -+ -+ _dbus_server_finalize_base (server); -+ -+ if (afbus_server->watch != NULL) -+ { -+ _dbus_watch_unref (afbus_server->watch); -+ afbus_server->watch = NULL; -+ } -+ -+ dbus_free (server); -+} -+ -+static void -+afbus_disconnect (DBusServer *server) -+{ -+ DBusServerAfbus *afbus_server = (DBusServerAfbus *) server; -+ -+ HAVE_LOCK_CHECK (server); -+ -+ if (afbus_server->watch) -+ { -+ _dbus_server_remove_watch (server, afbus_server->watch); -+ _dbus_watch_invalidate (afbus_server->watch); -+ _dbus_watch_unref (afbus_server->watch); -+ afbus_server->watch = NULL; -+ } -+ -+ _dbus_close_socket (afbus_server->fd, NULL); -+ afbus_server->fd = -1; -+ -+ HAVE_LOCK_CHECK (server); -+} -+ -+static const DBusServerVTable afbus_vtable = { -+ afbus_finalize, -+ afbus_disconnect -+}; -+ -+static dbus_bool_t -+handle_new_client (DBusServer *server, -+ int client_fd) -+{ -+ DBusTransport *transport; -+ DBusConnection *connection; -+ DBusNewConnectionFunction new_connection_function; -+ void *new_connection_data; -+ -+ _dbus_verbose ("Creating new client connection with fd %d\n", client_fd); -+ -+ if (!_dbus_set_fd_nonblocking (client_fd, NULL)) -+ { -+ SERVER_UNLOCK (server); -+ return TRUE; -+ } -+ -+ transport = _dbus_transport_new_for_afbus (client_fd, &server->guid_hex, NULL); -+ if (transport == NULL) -+ { -+ _dbus_close_socket (client_fd, NULL); -+ SERVER_UNLOCK (server); -+ return FALSE; -+ } -+ -+ if (!_dbus_transport_set_auth_mechanisms (transport, -+ (const char **) server->auth_mechanisms)) -+ { -+ _dbus_transport_unref (transport); -+ SERVER_UNLOCK (server); -+ return FALSE; -+ } -+ -+ /* note that client_fd is now owned by the transport, and will be -+ * closed on transport disconnection/finalization -+ */ -+ connection = _dbus_connection_new_for_transport (transport); -+ _dbus_transport_unref (transport); -+ transport = NULL; /* now under the connection lock */ -+ -+ if (connection == NULL) -+ { -+ SERVER_UNLOCK (server); -+ return FALSE; -+ } -+ -+ /* See if someone wants to handle this new connection, self-referencing -+ * for paranoia. -+ */ -+ new_connection_function = server->new_connection_function; -+ new_connection_data = server->new_connection_data; -+ -+ _dbus_server_ref_unlocked (server); -+ SERVER_UNLOCK (server); -+ -+ if (new_connection_function) -+ { -+ (* new_connection_function) (server, connection, -+ new_connection_data); -+ } -+ dbus_server_unref (server); -+ -+ /* If no one grabbed a reference, the connection will die. */ -+ _dbus_connection_close_if_only_one_ref (connection); -+ dbus_connection_unref (connection); -+ -+ return TRUE; -+} -+ -+static dbus_bool_t -+afbus_handle_watch (DBusWatch *watch, -+ unsigned int flags, -+ void *data) -+{ -+ DBusServerAfbus *afbus_server = (DBusServerAfbus *) data; -+ DBusServer *server = (DBusServer *) data; -+ -+ SERVER_LOCK (server); -+ -+#ifndef DBUS_DISABLE_ASSERT -+ _dbus_assert (afbus_server->watch == watch); -+#endif -+ -+ _dbus_verbose ("Handling client connection, flags 0x%x\n", flags); -+ -+ if (flags & DBUS_WATCH_READABLE) -+ { -+ int client_fd; -+ -+ client_fd = _dbus_accept (afbus_server->fd); -+ if (client_fd < 0) -+ { -+ /* EINTR handled for us */ -+ -+ if (_dbus_get_is_errno_eagain_or_ewouldblock ()) -+ _dbus_verbose ("No client available to accept after all\n"); -+ else -+ _dbus_verbose ("Failed to accept a client connection: %s\n", -+ _dbus_strerror_from_errno ()); -+ -+ SERVER_UNLOCK (server); -+ } -+ else -+ { -+ if (!handle_new_client (server, client_fd)) -+ _dbus_verbose ("Rejected client connection due to lack of memory\n"); -+ } -+ } -+ -+ if (flags & DBUS_WATCH_ERROR) -+ _dbus_verbose ("Error on server listening socket\n"); -+ -+ if (flags & DBUS_WATCH_HANGUP) -+ _dbus_verbose ("Hangup on server listening socket\n"); -+ -+ return TRUE; -+} -+ -+static DBusServer * -+_dbus_server_new_for_afbus (int fd, const char *path, DBusError *error) -+{ -+ DBusServerAfbus *afbus_server; -+ DBusServer *server; -+ struct sockaddr_bus sock_address; -+ -+ afbus_server = dbus_new0 (DBusServerAfbus, 1); -+ if (afbus_server == NULL) -+ return NULL; -+ -+ if (!_dbus_string_init (&afbus_server->address) || -+ !_dbus_string_append (&afbus_server->address, "afbus:path=") || -+ !_dbus_string_append (&afbus_server->address, path)) -+ { -+ dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL); -+ goto failed_1; -+ } -+ -+ afbus_server->fd = fd; -+ -+ sock_address.sbus_family = AF_BUS; -+ strcpy (sock_address.sbus_path, path); -+ if (bind (afbus_server->fd, (struct sockaddr *) &sock_address, sizeof (sock_address)) < 0) -+ { -+ dbus_set_error (error, _dbus_error_from_errno (errno), -+ "Failed to bind socket \"%s\": %s", -+ path, _dbus_strerror (errno)); -+ goto failed_1; -+ } -+ -+ if (listen (afbus_server->fd, 30 /* backlog */) < 0) -+ { -+ dbus_set_error (error, _dbus_error_from_errno (errno), -+ "Failed to listen on AF_BUS socket: %s", -+ _dbus_strerror (errno)); -+ goto failed_1; -+ } -+ -+ afbus_server->watch = _dbus_watch_new (fd, -+ DBUS_WATCH_READABLE, -+ TRUE, -+ afbus_handle_watch, afbus_server, -+ NULL); -+ if (afbus_server->watch == NULL) -+ goto failed_1; -+ -+ if (!_dbus_server_init_base (&afbus_server->base, -+ &afbus_vtable, &afbus_server->address)) -+ goto failed_2; -+ -+ server = (DBusServer *) afbus_server; -+ server->is_afbus = TRUE; -+ -+ -+ SERVER_LOCK (server); -+ -+ if (!_dbus_server_add_watch (&afbus_server->base, -+ afbus_server->watch)) -+ { -+ SERVER_UNLOCK (server); -+ _dbus_server_finalize_base (&afbus_server->base); -+ -+ goto failed_2; -+ } -+ -+ SERVER_UNLOCK (server); -+ -+ _dbus_server_trace_ref (&afbus_server->base, 0, 1, "new_for_afbus"); -+ return (DBusServer *) afbus_server; -+ -+ failed_2: -+ _dbus_watch_unref (afbus_server->watch); -+ -+ failed_1: -+ _dbus_close_socket (afbus_server->fd, NULL); -+ dbus_free (afbus_server); -+ -+ return NULL; -+} -+ -+/** -+ * Starts a DBusServer listening on AF_BUS socket. -+ * Sets error if the result is not OK. -+ * -+ * @param entry an address entry -+ * @param server_p location to store a new DBusServer, or #NULL on failure. -+ * @param error location to store rationale for failure on bad address -+ * @returns the outcome -+ * -+ */ -+DBusServerListenResult -+_dbus_server_listen_afbus (DBusAddressEntry *entry, -+ DBusServer **server_p, -+ DBusError *error) -+{ -+ const char *method, *path, *tmpdir; -+ int listen_fd; -+ -+ *server_p = NULL; -+ -+ method = dbus_address_entry_get_method (entry); -+ if (strcmp (method, "afbus") != 0) -+ { -+ /* If we don't handle the method, we return NULL with the -+ * error unset -+ */ -+ _DBUS_ASSERT_ERROR_IS_CLEAR(error); -+ return DBUS_SERVER_LISTEN_NOT_HANDLED; -+ } -+ -+ path = dbus_address_entry_get_value (entry, "path"); -+ tmpdir = dbus_address_entry_get_value (entry, "tmpdir"); -+ -+ if (path == NULL && tmpdir == NULL) -+ { -+ _dbus_set_bad_address(error, "unix", -+ "path or tmpdir", -+ NULL); -+ return DBUS_SERVER_LISTEN_BAD_ADDRESS; -+ } -+ -+ if (path && tmpdir) -+ { -+ _dbus_set_bad_address(error, NULL, NULL, -+ "cannot specify both \"path\" and \"tmpdir\" at the same time"); -+ return DBUS_SERVER_LISTEN_BAD_ADDRESS; -+ } -+ -+ if (!_dbus_open_socket (&listen_fd, PF_BUS, SOCK_SEQPACKET, BUS_PROTO_DBUS, error)) -+ return DBUS_SERVER_LISTEN_DID_NOT_CONNECT; -+ -+ if (!_dbus_set_fd_nonblocking (listen_fd, error)) -+ goto failed_1; -+ -+ if (tmpdir != NULL) -+ { -+ DBusString full_path; -+ DBusString filename; -+ -+ if (!_dbus_string_init (&full_path)) -+ { -+ dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL); -+ return DBUS_SERVER_LISTEN_DID_NOT_CONNECT; -+ } -+ -+ if (!_dbus_string_init (&filename)) -+ { -+ _dbus_string_free (&full_path); -+ dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL); -+ return DBUS_SERVER_LISTEN_DID_NOT_CONNECT; -+ } -+ -+ if (!_dbus_string_append (&filename, -+ "dbus-") || -+ !_dbus_generate_random_ascii (&filename, 10) || -+ !_dbus_string_append (&full_path, tmpdir) || -+ !_dbus_concat_dir_and_file (&full_path, &filename)) -+ { -+ _dbus_string_free (&full_path); -+ _dbus_string_free (&filename); -+ dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL); -+ return DBUS_SERVER_LISTEN_DID_NOT_CONNECT; -+ } -+ -+ path = _dbus_string_get_const_data (&full_path); -+ } -+ -+ *server_p = _dbus_server_new_for_afbus (listen_fd, path, error); -+ if (*server_p == NULL) -+ goto failed_1; -+ -+ return DBUS_SERVER_LISTEN_OK; -+ -+ failed_1: -+ _dbus_close_socket (listen_fd, NULL); -+ -+ return DBUS_SERVER_LISTEN_DID_NOT_CONNECT; -+} -diff --git a/dbus/dbus-server-afbus.h b/dbus/dbus-server-afbus.h -new file mode 100644 -index 0000000..8e5ad31 ---- /dev/null -+++ b/dbus/dbus-server-afbus.h -@@ -0,0 +1,36 @@ -+/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ -+/* dbus-server-unix.h Server implementation for Unix network protocols. -+ * -+ * Copyright (C) 2012 Collabora Ltd -+ * -+ * Licensed under the Academic Free License version 2.1 -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License as published by -+ * the Free Software Foundation; either version 2 of the License, or -+ * (at your option) any later version. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this program; if not, write to the Free Software -+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -+ * -+ */ -+#ifndef DBUS_SERVER_AFBUS_H -+#define DBUS_SERVER_AFBUS_H -+ -+#include "dbus-server-protected.h" -+ -+DBUS_BEGIN_DECLS -+ -+DBusServerListenResult _dbus_server_listen_afbus (DBusAddressEntry *entry, -+ DBusServer **server_p, -+ DBusError *error); -+ -+DBUS_END_DECLS -+ -+#endif -diff --git a/dbus/dbus-server-protected.h b/dbus/dbus-server-protected.h -index dd5234b..b423cb9 100644 ---- a/dbus/dbus-server-protected.h -+++ b/dbus/dbus-server-protected.h -@@ -89,6 +89,9 @@ struct DBusServer - #ifndef DBUS_DISABLE_CHECKS - unsigned int have_server_lock : 1; /**< Does someone have the server mutex locked */ - #endif -+#ifdef HAVE_AFBUS -+ unsigned int is_afbus : 1; /**< TRUE if this server listen on a AF_BUS socket */ -+#endif - }; - - dbus_bool_t _dbus_server_init_base (DBusServer *server, -diff --git a/dbus/dbus-server.c b/dbus/dbus-server.c -index b62c2b4..2a23252 100644 ---- a/dbus/dbus-server.c -+++ b/dbus/dbus-server.c -@@ -25,6 +25,9 @@ - #include "dbus-server.h" - #include "dbus-server-unix.h" - #include "dbus-server-socket.h" -+#ifdef HAVE_AFBUS -+#include "dbus-server-afbus.h" -+#endif - #include "dbus-string.h" - #ifdef DBUS_BUILD_TESTS - #include "dbus-server-debug-pipe.h" -@@ -529,6 +532,9 @@ static const struct { - } listen_funcs[] = { - { _dbus_server_listen_socket } - , { _dbus_server_listen_platform_specific } -+#ifdef HAVE_AFBUS -+ , { _dbus_server_listen_afbus } -+#endif - #ifdef DBUS_BUILD_TESTS - , { _dbus_server_listen_debug_pipe } - #endif -@@ -844,6 +850,30 @@ dbus_server_get_address (DBusServer *server) - } - - /** -+ * Returns TRUE if the server listens on an AF_BUS address -+ * -+ * @param server the server -+ * @returns TRUE if the server listens on an AF_BUS address -+ */ -+dbus_bool_t -+dbus_server_is_afbus (DBusServer *server) -+{ -+ dbus_bool_t retval; -+ -+ _dbus_return_val_if_fail (server != NULL, FALSE); -+ -+#ifdef HAVE_AFBUS -+ SERVER_LOCK (server); -+ retval = server->is_afbus; -+ SERVER_UNLOCK (server); -+#else -+ retval = FALSE; -+#endif -+ -+ return retval; -+} -+ -+/** - * Returns the unique ID of the server, as a newly-allocated - * string which must be freed by the caller. This ID is - * normally used by clients to tell when two #DBusConnection -diff --git a/dbus/dbus-server.h b/dbus/dbus-server.h -index bdbefa0..49cb9cf 100644 ---- a/dbus/dbus-server.h -+++ b/dbus/dbus-server.h -@@ -62,6 +62,8 @@ dbus_bool_t dbus_server_get_is_connected (DBusServer *server); - DBUS_EXPORT - char* dbus_server_get_address (DBusServer *server); - DBUS_EXPORT -+dbus_bool_t dbus_server_is_afbus (DBusServer *server); -+DBUS_EXPORT - char* dbus_server_get_id (DBusServer *server); - DBUS_EXPORT - void dbus_server_set_new_connection_function (DBusServer *server, -diff --git a/dbus/dbus-shared.h b/dbus/dbus-shared.h -index 6a57670..b6b29b3 100644 ---- a/dbus/dbus-shared.h -+++ b/dbus/dbus-shared.h -@@ -80,6 +80,10 @@ typedef enum - #define DBUS_PATH_DBUS "/org/freedesktop/DBus" - /** The object path used in local/in-process-generated messages. */ - #define DBUS_PATH_LOCAL "/org/freedesktop/DBus/Local" -+#ifdef HAVE_AFBUS -+/** The object path used for AF_BUS sockets. */ -+#define DBUS_PATH_AFBUS "/org/freedesktop/DBus/AF_BUS" -+#endif - - /* Interfaces, these #define don't do much other than - * catch typos at compile time -@@ -92,6 +96,10 @@ typedef enum - #define DBUS_INTERFACE_PROPERTIES "org.freedesktop.DBus.Properties" - /** The interface supported by most dbus peers */ - #define DBUS_INTERFACE_PEER "org.freedesktop.DBus.Peer" -+#ifdef HAVE_AFBUS -+/** The interface supported by AF_BUS transport */ -+#define DBUS_INTERFACE_AFBUS "org.freedesktop.DBus.AF_BUS" -+#endif - - /** This is a special interface whose methods can only be invoked - * by the local implementation (messages from remote apps aren't -diff --git a/dbus/dbus-sysdeps-unix.c b/dbus/dbus-sysdeps-unix.c -index cef8bd3..26e3d00 100644 ---- a/dbus/dbus-sysdeps-unix.c -+++ b/dbus/dbus-sysdeps-unix.c -@@ -122,7 +122,7 @@ - - #endif /* Solaris */ - --static dbus_bool_t -+dbus_bool_t - _dbus_open_socket (int *fd_p, - int domain, - int type, -diff --git a/dbus/dbus-sysdeps.h b/dbus/dbus-sysdeps.h -index 4052cda..a589486 100644 ---- a/dbus/dbus-sysdeps.h -+++ b/dbus/dbus-sysdeps.h -@@ -125,6 +125,11 @@ typedef unsigned long dbus_gid_t; - * - */ - -+dbus_bool_t _dbus_open_socket (int *fd_p, -+ int domain, -+ int type, -+ int protocol, -+ DBusError *error); - dbus_bool_t _dbus_close_socket (int fd, - DBusError *error); - int _dbus_read_socket (int fd, -diff --git a/dbus/dbus-transport-afbus.c b/dbus/dbus-transport-afbus.c -new file mode 100644 -index 0000000..9574bca ---- /dev/null -+++ b/dbus/dbus-transport-afbus.c -@@ -0,0 +1,394 @@ -+/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ -+/* dbus-transport-socket.h Socket subclasses of DBusTransport -+ * -+ * Copyright (C) 212 Collabora Ltd -+ * -+ * Licensed under the Academic Free License version 2.1 -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License as published by -+ * the Free Software Foundation; either version 2 of the License, or -+ * (at your option) any later version. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this program; if not, write to the Free Software -+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -+ * -+ */ -+ -+#include <config.h> -+#include <errno.h> -+#include <sys/socket.h> -+#include "dbus-connection-internal.h" -+#include "dbus-hash.h" -+#include "dbus-transport-afbus.h" -+#include "dbus-transport-socket.h" -+#include "dbus-watch.h" -+ -+static DBusHashTable *wkn_addresses_cache = NULL; -+ -+/** -+ * @defgroup DBusTransportAfbus AF_BUS-based DBusTransport implementation -+ * @ingroup DBusInternals -+ * @brief Implementation details of DBusTransport on AF_BUS sockets -+ * -+ * @{ -+ */ -+ -+/** -+ * Opaque object representing a AF_BUS-based transport. -+ */ -+typedef struct DBusTransportAfbus DBusTransportAfbus; -+ -+/** -+ * Implementation details of DBusTransportAfbus. All members are private. -+ */ -+struct DBusTransportAfbus -+{ -+ DBusTransportSocket base; /**< Parent instance */ -+}; -+ -+static dbus_bool_t -+get_write_destination (int fd, -+ DBusMessage *message, -+ struct sockaddr_bus *sock) -+{ -+ socklen_t addrlen; -+ const char *destination; -+ const char *sender; -+ -+ /* if the sender is the bus driver, don't set the sockaddr, just let the -+ * message be delivered to the peer socket -+ */ -+ sender = dbus_message_get_sender (message); -+ if (sender && strcmp (sender, DBUS_SERVICE_DBUS) == 0) -+ { -+ return FALSE; -+ } -+ -+ addrlen = sizeof(struct sockaddr_bus); -+ if (getsockname (fd, (struct sockaddr *) sock, &addrlen) != 0) -+ return FALSE; -+ if (addrlen != sizeof(struct sockaddr_bus)) -+ return FALSE; -+ if (sock->sbus_family != AF_BUS) -+ return FALSE; -+ -+ destination = dbus_message_get_destination (message); -+ if (destination && strcmp (destination, DBUS_SERVICE_DBUS) == 0) -+ { -+ /* a message for the bus driver */ -+ sock->sbus_addr.s_addr = 0; -+ return TRUE; -+ } -+ -+ if (destination != NULL && strlen (destination) > 0) -+ { -+ dbus_uint64_t peer = 0x0000000000000000ULL; -+ -+ /* If destination is a unique name, just retrieve the peer address from it */ -+ if (strncmp (destination, ":AF-BUS.", 8) == 0) -+ { -+ DBusString tmp; -+ -+ _dbus_string_init_const (&tmp, &destination[8]); -+ if (!_dbus_string_parse_uint (&tmp, 0, (unsigned long *) &peer, NULL)) -+ peer = 0x0000000000000000ULL; -+ _dbus_string_free (&tmp); -+ } -+ else -+ { -+ /* a message for a well known name */ -+ if (wkn_addresses_cache != NULL) -+ { -+ dbus_uint64_t *peer_pointer; -+ -+ peer_pointer = (dbus_uint64_t *) _dbus_hash_table_lookup_string (wkn_addresses_cache, destination); -+ if (peer_pointer != NULL) -+ peer = *peer_pointer; -+ } -+ } -+ -+ sock->sbus_addr.s_addr = peer; -+ -+ return TRUE; -+ } -+ else -+ { -+ /* a multicast message */ -+ sock->sbus_addr.s_addr = 0x0000ffffffffffffULL; -+ return TRUE; -+ } -+ -+ return FALSE; -+} -+ -+static int -+afbus_write_socket (DBusTransportSocket *socket_transport, -+ DBusMessage *message, -+ const DBusString *buffer, -+ int start, -+ int len) -+{ -+ int fd, bytes_written; -+ struct sockaddr_bus sock; -+ -+ if (!_dbus_transport_get_socket_fd ((DBusTransport *) socket_transport, &fd)) -+ { -+ _dbus_verbose ("Couldn't get socket's file descriptor\n"); -+ return -1; -+ } -+ -+ if (get_write_destination (fd, message, &sock)) -+ { -+ const char *data; -+ -+ /* Send the data to specific address */ -+ data = _dbus_string_get_const_data_len (buffer, start, len); -+ -+ bytes_written = sendto (fd, data, len, MSG_NOSIGNAL, -+ (struct sockaddr *) &sock, sizeof (struct sockaddr_bus)); -+ } -+ else -+ bytes_written = _dbus_write_socket (fd, buffer, start, len); -+ -+ return bytes_written; -+} -+ -+static int -+afbus_write_socket_two (DBusTransportSocket *socket_transport, -+ DBusMessage *message, -+ const DBusString *header, -+ int header_start, -+ int header_len, -+ const DBusString *body, -+ int body_start, -+ int body_len) -+{ -+ int fd, bytes_written; -+ struct sockaddr_bus sock; -+ -+ if (!_dbus_transport_get_socket_fd ((DBusTransport *) socket_transport, &fd)) -+ { -+ _dbus_verbose ("Couldn't get socket's file descriptor\n"); -+ return -1; -+ } -+ -+ if (get_write_destination (fd, message, &sock)) -+ { -+ struct iovec vectors[2]; -+ const char *data1, *data2; -+ struct msghdr m; -+ -+ data1 = _dbus_string_get_const_data_len (header, header_start, header_len); -+ if (body != NULL) -+ data2 = _dbus_string_get_const_data_len (body, body_start, body_len); -+ else -+ { -+ data2 = NULL; -+ body_start = body_len = 0; -+ } -+ -+ vectors[0].iov_base = (char *) data1; -+ vectors[0].iov_len = header_len; -+ vectors[1].iov_base = (char *) data2; -+ vectors[1].iov_len = body_len; -+ -+ _DBUS_ZERO(m); -+ m.msg_iov = vectors; -+ m.msg_iovlen = data2 ? 2 : 1; -+ m.msg_name = &sock; -+ m.msg_namelen = sizeof (sock); -+ -+ again: -+ bytes_written = sendmsg (fd, &m, MSG_NOSIGNAL); -+ if (bytes_written < 0 && errno == EINTR) -+ goto again; -+ } -+ else -+ bytes_written = _dbus_write_socket_two (fd, header, header_start, header_len, body, body_start, body_len); -+ -+ return bytes_written; -+} -+ -+static void -+afbus_authenticated (DBusTransportSocket *socket_transport) -+{ -+ if (socket_transport->base.is_server) -+ { -+ /* Make the client join the bus when authenticated, so that it can send -+ * unicast messages to peers other than the daemon */ -+ if (setsockopt (socket_transport->fd, SOL_BUS, BUS_JOIN_BUS, NULL, 0) != 0) -+ { -+ _dbus_verbose ("Could not join client to the bus\n"); -+ } -+ } -+} -+ -+static void -+afbus_message_received (DBusTransportSocket *socket_transport, -+ DBusMessage *message) -+{ -+ if (dbus_message_get_type (message) == DBUS_MESSAGE_TYPE_SIGNAL) -+ { -+ const char *path, *interface, *member; -+ -+ path = dbus_message_get_path (message); -+ interface = dbus_message_get_interface (message); -+ member = dbus_message_get_member (message); -+ -+ if (strcmp (path, DBUS_PATH_AFBUS) == 0 -+ && strcmp (interface, DBUS_INTERFACE_AFBUS) == 0 -+ && strcmp (member, "Forwarded") == 0) -+ { -+ char *wkn; -+ dbus_uint64_t peer; -+ dbus_uint64_t *peer_pointer; -+ -+ /* Update the cache */ -+ if (wkn_addresses_cache == NULL) -+ { -+ wkn_addresses_cache = _dbus_hash_table_new (DBUS_HASH_STRING, -+ dbus_free, -+ dbus_free); -+ if (wkn_addresses_cache == NULL) -+ return; -+ } -+ -+ dbus_message_get_args (message, NULL, -+ DBUS_TYPE_STRING, &wkn, -+ DBUS_TYPE_UINT64, &peer, -+ DBUS_TYPE_INVALID); -+ -+ peer_pointer = dbus_new (dbus_uint64_t, 1); -+ *peer_pointer = peer; -+ _dbus_hash_table_insert_string (wkn_addresses_cache, -+ _dbus_strdup (wkn), -+ (void *) peer_pointer); -+ } -+ } -+} -+ -+static const DBusTransportSocketVTable afbus_vtable = { -+ afbus_write_socket, -+ afbus_write_socket_two, -+ afbus_authenticated, -+ afbus_message_received -+}; -+ -+/** -+ * Creates a new AF_BUS-based transport for the given socket descriptor. -+ * -+ * @param fd the file descriptor. -+ * @param server_guid non-#NULL if this transport is on the server side of a connection -+ * @param address the transport's address -+ * @returns the new transport, or #NULL if no memory. -+ */ -+DBusTransport* -+_dbus_transport_new_for_afbus (int fd, -+ const DBusString *server_guid, -+ const DBusString *address) -+{ -+ DBusTransportAfbus *afbus_transport; -+ -+ afbus_transport = dbus_new0 (DBusTransportAfbus, 1); -+ if (afbus_transport == NULL) -+ return NULL; -+ -+ if (!_dbus_transport_socket_init_base (&afbus_transport->base, -+ fd, -+ &afbus_vtable, -+ server_guid, address)) -+ goto failed_1; -+ -+ return (DBusTransport *) afbus_transport; -+ -+ failed_1: -+ dbus_free (afbus_transport); -+ -+ return NULL; -+} -+ -+/** -+ * Opens a AF_BUS-based transport. -+ * -+ * @param entry the address entry to try opening as a tcp transport. -+ * @param transport_p return location for the opened transport -+ * @param error error to be set -+ * @returns result of the attempt -+ */ -+DBusTransportOpenResult -+_dbus_transport_open_afbus (DBusAddressEntry *entry, -+ DBusTransport **transport_p, -+ DBusError *error) -+{ -+ const char *method, *path; -+ DBusString address; -+ int fd; -+ struct sockaddr_bus sock_address; -+ -+ method = dbus_address_entry_get_method (entry); -+ if (strcmp (method, "afbus") != 0) -+ { -+ _DBUS_ASSERT_ERROR_IS_CLEAR (error); -+ return DBUS_TRANSPORT_OPEN_NOT_HANDLED; -+ } -+ -+ path = dbus_address_entry_get_value (entry, "path"); -+ if (path == NULL) -+ { -+ _dbus_set_bad_address (error, "afbus", -+ "path or tmpdir", -+ NULL); -+ return DBUS_TRANSPORT_OPEN_BAD_ADDRESS; -+ } -+ -+ if (!_dbus_string_init (&address) || -+ !_dbus_string_append (&address, "afbus:path=") || -+ !_dbus_string_append (&address, path)) -+ { -+ dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL); -+ return DBUS_TRANSPORT_OPEN_DID_NOT_CONNECT; -+ } -+ -+ if (!_dbus_open_socket (&fd, PF_BUS, SOCK_SEQPACKET, BUS_PROTO_DBUS, error)) -+ goto failed_1; -+ -+ if (!_dbus_set_fd_nonblocking (fd, error)) -+ goto failed_2; -+ -+ sock_address.sbus_family = AF_BUS; -+ strcpy (sock_address.sbus_path, path); -+ if (connect (fd, (struct sockaddr *) &sock_address, sizeof (sock_address)) < 0) -+ { -+ dbus_set_error (error, -+ _dbus_error_from_errno (errno), -+ "Failed to connect to socket %s: %s", -+ path, _dbus_strerror (errno)); -+ goto failed_2; -+ } -+ -+ *transport_p = _dbus_transport_new_for_afbus (fd, NULL, &address); -+ if (*transport_p == NULL) -+ { -+ dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL); -+ goto failed_2; -+ } -+ -+ _dbus_string_free (&address); -+ -+ return DBUS_TRANSPORT_OPEN_OK; -+ -+ failed_2: -+ _dbus_close_socket (fd, NULL); -+ -+ failed_1: -+ _dbus_string_free (&address); -+ -+ return DBUS_TRANSPORT_OPEN_DID_NOT_CONNECT; -+} -diff --git a/dbus/dbus-transport-afbus.h b/dbus/dbus-transport-afbus.h -new file mode 100644 -index 0000000..c94e32d ---- /dev/null -+++ b/dbus/dbus-transport-afbus.h -@@ -0,0 +1,41 @@ -+/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ -+/* dbus-transport-socket.h Socket subclasses of DBusTransport -+ * -+ * Copyright (C) 212 Collabora Ltd -+ * -+ * Licensed under the Academic Free License version 2.1 -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License as published by -+ * the Free Software Foundation; either version 2 of the License, or -+ * (at your option) any later version. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this program; if not, write to the Free Software -+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -+ * -+ */ -+#ifndef DBUS_TRANSPORT_AFBUS_H -+#define DBUS_TRANSPORT_AFBUS_H -+ -+#include <sys/socket.h> -+#include <sys/bus.h> -+#include <dbus/dbus-transport-protected.h> -+ -+DBUS_BEGIN_DECLS -+ -+DBusTransport *_dbus_transport_new_for_afbus (int fd, -+ const DBusString *server_guid, -+ const DBusString *address); -+DBusTransportOpenResult _dbus_transport_open_afbus (DBusAddressEntry *entry, -+ DBusTransport **transport_p, -+ DBusError *error); -+ -+DBUS_END_DECLS -+ -+#endif -diff --git a/dbus/dbus-transport-protected.h b/dbus/dbus-transport-protected.h -index 44b9d78..9becbdb 100644 ---- a/dbus/dbus-transport-protected.h -+++ b/dbus/dbus-transport-protected.h -@@ -69,6 +69,10 @@ struct DBusTransportVTable - dbus_bool_t (* get_socket_fd) (DBusTransport *transport, - int *fd_p); - /**< Get socket file descriptor */ -+ -+ void (* process_incoming_message) (DBusTransport *transport, -+ DBusMessage *message); -+ /**> Method to allow transport to filter messages */ - }; - - /** -diff --git a/dbus/dbus-transport-socket.c b/dbus/dbus-transport-socket.c -index 544d00a..a3951ef 100644 ---- a/dbus/dbus-transport-socket.c -+++ b/dbus/dbus-transport-socket.c -@@ -22,6 +22,7 @@ - */ - - #include <config.h> -+#include <sys/ioctl.h> - #include "dbus-internals.h" - #include "dbus-connection-internal.h" - #include "dbus-nonce.h" -@@ -38,43 +39,13 @@ - * @{ - */ - --/** -- * Opaque object representing a socket file descriptor transport. -- */ --typedef struct DBusTransportSocket DBusTransportSocket; -- --/** -- * Implementation details of DBusTransportSocket. All members are private. -- */ --struct DBusTransportSocket --{ -- DBusTransport base; /**< Parent instance */ -- int fd; /**< File descriptor. */ -- DBusWatch *read_watch; /**< Watch for readability. */ -- DBusWatch *write_watch; /**< Watch for writability. */ -- -- int max_bytes_read_per_iteration; /**< To avoid blocking too long. */ -- int max_bytes_written_per_iteration; /**< To avoid blocking too long. */ -- -- int message_bytes_written; /**< Number of bytes of current -- * outgoing message that have -- * been written. -- */ -- DBusString encoded_outgoing; /**< Encoded version of current -- * outgoing message. -- */ -- DBusString encoded_incoming; /**< Encoded version of current -- * incoming data. -- */ --}; -- - static void - free_watches (DBusTransport *transport) - { - DBusTransportSocket *socket_transport = (DBusTransportSocket*) transport; - - _dbus_verbose ("start\n"); -- -+ - if (socket_transport->read_watch) - { - if (transport->connection) -@@ -104,7 +75,7 @@ socket_finalize (DBusTransport *transport) - DBusTransportSocket *socket_transport = (DBusTransportSocket*) transport; - - _dbus_verbose ("\n"); -- -+ - free_watches (transport); - - _dbus_string_free (&socket_transport->encoded_outgoing); -@@ -136,7 +107,16 @@ check_write_watch (DBusTransport *transport) - _dbus_transport_ref (transport); - - if (_dbus_transport_get_is_authenticated (transport)) -- needed = _dbus_connection_has_messages_to_send_unlocked (transport->connection); -+ { -+ if (!socket_transport->auth_notified && -+ socket_transport->vtable->authenticated != NULL) -+ { -+ socket_transport->auth_notified = TRUE; -+ socket_transport->vtable->authenticated (socket_transport); -+ } -+ -+ needed = _dbus_connection_has_messages_to_send_unlocked (transport->connection); -+ } - else - { - if (transport->send_credentials_pending) -@@ -146,7 +126,7 @@ check_write_watch (DBusTransport *transport) - DBusAuthState auth_state; - - auth_state = _dbus_auth_do_work (transport->auth); -- -+ - /* If we need memory we install the write watch just in case, - * if there's no need for it, it will get de-installed - * next time we try reading. -@@ -191,9 +171,18 @@ check_read_watch (DBusTransport *transport) - _dbus_transport_ref (transport); - - if (_dbus_transport_get_is_authenticated (transport)) -- need_read_watch = -- (_dbus_counter_get_size_value (transport->live_messages) < transport->max_live_messages_size) && -- (_dbus_counter_get_unix_fd_value (transport->live_messages) < transport->max_live_messages_unix_fds); -+ { -+ if (!socket_transport->auth_notified && -+ socket_transport->vtable->authenticated != NULL) -+ { -+ socket_transport->auth_notified = TRUE; -+ socket_transport->vtable->authenticated (socket_transport); -+ } -+ -+ need_read_watch = -+ (_dbus_counter_get_size_value (transport->live_messages) < transport->max_live_messages_size) && -+ (_dbus_counter_get_unix_fd_value (transport->live_messages) < transport->max_live_messages_unix_fds); -+ } - else - { - if (transport->receive_credentials_pending) -@@ -489,6 +478,59 @@ do_authentication (DBusTransport *transport, - return TRUE; - } - -+static int -+_write_socket (DBusTransportSocket *socket_transport, -+ DBusMessage *message, -+ const DBusString *buffer, -+ int start, -+ int len) -+{ -+ int bytes_written; -+ -+ if (socket_transport->vtable->write_socket != NULL) -+ { -+ bytes_written = socket_transport->vtable->write_socket (socket_transport, -+ message, -+ buffer, start, len); -+ } -+ else -+ { -+ bytes_written = _dbus_write_socket (socket_transport->fd, -+ buffer, -+ start, len); -+ } -+ -+ return bytes_written; -+} -+ -+static int -+_write_socket_two (DBusTransportSocket *socket_transport, -+ DBusMessage *message, -+ const DBusString *header, -+ int header_start, -+ int header_len, -+ const DBusString *body, -+ int body_start, -+ int body_len) -+{ -+ int bytes_written; -+ -+ if (socket_transport->vtable->write_socket_two != NULL) -+ { -+ bytes_written = socket_transport->vtable->write_socket_two (socket_transport, message, -+ header, header_start, header_len, -+ body, body_start, body_len); -+ } -+ else -+ { -+ bytes_written = _dbus_write_socket_two (socket_transport->fd, -+ header, header_start, header_len, -+ body, body_start, body_len); -+ } -+ -+ return bytes_written; -+} -+ - /* returns false on oom */ - static dbus_bool_t - do_writing (DBusTransport *transport) -@@ -579,12 +621,13 @@ do_writing (DBusTransport *transport) - _dbus_verbose ("encoded message is %d bytes\n", - total_bytes_to_write); - #endif -- -+ - bytes_written = -- _dbus_write_socket (socket_transport->fd, -- &socket_transport->encoded_outgoing, -- socket_transport->message_bytes_written, -- total_bytes_to_write - socket_transport->message_bytes_written); -+ _write_socket (socket_transport, -+ message, -+ &socket_transport->encoded_outgoing, -+ socket_transport->message_bytes_written, -+ total_bytes_to_write - socket_transport->message_bytes_written); - } - else - { -@@ -623,21 +666,23 @@ do_writing (DBusTransport *transport) - if (socket_transport->message_bytes_written < header_len) - { - bytes_written = -- _dbus_write_socket_two (socket_transport->fd, -- header, -- socket_transport->message_bytes_written, -- header_len - socket_transport->message_bytes_written, -- body, -- 0, body_len); -+ _write_socket_two (socket_transport, -+ message, -+ header, -+ socket_transport->message_bytes_written, -+ header_len - socket_transport->message_bytes_written, -+ body, -+ 0, body_len); - } - else - { - bytes_written = -- _dbus_write_socket (socket_transport->fd, -- body, -- (socket_transport->message_bytes_written - header_len), -- body_len - -- (socket_transport->message_bytes_written - header_len)); -+ _write_socket (socket_transport, -+ message, -+ body, -+ (socket_transport->message_bytes_written - header_len), -+ body_len - -+ (socket_transport->message_bytes_written - header_len)); - } - } - } -@@ -696,7 +741,7 @@ do_reading (DBusTransport *transport) - { - DBusTransportSocket *socket_transport = (DBusTransportSocket*) transport; - DBusString *buffer; -- int bytes_read; -+ int bytes_read, bytes_available; - int total; - dbus_bool_t oom; - -@@ -730,7 +775,12 @@ do_reading (DBusTransport *transport) - - if (!dbus_watch_get_enabled (socket_transport->read_watch)) - return TRUE; -- -+ -+ if (ioctl (socket_transport->fd, FIONREAD, &bytes_available) < 0) -+ bytes_available = socket_transport->max_bytes_read_per_iteration; -+ else if (bytes_available < socket_transport->max_bytes_read_per_iteration) -+ bytes_available = socket_transport->max_bytes_read_per_iteration; -+ - if (_dbus_auth_needs_decoding (transport->auth)) - { - /* Does fd passing even make sense with encoded data? */ -@@ -741,7 +791,7 @@ do_reading (DBusTransport *transport) - else - bytes_read = _dbus_read_socket (socket_transport->fd, - &socket_transport->encoded_incoming, -- socket_transport->max_bytes_read_per_iteration); -+ bytes_available); - - _dbus_assert (_dbus_string_get_length (&socket_transport->encoded_incoming) == - bytes_read); -@@ -796,7 +846,7 @@ do_reading (DBusTransport *transport) - - bytes_read = _dbus_read_socket_with_unix_fds(socket_transport->fd, - buffer, -- socket_transport->max_bytes_read_per_iteration, -+ bytes_available, - fds, &n_fds); - - if (bytes_read >= 0 && n_fds > 0) -@@ -808,7 +858,7 @@ do_reading (DBusTransport *transport) - #endif - { - bytes_read = _dbus_read_socket (socket_transport->fd, -- buffer, socket_transport->max_bytes_read_per_iteration); -+ buffer, bytes_available); - } - - _dbus_message_loader_return_buffer (transport->loader, -@@ -1207,6 +1257,19 @@ socket_get_socket_fd (DBusTransport *transport, - return TRUE; - } - -+static void -+socket_process_incoming_message (DBusTransport *transport, -+ DBusMessage *message) -+{ -+ DBusTransportSocket *socket_transport = (DBusTransportSocket*) transport; -+ -+ if (socket_transport->vtable->message_received != NULL) -+ { -+ (* socket_transport->vtable->message_received) (socket_transport, -+ message); -+ } -+} -+ - static const DBusTransportVTable socket_vtable = { - socket_finalize, - socket_handle_watch, -@@ -1214,37 +1277,40 @@ static const DBusTransportVTable socket_vtable = { - socket_connection_set, - socket_do_iteration, - socket_live_messages_changed, -- socket_get_socket_fd -+ socket_get_socket_fd, -+ socket_process_incoming_message - }; - - /** -- * Creates a new transport for the given socket file descriptor. The file -- * descriptor must be nonblocking (use _dbus_set_fd_nonblocking() to -- * make it so). This function is shared by various transports that -- * boil down to a full duplex file descriptor. -+ * Initializes the base class members of DBusTransportSocket. Chained up to -+ * by subclasses in their constructor. The server GUID is the -+ * globally unique ID for the server creating this connection -+ * and will be #NULL for the client side of a connection. The GUID -+ * is in hex format. - * -- * @param fd the file descriptor. -+ * @param socket_transport the transport being created. -+ * @param fd The socket for this transport -+ * @param vtable the subclass vtable. - * @param server_guid non-#NULL if this transport is on the server side of a connection -- * @param address the transport's address -- * @returns the new transport, or #NULL if no memory. -+ * @param address the address of the transport -+ * @returns #TRUE on success. - */ --DBusTransport* --_dbus_transport_new_for_socket (int fd, -- const DBusString *server_guid, -- const DBusString *address) -+dbus_bool_t -+_dbus_transport_socket_init_base (DBusTransportSocket *socket_transport, -+ int fd, -+ const DBusTransportSocketVTable *vtable, -+ const DBusString *server_guid, -+ const DBusString *address) - { -- DBusTransportSocket *socket_transport; -- -- socket_transport = dbus_new0 (DBusTransportSocket, 1); -- if (socket_transport == NULL) -- return NULL; -- - if (!_dbus_string_init (&socket_transport->encoded_outgoing)) - goto failed_0; - - if (!_dbus_string_init (&socket_transport->encoded_incoming)) - goto failed_1; -- -+ -+ socket_transport->auth_notified = FALSE; -+ socket_transport->vtable = vtable; -+ - socket_transport->write_watch = _dbus_watch_new (fd, - DBUS_WATCH_WRITABLE, - FALSE, -@@ -1275,7 +1341,7 @@ _dbus_transport_new_for_socket (int fd, - socket_transport->max_bytes_read_per_iteration = 2048; - socket_transport->max_bytes_written_per_iteration = 2048; - -- return (DBusTransport*) socket_transport; -+ return TRUE; - - failed_4: - _dbus_watch_invalidate (socket_transport->read_watch); -@@ -1288,8 +1354,46 @@ _dbus_transport_new_for_socket (int fd, - failed_1: - _dbus_string_free (&socket_transport->encoded_outgoing); - failed_0: -- dbus_free (socket_transport); -- return NULL; -+ -+ return FALSE; -+} -+ -+/** -+ * Creates a new transport for the given socket file descriptor. The file -+ * descriptor must be nonblocking (use _dbus_set_fd_nonblocking() to -+ * make it so). This function is shared by various transports that -+ * boil down to a full duplex file descriptor. -+ * -+ * @param fd the file descriptor. -+ * @param server_guid non-#NULL if this transport is on the server side of a connection -+ * @param address the transport's address -+ * @returns the new transport, or #NULL if no memory. -+ */ -+DBusTransport* -+_dbus_transport_new_for_socket (int fd, -+ const DBusString *server_guid, -+ const DBusString *address) -+{ -+ DBusTransportSocket *socket_transport; -+ static const DBusTransportSocketVTable vtable = { -+ NULL -+ }; -+ -+ socket_transport = dbus_new0 (DBusTransportSocket, 1); -+ if (socket_transport == NULL) -+ return NULL; -+ -+ if (!_dbus_transport_socket_init_base (socket_transport, -+ fd, -+ &vtable, -+ server_guid, -+ address)) -+ { -+ dbus_free (socket_transport); -+ return NULL; -+ } -+ -+ return (DBusTransport *) socket_transport; - } - - /** -diff --git a/dbus/dbus-transport-socket.h b/dbus/dbus-transport-socket.h -index 8aefae3..ed7fdcc 100644 ---- a/dbus/dbus-transport-socket.h -+++ b/dbus/dbus-transport-socket.h -@@ -27,6 +27,80 @@ - - DBUS_BEGIN_DECLS - -+/** -+ * Opaque object representing a socket file descriptor transport. -+ */ -+typedef struct DBusTransportSocket DBusTransportSocket; -+ -+/** -+ * The virtual table that must be implemented to -+ * create a socket-based transport. -+ */ -+typedef struct DBusTransportSocketVTable DBusTransportSocketVTable; -+ -+struct DBusTransportSocketVTable -+{ -+ int (* write_socket) (DBusTransportSocket *socket_transport, -+ DBusMessage *message, -+ const DBusString *buffer, -+ int start, -+ int len); -+ /**< Write part of a message to the transport */ -+ -+ int (* write_socket_two) (DBusTransportSocket *socket_transport, -+ DBusMessage *message, -+ const DBusString *header, -+ int header_start, -+ int header_len, -+ const DBusString *body, -+ int body_start, -+ int body_len); -+ /**< Write header and body to the transport */ -+ -+ void (* authenticated) (DBusTransportSocket *socket_transport); -+ /**< Notification of authentication successful */ -+ -+ void (* message_received) (DBusTransportSocket *socket_transport, -+ DBusMessage *message); -+ /**< Notification of a message received */ -+}; -+ -+/** -+ * Implementation details of DBusTransportSocket. All members are private. -+ */ -+struct DBusTransportSocket -+{ -+ DBusTransport base; /**< Parent instance */ -+ int fd; /**< File descriptor. */ -+ DBusWatch *read_watch; /**< Watch for readability. */ -+ DBusWatch *write_watch; /**< Watch for writability. */ -+ -+ int max_bytes_read_per_iteration; /**< To avoid blocking too long. */ -+ int max_bytes_written_per_iteration; /**< To avoid blocking too long. */ -+ -+ int message_bytes_written; /**< Number of bytes of current -+ * outgoing message that have -+ * been written. -+ */ -+ DBusString encoded_outgoing; /**< Encoded version of current -+ * outgoing message. -+ */ -+ DBusString encoded_incoming; /**< Encoded version of current -+ * incoming data. -+ */ -+ dbus_bool_t auth_notified; /**< Have we notified subclasses -+ * we are authenticated? -+ */ -+ const DBusTransportSocketVTable *vtable; /**< Virtual table of transport methods. */ -+}; -+ -+dbus_bool_t _dbus_transport_socket_init_base (DBusTransportSocket *socket_transport, -+ int fd, -+ const DBusTransportSocketVTable *vtable, -+ const DBusString *server_guid, -+ const DBusString *address); -+void _dbus_transport_socket_finalize_base (DBusTransportSocket *socket_transport); -+ - DBusTransport* _dbus_transport_new_for_socket (int fd, - const DBusString *server_guid, - const DBusString *address); -diff --git a/dbus/dbus-transport.c b/dbus/dbus-transport.c -index 6b58fda..44923da 100644 ---- a/dbus/dbus-transport.c -+++ b/dbus/dbus-transport.c -@@ -25,6 +25,9 @@ - #include "dbus-transport-protected.h" - #include "dbus-transport-unix.h" - #include "dbus-transport-socket.h" -+#ifdef HAVE_AFBUS -+#include "dbus-transport-afbus.h" -+#endif - #include "dbus-connection-internal.h" - #include "dbus-watch.h" - #include "dbus-auth.h" -@@ -348,6 +351,9 @@ static const struct { - { _dbus_transport_open_socket }, - { _dbus_transport_open_platform_specific }, - { _dbus_transport_open_autolaunch } -+#ifdef HAVE_AFBUS -+ , { _dbus_transport_open_afbus } -+#endif - #ifdef DBUS_BUILD_TESTS - , { _dbus_transport_open_debug_pipe } - #endif -@@ -980,6 +986,28 @@ _dbus_transport_do_iteration (DBusTransport *transport, - _dbus_verbose ("end\n"); - } - -+/** -+ * Allows transports to process incoming messages -+ * -+ * @param transport the transport. -+ * @param message the message to be filtered -+ */ -+void -+_dbus_transport_process_incoming_message (DBusTransport *transport, -+ DBusMessage *message) -+{ -+ _dbus_verbose ("Transport message filtering\n"); -+ -+ if (transport->vtable->process_incoming_message != NULL) -+ { -+ _dbus_transport_ref (transport); -+ (* transport->vtable->process_incoming_message) (transport, message); -+ _dbus_transport_unref (transport); -+ } -+ -+ _dbus_verbose ("end\n"); -+} -+ - static dbus_bool_t - recover_unused_bytes (DBusTransport *transport) - { -@@ -1134,6 +1162,7 @@ _dbus_transport_queue_messages (DBusTransport *transport) - _dbus_assert (link != NULL); - - message = link->data; -+ _dbus_transport_process_incoming_message (transport, message); - - _dbus_verbose ("queueing received message %p\n", message); - -diff --git a/dbus/dbus-transport.h b/dbus/dbus-transport.h -index 4b82151..194b2c6 100644 ---- a/dbus/dbus-transport.h -+++ b/dbus/dbus-transport.h -@@ -52,6 +52,8 @@ dbus_bool_t _dbus_transport_set_connection (DBusTransport - void _dbus_transport_do_iteration (DBusTransport *transport, - unsigned int flags, - int timeout_milliseconds); -+void _dbus_transport_process_incoming_message (DBusTransport *transport, -+ DBusMessage *message); - DBusDispatchStatus _dbus_transport_get_dispatch_status (DBusTransport *transport); - dbus_bool_t _dbus_transport_queue_messages (DBusTransport *transport); - -diff --git a/test/data/valid-config-files/basic.conf b/test/data/valid-config-files/basic.conf -index 5297097..af46d8b 100644 ---- a/test/data/valid-config-files/basic.conf -+++ b/test/data/valid-config-files/basic.conf -@@ -4,6 +4,8 @@ - <user>mybususer</user> - <listen>unix:path=/foo/bar</listen> - <listen>tcp:port=1234</listen> -+ <listen_if_possible>tcp:port=1235</listen_if_possible> -+ <listen_if_possible>pigeon:port=carrier,speed=110mph</listen_if_possible> - <includedir>basic.d</includedir> - <servicedir>/usr/share/foo</servicedir> - <include ignore_missing="yes">nonexistent.conf</include> diff --git a/meta-ivi/recipes-core-ivi/dbus/dbus_%.bbappend b/meta-ivi/recipes-core-ivi/dbus/dbus_%.bbappend index ac73e11..e468884 100644 --- a/meta-ivi/recipes-core-ivi/dbus/dbus_%.bbappend +++ b/meta-ivi/recipes-core-ivi/dbus/dbus_%.bbappend @@ -1,9 +1,5 @@ FILESEXTRAPATHS_append := ":${THISDIR}/${PN}" -# add support for GENIVI AF_Bus D-Bus Optimization -# - http://projects.genivi.org/afbus-dbus-optimization/ -#SRC_URI_AFBUS = "file://dbus_1.6-add-afbus-support.patch" - # add support for GENIVI CommonAPI D-Bus runtime # - http://projects.genivi.org/commonapi/ SRC_URI_append = " \ |