Skip to content

Commit

Permalink
feat: add 'structopt' feature flag
Browse files Browse the repository at this point in the history
structopt was removed in edc5493.

However it is very useful for cli programs to be able to
expose p2p options on the command-line and read in a
qp2p Config easily.

This commit adds back structopt support for Config, now
as an optional feature flag, 'structopt'.
  • Loading branch information
dan-da committed Feb 11, 2022
1 parent b7b76dd commit d46d8a9
Show file tree
Hide file tree
Showing 2 changed files with 33 additions and 0 deletions.
1 change: 1 addition & 0 deletions Cargo.toml
Expand Up @@ -32,6 +32,7 @@ tokio = { version = "1.12.0", features = ["sync"] }
tracing = "~0.1.26"
webpki = "~0.21.3"
rustls = { version = "0.20.2", default-features = false, features = ["quic", "dangerous_configuration"] }
structopt = {version = "0.3.25", optional = true}

[dev-dependencies]
color-eyre = "0.5.11"
Expand Down
32 changes: 32 additions & 0 deletions src/config.rs
Expand Up @@ -15,6 +15,9 @@ use rustls::{Certificate, ClientConfig, ServerName};
use serde::{Deserialize, Serialize};
use std::{future::Future, net::IpAddr, sync::Arc, time::Duration};

#[cfg(feature = "structopt")]
use structopt::StructOpt;

/// Default for [`Config::upnp_lease_duration`] (2 minutes).
pub const DEFAULT_UPNP_LEASE_DURATION: Duration = Duration::from_secs(120);

Expand All @@ -23,6 +26,8 @@ pub const DEFAULT_UPNP_LEASE_DURATION: Duration = Duration::from_secs(120);
/// Together with the default max and multiplier,
/// gives 5-6 retries in ~30 s total retry time.
pub const DEFAULT_INITIAL_RETRY_INTERVAL: Duration = Duration::from_millis(500);
#[cfg(feature = "structopt")]
const DEFAULT_INITIAL_RETRY_INTERVAL_STR: &str = "500";

/// Default for [`Config::idle_timeout`] (18seconds).
///
Expand All @@ -34,18 +39,26 @@ pub const DEFAULT_IDLE_TIMEOUT: Duration = Duration::from_secs(18);
/// Together with the default min and multiplier,
/// gives 5-6 retries in ~30 s total retry time.
pub const DEFAULT_MAX_RETRY_INTERVAL: Duration = Duration::from_secs(15);
#[cfg(feature = "structopt")]
const DEFAULT_MAX_RETRY_INTERVAL_STR: &str = "15";

/// Default for [`RetryConfig::retry_delay_multiplier`] (x1.5).
///
/// Together with the default max and initial,
/// gives 5-6 retries in ~30 s total retry time.
pub const DEFAULT_RETRY_INTERVAL_MULTIPLIER: f64 = 1.5;
#[cfg(feature = "structopt")]
const DEFAULT_RETRY_INTERVAL_MULTIPLIER_STR: &str = "1.5";

/// Default for [`RetryConfig::retry_delay_rand_factor`] (0.3).
pub const DEFAULT_RETRY_DELAY_RAND_FACTOR: f64 = 0.3;
#[cfg(feature = "structopt")]
const DEFAULT_RETRY_DELAY_RAND_FACTOR_STR: &str = "0.3";

/// Default for [`RetryConfig::retrying_max_elapsed_time`] (30 s).
pub const DEFAULT_RETRYING_MAX_ELAPSED_TIME: Duration = Duration::from_secs(30);
#[cfg(feature = "structopt")]
const DEFAULT_RETRYING_MAX_ELAPSED_TIME_STR: &str = "30";

// We use a hard-coded server name for self-signed certificates.
pub(crate) const SERVER_NAME: &str = "maidsafe.net";
Expand Down Expand Up @@ -88,21 +101,25 @@ pub struct CertificateGenerationError(
);

