ClockBound Shared Memory Protocol Version 3

November 21, 2025 ยท View on GitHub

This protocol version corresponds with ClockBound daemon and client releases 3.0.0 and greater. The communication between the daemon and client are performed via shared memory. By default the shared memory segment is mapped to a file at path /var/run/clockbound/shm1.

Shared Memory Segment Layout

The byte ordering of data described below is in the native endian of the CPU architecture you are running on. For example, x86_64 and ARM-based Graviton CPUs use little endian.

0                   1                   2                   3
 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                                                               |
+                          Magic Number                         +
|                                                               |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+   8 bytes
|                          Segment Size                         |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 
|   Min Version |   Max Version |          Generation           |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+  16 bytes
|                                                               |
+                           As-Of TSC                           |
|                                                               |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+  24 bytes
|                                                               |
+                                                               |
|                                                               |
+                        As-Of Timestamp                        +  32 bytes
|                                                               |
+                                                               |
|                                                               |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+  40 bytes
|                                                               |
+                                                               |
|                                                               |
+                      Void-After Timestamp                     +  48 bytes
|                                                               |
+                                                               |
|                                                               |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+  56 bytes
|                                                               |
+                            Period                             |
|                                                               |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+  64 bytes
|                                                               |
+                         Period Error                          |
|                                                               |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+  72 bytes
|                                                               |
+                           Bound                               |
|                                                               |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+  80 bytes
|                                                               |
+                       Disruption Count                        |
|                                                               |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+  88 bytes
|                           Max Drift                           |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                         Clock Status                          |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+  96 bytes
|   Disruption  |  Period Shift |PeriodErrShift |    Padding    |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                            Padding                            |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 104 bytes

Description

Magic Number: (u64)

The signature that identifies a ClockBound shared memory segment.

0x41 0x4D 0x5A 0x4E 0x43 0x42 0x02 0x00

Segment Size: (u32)

The size of shared memory segment in bytes.

Mininum Version: (u8)

This field represents the minimum version supported by this layout.

That is the oldest version that is backward compatible with this layout

Maximum Version: (u8)

This fields represents the most recent version of this layout.

For example a Minimum Version of 3 and a Maximum Version of 5 means that clients that know 3, 4, and 5 are supported.

Generation: (u16)

The generation number is increased during updates to the shared memory content by the ClockBound daemon. It is set to an odd number before an update and it is set to an even number after an update is completed. Upon rolling over, the generation is not set to 0 but it is set to 2.

As-Of TSC: (u64)

the TSC counter value used to create the as_of timestamp.

This value can be read by either calling rdtsc on x86 architectures, or cntvct_el0 on aarch64 architectures.

As-Of Timestamp: (i64, i64)

The ClockBound calculated timestamp. This is the time at the TSC timestamp

The two signed 64-bit integers correspond to a libc::timespec's tv_sec and tv_nsec.

Void-After Timestamp: (i64, i64)

The time after which the bound of the clock error should not be trusted.

The two signed 64-bit integers correspond to a libc::timespec's tv_sec and tv_nsec.

Period: (u64)

The fractional part of the scaled period of the TSC

resolution is 1/2^(64 + p_shift), expressed in ppb

Period Error: (u64)

the fractional part of the period error of the Period estimation

resolution is 1/2^(64 + p_err_shift), expressed in ppb

Bound: (i64)

The absolute upper bound on the accuracy with regard to true time at the instant represented by the As-Of Timestamp. The units of this value is nanoseconds.

Disruption Marker: (u64)

The last disruption marker value that the ClockBound daemon has read from the VMClock.

Max Drift: (u32)

The maximum drift rate of the clock between updates of the synchronization daemon, represented in parts per billion (ppb).

Clock Status: (i32)

The clock status. Possible values are:

0 - Unknown: The status of the clock is unknown.

1 - Synchronized: The clock is kept accurate by the synchronization daemon.

2 - FreeRunning: The clock is free running and not updated by the synchronization daemon.

3 - Disrupted: The clock has been disrupted and the accuracy of time cannot be bounded.

Clock Disruption Support: (u8)

