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}