Difference between revisions of "Binary protocol"
(→See also: Document the Wireshark version.) |
(→Well-known numbers: Document the default buffer size in 5.0.) |
||
Line 11: | Line 11: | ||
:ff18::efc0:4a42 | :ff18::efc0:4a42 | ||
;Maximum packet size | ;Maximum packet size | ||
− | :1024 bytes (payload only, not including UDP / IP headers)<br />In versions [[Version 4.0|4.0]] through [[Version 4.7|4.7]], the receive buffer has a fixed size of 1024 bytes. When longer packets are received, the trailing data is simply ignored. Since [[version 4.8]], the buffer size can be configured. | + | :1024 bytes (payload only, not including UDP / IP headers)<br />In versions [[Version 4.0|4.0]] through [[Version 4.7|4.7]], the receive buffer has a fixed size of 1024 bytes. When longer packets are received, the trailing data is simply ignored. Since [[version 4.8]], the buffer size can be configured. [[Version 5.0]] will increase the default buffer size to ''1452 bytes'' (the maximum payload size when using UDP/IPv6 over Ethernet). |
== Protocol structure == | == Protocol structure == |
Revision as of 12:11, 24 September 2010
The binary protocol is the protocol implemented by the Network plugin and some external implementations to exchange data collected by collectd or to send data to an instance of collectd.
Until the Network plugin has been factorized out into a library, it is useful to have some documentation to reimplement it.
Contents
Well-known numbers
- Default UDP port
- 25826
- Default IPv4 Multicast group
- 239.192.74.66
- Default IPv6 multicast group
- ff18::efc0:4a42
- Maximum packet size
- 1024 bytes (payload only, not including UDP / IP headers)
In versions 4.0 through 4.7, the receive buffer has a fixed size of 1024 bytes. When longer packets are received, the trailing data is simply ignored. Since version 4.8, the buffer size can be configured. Version 5.0 will increase the default buffer size to 1452 bytes (the maximum payload size when using UDP/IPv6 over Ethernet).
Protocol structure
Each packet consists of one or more so called “parts”. Each part starts with the same four bytes: Two bytes that specify the “part type” (what kind of information is enclosed in the part) and two bytes which specify the length of the part, including the four header bytes itself. The maximum length of payload in any part is therefore 65531 bytes.
Using this layout, clients can determine the length of a part they don't know and lets them skip unknown data. This makes the protocol forward compatible so that new features can be added easily.
There are two part layouts that are used for a couple of “types”: numeric (an 8 byte integer) and string.
Numeric parts
Numeric integer values, e. g. the interval and time values, are transferred using 8 byte integers. The length field of those parts must therefore always be set to 12.
String parts
Strings are transferred including a null byte at the end. In the example you can see the encoding of the string “foobar”. The string is six characters long, followed by a null-byte and appended to a four byte header, leading to a length of 11 bytes for this part.
Value parts
Value parts encode an actual data sample. Preceding time, plugin, plugin instance, type, and type instance parts must have set the context for the data sample. The value part consists of:
- Type
0x0006
- Length (16 bit field)
- Number of values (16 bit field)
- Values, for each one:
- Data type code (8 bit field)
-
COUNTER
→ 0 -
GAUGE
→ 1 -
DERIVE
→ 2 -
ABSOLUTE
→ 3
-
- Value (64 bit field)
-
COUNTER
→ network (big endian) unsigned integer -
GAUGE
→ x86 (little endian) double -
DERIVE
→ network (big endian) signed integer -
ABSOLUTE
→ network (big endian) unsigned integer
-
- Data type code (8 bit field)
Many data samples have a single value, such as "cpu" (see types.db(5)), but others have multiple values, such as "disk_merged", which has read and write values.
Part types
The following numeric types are currently used to identify the type of a “part”. Defines are available from src/network.h.
ID | Name | Data type | Comment |
---|---|---|---|
0x0000
|
Host | String | The name of the host to associate with subsequent data values |
0x0001
|
Time | Numeric | The timestamp to associate with subsequent data values, unix time format (seconds since epoch) |
0x0002
|
Plugin | String | The plugin name to associate with subsequent data values, e.g. "cpu" |
0x0003
|
Plugin instance | String | The plugin instance name to associate with subsequent data values, e.g. "1" |
0x0004
|
Type | String | The type name to associate with subsequent data values, e.g. "cpu" |
0x0005
|
Type instance | String | The type instance name to associate with subsequent data values, e.g. "idle" |
0x0006
|
Values | other | Data values, see above |
0x0007
|
Interval | Numeric | Interval used to set the "step" when creating new RRDs unless rrdtool plugin forces StepSize. Also used to detect values that have timed out. |
0x0100
|
Message (notifications) | String | |
0x0101
|
Severity | Numeric | |
0x0200
|
Signature (HMAC-SHA-256) | other (todo) | |
0x0210
|
Encryption (AES-256/OFB/SHA-1) | other (todo) |
Implementations
- Small Python script by Adrian Perez
- PacketWriter.java of jcollectd
- Of course the Network plugin (src/network.c) of collectd itself
- Ruby implementation by Astro.
- erlang-collectd, an Erlang implementation by Astro
See also
- Network plugin
- The network protocol analyzer Wireshark supports dissecting this binary protocol since version 1.4. The code can be found in epan/dissectors/packet-collectd.c.