Session Establishment (INIT & OPEN)
Unicast session establishment uses a two-phase handshake consisting of four messages:
-
INIT SYN — initiator proposes session parameters.
-
INIT ACK — responder accepts, may modify parameters, and issues a challenge cookie.
-
OPEN SYN — initiator confirms parameters and returns the cookie.
-
OPEN ACK — responder activates the session.
This two-phase design separates negotiation (INIT) from activation (OPEN) and allows the cookie-based replay-prevention mechanism without a separate challenge/response round.
If at any point the responder cannot accept the session (wrong version, failed authentication, resource limits) it MUST reply with CLOSE instead of the next handshake message.
Full Handshake Flow
A B | | | [TCP connect / link up] | |─────────────────────────>| | | | INIT SYN (A=0) | propose version, ZID, WAI, resolution, batch_size |─────────────────────────>| | | | INIT ACK (A=1) | accept params; reply with cookie |<─────────────────────────| | | | OPEN SYN (A=0) | echo cookie; propose lease + initial_sn |─────────────────────────>| | | | OPEN ACK (A=1) | confirm; propose own lease + initial_sn |<─────────────────────────| | | | FRAME / direct network | session is live | messages | low-latency mode skips FRAME batching |<────────────────────────>|
Multicast Sessions (JOIN)
Multicast sessions use the JOIN message instead of INIT/OPEN. JOIN is self-contained and requires no handshake; see JOIN.
INIT Message (0x01)
INIT is used only on unicast transports.
Wire Format
Flags:
A If A==0 → InitSyn (proposal).
If A==1 → InitAck (response + cookie).
S If S==1 → resolution and batch_size fields are present.
InitAck with S==0 means the responder accepts the proposed values unchanged.
Z If Z==1 → extension chain follows.
7 6 5 4 3 2 1 0
+-+-+-+-+-+-+-+-+
|Z|S|A| INIT | ID = 0x01
+-+-+-+---------+
| version | Protocol version (u8). Current: 0x09.
+---------------+
|zid_len|X|X|WAI| Packed byte (see below)
+-+-+-+-+-+-+-+-+
~ ZID ~ ZenohID: (1 + zid_len) bytes
+---------------+
|X|X|X|X|RID|FSN| if S==1: Resolution byte
+---------------+
| batch_lo | if S==1: Maximum batch size (u16 LE, little-endian)
+---------------+
| batch_hi |
+---------------+
~ <u8;z16> ~ Cookie — present in InitAck (A==1) ONLY
+---------------+
~ [InitExts] ~ if Z==1
+---------------+
Packed Byte
| Sub-field | Bits | Meaning |
|---|---|---|
|
7:4 |
Actual ZID byte count = 1 + zid_len (1–16) |
|
3:2 |
Reserved (zero) |
|
1:0 |
WhatAmI: 0b00=Router, 0b01=Peer, 0b10=Client |
Resolution Byte
| Sub-field | Bits | Meaning |
|---|---|---|
|
1:0 |
Frame/Fragment Sequence Number resolution |
|
3:2 |
Request ID resolution |
Reserved |
7:4 |
MUST be zero |
Resolution codes: 0b00=8-bit, 0b01=16-bit, 0b10=32-bit (default), 0b11=64-bit.
Default resolution byte: 0x0A (both FSN and RID at 32-bit).
Batch Size
A u16 encoded in little-endian (2 fixed bytes, not VLE) representing the maximum batch size the sender can receive in bytes.
Default: 65 535.
The effective batch size for the session is the minimum of the two nodes' advertised values.
Cookie (InitAck only)
An opaque byte array (<u8;z16>) generated by the responder.
The initiator MUST return this cookie unchanged in OpenSyn.
The cookie is used for replay prevention and optionally carries cryptographic state for authentication extensions.
INIT Extensions
| Ext ID | Type | M | Extension |
|---|---|---|---|
0x1 |
Unit |
N |
QoS — negotiates QoS transport lanes |
0x1 |
Z64 |
N |
QoSLink — multilink QoS metadata (same numeric ID, different encoding) |
0x2 |
ZBuf |
N |
Shm — shared-memory capability probe; emitted only by implementations built with shared-memory support |
0x3 |
ZBuf |
N |
Auth — opaque authentication payload exchanged by the implementation |
0x4 |
ZBuf |
N |
MultiLink — multilink probe payload |
0x5 |
Unit |
N |
LowLatency — requests low-latency unicast mode |
0x6 |
Unit |
N |
Compression — requests link-level compression |
0x7 |
Z64 |
N |
Patch — protocol patch version (u8 encoded as z64) |
0x8 |
ZBuf |
N |
RegionName — administrative region identifier |
Patch extension values:
-
0(absent): base protocol as released in Zenoh 1.0.0. -
>= 1: fragmentation First/Drop markers supported (FRAGMENT ext IDs 0x2 and 0x3).
Extensions 0x1 (QoS) and 0x1 (QoSLink) share the same ID but differ by ENC bits in the extension header (Unit vs Z64).
Receivers MUST distinguish them by ENC.
The Shm extension is feature-gated in the current implementations and is absent when shared-memory support is not compiled in.
|
OPEN Message (0x02)
OPEN finalises the transport link. It is used only on unicast transports.
Wire Format
Flags:
A If A==0 → OpenSyn (confirm cookie + propose lease).
If A==1 → OpenAck (accept + propose own lease).
T If T==1 → lease duration is in seconds.
If T==0 → lease duration is in milliseconds.
Z If Z==1 → extension chain follows.
7 6 5 4 3 2 1 0
+-+-+-+-+-+-+-+-+
|Z|T|A| OPEN | ID = 0x02
+-+-+-+---------+
% lease % VLE-encoded lease duration (unit per T flag)
+---------------+
% initial_sn % VLE-encoded initial sequence number
+---------------+
~ <u8;z16> ~ Cookie (OpenSyn, A==0 only) — MUST match the cookie from InitAck
+---------------+
~ [OpenExts] ~ if Z==1
+---------------+
Lease
The proposed lease duration for the session. Both sides propose a lease; the effective lease is the minimum of the two values. The session expires if no message (including KEEP_ALIVE) is received within the effective lease period. See Keep-Alive. When low-latency mode is negotiated, OPEN still carries the same lease fields; only the post-handshake transport codec changes.
Initial Sequence Number
A randomly chosen starting value for the sender’s sequence number.
MUST fall within the range [0, 2^FSN_bits − 1] where FSN_bits is determined by the negotiated FSN resolution.
OpenSyn Extensions
| Ext ID | Type | M | Extension |
|---|---|---|---|
0x1 |
Unit |
N |
QoS — confirms QoS transport-lane use |
0x2 |
Z64 |
N |
Shm — shared-memory probe response; emitted only by implementations built with shared-memory support |
0x3 |
ZBuf |
N |
Auth — opaque authentication payload |
0x4 |
ZBuf |
N |
MultiLinkSyn — multilink challenge/payload |
0x5 |
Unit |
N |
LowLatency — confirms low-latency mode |
0x6 |
Unit |
N |
Compression — confirms compression |
0x7 |
Z64 |
N |
RemoteBound — implementation-defined south-bound routing hint |
OpenAck Extensions
| Ext ID | Type | M | Extension |
|---|---|---|---|
0x1 |
Unit |
N |
QoS — QoS transport lanes accepted |
0x2 |
Z64 |
N |
Shm — shared-memory probe response; emitted only by implementations built with shared-memory support |
0x3 |
ZBuf |
N |
Auth — opaque authentication payload |
0x4 |
Unit |
N |
MultiLinkAck — multilink acknowledgement |
0x5 |
Unit |
N |
LowLatency — low-latency mode accepted |
0x6 |
Unit |
N |
Compression — compression accepted |
0x7 |
Z64 |
N |
RemoteBound — implementation-defined south-bound routing hint |
Parameter Negotiation Rules
| Parameter | Negotiation rule |
|---|---|
Protocol version |
InitSyn proposes; if responder does not support it, replies CLOSE (UNSUPPORTED) |
Resolution (FSN, RID) |
Responder MAY lower resolution in InitAck (S==1); MUST NOT raise it |
Batch size |
Effective value = min(initiator, responder) |
Lease |
Effective value = min(OpenSyn, OpenAck) |
Initial SN |
Each side uses its own proposed value as its starting SN |
QoS lanes |
Supported only if both sides include the QoS extension |
Transport style |
FRAME/FRAGMENT transport is used by default; direct network-message transport is used only if both sides include |
For interoperability with the validated zenoh-rust baseline, a unicast session does not combine LowLatency and QoS transport lanes on the same link.
Session Teardown
An active session is terminated with a CLOSE message.