From 662f3cad1e53762d52e7743811c6138afd74d712 Mon Sep 17 00:00:00 2001 From: Sijie Yang Date: Mon, 29 Apr 2024 16:44:41 +0800 Subject: [PATCH] Tweak options of tquic tools (#252) - group different options by category and prioritize commonly used options - rename `max_requests_per_thread` to `total_requests_per_thread` - update description of some options --- tools/src/bin/tquic_client.rs | 247 ++++++++++++++++++++++++---------- tools/src/bin/tquic_server.rs | 150 +++++++++++++++------ 2 files changed, 281 insertions(+), 116 deletions(-) diff --git a/tools/src/bin/tquic_client.rs b/tools/src/bin/tquic_client.rs index 546c3259..9e9f2da0 100644 --- a/tools/src/bin/tquic_client.rs +++ b/tools/src/bin/tquic_client.rs @@ -77,157 +77,256 @@ static GLOBAL: jemallocator::Jemalloc = jemallocator::Jemalloc; #[derive(Parser, Debug, Clone)] #[clap(name = "client")] pub struct ClientOpt { - /// Request URLs. The host of the first one is used as SNI in Client Hello. + /// Server's address. + #[clap(short, long, value_name = "ADDR")] + pub connect_to: Option, + + /// Optional local IP addresses for client. e.g 192.168.1.10,192.168.2.20 + #[clap(long, value_delimiter = ',', value_name = "ADDR")] + pub local_addresses: Vec, + + /// Request URLs. The host of the first url is used as TLS SNI. #[clap(value_delimiter = ' ')] pub urls: Vec, /// Number of threads. - #[clap(short, long, default_value = "1", value_name = "NUM")] + #[clap( + short, + long, + default_value = "1", + value_name = "NUM", + help_heading = "Concurrency" + )] pub threads: u32, /// Number of concurrent connections per thread. - #[clap(long, default_value = "1", value_name = "NUM")] + #[clap( + long, + default_value = "1", + value_name = "NUM", + help_heading = "Concurrency" + )] pub max_concurrent_conns: u32, - /// Number of requests per thread. "0" means infinity mode. - #[clap(long, default_value = "1", value_name = "NUM")] - pub max_requests_per_thread: u64, + /// Number of concurrent requests per connection. + #[clap( + long, + default_value = "1", + value_name = "NUM", + help_heading = "Concurrency" + )] + pub max_concurrent_requests: u64, - /// Number of max requests per connection. "0" means infinity mode. - #[clap(long, default_value = "1", value_name = "NUM")] + /// Number of max requests per connection before re-establishment. "0" means infinity mode. + #[clap( + long, + default_value = "1", + value_name = "NUM", + help_heading = "Concurrency" + )] pub max_requests_per_conn: u64, - /// Number of max concurrent requests per connection. - #[clap(long, default_value = "1", value_name = "NUM")] - pub max_concurrent_requests: u64, + /// Total number of requests to send per thread. "0" means infinity mode. + /// Values below number of urls will be considered as number of urls. + #[clap( + long, + default_value = "1", + value_name = "NUM", + help_heading = "Concurrency" + )] + pub total_requests_per_thread: u64, /// Benchmarking duration in seconds. "0" means infinity mode. - /// Client will exit if either the max_requests or duration is reached. - #[clap(short, long, default_value = "0", value_name = "TIME")] + /// Client will exit upon reaching the total_requests_per_thread or duration limit. + #[clap( + short, + long, + default_value = "0", + value_name = "TIME", + help_heading = "Concurrency" + )] pub duration: u64, - /// Client will exit if consecutive failure reaches the threshold at the beginning. - #[clap(long, default_value = "10", value_name = "NUM")] - pub connection_failure_threshold: u64, - - /// Number of max samples per thread used for request time statistics. - #[clap(long, default_value = "100000", value_name = "NUM")] - pub max_sample: usize, - - /// Print response header and body to stdout. - #[clap(short, long)] - pub print_res: bool, - - /// Log level, support OFF/ERROR/WARN/INFO/DEBUG/TRACE. - #[clap(long, default_value = "INFO", value_name = "STR")] - pub log_level: log::LevelFilter, - - /// Log file path. If no file is specified, logs will be written to `stderr`. - #[clap(long, value_name = "FILE")] - pub log_file: Option, - - /// Override server's address. - #[clap(short, long, value_name = "ADDR")] - pub connect_to: Option, - /// ALPN, separated by ",". #[clap( short, long, value_delimiter = ',', default_value = "h3,http/0.9,hq-interop", - value_name = "STR" + value_name = "STR", + help_heading = "Protocol" )] pub alpn: Vec, - /// Dump response body into the given directory. - /// If the specified directory does not exist, a new directory will be created. - #[clap(long, value_name = "DIR")] - pub dump_dir: Option, - /// File used for session resumption. - #[clap(short, long, value_name = "FILE")] + #[clap(short, long, value_name = "FILE", help_heading = "Protocol")] pub session_file: Option, /// Enable early data. - #[clap(short, long)] + #[clap(short, long, help_heading = "Protocol")] pub enable_early_data: bool, /// Disable stateless reset. - #[clap(long)] + #[clap(long, help_heading = "Protocol")] pub disable_stateless_reset: bool, /// Congestion control algorithm. - #[clap(long, default_value = "BBR")] + #[clap(long, default_value = "BBR", help_heading = "Protocol")] pub congestion_control_algor: CongestionControlAlgorithm, /// Initial congestion window in packets. - #[clap(long, default_value = "32", value_name = "NUM")] + #[clap( + long, + default_value = "32", + value_name = "NUM", + help_heading = "Protocol" + )] pub initial_congestion_window: u64, /// Minimum congestion window in packets. - #[clap(long, default_value = "4", value_name = "NUM")] + #[clap( + long, + default_value = "4", + value_name = "NUM", + help_heading = "Protocol" + )] pub min_congestion_window: u64, /// Enable multipath transport. - #[clap(long)] + #[clap(long, help_heading = "Protocol")] pub enable_multipath: bool, /// Multipath scheduling algorithm. - #[clap(long, default_value = "MINRTT")] + #[clap(long, default_value = "MINRTT", help_heading = "Protocol")] pub multipath_algor: MultipathAlgorithm, - /// Optional local IP addresses for client. e.g 192.168.1.10,192.168.2.20 - #[clap(long, value_delimiter = ',', value_name = "ADDR")] - pub local_addresses: Vec, - /// Set active_connection_id_limit transport parameter. Values lower than 2 will be ignored. - #[clap(long, default_value = "2", value_name = "NUM")] + #[clap( + long, + default_value = "2", + value_name = "NUM", + help_heading = "Protocol" + )] pub active_cid_limit: u64, /// Set max_udp_payload_size transport parameter. - #[clap(long, default_value = "65527", value_name = "NUM")] + #[clap( + long, + default_value = "65527", + value_name = "NUM", + help_heading = "Protocol" + )] pub recv_udp_payload_size: u16, /// Set the maximum outgoing UDP payload size. - #[clap(long, default_value = "1200", value_name = "NUM")] + #[clap( + long, + default_value = "1200", + value_name = "NUM", + help_heading = "Protocol" + )] pub send_udp_payload_size: usize, /// Handshake timeout in microseconds. - #[clap(long, default_value = "10000", value_name = "TIME")] + #[clap( + long, + default_value = "10000", + value_name = "TIME", + help_heading = "Protocol" + )] pub handshake_timeout: u64, /// Connection idle timeout in microseconds. - #[clap(long, default_value = "30000", value_name = "TIME")] + #[clap( + long, + default_value = "30000", + value_name = "TIME", + help_heading = "Protocol" + )] pub idle_timeout: u64, /// Initial RTT in milliseconds. - #[clap(long, default_value = "333", value_name = "TIME")] + #[clap( + long, + default_value = "333", + value_name = "TIME", + help_heading = "Protocol" + )] pub initial_rtt: u64, /// Linear factor for calculating the probe timeout. - #[clap(long, default_value = "10", value_name = "NUM")] + #[clap( + long, + default_value = "10", + value_name = "NUM", + help_heading = "Protocol" + )] pub pto_linear_factor: u64, /// Upper limit of probe timeout in microseconds. - #[clap(long, default_value = "10000", value_name = "TIME")] + #[clap( + long, + default_value = "10000", + value_name = "TIME", + help_heading = "Protocol" + )] pub max_pto: u64, + /// Length of connection id in bytes. + #[clap( + long, + default_value = "8", + value_name = "NUM", + help_heading = "Protocol" + )] + pub cid_len: usize, + + /// Print response header and body to stdout. + #[clap(short, long, help_heading = "Output")] + pub print_res: bool, + + /// Dump response body into the given directory. + /// If the specified directory does not exist, a new directory will be created. + #[clap(long, value_name = "DIR", help_heading = "Output")] + pub dump_dir: Option, + + /// Log level, support OFF/ERROR/WARN/INFO/DEBUG/TRACE. + #[clap( + long, + default_value = "INFO", + value_name = "STR", + help_heading = "Output" + )] + pub log_level: log::LevelFilter, + + /// Log file path. If no file is specified, logs will be written to `stderr`. + #[clap(long, value_name = "FILE", help_heading = "Output")] + pub log_file: Option, + /// Save TLS key log into the given file. - #[clap(short, long, value_name = "FILE")] + #[clap(short, long, value_name = "FILE", help_heading = "Output")] pub keylog_file: Option, /// Save qlog file (.qlog) into the given directory. - #[clap(long, value_name = "DIR")] + #[clap(long, value_name = "DIR", help_heading = "Output")] pub qlog_dir: Option, - /// Length of connection id in bytes. - #[clap(long, default_value = "8", value_name = "NUM")] - pub cid_len: usize, + /// Client will exit if consecutive failure reaches the threshold at the beginning. + #[clap(long, default_value = "10", value_name = "NUM", help_heading = "Misc")] + pub connection_failure_threshold: u64, /// Batch size for sending packets. - #[clap(long, default_value = "1", value_name = "NUM")] + #[clap(long, default_value = "1", value_name = "NUM", help_heading = "Misc")] pub send_batch_size: usize, + + /// Number of max samples per thread used for request time statistics. + #[clap( + long, + default_value = "100000", + value_name = "NUM", + help_heading = "Misc" + )] + pub max_sample: usize, } const MAX_BUF_SIZE: usize = 65536; @@ -559,8 +658,8 @@ impl Worker { if (self.option.duration > 0 && (Instant::now() - self.start_time).as_secs() > self.option.duration) - || (self.option.max_requests_per_thread > 0 - && worker_ctx.request_done >= self.option.max_requests_per_thread) + || (self.option.total_requests_per_thread > 0 + && worker_ctx.request_done >= self.option.total_requests_per_thread) { debug!( "worker should exit, concurrent conns {}, request sent {}, request done {}", @@ -1427,9 +1526,9 @@ fn parse_option() -> std::result::Result { option.max_requests_per_conn = max(option.max_requests_per_conn, option.urls.len() as u64); } - if option.max_requests_per_thread != 0 { - option.max_requests_per_thread = - max(option.max_requests_per_thread, option.urls.len() as u64); + if option.total_requests_per_thread != 0 { + option.total_requests_per_thread = + max(option.total_requests_per_thread, option.urls.len() as u64); } Ok(option) diff --git a/tools/src/bin/tquic_server.rs b/tools/src/bin/tquic_server.rs index 9c1c8607..021b2aaf 100644 --- a/tools/src/bin/tquic_server.rs +++ b/tools/src/bin/tquic_server.rs @@ -54,6 +54,10 @@ static GLOBAL: jemallocator::Jemalloc = jemallocator::Jemalloc; #[derive(Parser, Debug)] #[clap(name = "server")] pub struct ServerOpt { + /// Address to listen. + #[clap(short, long, default_value = "0.0.0.0:4433", value_name = "ADDR")] + pub listen: SocketAddr, + /// TLS certificate in PEM format. #[clap( short, @@ -67,108 +71,170 @@ pub struct ServerOpt { #[clap(short, long = "key", default_value = "./cert.key", value_name = "FILE")] pub key_file: String, - /// Log level, support OFF/ERROR/WARN/INFO/DEBUG/TRACE. - #[clap(long, default_value = "INFO")] - pub log_level: log::LevelFilter, - - /// Log file path. If no file is specified, logs will be written to `stderr`. - #[clap(long, value_name = "FILE")] - pub log_file: Option, - - /// Address to listen. - #[clap(short, long, default_value = "0.0.0.0:4433", value_name = "ADDR")] - pub listen: SocketAddr, - /// Document root directory. - #[clap(long, default_value = "./", value_name = "DIR")] + #[clap(short, long, default_value = "./", value_name = "DIR")] pub root: String, /// Session ticket key. - #[clap(long, default_value = "tquic key", value_name = "STR")] + #[clap( + short, + long, + default_value = "tquic key", + value_name = "STR", + help_heading = "Protocol" + )] pub ticket_key: String, /// Key for generating address token. - #[clap(long, value_name = "STR")] + #[clap(long, value_name = "STR", help_heading = "Protocol")] pub address_token_key: Option, /// Enable stateless retry. - #[clap(long)] + #[clap(long, help_heading = "Protocol")] pub enable_retry: bool, /// Disable stateless reset. - #[clap(long)] + #[clap(long, help_heading = "Protocol")] pub disable_stateless_reset: bool, /// Congestion control algorithm. - #[clap(long, default_value = "BBR")] + #[clap(long, default_value = "BBR", help_heading = "Protocol")] pub congestion_control_algor: CongestionControlAlgorithm, /// Initial congestion window in packets. - #[clap(long, default_value = "32", value_name = "NUM")] + #[clap( + long, + default_value = "32", + value_name = "NUM", + help_heading = "Protocol" + )] pub initial_congestion_window: u64, /// Minimum congestion window in packets. - #[clap(long, default_value = "4", value_name = "NUM")] + #[clap( + long, + default_value = "4", + value_name = "NUM", + help_heading = "Protocol" + )] pub min_congestion_window: u64, /// Enable multipath transport. - #[clap(long)] + #[clap(short, long, help_heading = "Protocol")] pub enable_multipath: bool, /// Multipath scheduling algorithm - #[clap(long, default_value = "MINRTT")] + #[clap(short, long, default_value = "MINRTT", help_heading = "Protocol")] pub multipath_algor: MultipathAlgorithm, /// Set active_connection_id_limit transport parameter. Values lower than 2 will be ignored. - #[clap(long, default_value = "2", value_name = "NUM")] + #[clap( + long, + default_value = "2", + value_name = "NUM", + help_heading = "Protocol" + )] pub active_cid_limit: u64, /// Set max_udp_payload_size transport parameter. - #[clap(long, default_value = "65527", value_name = "NUM")] + #[clap( + long, + default_value = "65527", + value_name = "NUM", + help_heading = "Protocol" + )] pub recv_udp_payload_size: u16, /// Set the maximum outgoing UDP payload size. - #[clap(long, default_value = "1200", value_name = "NUM")] + #[clap( + long, + default_value = "1200", + value_name = "NUM", + help_heading = "Protocol" + )] pub send_udp_payload_size: usize, /// Handshake timeout in microseconds. - #[clap(long, default_value = "10000", value_name = "TIME")] + #[clap( + long, + default_value = "10000", + value_name = "TIME", + help_heading = "Protocol" + )] pub handshake_timeout: u64, /// Connection idle timeout in microseconds. - #[clap(long, default_value = "30000", value_name = "TIME")] + #[clap( + long, + default_value = "30000", + value_name = "TIME", + help_heading = "Protocol" + )] pub idle_timeout: u64, /// Initial RTT in milliseconds. - #[clap(long, default_value = "333", value_name = "TIME")] + #[clap( + long, + default_value = "333", + value_name = "TIME", + help_heading = "Protocol" + )] pub initial_rtt: u64, /// Linear factor for calculating the probe timeout. - #[clap(long, default_value = "10", value_name = "NUM")] + #[clap( + long, + default_value = "10", + value_name = "NUM", + help_heading = "Protocol" + )] pub pto_linear_factor: u64, /// Upper limit of probe timeout in microseconds. - #[clap(long, default_value = "10000", value_name = "TIME")] + #[clap( + long, + default_value = "10000", + value_name = "TIME", + help_heading = "Protocol" + )] pub max_pto: u64, + /// Anti amplification factor. + #[clap( + long, + default_value = "3", + value_name = "NUM", + help_heading = "Protocol" + )] + pub anti_amplification_factor: usize, + + /// Length of connection id in bytes. + #[clap( + long, + default_value = "8", + value_name = "NUM", + help_heading = "Protocol" + )] + pub cid_len: usize, + + /// Log level, support OFF/ERROR/WARN/INFO/DEBUG/TRACE. + #[clap(long, default_value = "INFO", help_heading = "Output")] + pub log_level: log::LevelFilter, + + /// Log file path. If no file is specified, logs will be written to `stderr`. + #[clap(long, value_name = "FILE", help_heading = "Output")] + pub log_file: Option, + /// Save TLS key log into the given file. - #[clap(long, value_name = "FILE")] + #[clap(long, value_name = "FILE", help_heading = "Output")] pub keylog_file: Option, /// Save qlog file (.qlog) into the given directory. - #[clap(long, value_name = "DIR")] + #[clap(long, value_name = "DIR", help_heading = "Output")] pub qlog_dir: Option, - /// Length of connection id in bytes. - #[clap(long, default_value = "8", value_name = "NUM")] - pub cid_len: usize, - - /// Anti amplification factor. - #[clap(long, default_value = "3", value_name = "NUM")] - pub anti_amplification_factor: usize, - /// Batch size for sending packets. - #[clap(long, default_value = "16", value_name = "NUM")] + #[clap(long, default_value = "16", value_name = "NUM", help_heading = "Misc")] pub send_batch_size: usize, } @@ -814,7 +880,7 @@ fn main() -> Result<()> { let mut server = Server::new(&option)?; // Run event loop. - debug!( + info!( "{} listen on {:?}", server.endpoint.trace_id(), option.listen