The flag which indicates that clock disruption support is enabled.

0 - Clock disruption support is not enabled.

1 - Clock disruption support is enabled.

Period Shift: (u8)

The value used to scale the period.

See the above Period section on how to use this field.

Period Error Shift: (u8)

The value used to scale the period error.

See the above Period Error section on how to use this field.

ClockBound Shared Memory Protocol Version 2

This protocol version corresponds with ClockBound daemon and client releases 2.0.0 and greater. The communication between the daemon and client are performed via shared memory. By default the shared memory segment is mapped to a file at path /var/run/clockbound/shm0.

Shared Memory Segment Layout

The byte ordering of data described below is in the native endian of the CPU architecture you are running on. For example, x86_64 and ARM-based Graviton CPUs use little endian.

 0                   1                   2                   3
 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                                                               |
+                          Magic Number                         +
|                                                               |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                          Segment Size                         |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|            Version            |           Generation          |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                                                               |
+                                                               +
|                                                               |
+                        As-Of Timestamp                        +
|                                                               |
+                                                               +
|                                                               |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                                                               |
+                                                               +
|                                                               |
+                      Void-After Timestamp                     +
|                                                               |
+                                                               +
|                                                               |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                                                               |
+                             Bound                             +
|                                                               |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                                                               |
+                       Disruption Marker                       +
|                                                               |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                           Max Drift                           |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                          Clock Status                         |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Clk Disr Supp |            Padding                            |
+-+-+-+-+-+-+-+-+                                               +
|                                                               |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

Description

Magic Number: (u64)

The signature that identifies a ClockBound shared memory segment.

0x41 0x4D 0x5A 0x4E 0x43 0x42 0x02 0x00

Segment Size: (u32)

The size of shared memory segment in bytes.

Version: (u16)

The version number identifying the contents and layout of the data in the shared memory segment.

Generation: (u16)

The generation number is increased during updates to the shared memory content by the ClockBound daemon. It is set to an odd number before an update and it is set to an even number after an update is completed. Upon rolling over the generation is not set to 0 but it is set to 2.

As-Of Timestamp: (i64, i64)

The CLOCK_MONOTONIC_COARSE timestamp recorded when the bound on clock error was calculated.

The two signed 64-bit integers correspond to a libc::timespec's tv_sec and tv_nsec.

Void-After Timestamp: (i64, i64)

The CLOCK_MONOTONIC_COARSE timestamp beyond which the bound on clock error should not be trusted.

The two signed 64-bit integers correspond to a libc::timespec's tv_sec and tv_nsec.

Bound: (i64)

The absolute upper bound on the accuracy of the CLOCK_REALTIME clock with regard to true time at the instant represented by the As-Of Timestamp. The units of this value is nanoseconds.

Disruption Marker: (u64)

The last disruption marker value that the ClockBound daemon has read from the VMClock.

Max Drift: (u32)

The maximum drift rate of the clock between updates of the synchronization daemon, represented in parts per billion (ppb).

Clock Status: (i32)

The clock status. Possible values are:

0 - Unknown: The status of the clock is unknown.

1 - Synchronized: The clock is kept accurate by the synchronization daemon.

2 - FreeRunning: The clock is free running and not updated by the synchronization daemon.

3 - Disrupted: The clock has been disrupted and the accuracy of time cannot be bounded.

Clock Disruption Support: (u8)

The flag which indicates that clock disruption support is enabled.

0 - Clock disruption support is not enabled.

1 - Clock disruption support is enabled.

ClockBound Shared Memory Protocol Version 1

This protocol version corresponds with ClockBound daemon and client releases 1.0.0 and greater. The communication between the daemon and client are performed via shared memory. By default the shared memory segment is mapped to a file at path /var/run/clockbound/shm.

Shared Memory Segment Layout

The byte ordering of data described below is in the native endian of the CPU architecture you are running on. For example, x86_64 and ARM-based Graviton CPUs use little endian.

 0                   1                   2                   3
 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                                                               |
