/ tcp / src / helpers / config.rs
config.rs
 1  // Copyright (c) 2025 ADnet Contributors
 2  // This file is part of the adnet-core library.
 3  // Derived from snarkOS, originally by Provable Inc.
 4  
 5  // Licensed under the Apache License, Version 2.0 (the "License");
 6  // you may not use this file except in compliance with the License.
 7  // You may obtain a copy of the License at:
 8  
 9  // http://www.apache.org/licenses/LICENSE-2.0
10  
11  // Unless required by applicable law or agreed to in writing, software
12  // distributed under the License is distributed on an "AS IS" BASIS,
13  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  // See the License for the specific language governing permissions and
15  // limitations under the License.
16  
17  use std::{
18      io::{self, ErrorKind::*},
19      net::{IpAddr, Ipv4Addr, SocketAddr},
20  };
21  
22  #[cfg(doc)]
23  use crate::protocols::{self, Handshake, Reading, Writing};
24  
25  /// The Tcp's configuration. See the source of [`Config::default`] for the defaults.
26  #[derive(Debug, Clone)]
27  pub struct Config {
28      /// A user-friendly identifier of the Tcp. It is visible in the logs, where it allows Tcp instances to be
29      /// distinguished more easily if multiple are run at the same time.
30      ///
31      /// note: If set to `None` when the configuration is initially created, it will be automatically assigned
32      /// (the string representation of) a sequential, zero-based numeric identifier. So this is essentially never
33      /// `None`, in a running node.
34      pub name: Option<String>,
35      /// The IP address the Tcp's connection listener should bind to.
36      ///
37      /// note: If set to `None`, the Tcp will not listen for inbound connections at all.
38      pub listener_ip: Option<IpAddr>,
39      /// The desired listening port of the Tcp. If [`Config::allow_random_port`] is set to `true`, the Tcp
40      /// will attempt to bind its listener to a different port if the desired one is not available.
41      ///
42      /// note: [`Config::listener_ip`] must not be `None` in order for it to have any effect.
43      pub desired_listening_port: Option<u16>,
44      /// Allow listening on a different port if [`Config::desired_listening_port`] is unavailable.
45      ///
46      /// note: [`Config::listener_ip`] must not be `None` in order for it to have any effect.
47      pub allow_random_port: bool,
48      /// The list of IO errors considered fatal and causing the connection to be dropped.
49      ///
50      /// note: Tcp needs to implement the [`Reading`] and/or [`Writing`] protocol in order for it to have any effect.
51      pub fatal_io_errors: Vec<io::ErrorKind>,
52      /// The maximum number of active connections Tcp can maintain at any given time.
53      ///
54      /// note: This number can very briefly be breached by 1 in case of inbound connection attempts. It can never be
55      /// breached by outbound connection attempts, though.
56      pub max_connections: u16,
57      /// The maximum time (in milliseconds) allowed to establish a raw (before the [`Handshake`] protocol) TCP connection.
58      pub connection_timeout_ms: u16,
59  }
60  
61  impl Config {
62      /// Initializes a new Tcp configuration with a listener address,
63      /// a maximum number of connections, and the default values.
64      pub fn new(listener_address: SocketAddr, max_connections: u16) -> Self {
65          Self {
66              listener_ip: Some(listener_address.ip()),
67              desired_listening_port: Some(listener_address.port()),
68              max_connections,
69              ..Default::default()
70          }
71      }
72  }
73  
74  impl Default for Config {
75      /// Initializes a new Tcp configuration with the default values.
76      fn default() -> Self {
77          fn default_ip() -> Option<IpAddr> {
78              Some(IpAddr::V4(Ipv4Addr::UNSPECIFIED))
79          }
80  
81          Self {
82              name: None,
83              listener_ip: default_ip(),
84              desired_listening_port: None,
85              allow_random_port: true,
86              fatal_io_errors: vec![
87                  ConnectionReset,
88                  ConnectionAborted,
89                  BrokenPipe,
90                  InvalidData,
91                  UnexpectedEof,
92              ],
93              max_connections: 100,
94              connection_timeout_ms: 1_000,
95          }
96      }
97  }