@@ -5,7 +5,9 @@ use std::fs;
55use std::net::IpAddr;
66use std::path::{Path, PathBuf};
77
8- use crate::config_access::{validate_access_rule_list, validate_client_cert_sha256_list};
8+ pub use crate::config_access::{
9+ AccessPolicyConfig, ConcurrencyLimitConfig, RateLimitConfig, RateLimitMode,
10+ };
911#[cfg(test)]
1012pub(crate) use crate::config_acme::MAX_ACME_ISSUERS;
1113pub use crate::config_acme::{
@@ -1887,272 +1889,6 @@ impl VhostConfig {
18871889 }
18881890}
18891891
1890- #[derive(Debug, Clone, Eq, PartialEq, Deserialize, Serialize)]
1891- #[serde(deny_unknown_fields)]
1892- pub struct AccessPolicyConfig {
1893- #[serde(default = "default_true")]
1894- pub enabled: bool,
1895- #[serde(default)]
1896- pub allow: Vec<String>,
1897- #[serde(default)]
1898- pub deny: Vec<String>,
1899- #[serde(default)]
1900- pub require_client_cert: bool,
1901- #[serde(default)]
1902- pub allow_client_cert_sha256: Vec<String>,
1903- #[serde(default)]
1904- pub deny_client_cert_sha256: Vec<String>,
1905- }
1906-
1907- impl Default for AccessPolicyConfig {
1908- fn default() -> Self {
1909- Self {
1910- enabled: true,
1911- allow: Vec::new(),
1912- deny: Vec::new(),
1913- require_client_cert: false,
1914- allow_client_cert_sha256: Vec::new(),
1915- deny_client_cert_sha256: Vec::new(),
1916- }
1917- }
1918- }
1919-
1920- impl AccessPolicyConfig {
1921- fn validate(&self, scope: &'static str) -> Result<(), ConfigError> {
1922- validate_access_rule_list(scope, "allow", &self.allow)?;
1923- validate_access_rule_list(scope, "deny", &self.deny)?;
1924- validate_client_cert_sha256_list(
1925- scope,
1926- "allow_client_cert_sha256",
1927- &self.allow_client_cert_sha256,
1928- )?;
1929- validate_client_cert_sha256_list(
1930- scope,
1931- "deny_client_cert_sha256",
1932- &self.deny_client_cert_sha256,
1933- )?;
1934- Ok(())
1935- }
1936- }
1937-
1938- const MAX_RATE_LIMIT_REQUESTS_PER_SECOND: u32 = 1_000_000;
1939- const MAX_RATE_LIMIT_BURST: u32 = 1_000_000;
1940- const MAX_RATE_LIMIT_TABLE_ENTRIES: usize = 1_000_000;
1941- const MAX_RATE_LIMIT_ENTRY_TTL_SECS: u64 = 86_400;
1942- const MAX_RATE_LIMIT_DELAY_MS: u64 = 60_000;
1943-
1944- #[derive(Debug, Clone, Copy, Default, Eq, PartialEq, Deserialize, Serialize)]
1945- #[serde(rename_all = "kebab-case")]
1946- pub enum RateLimitMode {
1947- #[default]
1948- Nodelay,
1949- Delay,
1950- }
1951-
1952- #[derive(Debug, Clone, Copy, Eq, PartialEq, Deserialize, Serialize)]
1953- #[serde(deny_unknown_fields)]
1954- pub struct RateLimitConfig {
1955- #[serde(default)]
1956- pub enabled: bool,
1957- #[serde(default)]
1958- pub requests_per_second: u32,
1959- #[serde(default)]
1960- pub burst: u32,
1961- #[serde(default = "default_rate_limit_status")]
1962- pub status: u16,
1963- #[serde(default = "default_rate_limit_table_max_entries")]
1964- pub table_max_entries: usize,
1965- #[serde(default = "default_rate_limit_entry_ttl_secs")]
1966- pub entry_ttl_secs: u64,
1967- #[serde(default)]
1968- pub mode: RateLimitMode,
1969- #[serde(default = "default_rate_limit_max_delay_ms")]
1970- pub max_delay_ms: u64,
1971- #[serde(default)]
1972- pub reject_indeterminate: bool,
1973- }
1974-
1975- impl Default for RateLimitConfig {
1976- fn default() -> Self {
1977- Self {
1978- enabled: false,
1979- requests_per_second: 0,
1980- burst: 0,
1981- status: default_rate_limit_status(),
1982- table_max_entries: default_rate_limit_table_max_entries(),
1983- entry_ttl_secs: default_rate_limit_entry_ttl_secs(),
1984- mode: RateLimitMode::Nodelay,
1985- max_delay_ms: default_rate_limit_max_delay_ms(),
1986- reject_indeterminate: false,
1987- }
1988- }
1989- }
1990-
1991- impl RateLimitConfig {
1992- fn validate(&self, scope: &'static str) -> Result<(), ConfigError> {
1993- if !self.enabled {
1994- return Ok(());
1995- }
1996- if self.requests_per_second == 0
1997- || self.requests_per_second > MAX_RATE_LIMIT_REQUESTS_PER_SECOND
1998- {
1999- return Err(ConfigError::InvalidRateLimit {
2000- field: rate_limit_field(scope, "requests_per_second"),
2001- });
2002- }
2003- if self.burst > MAX_RATE_LIMIT_BURST {
2004- return Err(ConfigError::InvalidRateLimit {
2005- field: rate_limit_field(scope, "burst"),
2006- });
2007- }
2008- if !(400..=599).contains(&self.status) {
2009- return Err(ConfigError::InvalidRateLimit {
2010- field: rate_limit_field(scope, "status"),
2011- });
2012- }
2013- if self.table_max_entries == 0 || self.table_max_entries > MAX_RATE_LIMIT_TABLE_ENTRIES {
2014- return Err(ConfigError::InvalidRateLimit {
2015- field: rate_limit_field(scope, "table_max_entries"),
2016- });
2017- }
2018- if self.entry_ttl_secs == 0 || self.entry_ttl_secs > MAX_RATE_LIMIT_ENTRY_TTL_SECS {
2019- return Err(ConfigError::InvalidRateLimit {
2020- field: rate_limit_field(scope, "entry_ttl_secs"),
2021- });
2022- }
2023- if matches!(self.mode, RateLimitMode::Delay) && self.max_delay_ms == 0 {
2024- return Err(ConfigError::InvalidRateLimit {
2025- field: rate_limit_field(scope, "max_delay_ms"),
2026- });
2027- }
2028- if self.max_delay_ms > MAX_RATE_LIMIT_DELAY_MS {
2029- return Err(ConfigError::InvalidRateLimit {
2030- field: rate_limit_field(scope, "max_delay_ms"),
2031- });
2032- }
2033-
2034- Ok(())
2035- }
2036- }
2037-
2038- fn default_rate_limit_status() -> u16 {
2039- 429
2040- }
2041-
2042- fn default_rate_limit_table_max_entries() -> usize {
2043- 65_536
2044- }
2045-
2046- fn default_rate_limit_entry_ttl_secs() -> u64 {
2047- 300
2048- }
2049-
2050- fn default_rate_limit_max_delay_ms() -> u64 {
2051- 1000
2052- }
2053-
2054- fn rate_limit_field(scope: &'static str, field: &'static str) -> &'static str {
2055- match (scope, field) {
2056- ("vhosts.rate_limit", "requests_per_second") => "vhosts.rate_limit.requests_per_second",
2057- ("vhosts.rate_limit", "burst") => "vhosts.rate_limit.burst",
2058- ("vhosts.rate_limit", "status") => "vhosts.rate_limit.status",
2059- ("vhosts.rate_limit", "table_max_entries") => "vhosts.rate_limit.table_max_entries",
2060- ("vhosts.rate_limit", "entry_ttl_secs") => "vhosts.rate_limit.entry_ttl_secs",
2061- ("vhosts.rate_limit", "max_delay_ms") => "vhosts.rate_limit.max_delay_ms",
2062- ("vhosts.routes.rate_limit", "requests_per_second") => {
2063- "vhosts.routes.rate_limit.requests_per_second"
2064- }
2065- ("vhosts.routes.rate_limit", "burst") => "vhosts.routes.rate_limit.burst",
2066- ("vhosts.routes.rate_limit", "status") => "vhosts.routes.rate_limit.status",
2067- ("vhosts.routes.rate_limit", "table_max_entries") => {
2068- "vhosts.routes.rate_limit.table_max_entries"
2069- }
2070- ("vhosts.routes.rate_limit", "entry_ttl_secs") => "vhosts.routes.rate_limit.entry_ttl_secs",
2071- ("vhosts.routes.rate_limit", "max_delay_ms") => "vhosts.routes.rate_limit.max_delay_ms",
2072- _ => "rate_limit",
2073- }
2074- }
2075-
2076- const MAX_CONCURRENCY_LIMIT: usize = 1_000_000;
2077- const MAX_CONCURRENCY_QUEUE_TIMEOUT_MS: u64 = 60_000;
2078-
2079- #[derive(Debug, Clone, Copy, Eq, PartialEq, Deserialize, Serialize)]
2080- #[serde(deny_unknown_fields)]
2081- pub struct ConcurrencyLimitConfig {
2082- #[serde(default)]
2083- pub enabled: bool,
2084- #[serde(default)]
2085- pub max_in_flight: usize,
2086- #[serde(default)]
2087- pub max_queue: usize,
2088- #[serde(default = "default_concurrency_limit_status")]
2089- pub status: u16,
2090- #[serde(default)]
2091- pub queue_timeout_ms: u64,
2092- }
2093-
2094- impl Default for ConcurrencyLimitConfig {
2095- fn default() -> Self {
2096- Self {
2097- enabled: false,
2098- max_in_flight: 0,
2099- max_queue: 0,
2100- status: default_concurrency_limit_status(),
2101- queue_timeout_ms: 0,
2102- }
2103- }
2104- }
2105-
2106- impl ConcurrencyLimitConfig {
2107- fn validate(&self, scope: &'static str) -> Result<(), ConfigError> {
2108- if !self.enabled {
2109- return Ok(());
2110- }
2111- if self.max_in_flight == 0 || self.max_in_flight > MAX_CONCURRENCY_LIMIT {
2112- return Err(ConfigError::InvalidConcurrencyLimit {
2113- field: concurrency_limit_field(scope, "max_in_flight"),
2114- });
2115- }
2116- if self.max_queue > MAX_CONCURRENCY_LIMIT {
2117- return Err(ConfigError::InvalidConcurrencyLimit {
2118- field: concurrency_limit_field(scope, "max_queue"),
2119- });
2120- }
2121- if !(400..=599).contains(&self.status) {
2122- return Err(ConfigError::InvalidConcurrencyLimit {
2123- field: concurrency_limit_field(scope, "status"),
2124- });
2125- }
2126- if self.queue_timeout_ms > MAX_CONCURRENCY_QUEUE_TIMEOUT_MS {
2127- return Err(ConfigError::InvalidConcurrencyLimit {
2128- field: concurrency_limit_field(scope, "queue_timeout_ms"),
2129- });
2130- }
2131-
2132- Ok(())
2133- }
2134- }
2135-
2136- fn default_concurrency_limit_status() -> u16 {
2137- 503
2138- }
2139-
2140- fn concurrency_limit_field(scope: &'static str, field: &'static str) -> &'static str {
2141- match (scope, field) {
2142- ("vhosts.concurrency", "max_in_flight") => "vhosts.concurrency.max_in_flight",
2143- ("vhosts.concurrency", "max_queue") => "vhosts.concurrency.max_queue",
2144- ("vhosts.concurrency", "status") => "vhosts.concurrency.status",
2145- ("vhosts.concurrency", "queue_timeout_ms") => "vhosts.concurrency.queue_timeout_ms",
2146- ("vhosts.routes.concurrency", "max_in_flight") => "vhosts.routes.concurrency.max_in_flight",
2147- ("vhosts.routes.concurrency", "max_queue") => "vhosts.routes.concurrency.max_queue",
2148- ("vhosts.routes.concurrency", "status") => "vhosts.routes.concurrency.status",
2149- ("vhosts.routes.concurrency", "queue_timeout_ms") => {
2150- "vhosts.routes.concurrency.queue_timeout_ms"
2151- }
2152- _ => "concurrency",
2153- }
2154- }
2155-
21561892#[derive(Debug, Clone, Copy, Eq, PartialEq, Deserialize, Serialize)]
21571893#[serde(deny_unknown_fields)]
21581894pub struct GrpcRouteConfig {
0 commit comments