mirror of https://github.com/telemt/telemt.git
Merge remote-tracking branch 'upstream/main'
This commit is contained in:
commit
f34b784619
|
|
@ -7,7 +7,7 @@ const DEFAULT_NETWORK_IPV6: Option<bool> = Some(false);
|
||||||
const DEFAULT_STUN_TCP_FALLBACK: bool = true;
|
const DEFAULT_STUN_TCP_FALLBACK: bool = true;
|
||||||
const DEFAULT_MIDDLE_PROXY_WARM_STANDBY: usize = 16;
|
const DEFAULT_MIDDLE_PROXY_WARM_STANDBY: usize = 16;
|
||||||
const DEFAULT_ME_RECONNECT_MAX_CONCURRENT_PER_DC: u32 = 8;
|
const DEFAULT_ME_RECONNECT_MAX_CONCURRENT_PER_DC: u32 = 8;
|
||||||
const DEFAULT_ME_RECONNECT_FAST_RETRY_COUNT: u32 = 12;
|
const DEFAULT_ME_RECONNECT_FAST_RETRY_COUNT: u32 = 16;
|
||||||
const DEFAULT_LISTEN_ADDR_IPV6: &str = "::";
|
const DEFAULT_LISTEN_ADDR_IPV6: &str = "::";
|
||||||
const DEFAULT_ACCESS_USER: &str = "default";
|
const DEFAULT_ACCESS_USER: &str = "default";
|
||||||
const DEFAULT_ACCESS_SECRET: &str = "00000000000000000000000000000000";
|
const DEFAULT_ACCESS_SECRET: &str = "00000000000000000000000000000000";
|
||||||
|
|
@ -21,7 +21,7 @@ pub(crate) fn default_port() -> u16 {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn default_tls_domain() -> String {
|
pub(crate) fn default_tls_domain() -> String {
|
||||||
"www.google.com".to_string()
|
"petrovich.ru".to_string()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn default_mask_port() -> u16 {
|
pub(crate) fn default_mask_port() -> u16 {
|
||||||
|
|
@ -45,7 +45,7 @@ pub(crate) fn default_replay_window_secs() -> u64 {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn default_handshake_timeout() -> u64 {
|
pub(crate) fn default_handshake_timeout() -> u64 {
|
||||||
15
|
30
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn default_connect_timeout() -> u64 {
|
pub(crate) fn default_connect_timeout() -> u64 {
|
||||||
|
|
@ -60,17 +60,21 @@ pub(crate) fn default_ack_timeout() -> u64 {
|
||||||
300
|
300
|
||||||
}
|
}
|
||||||
pub(crate) fn default_me_one_retry() -> u8 {
|
pub(crate) fn default_me_one_retry() -> u8 {
|
||||||
3
|
12
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn default_me_one_timeout() -> u64 {
|
pub(crate) fn default_me_one_timeout() -> u64 {
|
||||||
1500
|
1200
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn default_listen_addr() -> String {
|
pub(crate) fn default_listen_addr() -> String {
|
||||||
"0.0.0.0".to_string()
|
"0.0.0.0".to_string()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub(crate) fn default_listen_addr_ipv4() -> Option<String> {
|
||||||
|
Some(default_listen_addr())
|
||||||
|
}
|
||||||
|
|
||||||
pub(crate) fn default_weight() -> u16 {
|
pub(crate) fn default_weight() -> u16 {
|
||||||
1
|
1
|
||||||
}
|
}
|
||||||
|
|
@ -102,6 +106,32 @@ pub(crate) fn default_pool_size() -> usize {
|
||||||
8
|
8
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub(crate) fn default_proxy_secret_path() -> Option<String> {
|
||||||
|
Some("proxy-secret".to_string())
|
||||||
|
}
|
||||||
|
|
||||||
|
pub(crate) fn default_middle_proxy_nat_stun() -> Option<String> {
|
||||||
|
Some("stun.l.google.com:19302".to_string())
|
||||||
|
}
|
||||||
|
|
||||||
|
pub(crate) fn default_middle_proxy_nat_stun_servers() -> Vec<String> {
|
||||||
|
vec![
|
||||||
|
"stun.l.google.com:5349".to_string(),
|
||||||
|
"stun1.l.google.com:3478".to_string(),
|
||||||
|
"stun.gmx.net:3478".to_string(),
|
||||||
|
"stun.l.google.com:19302".to_string(),
|
||||||
|
"stun.1und1.de:3478".to_string(),
|
||||||
|
"stun1.l.google.com:19302".to_string(),
|
||||||
|
"stun2.l.google.com:19302".to_string(),
|
||||||
|
"stun3.l.google.com:19302".to_string(),
|
||||||
|
"stun4.l.google.com:19302".to_string(),
|
||||||
|
"stun.services.mozilla.com:3478".to_string(),
|
||||||
|
"stun.stunprotocol.org:3478".to_string(),
|
||||||
|
"stun.nextcloud.com:3478".to_string(),
|
||||||
|
"stun.voip.eutelia.it:3478".to_string(),
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
pub(crate) fn default_middle_proxy_warm_standby() -> usize {
|
pub(crate) fn default_middle_proxy_warm_standby() -> usize {
|
||||||
DEFAULT_MIDDLE_PROXY_WARM_STANDBY
|
DEFAULT_MIDDLE_PROXY_WARM_STANDBY
|
||||||
}
|
}
|
||||||
|
|
@ -303,6 +333,10 @@ pub(crate) fn default_listen_addr_ipv6() -> String {
|
||||||
DEFAULT_LISTEN_ADDR_IPV6.to_string()
|
DEFAULT_LISTEN_ADDR_IPV6.to_string()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub(crate) fn default_listen_addr_ipv6_opt() -> Option<String> {
|
||||||
|
Some(default_listen_addr_ipv6())
|
||||||
|
}
|
||||||
|
|
||||||
pub(crate) fn default_access_users() -> HashMap<String, String> {
|
pub(crate) fn default_access_users() -> HashMap<String, String> {
|
||||||
HashMap::from([(
|
HashMap::from([(
|
||||||
DEFAULT_ACCESS_USER.to_string(),
|
DEFAULT_ACCESS_USER.to_string(),
|
||||||
|
|
|
||||||
|
|
@ -116,8 +116,27 @@ impl ProxyConfig {
|
||||||
let base_dir = path.as_ref().parent().unwrap_or(Path::new("."));
|
let base_dir = path.as_ref().parent().unwrap_or(Path::new("."));
|
||||||
let processed = preprocess_includes(&content, base_dir, 0)?;
|
let processed = preprocess_includes(&content, base_dir, 0)?;
|
||||||
|
|
||||||
let mut config: ProxyConfig =
|
let parsed_toml: toml::Value =
|
||||||
toml::from_str(&processed).map_err(|e| ProxyError::Config(e.to_string()))?;
|
toml::from_str(&processed).map_err(|e| ProxyError::Config(e.to_string()))?;
|
||||||
|
let general_table = parsed_toml
|
||||||
|
.get("general")
|
||||||
|
.and_then(|value| value.as_table());
|
||||||
|
let update_every_is_explicit = general_table
|
||||||
|
.map(|table| table.contains_key("update_every"))
|
||||||
|
.unwrap_or(false);
|
||||||
|
let legacy_secret_is_explicit = general_table
|
||||||
|
.map(|table| table.contains_key("proxy_secret_auto_reload_secs"))
|
||||||
|
.unwrap_or(false);
|
||||||
|
let legacy_config_is_explicit = general_table
|
||||||
|
.map(|table| table.contains_key("proxy_config_auto_reload_secs"))
|
||||||
|
.unwrap_or(false);
|
||||||
|
|
||||||
|
let mut config: ProxyConfig =
|
||||||
|
parsed_toml.try_into().map_err(|e| ProxyError::Config(e.to_string()))?;
|
||||||
|
|
||||||
|
if !update_every_is_explicit && (legacy_secret_is_explicit || legacy_config_is_explicit) {
|
||||||
|
config.general.update_every = None;
|
||||||
|
}
|
||||||
|
|
||||||
if let Some(update_every) = config.general.update_every {
|
if let Some(update_every) = config.general.update_every {
|
||||||
if update_every == 0 {
|
if update_every == 0 {
|
||||||
|
|
@ -437,15 +456,24 @@ mod tests {
|
||||||
"#;
|
"#;
|
||||||
let cfg: ProxyConfig = toml::from_str(toml).unwrap();
|
let cfg: ProxyConfig = toml::from_str(toml).unwrap();
|
||||||
|
|
||||||
assert_eq!(cfg.network.ipv6, None);
|
assert_eq!(cfg.network.ipv6, default_network_ipv6());
|
||||||
assert!(!cfg.network.stun_tcp_fallback);
|
assert_eq!(cfg.network.stun_tcp_fallback, default_stun_tcp_fallback());
|
||||||
assert_eq!(cfg.general.middle_proxy_warm_standby, 0);
|
assert_eq!(
|
||||||
assert_eq!(cfg.general.me_reconnect_max_concurrent_per_dc, 0);
|
cfg.general.middle_proxy_warm_standby,
|
||||||
assert_eq!(cfg.general.me_reconnect_fast_retry_count, 0);
|
default_middle_proxy_warm_standby()
|
||||||
assert_eq!(cfg.general.update_every, None);
|
);
|
||||||
assert_eq!(cfg.server.listen_addr_ipv4, None);
|
assert_eq!(
|
||||||
assert_eq!(cfg.server.listen_addr_ipv6, None);
|
cfg.general.me_reconnect_max_concurrent_per_dc,
|
||||||
assert!(cfg.access.users.is_empty());
|
default_me_reconnect_max_concurrent_per_dc()
|
||||||
|
);
|
||||||
|
assert_eq!(
|
||||||
|
cfg.general.me_reconnect_fast_retry_count,
|
||||||
|
default_me_reconnect_fast_retry_count()
|
||||||
|
);
|
||||||
|
assert_eq!(cfg.general.update_every, default_update_every());
|
||||||
|
assert_eq!(cfg.server.listen_addr_ipv4, default_listen_addr_ipv4());
|
||||||
|
assert_eq!(cfg.server.listen_addr_ipv6, default_listen_addr_ipv6_opt());
|
||||||
|
assert_eq!(cfg.access.users, default_access_users());
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
|
|
||||||
|
|
@ -87,7 +87,7 @@ pub struct NetworkConfig {
|
||||||
pub ipv4: bool,
|
pub ipv4: bool,
|
||||||
|
|
||||||
/// None = auto-detect IPv6 availability.
|
/// None = auto-detect IPv6 availability.
|
||||||
#[serde(default)]
|
#[serde(default = "default_network_ipv6")]
|
||||||
pub ipv6: Option<bool>,
|
pub ipv6: Option<bool>,
|
||||||
|
|
||||||
/// 4 or 6.
|
/// 4 or 6.
|
||||||
|
|
@ -102,7 +102,7 @@ pub struct NetworkConfig {
|
||||||
pub stun_servers: Vec<String>,
|
pub stun_servers: Vec<String>,
|
||||||
|
|
||||||
/// Enable TCP STUN fallback when UDP is blocked.
|
/// Enable TCP STUN fallback when UDP is blocked.
|
||||||
#[serde(default)]
|
#[serde(default = "default_stun_tcp_fallback")]
|
||||||
pub stun_tcp_fallback: bool,
|
pub stun_tcp_fallback: bool,
|
||||||
|
|
||||||
/// HTTP-based public IP detection endpoints (fallback after STUN).
|
/// HTTP-based public IP detection endpoints (fallback after STUN).
|
||||||
|
|
@ -140,7 +140,7 @@ pub struct GeneralConfig {
|
||||||
#[serde(default = "default_true")]
|
#[serde(default = "default_true")]
|
||||||
pub fast_mode: bool,
|
pub fast_mode: bool,
|
||||||
|
|
||||||
#[serde(default)]
|
#[serde(default = "default_true")]
|
||||||
pub use_middle_proxy: bool,
|
pub use_middle_proxy: bool,
|
||||||
|
|
||||||
#[serde(default)]
|
#[serde(default)]
|
||||||
|
|
@ -148,7 +148,7 @@ pub struct GeneralConfig {
|
||||||
|
|
||||||
/// Path to proxy-secret binary file (auto-downloaded if absent).
|
/// Path to proxy-secret binary file (auto-downloaded if absent).
|
||||||
/// Infrastructure secret from https://core.telegram.org/getProxySecret.
|
/// Infrastructure secret from https://core.telegram.org/getProxySecret.
|
||||||
#[serde(default)]
|
#[serde(default = "default_proxy_secret_path")]
|
||||||
pub proxy_secret_path: Option<String>,
|
pub proxy_secret_path: Option<String>,
|
||||||
|
|
||||||
/// Public IP override for middle-proxy NAT environments.
|
/// Public IP override for middle-proxy NAT environments.
|
||||||
|
|
@ -157,15 +157,15 @@ pub struct GeneralConfig {
|
||||||
pub middle_proxy_nat_ip: Option<IpAddr>,
|
pub middle_proxy_nat_ip: Option<IpAddr>,
|
||||||
|
|
||||||
/// Enable STUN-based NAT probing to discover public IP:port for ME KDF.
|
/// Enable STUN-based NAT probing to discover public IP:port for ME KDF.
|
||||||
#[serde(default)]
|
#[serde(default = "default_true")]
|
||||||
pub middle_proxy_nat_probe: bool,
|
pub middle_proxy_nat_probe: bool,
|
||||||
|
|
||||||
/// Optional STUN server address (host:port) for NAT probing.
|
/// Optional STUN server address (host:port) for NAT probing.
|
||||||
#[serde(default)]
|
#[serde(default = "default_middle_proxy_nat_stun")]
|
||||||
pub middle_proxy_nat_stun: Option<String>,
|
pub middle_proxy_nat_stun: Option<String>,
|
||||||
|
|
||||||
/// Optional list of STUN servers for NAT probing fallback.
|
/// Optional list of STUN servers for NAT probing fallback.
|
||||||
#[serde(default)]
|
#[serde(default = "default_middle_proxy_nat_stun_servers")]
|
||||||
pub middle_proxy_nat_stun_servers: Vec<String>,
|
pub middle_proxy_nat_stun_servers: Vec<String>,
|
||||||
|
|
||||||
/// Desired size of active Middle-Proxy writer pool.
|
/// Desired size of active Middle-Proxy writer pool.
|
||||||
|
|
@ -173,7 +173,7 @@ pub struct GeneralConfig {
|
||||||
pub middle_proxy_pool_size: usize,
|
pub middle_proxy_pool_size: usize,
|
||||||
|
|
||||||
/// Number of warm standby ME connections kept pre-initialized.
|
/// Number of warm standby ME connections kept pre-initialized.
|
||||||
#[serde(default)]
|
#[serde(default = "default_middle_proxy_warm_standby")]
|
||||||
pub middle_proxy_warm_standby: usize,
|
pub middle_proxy_warm_standby: usize,
|
||||||
|
|
||||||
/// Enable ME keepalive padding frames.
|
/// Enable ME keepalive padding frames.
|
||||||
|
|
@ -207,7 +207,7 @@ pub struct GeneralConfig {
|
||||||
pub desync_all_full: bool,
|
pub desync_all_full: bool,
|
||||||
|
|
||||||
/// Enable per-IP forensic observation buckets for scanners and handshake failures.
|
/// Enable per-IP forensic observation buckets for scanners and handshake failures.
|
||||||
#[serde(default)]
|
#[serde(default = "default_true")]
|
||||||
pub beobachten: bool,
|
pub beobachten: bool,
|
||||||
|
|
||||||
/// Observation retention window in minutes for per-IP forensic buckets.
|
/// Observation retention window in minutes for per-IP forensic buckets.
|
||||||
|
|
@ -240,7 +240,7 @@ pub struct GeneralConfig {
|
||||||
pub me_warmup_step_jitter_ms: u64,
|
pub me_warmup_step_jitter_ms: u64,
|
||||||
|
|
||||||
/// Max concurrent reconnect attempts per DC.
|
/// Max concurrent reconnect attempts per DC.
|
||||||
#[serde(default)]
|
#[serde(default = "default_me_reconnect_max_concurrent_per_dc")]
|
||||||
pub me_reconnect_max_concurrent_per_dc: u32,
|
pub me_reconnect_max_concurrent_per_dc: u32,
|
||||||
|
|
||||||
/// Base backoff in ms for reconnect.
|
/// Base backoff in ms for reconnect.
|
||||||
|
|
@ -252,7 +252,7 @@ pub struct GeneralConfig {
|
||||||
pub me_reconnect_backoff_cap_ms: u64,
|
pub me_reconnect_backoff_cap_ms: u64,
|
||||||
|
|
||||||
/// Fast retry attempts before backoff.
|
/// Fast retry attempts before backoff.
|
||||||
#[serde(default)]
|
#[serde(default = "default_me_reconnect_fast_retry_count")]
|
||||||
pub me_reconnect_fast_retry_count: u32,
|
pub me_reconnect_fast_retry_count: u32,
|
||||||
|
|
||||||
/// Ignore STUN/interface IP mismatch (keep using Middle Proxy even if NAT detected).
|
/// Ignore STUN/interface IP mismatch (keep using Middle Proxy even if NAT detected).
|
||||||
|
|
@ -280,7 +280,7 @@ pub struct GeneralConfig {
|
||||||
|
|
||||||
/// Unified ME updater interval in seconds for getProxyConfig/getProxyConfigV6/getProxySecret.
|
/// Unified ME updater interval in seconds for getProxyConfig/getProxyConfigV6/getProxySecret.
|
||||||
/// When omitted, effective value falls back to legacy proxy_*_auto_reload_secs fields.
|
/// When omitted, effective value falls back to legacy proxy_*_auto_reload_secs fields.
|
||||||
#[serde(default)]
|
#[serde(default = "default_update_every")]
|
||||||
pub update_every: Option<u64>,
|
pub update_every: Option<u64>,
|
||||||
|
|
||||||
/// Periodic ME pool reinitialization interval in seconds.
|
/// Periodic ME pool reinitialization interval in seconds.
|
||||||
|
|
@ -371,13 +371,13 @@ impl Default for GeneralConfig {
|
||||||
modes: ProxyModes::default(),
|
modes: ProxyModes::default(),
|
||||||
prefer_ipv6: false,
|
prefer_ipv6: false,
|
||||||
fast_mode: default_true(),
|
fast_mode: default_true(),
|
||||||
use_middle_proxy: false,
|
use_middle_proxy: default_true(),
|
||||||
ad_tag: None,
|
ad_tag: None,
|
||||||
proxy_secret_path: None,
|
proxy_secret_path: default_proxy_secret_path(),
|
||||||
middle_proxy_nat_ip: None,
|
middle_proxy_nat_ip: None,
|
||||||
middle_proxy_nat_probe: true,
|
middle_proxy_nat_probe: default_true(),
|
||||||
middle_proxy_nat_stun: None,
|
middle_proxy_nat_stun: default_middle_proxy_nat_stun(),
|
||||||
middle_proxy_nat_stun_servers: Vec::new(),
|
middle_proxy_nat_stun_servers: default_middle_proxy_nat_stun_servers(),
|
||||||
middle_proxy_pool_size: default_pool_size(),
|
middle_proxy_pool_size: default_pool_size(),
|
||||||
middle_proxy_warm_standby: default_middle_proxy_warm_standby(),
|
middle_proxy_warm_standby: default_middle_proxy_warm_standby(),
|
||||||
me_keepalive_enabled: default_true(),
|
me_keepalive_enabled: default_true(),
|
||||||
|
|
@ -399,7 +399,7 @@ impl Default for GeneralConfig {
|
||||||
crypto_pending_buffer: default_crypto_pending_buffer(),
|
crypto_pending_buffer: default_crypto_pending_buffer(),
|
||||||
max_client_frame: default_max_client_frame(),
|
max_client_frame: default_max_client_frame(),
|
||||||
desync_all_full: default_desync_all_full(),
|
desync_all_full: default_desync_all_full(),
|
||||||
beobachten: true,
|
beobachten: default_true(),
|
||||||
beobachten_minutes: default_beobachten_minutes(),
|
beobachten_minutes: default_beobachten_minutes(),
|
||||||
beobachten_flush_secs: default_beobachten_flush_secs(),
|
beobachten_flush_secs: default_beobachten_flush_secs(),
|
||||||
beobachten_file: default_beobachten_file(),
|
beobachten_file: default_beobachten_file(),
|
||||||
|
|
@ -450,11 +450,11 @@ impl GeneralConfig {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// `[general.links]` — proxy link generation settings.
|
/// `[general.links]` — proxy link generation settings.
|
||||||
#[derive(Debug, Clone, Serialize, Deserialize, Default)]
|
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||||
pub struct LinksConfig {
|
pub struct LinksConfig {
|
||||||
/// List of usernames whose tg:// links to display at startup.
|
/// List of usernames whose tg:// links to display at startup.
|
||||||
/// `"*"` = all users, `["alice", "bob"]` = specific users.
|
/// `"*"` = all users, `["alice", "bob"]` = specific users.
|
||||||
#[serde(default)]
|
#[serde(default = "default_links_show")]
|
||||||
pub show: ShowLink,
|
pub show: ShowLink,
|
||||||
|
|
||||||
/// Public hostname/IP for tg:// link generation (overrides detected IP).
|
/// Public hostname/IP for tg:// link generation (overrides detected IP).
|
||||||
|
|
@ -466,15 +466,25 @@ pub struct LinksConfig {
|
||||||
pub public_port: Option<u16>,
|
pub public_port: Option<u16>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl Default for LinksConfig {
|
||||||
|
fn default() -> Self {
|
||||||
|
Self {
|
||||||
|
show: default_links_show(),
|
||||||
|
public_host: None,
|
||||||
|
public_port: None,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||||
pub struct ServerConfig {
|
pub struct ServerConfig {
|
||||||
#[serde(default = "default_port")]
|
#[serde(default = "default_port")]
|
||||||
pub port: u16,
|
pub port: u16,
|
||||||
|
|
||||||
#[serde(default)]
|
#[serde(default = "default_listen_addr_ipv4")]
|
||||||
pub listen_addr_ipv4: Option<String>,
|
pub listen_addr_ipv4: Option<String>,
|
||||||
|
|
||||||
#[serde(default)]
|
#[serde(default = "default_listen_addr_ipv6_opt")]
|
||||||
pub listen_addr_ipv6: Option<String>,
|
pub listen_addr_ipv6: Option<String>,
|
||||||
|
|
||||||
#[serde(default)]
|
#[serde(default)]
|
||||||
|
|
@ -509,8 +519,8 @@ impl Default for ServerConfig {
|
||||||
fn default() -> Self {
|
fn default() -> Self {
|
||||||
Self {
|
Self {
|
||||||
port: default_port(),
|
port: default_port(),
|
||||||
listen_addr_ipv4: Some(default_listen_addr()),
|
listen_addr_ipv4: default_listen_addr_ipv4(),
|
||||||
listen_addr_ipv6: Some(default_listen_addr_ipv6()),
|
listen_addr_ipv6: default_listen_addr_ipv6_opt(),
|
||||||
listen_unix_sock: None,
|
listen_unix_sock: None,
|
||||||
listen_unix_sock_perm: None,
|
listen_unix_sock_perm: None,
|
||||||
listen_tcp: None,
|
listen_tcp: None,
|
||||||
|
|
@ -583,7 +593,7 @@ pub struct AntiCensorshipConfig {
|
||||||
pub fake_cert_len: usize,
|
pub fake_cert_len: usize,
|
||||||
|
|
||||||
/// Enable TLS certificate emulation using cached real certificates.
|
/// Enable TLS certificate emulation using cached real certificates.
|
||||||
#[serde(default)]
|
#[serde(default = "default_true")]
|
||||||
pub tls_emulation: bool,
|
pub tls_emulation: bool,
|
||||||
|
|
||||||
/// Directory to store TLS front cache (on disk).
|
/// Directory to store TLS front cache (on disk).
|
||||||
|
|
@ -643,7 +653,7 @@ impl Default for AntiCensorshipConfig {
|
||||||
|
|
||||||
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
|
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
|
||||||
pub struct AccessConfig {
|
pub struct AccessConfig {
|
||||||
#[serde(default)]
|
#[serde(default = "default_access_users")]
|
||||||
pub users: HashMap<String, String>,
|
pub users: HashMap<String, String>,
|
||||||
|
|
||||||
#[serde(default)]
|
#[serde(default)]
|
||||||
|
|
@ -753,7 +763,7 @@ pub struct ListenerConfig {
|
||||||
/// In TOML, this can be:
|
/// In TOML, this can be:
|
||||||
/// - `show_link = "*"` — show links for all users
|
/// - `show_link = "*"` — show links for all users
|
||||||
/// - `show_link = ["a", "b"]` — show links for specific users
|
/// - `show_link = ["a", "b"]` — show links for specific users
|
||||||
/// - omitted — show no links (default)
|
/// - omitted — default depends on the owning config field
|
||||||
#[derive(Debug, Clone, Default)]
|
#[derive(Debug, Clone, Default)]
|
||||||
pub enum ShowLink {
|
pub enum ShowLink {
|
||||||
/// Don't show any links (default when omitted).
|
/// Don't show any links (default when omitted).
|
||||||
|
|
@ -765,6 +775,10 @@ pub enum ShowLink {
|
||||||
Specific(Vec<String>),
|
Specific(Vec<String>),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn default_links_show() -> ShowLink {
|
||||||
|
ShowLink::All
|
||||||
|
}
|
||||||
|
|
||||||
impl ShowLink {
|
impl ShowLink {
|
||||||
/// Returns true if no links should be shown.
|
/// Returns true if no links should be shown.
|
||||||
pub fn is_empty(&self) -> bool {
|
pub fn is_empty(&self) -> bool {
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue