zenoh_protocol/scouting/hello.rs
1//
2// Copyright (c) 2023 ZettaScale Technology
3//
4// This program and the accompanying materials are made available under the
5// terms of the Eclipse Public License 2.0 which is available at
6// http://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0
7// which is available at https://www.apache.org/licenses/LICENSE-2.0.
8//
9// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0
10//
11// Contributors:
12// ZettaScale Zenoh Team, <zenoh@zettascale.tech>
13//
14use alloc::vec::Vec;
15
16use crate::core::{Locator, WhatAmI, ZenohIdProto};
17
18/// # Hello message
19///
20/// The `Hello` message is used to advertise the locators a zenoh node is reachable at.
21/// The `Hello` message SHOULD be sent in a unicast fashion in response to a [`super::Scout`]
22/// message as shown below:
23///
24/// ```text
25/// A B C
26/// | SCOUT | |
27/// |------------------>| |
28/// | \---------------------------->|
29/// | | |
30/// | HELLO | |
31/// |<------------------| |
32/// | | HELLO |
33/// |<--------------------------------------|
34/// | | |
35/// ```
36///
37/// Moreover, a `Hello` message MAY be sent in the network in a multicast
38/// fashion to advertise the presence of zenoh node. The advertisement operation MAY be performed
39/// periodically as shown below:
40///
41///```text
42/// A B C
43/// | HELLO | |
44/// |------------------>| |
45/// | \---------------------------->|
46/// | | |
47/// ~ ... ~ ... ~
48/// | | |
49/// | HELLO | |
50/// |------------------>| |
51/// | \---------------------------->|
52/// | | |
53/// ~ ... ~ ... ~
54/// | | |
55/// ```
56///
57/// Examples of locators included in the `Hello` message are:
58///
59/// ```text
60/// udp/192.168.1.1:7447
61/// tcp/192.168.1.1:7447
62/// udp/224.0.0.224:7447
63/// tcp/localhost:7447
64/// ```
65///
66/// The `Hello` message structure is defined as follows:
67///
68/// ```text
69/// Header flags:
70/// - L: Locators If L==1 then the list of locators is present, else the src address is the locator
71/// - X: Reserved
72/// - Z: Extensions If Z==1 then zenoh extensions will follow.
73///
74/// 7 6 5 4 3 2 1 0
75/// +-+-+-+-+-+-+-+-+
76/// |Z|X|L| HELLO |
77/// +-+-+-+---------+
78/// | version |
79/// +---------------+
80/// |zid_len|X|X|wai| (*)
81/// +-+-+-+-+-+-+-+-+
82/// ~ [u8] ~ -- ZenohID
83/// +---------------+
84/// ~ <utf8;z8> ~ if Flag(L)==1 -- List of locators
85/// +---------------+
86///
87/// (*) WhatAmI. It indicates the role of the zenoh node sending the HELLO message.
88/// The valid WhatAmI values are:
89/// - 0b00: Router
90/// - 0b01: Peer
91/// - 0b10: Client
92/// - 0b11: Reserved
93/// ```
94///
95pub mod flag {
96 pub const L: u8 = 1 << 5; // 0x20 Locators if L==1 then the list of locators is present, else the src address is the locator
97 // pub const X: u8 = 1 << 6; // 0x40 Reserved
98 pub const Z: u8 = 1 << 7; // 0x80 Extensions if Z==1 then an extension will follow
99}
100
101#[derive(Debug, Clone, PartialEq, Eq)]
102pub struct HelloProto {
103 pub version: u8,
104 pub whatami: WhatAmI,
105 pub zid: ZenohIdProto,
106 pub locators: Vec<Locator>,
107}
108
109impl HelloProto {
110 #[cfg(feature = "test")]
111 #[doc(hidden)]
112 pub fn rand() -> Self {
113 use rand::Rng;
114
115 let mut rng = rand::thread_rng();
116
117 let version: u8 = rng.gen();
118 let zid = ZenohIdProto::default();
119 let whatami = WhatAmI::rand();
120 let locators = if rng.gen_bool(0.5) {
121 Vec::from_iter((1..5).map(|_| Locator::rand()))
122 } else {
123 vec![]
124 };
125 Self {
126 version,
127 zid,
128 whatami,
129 locators,
130 }
131 }
132}