snarkos_node_tcp/helpers/
config.rs

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