Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 6 additions & 1 deletion lightway-app-utils/src/args/connection_type.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,10 +19,15 @@ pub enum ConnectionType {
}

impl ConnectionType {
/// A helper function easier to use especially in mobile
#[allow(missing_docs)]
pub fn is_tcp(&self) -> bool {
*self == ConnectionType::Tcp
}

#[allow(missing_docs)]
pub fn is_udp(&self) -> bool {
*self == ConnectionType::Udp
}
}

impl From<ConnectionType> for LWConnectionType {
Expand Down
47 changes: 47 additions & 0 deletions lightway-server/src/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -225,3 +225,50 @@ impl Default for Config {
}
}
}

impl Config {
/// Ensure the config is validated, and alerted when there's a conflict in the settings.
pub fn validate(&self) -> anyhow::Result<()> {
if self.enable_expresslane {
anyhow::ensure!(self.mode.is_udp(), "Expresslane only work in udp mode")
}

if self.proxy_protocol {
anyhow::ensure!(
self.mode.is_tcp(),
"Proxy protocol only support with tcp mode"
)
}

Ok(())
}
}

// Note it easier to see what is different from default in each testcase
#[allow(clippy::field_reassign_with_default)]
#[cfg(test)]
mod tests {
use super::*;

#[test]
fn validate_default_config() {
let config = Config::default();
assert!(config.validate().is_ok());
}

#[test]
fn validate_enable_expresslane() {
let mut config = Config::default();
config.mode = ConnectionType::Tcp;
config.enable_expresslane = true;
assert!(config.validate().is_err());
}

#[test]
fn validate_proxy_protocol() {
let mut config = Config::default();
config.mode = ConnectionType::Udp;
config.proxy_protocol = true;
assert!(config.validate().is_err());
}
}
61 changes: 61 additions & 0 deletions lightway-server/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -262,6 +262,67 @@ pub struct ServerConfig<SA: for<'a> ServerAuth<AuthState<'a>>> {
pub randomize_ippool: bool,
}

impl<SA: for<'a> ServerAuth<AuthState<'a>>> ServerConfig<SA> {
pub fn try_from_auth_and_config(auth: SA, config: config::Config) -> Result<Self> {
config.validate()?;

let mut tun_config = lightway_app_utils::TunConfig::default();
if let Some(tun_name) = config.tun_name {
tun_config.tun_name(tun_name);
}
tun_config.up();

Ok(crate::ServerConfig {
mode: match config.mode {
lightway_app_utils::args::ConnectionType::Udp => {
crate::ServerConnectionMode::Datagram(None)
}
lightway_app_utils::args::ConnectionType::Tcp => {
crate::ServerConnectionMode::Stream(None)
}
},
auth,
server_cert: config.server_cert,
server_key: config.server_key,
tun_config,
ip_pool: config.ip_pool,
ip_map: config.ip_map.unwrap_or_default().try_into()?,
inside_io: None,
tun_ip: config.tun_ip,
lightway_server_ip: config.lightway_server_ip,
lightway_client_ip: config.lightway_client_ip,
lightway_dns_ip: config.lightway_dns_ip,
use_dynamic_client_ip: false,
enable_expresslane: config.enable_expresslane,
expresslane_keys_rotation_interval: config.expresslane_keys_rotation_interval.into(),
expresslane_cb: None,
expresslane_metrics: None,
event_cb: None,
enable_pqc: config.enable_pqc,
#[cfg(target_os = "linux")]
enable_tun_offload: config.enable_tun_offload,
#[cfg(feature = "io-uring")]
enable_tun_iouring: config.enable_tun_iouring,
#[cfg(feature = "io-uring")]
iouring_entry_count: config.iouring_entry_count,
#[cfg(feature = "io-uring")]
iouring_sqpoll_idle_time: config.iouring_sqpoll_idle_time.into(),
key_update_interval: config.key_update_interval.into(),
connection_age_expiration_interval: config.connection_age_expiration_interval.into(),
statistics_reporting_interval: config.statistics_reporting_interval.into(),
inside_plugins: Default::default(),
outside_plugins: Default::default(),
inside_pkt_codec: None,
bind_address: config.bind_address,
proxy_protocol: config.proxy_protocol,
udp_buffer_size: config.udp_buffer_size,
enable_batch_receive: config.enable_batch_receive,
#[cfg(feature = "debug")]
randomize_ippool: config.randomize_ippool,
})
}
}

