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}