chiark / gitweb /
sd-bus: support matching on destination names
authorDavid Herrmann <dh.herrmann@gmail.com>
Mon, 6 Jul 2015 15:43:36 +0000 (17:43 +0200)
committerSven Eden <yamakuzure@gmx.net>
Tue, 14 Mar 2017 09:05:56 +0000 (10:05 +0100)
Right now, we never install destination matches on kdbus as the kernel did
not support MATCH rules on those. With the introduction of
KDBUS_ITEM_DST_ID we can now match on destination IDs, so add explicit
support for those.

This requires a recent kdbus module to work. However, there seems to be no
user-space that uses "Destination=''" matches, yet, so old kdbus modules
still work fine (we couldn't find any real user).

This is needed to match on unicast signals in bus-proxy. A followup will
add support for this.

src/libelogind/sd-bus/bus-control.c
src/libelogind/sd-bus/kdbus.h

index 7a59702..a38c5c5 100644 (file)
@@ -1219,7 +1219,7 @@ int bus_add_match_internal_kernel(
         size_t sz;
         const char *sender = NULL;
         size_t sender_length = 0;
-        uint64_t src_id = KDBUS_MATCH_ID_ANY;
+        uint64_t src_id = KDBUS_MATCH_ID_ANY, dst_id = KDBUS_MATCH_ID_ANY;
         bool using_bloom = false;
         unsigned i;
         bool matches_name_change = true;
@@ -1332,13 +1332,21 @@ int bus_add_match_internal_kernel(
                         break;
                 }
 
-                case BUS_MATCH_DESTINATION:
-                        /* The bloom filter does not include
-                           the destination, since it is only
-                           available for broadcast messages
-                           which do not carry a destination
-                           since they are undirected. */
+                case BUS_MATCH_DESTINATION: {
+                        /*
+                         * Kernel only supports matching on destination IDs, but
+                         * not on destination names. So just skip the
+                         * destination name restriction and verify it in
+                         * user-space on retrieval.
+                         */
+                        r = bus_kernel_parse_unique_name(c->value_str, &dst_id);
+                        if (r < 0)
+                                return r;
+                        else if (r > 0)
+                                sz += ALIGN8(offsetof(struct kdbus_item, id) + sizeof(uint64_t));
+
                         break;
+                }
 
                 case BUS_MATCH_ROOT:
                 case BUS_MATCH_VALUE:
@@ -1365,6 +1373,13 @@ int bus_add_match_internal_kernel(
                 item = KDBUS_ITEM_NEXT(item);
         }
 
+        if (dst_id != KDBUS_MATCH_ID_ANY) {
+                item->size = offsetof(struct kdbus_item, id) + sizeof(uint64_t);
+                item->type = KDBUS_ITEM_DST_ID;
+                item->id = dst_id;
+                item = KDBUS_ITEM_NEXT(item);
+        }
+
         if (using_bloom) {
                 item->size = offsetof(struct kdbus_item, data64) + bus->bloom_size;
                 item->type = KDBUS_ITEM_BLOOM_MASK;
index 00a6e14..ecffc6b 100644 (file)
@@ -374,6 +374,7 @@ enum kdbus_item_type {
        KDBUS_ITEM_ATTACH_FLAGS_RECV,
        KDBUS_ITEM_ID,
        KDBUS_ITEM_NAME,
+       KDBUS_ITEM_DST_ID,
 
        /* keep these item types in sync with KDBUS_ATTACH_* flags */
        _KDBUS_ITEM_ATTACH_BASE = 0x1000,