summaryrefslogtreecommitdiffstats
path: root/src/libsystemd/sd-bus/GVARIANT-SERIALIZATION
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-27 13:00:47 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-27 13:00:47 +0000
commit2cb7e0aaedad73b076ea18c6900b0e86c5760d79 (patch)
treeda68ca54bb79f4080079bf0828acda937593a4e1 /src/libsystemd/sd-bus/GVARIANT-SERIALIZATION
parentInitial commit. (diff)
downloadsystemd-upstream.tar.xz
systemd-upstream.zip
Adding upstream version 247.3.upstream/247.3upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'src/libsystemd/sd-bus/GVARIANT-SERIALIZATION')
-rw-r--r--src/libsystemd/sd-bus/GVARIANT-SERIALIZATION105
1 files changed, 105 insertions, 0 deletions
diff --git a/src/libsystemd/sd-bus/GVARIANT-SERIALIZATION b/src/libsystemd/sd-bus/GVARIANT-SERIALIZATION
new file mode 100644
index 0000000..973a063
--- /dev/null
+++ b/src/libsystemd/sd-bus/GVARIANT-SERIALIZATION
@@ -0,0 +1,105 @@
+How we use GVariant for serializing D-Bus messages
+--------------------------------------------------
+
+We stay close to the original dbus1 framing as possible, but make
+certain changes to adapt for GVariant. dbus1 has the following
+framing:
+
+ 1. A fixed header of "yyyyuu"
+ 2. Additional header fields of "a(yv)"
+ 3. Padding with NUL bytes to pad up to next 8byte boundary
+ 4. The body
+
+Note that the body is not padded at the end, the complete message
+hence might have a non-aligned size. Reading multiple messages at once
+will hence result in possibly unaligned messages in memory.
+
+The header consists of the following:
+
+ y Endianness, 'l' or 'B'
+ y Message Type
+ y Flags
+ y Protocol version, '1'
+ u Length of the body, i.e. the length of part 4 above
+ u 32bit Serial number
+
+ = 12 bytes
+
+This header is then followed by the fields array, whose first value is
+a 32bit array size.
+
+When using GVariant we keep the basic structure in place, only
+slightly alter the header, and define protocol version '2'. The new
+header:
+
+ y Endianness, 'l' or 'B'
+ y Message Type
+ y Flags
+ y Protocol version, '2'
+ u Reserved, must be 0
+ t 64bit Cookie
+
+ = 16 bytes
+
+This is then followed by the GVariant fields array ("a{tv}"), and
+finally the actual body as variant (v). Putting this altogether a
+packet on dbus2 hence qualifies as a fully compliant GVariant
+structure of (yyyyuta{tv}v).
+
+For details on gvariant, see:
+
+https://people.gnome.org/~desrt/gvariant-serialisation.pdf
+
+Regarding the framing of dbus2, also see:
+
+https://wiki.gnome.org/Projects/GLib/GDBus/Version2
+
+The first four bytes of the header are defined the same way for dbus1
+and dbus2. The first bytes contain the endianness field and the
+protocol version, so that the remainder of the message can be safely
+made sense of just by looking at the first 32bit.
+
+Note that the length of the body is no longer included in the header
+on dbus2! In fact, the message size must be known in advance, from the
+underlying transport in order to parse dbus2 messages, while it is
+directly included in dbus1 message headers. This change of semantics
+is an effect of GVariant's basic design.
+
+The serial number has been renamed cookie and has been extended from
+32bit to 64bit. It is recommended to avoid the higher 32bit of the
+cookie field though, to simplify compatibility with dbus1 peers. Note
+that not only the cookie/serial field in the fixed header, but also
+the reply_cookie/reply_serial additional header field has been
+increased from 32bit to 64bit, too!
+
+The header field identifiers have been extended from 8bit to
+64bit. This has been done to simplify things, and has no effect
+on the serialization size, as due to alignment for each 8bit
+header field identifier 56 bits of padding had to be added.
+
+Note that the header size changed, due to these changes. However,
+consider that on dbus1 the beginning of the fields array contains the
+32bit array size (since that is how arrays are encoded on dbus1),
+thus, if one considers that size part of the header, instead of the
+array, the size of the header on dbus1 and dbus2 stays identical, at
+16 bytes.
+
+ 0 4 8 12 16
+ Common: | E | T | F | V | ...
+
+ dbus1: | (as above) | Body Length | Serial | Fields Length | Fields array ...
+
+ gvariant: | (as above) | Reserved | Cookie | Fields array ...
+
+And that's already it.
+
+Note: To simplify parsing, valid dbus2 messages must include the entire
+ fixed header and additional header fields in a single non-memfd
+ message part. Also, the signature string of the body variant all the
+ way to the end of the message must be in a single non-memfd part
+ too. The parts for this extended header and footer can be the same
+ one, and can also continue any amount of additional body bytes.
+
+Note: The GVariant "MAYBE" type is not supported, so that messages can
+ be fully converted forth and back between dbus1 and gvariant
+ representations.