X-Git-Url: https://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?a=blobdiff_plain;f=src%2Flibsystemd%2Fsd-bus%2FGVARIANT-SERIALIZATION;h=5dffc25bb3542523e81a6e6f99d29149c887b216;hb=954871d8ba15911d014f76ed2c7a9492953cf39d;hp=859e2715f9c3081e4de030dee48f6f818b2cb43f;hpb=82c28f5621ad80585eb6c232a988af955a07060c;p=elogind.git diff --git a/src/libsystemd/sd-bus/GVARIANT-SERIALIZATION b/src/libsystemd/sd-bus/GVARIANT-SERIALIZATION index 859e2715f..5dffc25bb 100644 --- a/src/libsystemd/sd-bus/GVARIANT-SERIALIZATION +++ b/src/libsystemd/sd-bus/GVARIANT-SERIALIZATION @@ -1,9 +1,8 @@ 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: +We stay as close to the original dbus1 framing as possible. dbus1 has +the following framing: 1. A fixed header of "yyyyuu" 2. Additional header fields of "a(yv)" @@ -21,86 +20,40 @@ The header consists of the following: y Flags y Protocol version, '1' u Length of the body, i.e. the length of part 4 above - u 32bit Serial number + u Serial number = 12 bytes -This header is then followed by the 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 +slightly extend 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 + u Length of the body, i.e. the length of part 4 above + u Serial number + u Length of the additional header fields array = 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 endianess 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 (as kdbus otherwise uses -exclusively 64bit types, unless there is a strong reason not to), 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. +This has the nice benefit that the beginning of the additional header +fields array is aligned to an 8 byte boundary. Also, in dbus1 +marshalling arrays start with a length value of 32bit, which means in +both dbus1 and gvariant marshallings the size of the header fields +array will be at the same location between bytes 12 and 16. To +visualize that: 0 4 8 12 16 - Common: | E | T | F | V | ... + Common: | E | T | F | V | Body Length | Serial | Fields Length | - dbus1: | (as above) | Body Length | Serial | Fields Length | Fields array ... + dbus1: | ... (as above) ... | Fields array ... - gvariant: | (as above) | Reserved | Cookie | Fields array ... + gvariant: | ... (as above) ... | Fields Length | Fields array ... And that's already it. -Note: to simplify parsing, valid kdbus/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: on kdbus only native endian messages marshalled in gvariant may be sent. If a client receives a message in non-native endianness or in dbus1 marshalling it shall ignore the message.