sd-bus: add arrays of strings in the bloom filter

Let's do this right from the beginning, to prepare ground for udev
messages that most likely want to store list of strings (for device
tags) in messages, and filter on them.
This commit is contained in:
Lennart Poettering
2014-11-28 20:29:44 +01:00
parent a6a6ac1603
commit 1abe54d9a9
2 changed files with 84 additions and 48 deletions
+56 -27
View File
@@ -135,6 +135,32 @@ static void append_fds(struct kdbus_item **d, const int fds[], unsigned n_fds) {
*d = (struct kdbus_item *) ((uint8_t*) *d + (*d)->size);
}
static void add_bloom_arg(void *data, size_t size, unsigned n_hash, unsigned i, const char *t) {
char buf[sizeof("arg")-1 + 2 + sizeof("-slash-prefix")];
char *e;
assert(data);
assert(size > 0);
assert(i < 64);
assert(t);
e = stpcpy(buf, "arg");
if (i < 10)
*(e++) = '0' + (char) i;
else {
*(e++) = '0' + (char) (i / 10);
*(e++) = '0' + (char) (i % 10);
}
*e = 0;
bloom_add_pair(data, size, n_hash, buf, t);
strcpy(e, "-dot-prefix");
bloom_add_prefixes(data, size, n_hash, buf, t, '.');
strcpy(e, "-slash-prefix");
bloom_add_prefixes(data, size, n_hash, buf, t, '/');
}
static int bus_message_setup_bloom(sd_bus_message *m, struct kdbus_bloom_filter *bloom) {
void *data;
unsigned i;
@@ -164,39 +190,42 @@ static int bus_message_setup_bloom(sd_bus_message *m, struct kdbus_bloom_filter
return r;
for (i = 0; i < 64; i++) {
const char *t, *contents;
char type;
const char *t;
char buf[sizeof("arg")-1 + 2 + sizeof("-slash-prefix")];
char *e;
r = sd_bus_message_peek_type(m, &type, NULL);
r = sd_bus_message_peek_type(m, &type, &contents);
if (r < 0)
return r;
if (type != SD_BUS_TYPE_STRING &&
type != SD_BUS_TYPE_OBJECT_PATH &&
type != SD_BUS_TYPE_SIGNATURE)
if (IN_SET(type, SD_BUS_TYPE_STRING, SD_BUS_TYPE_OBJECT_PATH, SD_BUS_TYPE_SIGNATURE)) {
/* The bloom filter includes simple strings of any kind */
r = sd_bus_message_read_basic(m, type, &t);
if (r < 0)
return r;
add_bloom_arg(data, m->bus->bloom_size, m->bus->bloom_n_hash, i, t);
} if (type == SD_BUS_TYPE_ARRAY && STR_IN_SET(contents, "s", "o", "g")) {
/* As well as array of simple strings of any kinds */
r = sd_bus_message_enter_container(m, type, contents);
if (r < 0)
return r;
while ((r = sd_bus_message_read_basic(m, contents[0], &t)) > 0)
add_bloom_arg(data, m->bus->bloom_size, m->bus->bloom_n_hash, i, t);
if (r < 0)
return r;
r = sd_bus_message_exit_container(m);
if (r < 0)
return r;
} else
/* Stop adding to bloom filter as soon as we
* run into the first argument we cannot add
* to it. */
break;
r = sd_bus_message_read_basic(m, type, &t);
if (r < 0)
return r;
e = stpcpy(buf, "arg");
if (i < 10)
*(e++) = '0' + (char) i;
else {
*(e++) = '0' + (char) (i / 10);
*(e++) = '0' + (char) (i % 10);
}
*e = 0;
bloom_add_pair(data, m->bus->bloom_size, m->bus->bloom_n_hash, buf, t);
strcpy(e, "-dot-prefix");
bloom_add_prefixes(data, m->bus->bloom_size, m->bus->bloom_n_hash, buf, t, '.');
strcpy(e, "-slash-prefix");
bloom_add_prefixes(data, m->bus->bloom_size, m->bus->bloom_n_hash, buf, t, '/');
}
return 0;
+28 -21
View File
@@ -32,6 +32,7 @@ static void test_one(
const char *path,
const char *interface,
const char *member,
bool as_list,
const char *arg0,
const char *match,
bool good) {
@@ -76,7 +77,11 @@ static void test_one(
assert_se(r >= 0);
log_debug("signal");
r = sd_bus_emit_signal(a, path, interface, member, "s", arg0);
if (as_list)
r = sd_bus_emit_signal(a, path, interface, member, "as", 1, arg0);
else
r = sd_bus_emit_signal(a, path, interface, member, "s", arg0);
assert_se(r >= 0);
r = sd_bus_process(b, &m);
@@ -89,27 +94,29 @@ static void test_one(
int main(int argc, char *argv[]) {
log_set_max_level(LOG_DEBUG);
test_one("/foo/bar/waldo", "waldo.com", "Piep", "foobar", "", true);
test_one("/foo/bar/waldo", "waldo.com", "Piep", "foobar", "path='/foo/bar/waldo'", true);
test_one("/foo/bar/waldo", "waldo.com", "Piep", "foobar", "path='/foo/bar/waldo/tuut'", false);
test_one("/foo/bar/waldo", "waldo.com", "Piep", "foobar", "interface='waldo.com'", true);
test_one("/foo/bar/waldo", "waldo.com", "Piep", "foobar", "member='Piep'", true);
test_one("/foo/bar/waldo", "waldo.com", "Piep", "foobar", "member='Pi_ep'", false);
test_one("/foo/bar/waldo", "waldo.com", "Piep", "foobar", "arg0='foobar'", true);
test_one("/foo/bar/waldo", "waldo.com", "Piep", "foobar", "arg0='foo_bar'", false);
test_one("/foo/bar/waldo", "waldo.com", "Piep", "foobar", "path='/foo/bar/waldo',interface='waldo.com',member='Piep',arg0='foobar'", true);
test_one("/foo/bar/waldo", "waldo.com", "Piep", "foobar", "path='/foo/bar/waldo',interface='waldo.com',member='Piep',arg0='foobar2'", false);
test_one("/foo/bar/waldo", "waldo.com", "Piep", false, "foobar", "", true);
test_one("/foo/bar/waldo", "waldo.com", "Piep", false, "foobar", "path='/foo/bar/waldo'", true);
test_one("/foo/bar/waldo", "waldo.com", "Piep", false, "foobar", "path='/foo/bar/waldo/tuut'", false);
test_one("/foo/bar/waldo", "waldo.com", "Piep", false, "foobar", "interface='waldo.com'", true);
test_one("/foo/bar/waldo", "waldo.com", "Piep", false, "foobar", "member='Piep'", true);
test_one("/foo/bar/waldo", "waldo.com", "Piep", false, "foobar", "member='Pi_ep'", false);
test_one("/foo/bar/waldo", "waldo.com", "Piep", false, "foobar", "arg0='foobar'", true);
test_one("/foo/bar/waldo", "waldo.com", "Piep", false, "foobar", "arg0='foo_bar'", false);
test_one("/foo/bar/waldo", "waldo.com", "Piep", true, "foobar", "arg0='foobar'", true);
test_one("/foo/bar/waldo", "waldo.com", "Piep", true, "foobar", "arg0='foo_bar'", false);
test_one("/foo/bar/waldo", "waldo.com", "Piep", false, "foobar", "path='/foo/bar/waldo',interface='waldo.com',member='Piep',arg0='foobar'", true);
test_one("/foo/bar/waldo", "waldo.com", "Piep", false, "foobar", "path='/foo/bar/waldo',interface='waldo.com',member='Piep',arg0='foobar2'", false);
test_one("/foo/bar/waldo", "waldo.com", "Piep", "foobar", "path='/foo/bar/waldo'", true);
test_one("/foo/bar/waldo", "waldo.com", "Piep", "foobar", "path='/foo/bar'", false);
test_one("/foo/bar/waldo", "waldo.com", "Piep", "foobar", "path='/foo'", false);
test_one("/foo/bar/waldo", "waldo.com", "Piep", "foobar", "path='/'", false);
test_one("/foo/bar/waldo", "waldo.com", "Piep", "foobar", "path='/foo/bar/waldo/quux'", false);
test_one("/foo/bar/waldo", "waldo.com", "Piep", "foobar", "path_namespace='/foo/bar/waldo'", true);
test_one("/foo/bar/waldo", "waldo.com", "Piep", "foobar", "path_namespace='/foo/bar'", true);
test_one("/foo/bar/waldo", "waldo.com", "Piep", "foobar", "path_namespace='/foo'", true);
test_one("/foo/bar/waldo", "waldo.com", "Piep", "foobar", "path_namespace='/'", true);
test_one("/foo/bar/waldo", "waldo.com", "Piep", "foobar", "path_namespace='/quux'", false);
test_one("/foo/bar/waldo", "waldo.com", "Piep", false, "foobar", "path='/foo/bar/waldo'", true);
test_one("/foo/bar/waldo", "waldo.com", "Piep", false, "foobar", "path='/foo/bar'", false);
test_one("/foo/bar/waldo", "waldo.com", "Piep", false, "foobar", "path='/foo'", false);
test_one("/foo/bar/waldo", "waldo.com", "Piep", false, "foobar", "path='/'", false);
test_one("/foo/bar/waldo", "waldo.com", "Piep", false, "foobar", "path='/foo/bar/waldo/quux'", false);
test_one("/foo/bar/waldo", "waldo.com", "Piep", false, "foobar", "path_namespace='/foo/bar/waldo'", true);
test_one("/foo/bar/waldo", "waldo.com", "Piep", false, "foobar", "path_namespace='/foo/bar'", true);
test_one("/foo/bar/waldo", "waldo.com", "Piep", false, "foobar", "path_namespace='/foo'", true);
test_one("/foo/bar/waldo", "waldo.com", "Piep", false, "foobar", "path_namespace='/'", true);
test_one("/foo/bar/waldo", "waldo.com", "Piep", false, "foobar", "path_namespace='/quux'", false);
return 0;
}