2.2.2.1.1 Common Header

The Common Header is used as part of the information exchanged prior to any requests or responses that are included in the exchange. Each channel is responsible for defining its own inner protocol and message types.

Message deserialization is split into two phases. The first phase consists of parsing the header, validating authenticity, deduping, and decryption. In the second part of the deserialization the Payload field is sent to the owner to manage.


0


1


2


3


4


5


6


7


8


9

1
0


1


2


3


4


5


6


7


8


9

2
0


1


2


3


4


5


6


7


8


9

3
0


1

Signature

MessageLength

Version

MessageType

MessageFlags

SequenceNumber

RequestID

...

FragmentIndex

FragmentCount

SessionID

...

ChannelID

...

Next Header

Next Header Size

Payload (variable)

...

...

...

HMAC (variable)

...

...

...

Signature (2 bytes): Fixed signature, which is always 0x3030 (0011 0000 0011 0000 binary).

MessageLength (2 bytes): Entire message length in bytes including signature.

Version (1 byte): Protocol version the sender is using. For this protocol the version is always 3. Lower values indicate older versions of the protocol that are not covered by this document.

MessageType (1 byte): Indicates current message type.

Value

Meaning

0

None

1

Discovery

2

Connect

3

Control

4

Session

5

Ack

7

Disconnect

MessageFlags (2 bytes): A value describing the message properties.

Value

Meaning

ShouldAck
0x0001

The caller expects ACK to be sent back to confirm that the message has been received.

HasHMAC
0x0002

The message contains a hashed message authentication code which will be validated by the receiver. If not set, the HMAC field is not present. See “HMAC” below.

SessionEncrypted
0x0004

If true, indicates that the message is encrypted at the session level. This is false for non-session messages (which don’t require encryption/decryption).

WakeTarget
0x0008

If true, indicates whether the remote application should be woken up.<1>

SequenceNumber (4 bytes): Current message number for this session.

RequestID (8 bytes): A monotonically increasing number, generated on the sending side, that uniquely identifies the message. It can then be used to correlate response messages to their corresponding request messages.

FragmentIndex (2 bytes): Current fragment for current message.

FragmentCount (2 bytes): Number of total fragments for current message.

SessionID (8 bytes): ID representing the session.

ChannelID (8 bytes): Zero if the SessionID is zero.

Next Header (1 byte): If an additional header record is included, this value indicates the type. Some values are implementation-specific. <2>

Value

Meaning

0

No more headers.

1

ReplyToID. If included, the payload would contain a Next Header Size-sized ID of the message to which this message responds.

2

Correlation vector. A uniquely identifiable payload meant to identify communication over devices.

3

Watermark ID. Identifies the last seen message that both participants can agree upon.

Next Header Size (1 byte): Amount of data in the next header record (so clients can skip).

Payload (variable): The encrypted payload.

HMAC (variable): Not present if MessageFlags::HasHMAC is not set. Only required for Control and Session messages.

Each channel is responsible for defining its own inner protocol and message types.

Message deserialization will therefore be split into two phases. With the first phase consisting of the parsing header, validating authenticity, deduping, and decryption. The Payload field will be passed up to the owner to manage the second part of the deserialization.