sentinel_config/
server.rs

1//! Server and listener configuration types
2//!
3//! This module contains configuration types for the proxy server itself
4//! and its listeners (ports/addresses it binds to).
5
6use serde::{Deserialize, Serialize};
7use std::path::PathBuf;
8use validator::Validate;
9
10use sentinel_common::types::{TlsVersion, TraceIdFormat};
11
12// ============================================================================
13// Server Configuration
14// ============================================================================
15
16/// Server-wide configuration
17#[derive(Debug, Clone, Serialize, Deserialize, Validate)]
18pub struct ServerConfig {
19    /// Number of worker threads (0 = number of CPU cores)
20    #[serde(default = "default_worker_threads")]
21    pub worker_threads: usize,
22
23    /// Maximum number of connections
24    #[serde(default = "default_max_connections")]
25    pub max_connections: usize,
26
27    /// Graceful shutdown timeout
28    #[serde(default = "default_graceful_shutdown_timeout")]
29    pub graceful_shutdown_timeout_secs: u64,
30
31    /// Enable daemon mode
32    #[serde(default)]
33    pub daemon: bool,
34
35    /// PID file path
36    pub pid_file: Option<PathBuf>,
37
38    /// User to switch to after binding
39    pub user: Option<String>,
40
41    /// Group to switch to after binding
42    pub group: Option<String>,
43
44    /// Working directory
45    pub working_directory: Option<PathBuf>,
46
47    /// Trace ID format for request tracing
48    ///
49    /// - `tinyflake` (default): 11-char Base58, operator-friendly
50    /// - `uuid`: 36-char UUID v4, guaranteed unique
51    #[serde(default)]
52    pub trace_id_format: TraceIdFormat,
53
54    /// Enable automatic configuration reload on file changes
55    ///
56    /// When enabled, the proxy will watch the configuration file for changes
57    /// and automatically reload when modifications are detected.
58    #[serde(default)]
59    pub auto_reload: bool,
60}
61
62// ============================================================================
63// Listener Configuration
64// ============================================================================
65
66/// Listener configuration (port binding)
67#[derive(Debug, Clone, Serialize, Deserialize, Validate)]
68pub struct ListenerConfig {
69    /// Unique identifier for this listener
70    pub id: String,
71
72    /// Socket address to bind to
73    #[validate(custom(function = "crate::validation::validate_socket_addr"))]
74    pub address: String,
75
76    /// Protocol (http, https)
77    pub protocol: ListenerProtocol,
78
79    /// TLS configuration (required for https)
80    pub tls: Option<TlsConfig>,
81
82    /// Default route if no other matches
83    pub default_route: Option<String>,
84
85    /// Request timeout
86    #[serde(default = "default_request_timeout")]
87    pub request_timeout_secs: u64,
88
89    /// Keep-alive timeout
90    #[serde(default = "default_keepalive_timeout")]
91    pub keepalive_timeout_secs: u64,
92
93    /// Maximum concurrent streams (HTTP/2)
94    #[serde(default = "default_max_concurrent_streams")]
95    pub max_concurrent_streams: u32,
96}
97
98/// Listener protocol
99#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
100#[serde(rename_all = "lowercase")]
101pub enum ListenerProtocol {
102    Http,
103    Https,
104    #[serde(rename = "h2")]
105    Http2,
106    #[serde(rename = "h3")]
107    Http3,
108}
109
110// ============================================================================
111// TLS Configuration
112// ============================================================================
113
114/// TLS configuration
115#[derive(Debug, Clone, Serialize, Deserialize, Validate)]
116pub struct TlsConfig {
117    /// Default certificate file path (used when no SNI match)
118    pub cert_file: PathBuf,
119
120    /// Default private key file path
121    pub key_file: PathBuf,
122
123    /// Additional certificates for SNI support
124    /// Maps hostname patterns to certificate configurations
125    #[serde(default)]
126    pub additional_certs: Vec<SniCertificate>,
127
128    /// CA certificate file path for client verification (mTLS)
129    pub ca_file: Option<PathBuf>,
130
131    /// Minimum TLS version
132    #[serde(default = "default_min_tls_version")]
133    pub min_version: TlsVersion,
134
135    /// Maximum TLS version
136    pub max_version: Option<TlsVersion>,
137
138    /// Cipher suites (empty = use defaults)
139    #[serde(default)]
140    pub cipher_suites: Vec<String>,
141
142    /// Require client certificates (mTLS)
143    #[serde(default)]
144    pub client_auth: bool,
145
146    /// OCSP stapling
147    #[serde(default = "default_ocsp_stapling")]
148    pub ocsp_stapling: bool,
149
150    /// Session resumption
151    #[serde(default = "default_session_resumption")]
152    pub session_resumption: bool,
153}
154
155/// SNI certificate configuration
156#[derive(Debug, Clone, Serialize, Deserialize)]
157pub struct SniCertificate {
158    /// Hostname patterns to match (e.g., "example.com", "*.example.com")
159    pub hostnames: Vec<String>,
160
161    /// Certificate file path
162    pub cert_file: PathBuf,
163
164    /// Private key file path
165    pub key_file: PathBuf,
166}
167
168// ============================================================================
169// Default Value Functions
170// ============================================================================
171
172pub(crate) fn default_worker_threads() -> usize {
173    0
174}
175
176pub(crate) fn default_max_connections() -> usize {
177    10000
178}
179
180pub(crate) fn default_graceful_shutdown_timeout() -> u64 {
181    30
182}
183
184pub(crate) fn default_request_timeout() -> u64 {
185    60
186}
187
188pub(crate) fn default_keepalive_timeout() -> u64 {
189    75
190}
191
192pub(crate) fn default_max_concurrent_streams() -> u32 {
193    100
194}
195
196fn default_min_tls_version() -> TlsVersion {
197    TlsVersion::Tls12
198}
199
200fn default_ocsp_stapling() -> bool {
201    true
202}
203
204fn default_session_resumption() -> bool {
205    true
206}