aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--meta-ivi/recipes-core-ivi/dbus/dbus/dbus_1.6-add-afbus-support.patch3201
-rw-r--r--meta-ivi/recipes-core-ivi/dbus/dbus_%.bbappend4
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 = " \