Skip to main content

quic_p2p/
peer_config.rs

1// Copyright 2019 MaidSafe.net limited.
2//
3// This SAFE Network Software is licensed to you under the MIT license <LICENSE-MIT
4// http://opensource.org/licenses/MIT> or the Modified BSD license <LICENSE-BSD
5// https://opensource.org/licenses/BSD-3-Clause>, at your option. This file may not be copied,
6// modified, or distributed except according to those terms. Please review the Licences for the
7// specific language governing permissions and limitations relating to use of the SAFE Network
8// Software.
9
10use crate::QuicP2pError;
11use crate::R;
12use std::sync::Arc;
13use std::time::Duration;
14
15/// Default interval within which if we hear nothing from the peer we declare it offline to us.
16///
17/// This is based on average time in which routers would close the UDP mapping to the peer if they
18/// see no conversation between them.
19///
20/// The value is in milliseconds.
21pub const DEFAULT_IDLE_TIMEOUT_MSEC: u64 = 30_000; // 30secs
22/// Default Interval to send keep-alives if we are idling so that the peer does not disconnect from
23/// us declaring us offline. If none is supplied we'll default to the documented constant.
24///
25/// The value is in milliseconds.
26pub const DEFAULT_KEEP_ALIVE_INTERVAL_MSEC: u32 = 10_000; // 10secs
27
28pub fn new_client_cfg(
29    idle_timeout_msec: u64,
30    keep_alive_interval_msec: u32,
31) -> R<quinn::ClientConfig> {
32    let mut cfg = quinn::ClientConfigBuilder::default().build();
33    let crypto_cfg =
34        Arc::get_mut(&mut cfg.crypto).expect("the crypto config should not be shared yet");
35    crypto_cfg
36        .dangerous()
37        .set_certificate_verifier(SkipServerVerification::new());
38    cfg.transport = Arc::new(new_transport_cfg(
39        idle_timeout_msec,
40        keep_alive_interval_msec,
41    )?);
42    Ok(cfg)
43}
44
45pub fn new_our_cfg(
46    idle_timeout_msec: u64,
47    keep_alive_interval_msec: u32,
48    our_cert: quinn::Certificate,
49    our_key: quinn::PrivateKey,
50) -> R<quinn::ServerConfig> {
51    let mut our_cfg_builder = {
52        let mut our_cfg = quinn::ServerConfig::default();
53        our_cfg.transport = Arc::new(new_transport_cfg(
54            idle_timeout_msec,
55            keep_alive_interval_msec,
56        )?);
57
58        quinn::ServerConfigBuilder::new(our_cfg)
59    };
60    let _ = our_cfg_builder
61        .certificate(quinn::CertificateChain::from_certs(vec![our_cert]), our_key)?
62        .use_stateless_retry(true);
63
64    Ok(our_cfg_builder.build())
65}
66
67fn new_transport_cfg(
68    idle_timeout_msec: u64,
69    keep_alive_interval_msec: u32,
70) -> R<quinn::TransportConfig> {
71    let mut transport_config = quinn::TransportConfig::default();
72    let _ = transport_config
73        .max_idle_timeout(Some(Duration::from_millis(idle_timeout_msec)))
74        .map_err(|e| QuicP2pError::Configuration { e: e.to_string() })?;
75    let _ = transport_config
76        .keep_alive_interval(Some(Duration::from_millis(keep_alive_interval_msec.into())));
77    Ok(transport_config)
78}
79
80/// Dummy certificate verifier that treats any certificate as valid.
81struct SkipServerVerification;
82
83impl SkipServerVerification {
84    fn new() -> Arc<Self> {
85        Arc::new(Self)
86    }
87}
88
89impl rustls::ServerCertVerifier for SkipServerVerification {
90    fn verify_server_cert(
91        &self,
92        _roots: &rustls::RootCertStore,
93        _presented_certs: &[rustls::Certificate],
94        _dns_name: webpki::DNSNameRef,
95        _ocsp_response: &[u8],
96    ) -> Result<rustls::ServerCertVerified, rustls::TLSError> {
97        Ok(rustls::ServerCertVerified::assertion())
98    }
99}