everscale_network/adnl/mod.rs
1//! ## ADNL - Abstract Datagram Network Layer
2//!
3//! ADNL is a UDP-based data transfer protocol. It is a base layer for other protocols, used
4//! in Everscale. It provides no guarantees of reliability, so it should only be used for
5//! small data transfers. There is a support for multipart transfers, but the user must be
6//! prepared, that some parts of them may be lost and full transfer will be lost.
7//!
8//! #### Brief overview
9//!
10//! Each peer has its own keypair. In most cases it is a ed25519 keypair
11//! (see [`KeyPair`]). The public key of this keypair is also called
12//! a **full peer id** ([`NodeIdFull`]). The hash of the TL representation
13//! of its full id is a **short peer id** ([`NodeIdShort`]).
14//!
15//! Each peer remembers unix timestamp (in seconds) at the moment of initialization.
16//! It is called **reinit date** and used to describe peer's state "version".
17//! If other peers see that the reinit date of peer `A` has changed, they must treat
18//! peer `A` as a completely new peer.
19//!
20//! ADNL maintains a state for each peer it has communicated with. This state contains
21//! unique channel keypair, reinit date of the remote peer and sequence numbers of packets
22//! for both directions.
23//!
24//! Communication between peers is done by sending packets through UDP. Each packet length must be
25//! less than MTU (*1500 bytes*). Packets are encrypted with a shared secret key and have some basic
26//! integrity checks (checksum), ordering (sequence numbers, timings) and deduplication
27//! (short packets history). Packet can contain multiple ADNL messages ([`Message`]) and must
28//! address a specific peer by specifying its short or full peer id.
29//!
30//! #### Packet versions
31//!
32//! - **Handshake packet**: when peer `A` sends its first message to the peer `B` it wraps it into
33//! a handshake packet. For each packet peer `A` generates new keypair.
34//! It computes shared secret using `x25519(random_secret_key, peer_B_public_key)` and uses it
35//! to encrypt data. When peer `B` receives this packet it computes shared secret using
36//! `x25519(peer_B_secret_key, random_public_key)` and uses it to decrypt data. So handshake
37//! packet contains peer `B` short id, public key of the random keypair, checksum and encrypted data.
38//!
39//! - **Channel packet**: after channel has been established, each peer will use a smaller packet
40//! structure called channel packet. Instead of generating a new keypair for each packet it will
41//! use shared secret from the channel to encrypt and decrypt data. Channel packet contains
42//! channel id, checksum and encrypted data.
43//!
44//! #### Message types
45//!
46//! - **`Nop`** - an empty message that is only used by the other peer to update the state of our peer.
47//! - **`Custom`** - a one-way message that just contains a raw data. Mostly used by RLDP or other
48//! protocols on top of ADNL.
49//! - **`Query`** - a request to the other peer which in most cases requires a response.
50//! - **`Answer`** - a response to the **`Query`** message.
51//! - **`CreateChannel`** - a special message with the info about newly created channel. Remote peer
52//! should also create a channel and send a confirmation about this.
53//! - **`ConfirmChannel`** - channel confirmation to the **`CreateChannel`** message.
54//! - **`Part`** - special message that is used to split a large message across multiple packets.
55//! After all message parts are received, the data is combined and deserialized into the original
56//! message. Will mostly be used for large **`Custom`**, **`Query`** or **`Answer`** messages.
57//!
58//! #### Channels
59//!
60//! Communication using only handshake packets is quite inefficient, so there is a some kind of
61//! short-lived connections. When new remove peer is added, the channel keypair is also generated.
62//! With the first packet, peer `A` sends a **`CreateChannel`** message where it specifies channel
63//! public key from its side (and the date of its creation). Peer `B` replies with a **`ConfirmChannel`**
64//! message where it specifies same values and the channel public key from its side.
65//!
66//! Each peer can now create four shared secrets: two for encryption and two for decryption. Why two?
67//! Because there are two versions of channels - ordinary and priority. There is not a lot of difference
68//! between them, but some nodes could handle packet from the priority channel first.
69//!
70//! When remove peer is inactive for some time, and any query to it completes with timeout, the channel
71//! is regenerated.
72//!
73//! [`KeyPair`]: everscale_crypto::ed25519::KeyPair
74//! [`NodeIdFull`]: NodeIdFull
75//! [`NodeIdShort`]: NodeIdShort
76//! [`Message`]: crate::proto::adnl::Message
77
78use std::net::{SocketAddr, SocketAddrV4, ToSocketAddrs};
79use std::sync::Arc;
80
81use anyhow::{Context, Result};
82use frunk_core::hlist::{HCons, HList, HNil, Selector};
83use frunk_core::indices::Here;
84
85pub use self::keystore::{Key, Keystore};
86pub use self::node::{Node, NodeMetrics, NodeOptions};
87pub use self::node_id::{ComputeNodeIds, NodeIdFull, NodeIdShort};
88pub use self::peer::{NewPeerContext, PeerFilter};
89pub use self::peers_set::PeersSet;
90
91use crate::subscriber::{MessageSubscriber, QuerySubscriber};
92use crate::util::{DeferredInitialization, NetworkBuilder};
93
94mod channel;
95mod encryption;
96mod handshake;
97mod keystore;
98mod node;
99mod node_id;
100mod packet_view;
101mod peer;
102mod peers_set;
103mod ping_subscriber;
104mod queries_cache;
105mod socket;
106mod transfer;
107
108pub(crate) type Deferred = Result<Arc<Node>>;
109
110impl DeferredInitialization for Deferred {
111 type Initialized = Arc<Node>;
112
113 fn initialize(self) -> Result<Self::Initialized> {
114 let adnl = self?;
115 adnl.start()?;
116 Ok(adnl)
117 }
118}
119
120impl NetworkBuilder<HNil, (Here, Here)> {
121 /// Creates a basic network layer that is an ADNL node
122 ///
123 /// See [`with_adnl_ext`] if you need a node with a peer filter
124 ///
125 /// [`with_adnl_ext`]: fn@crate::util::NetworkBuilder::with_adnl_ext
126 ///
127 /// # Examples
128 ///
129 /// ```
130 /// # use anyhow::Result;
131 /// # use everscale_network::{adnl, NetworkBuilder};
132 /// #[tokio::main]
133 /// async fn main() -> Result<()> {
134 /// let keystore = adnl::Keystore::builder()
135 /// .with_tagged_key([0; 32], 0)?
136 /// .build();
137 ///
138 /// let options = adnl::NodeOptions::default();
139 ///
140 /// let adnl = NetworkBuilder::with_adnl("127.0.0.1:10000", keystore, options).build()?;
141 ///
142 /// Ok(())
143 /// }
144 /// ```
145 pub fn with_adnl<T>(
146 addr: T,
147 keystore: Keystore,
148 options: NodeOptions,
149 ) -> NetworkBuilder<HCons<Deferred, HNil>, (Here, Here)>
150 where
151 T: ToSocketAddrs,
152 {
153 NetworkBuilder(
154 HCons {
155 head: parse_socket_addr(addr)
156 .and_then(|addr| Node::new(addr, keystore, options, None)),
157 tail: HNil,
158 },
159 Default::default(),
160 )
161 }
162
163 /// Creates a basic network layer that is an ADNL node with additional filter
164 ///
165 /// # Examples
166 ///
167 /// ```
168 /// # use std::net::SocketAddrV4;
169 /// # use std::sync::Arc;
170 /// # use anyhow::Result;
171 /// # use everscale_network::{adnl, NetworkBuilder};
172 /// struct MyFilter;
173 ///
174 /// impl adnl::PeerFilter for MyFilter {
175 /// fn check(
176 /// &self,
177 /// ctx: adnl::NewPeerContext,
178 /// addr: SocketAddrV4,
179 /// peer_id: &adnl::NodeIdShort,
180 /// ) -> bool {
181 /// // Allow only non-loopback IPs
182 /// !addr.ip().is_loopback()
183 /// }
184 /// }
185 ///
186 /// #[tokio::main]
187 /// async fn main() -> Result<()> {
188 /// let keystore = adnl::Keystore::builder()
189 /// .with_tagged_key([0; 32], 0)?
190 /// .build();
191 ///
192 /// let options = adnl::NodeOptions::default();
193 ///
194 /// let peer_filter = Arc::new(MyFilter);
195 ///
196 /// let adnl = NetworkBuilder::with_adnl_ext("127.0.0.1:10000", keystore, options, peer_filter)
197 /// .build()?;
198 ///
199 /// Ok(())
200 /// }
201 /// ```
202 pub fn with_adnl_ext<T>(
203 addr: T,
204 keystore: Keystore,
205 options: NodeOptions,
206 peer_filter: Arc<dyn PeerFilter>,
207 ) -> NetworkBuilder<HCons<Deferred, HNil>, (Here, Here)>
208 where
209 T: ToSocketAddrs,
210 {
211 NetworkBuilder(
212 HCons {
213 head: parse_socket_addr(addr)
214 .and_then(|addr| Node::new(addr, keystore, options, Some(peer_filter))),
215 tail: HNil,
216 },
217 Default::default(),
218 )
219 }
220}
221
222impl<L, A, R> NetworkBuilder<L, (A, R)>
223where
224 L: HList + Selector<Deferred, A>,
225{
226 /// Adds query subscriber if ADNL was successfully initialized.
227 ///
228 /// # Examples
229 ///
230 /// ```
231 /// # use std::sync::Arc;
232 /// # use std::borrow::Cow;
233 /// # use anyhow::Result;
234 /// # use everscale_network::{adnl, NetworkBuilder, QuerySubscriber, QueryConsumingResult, SubscriberContext};
235 /// struct Service;
236 ///
237 /// #[async_trait::async_trait]
238 /// impl QuerySubscriber for Service {
239 /// async fn try_consume_query<'a>(
240 /// &self,
241 /// _ctx: SubscriberContext<'a>,
242 /// _constructor: u32,
243 /// _query: Cow<'a, [u8]>,
244 /// ) -> Result<QueryConsumingResult<'a>> {
245 /// Ok(QueryConsumingResult::Consumed(None))
246 /// }
247 /// }
248 ///
249 /// #[tokio::main]
250 /// async fn main() -> Result<()> {
251 /// let keystore = adnl::Keystore::builder()
252 /// .with_tagged_key([0; 32], 0)?
253 /// .build();
254 ///
255 /// let options = adnl::NodeOptions::default();
256 ///
257 /// let adnl = NetworkBuilder::with_adnl("127.0.0.1:10000", keystore, options)
258 /// .with_query_subscriber(Arc::new(Service))
259 /// .build()?;
260 ///
261 /// Ok(())
262 /// }
263 /// ```
264 pub fn with_query_subscriber(self, subscriber: Arc<dyn QuerySubscriber>) -> Self {
265 if let Ok(adnl) = self.0.get() {
266 adnl.add_query_subscriber(subscriber).ok();
267 }
268 self
269 }
270
271 /// Adds custom message subscriber if ADNL was successfully initialized.
272 ///
273 /// # Examples
274 ///
275 /// ```
276 /// # use std::sync::Arc;
277 /// # use anyhow::Result;
278 /// # use everscale_network::{adnl, MessageSubscriber, NetworkBuilder, SubscriberContext};
279 /// struct Service;
280 ///
281 /// #[async_trait::async_trait]
282 /// impl MessageSubscriber for Service {
283 /// async fn try_consume_custom<'a>(
284 /// &self,
285 /// _ctx: SubscriberContext<'a>,
286 /// _constructor: u32,
287 /// _data: &'a [u8],
288 /// ) -> Result<bool> {
289 /// Ok(true)
290 /// }
291 /// }
292 ///
293 /// #[tokio::main]
294 /// async fn main() -> Result<()> {
295 /// let keystore = adnl::Keystore::builder()
296 /// .with_tagged_key([0; 32], 0)?
297 /// .build();
298 ///
299 /// let options = adnl::NodeOptions::default();
300 ///
301 /// let adnl = NetworkBuilder::with_adnl("127.0.0.1:10000", keystore, options)
302 /// .with_message_subscriber(Arc::new(Service))
303 /// .build()?;
304 ///
305 /// Ok(())
306 /// }
307 /// ```
308 pub fn with_message_subscriber(self, subscriber: Arc<dyn MessageSubscriber>) -> Self {
309 if let Ok(adnl) = self.0.get() {
310 adnl.add_message_subscriber(subscriber).ok();
311 }
312 self
313 }
314}
315
316fn parse_socket_addr<T: ToSocketAddrs>(addr: T) -> Result<SocketAddrV4> {
317 match addr
318 .to_socket_addrs()
319 .context("Failed to parse socket addr")?
320 .next()
321 {
322 Some(SocketAddr::V4(addr)) => Ok(addr),
323 Some(SocketAddr::V6(_)) => anyhow::bail!("IPv6 is not supported"),
324 None => anyhow::bail!("Invalid ip address"),
325 }
326}