diff options
author | Lukasz Skalski <l.skalski@samsung.com> | 2016-05-25 14:46:10 +0200 |
---|---|---|
committer | Lukasz Skalski <l.skalski@samsung.com> | 2016-05-25 14:46:45 +0200 |
commit | 4267655bc24521da58c89f6a42660638680c4229 (patch) | |
tree | 8f6cb030affbccc50aef6fc2de970f4cbcf8ab5d | |
parent | d6774e513d1a1473bd11913127a3640b6e82b099 (diff) | |
download | dbus-accepted/tizen/common/20160530.131628.tar.gz dbus-accepted/tizen/common/20160530.131628.tar.bz2 dbus-accepted/tizen/common/20160530.131628.zip |
kdbus: always pack message header as as single PAYLOAD_VEC itemsubmit/tizen/20160527.082529accepted/tizen/wearable/20160602.021621accepted/tizen/tv/20160602.021607accepted/tizen/mobile/20160602.021631accepted/tizen/ivi/20160602.021635accepted/tizen/common/20160530.131628
According to PORTING-DBUS1 document [1], the message header in its
entirety must be contained in a single PAYLOAD_VEC item. What's more,
in case of memfd transport, message footer (which contains body signature
and offsets size) has to be attached at the end of message as a yet another
PAYLOAD_VEC item.
[1] https://cgit.freedesktop.org/systemd/systemd/tree/src/libsystemd/sd-bus/PORTING-DBUS1
Change-Id: I282589c0641c1eb97f874fcfd6e3bee6ecacc8ae
-rw-r--r-- | dbus/dbus-message.c | 2 | ||||
-rw-r--r-- | dbus/dbus-transport-kdbus.c | 113 | ||||
-rw-r--r-- | dbus/kdbus-common.c | 9 |
3 files changed, 77 insertions, 47 deletions
diff --git a/dbus/dbus-message.c b/dbus/dbus-message.c index 0792e113..e058b7ad 100644 --- a/dbus/dbus-message.c +++ b/dbus/dbus-message.c @@ -4679,7 +4679,7 @@ _dbus_decode_kmsg (DBusString *data, if (n_unix_fds > n_fds) { _dbus_verbose("Message contains references to more unix fds than were sent %u != %u\n", - n_unix_fds, loader->n_unix_fds); + n_unix_fds, message->n_unix_fds); dbus_message_unref (message); return NULL; } diff --git a/dbus/dbus-transport-kdbus.c b/dbus/dbus-transport-kdbus.c index 80c5b3ec..75cc1808 100644 --- a/dbus/dbus-transport-kdbus.c +++ b/dbus/dbus-transport-kdbus.c @@ -504,30 +504,22 @@ parse_name (const char *name) static int prepare_mfd (int memfd, - const char *header, - uint64_t header_size, const char *body, uint64_t body_size) { - const char *data[] = { header, body }; - uint64_t count[] = { header_size, body_size }; int64_t wr; - size_t p; _dbus_verbose ("sending data via memfd\n"); - for (p = 0; p < sizeof (data) / sizeof (data[0]); ++p) + while (body_size) { - while (count[p]) + wr = write (memfd, body, body_size); + if (wr < 0) { - wr = write (memfd, data[p], count[p]); - if (wr < 0) - { - _dbus_verbose ("writing to memfd failed: (%d) %m\n", errno); - return -1; - } - count[p] -= wr; - data[p] += wr; + _dbus_verbose ("writing to memfd failed: (%d) %m\n", errno); + return -1; } + body_size -= wr; + body += wr; } // seal data - kdbus module needs it @@ -717,6 +709,7 @@ kdbus_write_msg_internal (DBusTransportKdbus *transport, int memfd = -1; const int *unix_fds; unsigned fds_count; + const char* header_data; DBusError error; dbus_uint64_t items_size; @@ -807,47 +800,79 @@ kdbus_write_msg_internal (DBusTransportKdbus *transport, /* build message contents */ item = msg->items; - if (memfd >= 0) + header_data = _dbus_string_get_const_data (header); + + _dbus_verbose ("sending data by vec\n"); + item = _kdbus_item_add_payload_vec (item, + header_size, + (uintptr_t)header_data); + if (body_size > 0) { - if (prepare_mfd (memfd, - _dbus_string_get_const_data (header), header_size, - _dbus_string_get_const_data (body), body_size) == -1) + const char* body_data = _dbus_string_get_const_data (body); + +#ifdef DBUS_ENABLE_VERBOSE_MODE + if (-1 != debug) { - ret_size = -1; - goto out; + debug_str ("Header to send:", header); + debug_str ("Body to send:", body); } +#endif - item = _kdbus_item_add_payload_memfd (item, - 0, - ret_size, - memfd); - } - else - { - const char* header_data = _dbus_string_get_const_data (header); - - _dbus_verbose ("sending data by vec\n"); - item = _kdbus_item_add_payload_vec (item, - header_size, - (uintptr_t)header_data); - if (body_size > 0) + if (memfd >= 0) { - const char* body_data = _dbus_string_get_const_data (body); -#ifdef DBUS_ENABLE_VERBOSE_MODE - if (-1 != debug) + size_t body_offsets_size; + const char *footer_ptr; + + /* determine body offsets size */ + if (ret_size <= 0xFF) + body_offsets_size = 1; + else if (ret_size <= 0xFFFF) + body_offsets_size = 2; + else if (ret_size <= 0xFFFFFFFF) + body_offsets_size = 4; + else + body_offsets_size = 8; + + /* check footer size */ + footer_ptr = body_data + body_size - body_offsets_size -1; + while (footer_ptr >= body_data && (*footer_ptr) != 0) + footer_ptr--; + + if (footer_ptr < body_data) { - debug_str ("Header to send:", header); - debug_str ("Body to send:", body); + ret_size = -1; + goto out; } -#endif + /* prepare memfd for body */ + if (prepare_mfd (memfd, + body_data, + (footer_ptr - body_data) * sizeof(char)) == -1) + { + ret_size = -1; + goto out; + } + + /* body */ + item = _kdbus_item_add_payload_memfd (item, + 0, + (footer_ptr - body_data) * sizeof(char), + memfd); + + /* footer */ + item = _kdbus_item_add_payload_vec (item, + (body_data + body_size - footer_ptr) * sizeof(char), + (uintptr_t)footer_ptr); + } + else + { while (body_size > 0) { dbus_uint64_t part_size = body_size; if (part_size > KDBUS_MSG_MAX_PAYLOAD_VEC_SIZE) - part_size = KDBUS_MSG_MAX_PAYLOAD_VEC_SIZE; + part_size = KDBUS_MSG_MAX_PAYLOAD_VEC_SIZE; _dbus_verbose ("attaching body part\n"); item = _kdbus_item_add_payload_vec (item, @@ -856,8 +881,8 @@ kdbus_write_msg_internal (DBusTransportKdbus *transport, body_data += part_size; body_size -= part_size; } - } - } + } /* memfd */ + } /* body_size */ if (fds_count) item = _kdbus_item_add_fds (item, unix_fds, fds_count); diff --git a/dbus/kdbus-common.c b/dbus/kdbus-common.c index e0af233f..c2c2e0ca 100644 --- a/dbus/kdbus-common.c +++ b/dbus/kdbus-common.c @@ -698,16 +698,21 @@ _kdbus_compute_msg_items_size (kdbus_t *kdbus, { __u64 items_size = 0; + /* header */ + items_size += KDBUS_ITEM_SIZE (sizeof (struct kdbus_vec)); + if (use_memfd) { + /* body */ items_size += KDBUS_ITEM_SIZE (sizeof (struct kdbus_memfd)); + + /* footer */ + items_size += KDBUS_ITEM_SIZE (sizeof (struct kdbus_vec)); } else { __u64 vectors = (body_size + KDBUS_MSG_MAX_PAYLOAD_VEC_SIZE - 1) / KDBUS_MSG_MAX_PAYLOAD_VEC_SIZE; - /* 1st vector -> for header */ - items_size += KDBUS_ITEM_SIZE (sizeof (struct kdbus_vec)); /* subsequent vectors -> parts of body */ items_size += vectors * KDBUS_ITEM_SIZE (sizeof (struct kdbus_vec)); } |