/// QuicP2p configurations
#[cfg_attr(feature = "structopt", derive(StructOpt))]
#[derive(Clone, Debug, Default, Serialize, Deserialize)]
pub struct Config {
/// Specify if port forwarding via UPnP should be done or not. This can be set to false if the network
/// is run locally on the network loopback or on a local area network.
#[cfg(feature = "igd")]
#[cfg_attr(feature = "structopt", structopt(long))]
pub forward_port: bool,

/// External port number assigned to the socket address of the program.
/// If this is provided, QP2p considers that the local port provided has been mapped to the
/// provided external port number and automatic port forwarding will be skipped.
#[cfg_attr(feature = "structopt", structopt(long))]
pub external_port: Option<u16>,

/// External IP address of the computer on the WAN. This field is mandatory if the node is the genesis node and
/// port forwarding is not available. In case of non-genesis nodes, the external IP address will be resolved
/// using the Echo service.
#[cfg_attr(feature = "structopt", structopt(long))]
pub external_ip: Option<IpAddr>,

/// How long to wait to hear from a peer before timing out a connection.
Expand All @@ -112,6 +129,7 @@ pub struct Config {
///
/// If unspecified, this will default to [`DEFAULT_IDLE_TIMEOUT`].
#[serde(default)]
#[cfg_attr(feature = "structopt", structopt(long, parse(try_from_str = parse_millis), value_name = "MILLIS"))]
pub idle_timeout: Option<Duration>,

/// Interval at which to send keep-alives to maintain otherwise idle connections.
Expand All @@ -120,6 +138,7 @@ pub struct Config {
///
/// If unspecified, this will default to `None`, disabling keep-alives.
#[serde(default)]
#[cfg_attr(feature = "structopt", structopt(long, parse(try_from_str = parse_millis), value_name = "MILLIS"))]
pub keep_alive_interval: Option<Duration>,

/// How long UPnP port mappings will last.
Expand All @@ -129,22 +148,31 @@ pub struct Config {
/// If unspecified, this will default to [`DEFAULT_UPNP_LEASE_DURATION`], which should be
/// suitable in most cases but some routers may clear UPnP port mapping more frequently.
#[serde(default)]
#[cfg_attr(feature = "structopt", structopt(long, parse(try_from_str = parse_millis), value_name = "MILLIS"))]
pub upnp_lease_duration: Option<Duration>,

/// Retry configurations for establishing connections and sending messages.
/// Determines the retry behaviour of requests, by setting the back off strategy used.
#[serde(default)]
#[cfg_attr(feature = "structopt", structopt(flatten))]
pub retry_config: RetryConfig,
}

#[cfg(feature = "structopt")]
fn parse_millis(millis: &str) -> Result<Duration, std::num::ParseIntError> {
Ok(Duration::from_millis(millis.parse()?))
}

/// Retry configurations for establishing connections and sending messages.
/// Determines the retry behaviour of requests, by setting the back off strategy used.
#[cfg_attr(feature = "structopt", derive(StructOpt))]
#[derive(Clone, Debug, Copy, Serialize, Deserialize)]
pub struct RetryConfig {
/// The initial retry interval.
///
/// This is the first delay before a retry, for establishing connections and sending messages.
/// The subsequent delay will be decided by the `retry_delay_multiplier`.
#[cfg_attr(feature = "structopt", structopt(long, default_value = DEFAULT_INITIAL_RETRY_INTERVAL_STR, parse(try_from_str = parse_millis), value_name = "MILLIS"))]
pub initial_retry_interval: Duration,
/// The maximum value of the back off period. Once the retry interval reaches this
/// value it stops increasing.
Expand All @@ -154,18 +182,22 @@ pub struct RetryConfig {
/// Retrying continues even after the duration times have reached this duration.
/// The number of retries before that happens, will be decided by the `retry_delay_multiplier`.
/// The number of retries after that, will be decided by the `retrying_max_elapsed_time`.
#[cfg_attr(feature = "structopt", structopt(long, default_value = DEFAULT_MAX_RETRY_INTERVAL_STR, parse(try_from_str = parse_millis), value_name = "MILLIS"))]
pub max_retry_interval: Duration,
/// The value to multiply the current interval with for each retry attempt.
#[cfg_attr(feature = "structopt", structopt(long, default_value = DEFAULT_RETRY_INTERVAL_MULTIPLIER_STR))]
pub retry_delay_multiplier: f64,
/// The randomization factor to use for creating a range around the retry interval.
///
/// A randomization factor of 0.5 results in a random period ranging between 50% below and 50%
/// above the retry interval.
#[cfg_attr(feature = "structopt", structopt(long, default_value = DEFAULT_RETRY_DELAY_RAND_FACTOR_STR))]
pub retry_delay_rand_factor: f64,
/// The maximum elapsed time after instantiating
///
/// Retrying continues until this time has elapsed.
/// The number of retries before that happens, will be decided by the other retry config options.
#[cfg_attr(feature = "structopt", structopt(long, default_value = DEFAULT_RETRYING_MAX_ELAPSED_TIME_STR, parse(try_from_str = parse_millis), value_name = "MILLIS"))]
pub retrying_max_elapsed_time: Duration,
}

Expand Down

0 comments on commit d46d8a9

Please sign in to comment.