pub(crate) fn handle_inside_io_error(conn: Arc<Connection>, result: ConnectionResult<()>) {
match result {
Ok(()) => {}
Expand Down
71 changes: 10 additions & 61 deletions lightway-server/src/main.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
mod auth;
mod config;

use anyhow::{Context, Result, anyhow};
use clap::Parser;
Expand All @@ -10,10 +9,10 @@ use tokio::fs::read_to_string;
use tokio_stream::StreamExt;
use tracing::{error, trace};

use config::{Config, ConfigPatch};
use lightway_app_utils::{TunConfig, Validate, validate_configuration_file_path};
use lightway_app_utils::{Validate, validate_configuration_file_path};
#[cfg(feature = "debug")]
use lightway_core::set_logging_callback;
use lightway_server::config::{Config, ConfigPatch};
use lightway_server::*;

async fn metrics_debug() {
Expand Down Expand Up @@ -115,6 +114,13 @@ async fn main() -> Result<()> {
let fmt = tracing_subscriber::fmt().with_env_filter(filter);

config.log_format.init_with_env_filter(fmt);
let server_config = crate::ServerConfig::try_from_auth_and_config(
crate::auth::Auth::new(
config.user_db.as_ref().map(AsRef::as_ref),
config.token_rsa_pub_key_pem.as_ref().map(AsRef::as_ref),
)?,
config,
)?;

tokio::spawn(metrics_debug());

Expand All @@ -140,62 +146,5 @@ async fn main() -> Result<()> {
}
});

let auth = auth::Auth::new(
config.user_db.as_ref().map(AsRef::as_ref),
config.token_rsa_pub_key_pem.as_ref().map(AsRef::as_ref),
)?;

let mut tun_config = TunConfig::default();
if let Some(tun_name) = config.tun_name {
tun_config.tun_name(tun_name);
}
tun_config.up();
let mode = match config.mode {
lightway_app_utils::args::ConnectionType::Udp => ServerConnectionMode::Datagram(None),
lightway_app_utils::args::ConnectionType::Tcp => ServerConnectionMode::Stream(None),
};

let config = ServerConfig {
mode,
auth,
server_cert: config.server_cert,
server_key: config.server_key,
tun_config,
ip_pool: config.ip_pool,
ip_map: config.ip_map.unwrap_or_default().try_into()?,
inside_io: None,
tun_ip: config.tun_ip,
lightway_server_ip: config.lightway_server_ip,
lightway_client_ip: config.lightway_client_ip,
lightway_dns_ip: config.lightway_dns_ip,
use_dynamic_client_ip: false,
enable_expresslane: config.enable_expresslane,
expresslane_keys_rotation_interval: config.expresslane_keys_rotation_interval.into(),
expresslane_cb: None,
expresslane_metrics: None,
event_cb: None,
enable_pqc: config.enable_pqc,
#[cfg(target_os = "linux")]
enable_tun_offload: config.enable_tun_offload,
#[cfg(feature = "io-uring")]
enable_tun_iouring: config.enable_tun_iouring,
#[cfg(feature = "io-uring")]
iouring_entry_count: config.iouring_entry_count,
#[cfg(feature = "io-uring")]
iouring_sqpoll_idle_time: config.iouring_sqpoll_idle_time.into(),
key_update_interval: config.key_update_interval.into(),
connection_age_expiration_interval: config.connection_age_expiration_interval.into(),
statistics_reporting_interval: config.statistics_reporting_interval.into(),
inside_plugins: Default::default(),
outside_plugins: Default::default(),
inside_pkt_codec: None,
bind_address: config.bind_address,
proxy_protocol: config.proxy_protocol,
udp_buffer_size: config.udp_buffer_size,
enable_batch_receive: config.enable_batch_receive,
#[cfg(feature = "debug")]
randomize_ippool: config.randomize_ippool,
};

server(config).await
server(server_config).await
}
Loading