+                          Magic Number                         +
|                                                               |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                          Segment Size                         |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|            Version            |           Generation          |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                                                               |
+                                                               +
|                                                               |
+                        As-Of Timestamp                        +
|                                                               |
+                                                               +
|                                                               |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                                                               |
+                                                               +
|                                                               |
+                      Void-After Timestamp                     +
|                                                               |
+                                                               +
|                                                               |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                                                               |
+                             Bound                             +
|                                                               |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                           Max Drift                           |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                            Reserved                           |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                          Clock Status                         |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                            Padding                            |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

Description

Magic Number: (u64)

The signature that identifies a ClockBound shared memory segment.

0x41 0x4D 0x5A 0x4E 0x43 0x42 0x02 0x00

Segment Size: (u32)

The size of shared memory segment in bytes.

Version: (u16)

The version number identifying the contents and layout of the data in the shared memory segment.

Generation: (u16)

The generation number is increased during updates to the shared memory content by the ClockBound daemon. It is set to an odd number before an update and it is set to an even number after an update is completed. Upon rolling over the generation is not set to 0 but it is set to 2.

As-Of Timestamp: (i64, i64)

The CLOCK_MONOTONIC_COARSE timestamp recorded when the bound on clock error was calculated.

The two signed 64-bit integers correspond to a libc::timespec's tv_sec and tv_nsec.

Void-After Timestamp: (i64, i64)

The CLOCK_MONOTONIC_COARSE timestamp beyond which the bound on clock error should not be trusted.

The two signed 64-bit integers correspond to a libc::timespec's tv_sec and tv_nsec.

Bound: (i64)

The absolute upper bound on the accuracy of the CLOCK_REALTIME clock with regard to true time at the instant represented by the As-Of Timestamp. The units of this value is nanoseconds.

Max Drift: (u32)

The maximum drift rate of the clock between updates of the synchronization daemon, represented in parts per billion (ppb).

Reserved: (u32)

Space reserved for future use.

Clock Status: (i32)

The clock status. Possible values are:

0 - Unknown: The status of the clock is unknown.

1 - Synchronized: The clock is kept accurate by the synchronization daemon.

2 - FreeRunning: The clock is free running and not updated by the synchronization daemon.

ClockBound Unix Datagram Socket Protocol Version 1

This protocol version corresponds with ClockBound daemon and client releases prior to 1.0.0. The communication between the daemon and client are performed via Unix datagram socket.

Request

Request Header

0123
VTRSVRSV

V, u8: The protocol version of the request (1). T, u8: The request type: Now (1), Before (2), After (3). RSV, u8: Reserved. RSV, u8: Reserved.

Now Request

0 1 2 3
HEADER

HEADER: See header definition above. Now request only has the header. T set to Now (1).

Before/After Request

0 1 2 34 5 6 7 8 9 10 11
HEADEREPOCH

HEADER: See header defintion above. T set to either Before (2) or After (3). EPOCH, u64: The time we are testing against represented as the number of nanoseconds from the unix epoch (Jan 1 1970 UTC)

Response

Response Header

0123
VTFRSV

V, u8: The protocol version of this response. T, u8: The response type. Should always match a valid request type; otherwise returns Error (0). F, u8: Set to 1 if Chrony is not synchronized. Set to 0 otherwise. RSV, u8: Reserved.

Now Response

0 1 2 34 5 6 7 8 9 10 1112 13 14 15 16 17 18 19
HEADEREARLIESTLATEST

HEADER: See header definition above. EARLIEST, u64: Clock Time - Clock Error Bound represented as the number of nanoseconds from the unix epoch (Jan 1 1970 UTC). LATEST, u64: Clock Time + Clock Error Bound represented as the number of nanoseconds from the unix epoch (Jan 1 1970 UTC).

After Response

0 1 2 34
HEADERA

A, u8: Set to 1 (true) if the requested time happened after the latest error bound of the current system time, otherwise 0 (false).

Before Response

0 1 2 34
HEADERB

B, u8: Set to 1 (true) if the requested time happened before the earliest error bound of the current system time, otherwise 0 (false).

Error Response

0 1 2 3
HEADER

HEADER: See header definition above. An error response returns the header with T set to Error (0).