Session Establishment (INIT & OPEN)

Unicast session establishment uses a two-phase handshake consisting of four messages:

  1. INIT SYN — initiator proposes session parameters.

  2. INIT ACK — responder accepts, may modify parameters, and issues a challenge cookie.

  3. OPEN SYN — initiator confirms parameters and returns the cookie.

  4. 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
+---------------+

Flag Constants

Flag Bit Value

A

5

0x20

S

6

0x40

Z

7

0x80

Packed Byte

Sub-field Bits Meaning

zid_len

7:4

Actual ZID byte count = 1 + zid_len (1–16)

X

3:2

Reserved (zero)

WAI

1:0

WhatAmI: 0b00=Router, 0b01=Peer, 0b10=Client

Resolution Byte

Sub-field Bits Meaning

FSN

1:0

Frame/Fragment Sequence Number resolution

RID

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.

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
+---------------+

Flag Constants

Flag Bit Value

A

5

0x20

T

6

0x40

Z

7

0x80

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 LowLatency

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.