Loading crates/arti/src/arti-example-config.toml +10 −0 Original line number Diff line number Diff line Loading @@ -61,6 +61,16 @@ # https://spec.torproject.org/http-connect.html #enable_http_connect = true # The socket buffer sizes (`SO_SNDBUF` and `SO_RCVBUF`) to use for # SOCKS and HTTP CONNECT sockets. # # The defaults are intended to work well for all use cases. # If you find that you need to change these options, # you may want to open an issue at # https://gitlab.torproject.org/tpo/core/arti/-/work_items. #socket_send_buf_size = "128 KB" #socket_recv_buf_size = "128 KB" # Configure logging [logging] Loading crates/arti/src/cfg.rs +28 −0 Original line number Diff line number Diff line Loading @@ -3,6 +3,7 @@ // (This module is called `cfg` to avoid name clash with the `config` crate, which we use.) use derive_deftly::Deftly; use tor_basic_utils::ByteQty; use tor_config_path::CfgPath; #[cfg(feature = "onion-service-service")] Loading Loading @@ -50,6 +51,23 @@ pub(crate) const ARTI_EXAMPLE_CONFIG: &str = concat!(include_str!("./arti-exampl #[cfg(test)] const OLDEST_SUPPORTED_CONFIG: &str = concat!(include_str!("./oldest-supported-config.toml"),); // Our proxy sockets will use a small-ish fixed kernel socket buffer size. // Tor streams are slow relative to a pair of loopback sockets, // so don't need socket buffers as large as what Linux provides by default // (sometimes several MBs). // // This has a few advantages over the defaults: // - Less buffer bloat. // - Better ability to make congestion/flow control decisions. // - Disables TCP autotuning, which means behaviour will better match Shadow sims. // - Easier to reason about stream performance when the buffer size isn't dynamic. // // See https://gitlab.torproject.org/tpo/core/arti/-/work_items/2500. /// See [`ProxyConfig::socket_send_buf_size`]. const DEFAULT_SEND_BUF_SIZE: usize = 128_000; /// See [`ProxyConfig::socket_recv_buf_size`]. const DEFAULT_RECV_BUF_SIZE: usize = 128_000; /// Replacement for rpc config when the rpc feature is disabled. #[cfg(not(feature = "rpc"))] type RpcConfig = (); Loading Loading @@ -120,6 +138,14 @@ pub(crate) struct ProxyConfig { ))] #[deftly(tor_config(default = "true"))] pub(crate) enable_http_connect: bool, /// The send buffer size (`SO_SNDBUF`) of proxy sockets. #[deftly(tor_config(default = "ByteQty(DEFAULT_SEND_BUF_SIZE)"))] pub(crate) socket_send_buf_size: ByteQty, /// The receive buffer size (`SO_RCVBUF`) of proxy sockets. #[deftly(tor_config(default = "ByteQty(DEFAULT_RECV_BUF_SIZE)"))] pub(crate) socket_recv_buf_size: ByteQty, } impl ProxyConfig { Loading Loading @@ -561,6 +587,8 @@ mod test { "use_obsolete_software", "circuit_timing.disused_circuit_timeout", "storage.port_info_file", "proxy.socket_send_buf_size", "proxy.socket_recv_buf_size", ], ); Loading crates/arti/src/proxy.rs +2 −20 Original line number Diff line number Diff line Loading @@ -17,7 +17,7 @@ use futures::stream::StreamExt; use std::net::IpAddr; use std::sync::Arc; use tor_basic_utils::error_sources::ErrorSources; use tor_rtcompat::{NetStreamProvider, SpawnExt}; use tor_rtcompat::{NetStreamProvider, SpawnExt, TcpListenOptions}; use tracing::{debug, error, info, instrument, warn}; #[allow(unused)] Loading Loading @@ -386,6 +386,7 @@ pub(crate) async fn bind_proxy<R: Runtime>( runtime: R, tor_client: TorClient<R>, listen: Listen, listen_options: TcpListenOptions, protocols: ListenProtocols, rpc_mgr: Option<Arc<RpcMgr>>, ) -> Result<StreamProxy<R>> { Loading @@ -396,25 +397,6 @@ pub(crate) async fn bind_proxy<R: Runtime>( ); } // Our proxy sockets will use a small-ish fixed kernel socket buffer size. // Tor streams are slow relative to a pair of loopback sockets, // so don't need socket buffers as large as what Linux provides by default // (sometimes several MBs). // // This has a few advantages over the defaults: // - Less buffer bloat. // - Better ability to make congestion/flow control decisions. // - Disables TCP autotuning, which means behaviour will better match Shadow sims. // - Easier to reason about stream performance when the buffer size isn't dynamic. // // See https://gitlab.torproject.org/tpo/core/arti/-/work_items/2500. let mut listen_options = tor_rtcompat::TcpListenOptions::builder(); listen_options .common() .send_buffer_size(Some(128_000)) .recv_buffer_size(Some(128_000)); let listen_options = listen_options.build()?; let mut listeners = Vec::new(); // Try to bind to the listener ports. Loading crates/arti/src/subcommands/proxy.rs +18 −3 Original line number Diff line number Diff line Loading @@ -185,6 +185,14 @@ async fn run_proxy<R: ToplevelRuntime>( } } // The options that we'll use for our listening proxy sockets. let mut listen_options = tor_rtcompat::TcpListenOptions::builder(); listen_options .common() .send_buffer_size(Some(arti_config.proxy().socket_send_buf_size.as_usize())) .recv_buffer_size(Some(arti_config.proxy().socket_recv_buf_size.as_usize())); let listen_options = listen_options.build()?; let mut proxy: Vec<PinnedFuture<Result<()>>> = Vec::new(); let mut ports = Vec::new(); if !socks_listen.is_empty() { Loading @@ -193,7 +201,14 @@ async fn run_proxy<R: ToplevelRuntime>( let socks_listen = socks_listen.clone(); let listener_type = protocols.to_string(); let stream_proxy = proxy::bind_proxy(runtime, client, socks_listen, protocols, rpc_mgr) let stream_proxy = proxy::bind_proxy( runtime, client, socks_listen, listen_options, protocols, rpc_mgr, ) .await .with_context(|| format!("Unable to launch {listener_type} proxy"))?; let port_info = stream_proxy.port_info()?; Loading Loading
crates/arti/src/arti-example-config.toml +10 −0 Original line number Diff line number Diff line Loading @@ -61,6 +61,16 @@ # https://spec.torproject.org/http-connect.html #enable_http_connect = true # The socket buffer sizes (`SO_SNDBUF` and `SO_RCVBUF`) to use for # SOCKS and HTTP CONNECT sockets. # # The defaults are intended to work well for all use cases. # If you find that you need to change these options, # you may want to open an issue at # https://gitlab.torproject.org/tpo/core/arti/-/work_items. #socket_send_buf_size = "128 KB" #socket_recv_buf_size = "128 KB" # Configure logging [logging] Loading
crates/arti/src/cfg.rs +28 −0 Original line number Diff line number Diff line Loading @@ -3,6 +3,7 @@ // (This module is called `cfg` to avoid name clash with the `config` crate, which we use.) use derive_deftly::Deftly; use tor_basic_utils::ByteQty; use tor_config_path::CfgPath; #[cfg(feature = "onion-service-service")] Loading Loading @@ -50,6 +51,23 @@ pub(crate) const ARTI_EXAMPLE_CONFIG: &str = concat!(include_str!("./arti-exampl #[cfg(test)] const OLDEST_SUPPORTED_CONFIG: &str = concat!(include_str!("./oldest-supported-config.toml"),); // Our proxy sockets will use a small-ish fixed kernel socket buffer size. // Tor streams are slow relative to a pair of loopback sockets, // so don't need socket buffers as large as what Linux provides by default // (sometimes several MBs). // // This has a few advantages over the defaults: // - Less buffer bloat. // - Better ability to make congestion/flow control decisions. // - Disables TCP autotuning, which means behaviour will better match Shadow sims. // - Easier to reason about stream performance when the buffer size isn't dynamic. // // See https://gitlab.torproject.org/tpo/core/arti/-/work_items/2500. /// See [`ProxyConfig::socket_send_buf_size`]. const DEFAULT_SEND_BUF_SIZE: usize = 128_000; /// See [`ProxyConfig::socket_recv_buf_size`]. const DEFAULT_RECV_BUF_SIZE: usize = 128_000; /// Replacement for rpc config when the rpc feature is disabled. #[cfg(not(feature = "rpc"))] type RpcConfig = (); Loading Loading @@ -120,6 +138,14 @@ pub(crate) struct ProxyConfig { ))] #[deftly(tor_config(default = "true"))] pub(crate) enable_http_connect: bool, /// The send buffer size (`SO_SNDBUF`) of proxy sockets. #[deftly(tor_config(default = "ByteQty(DEFAULT_SEND_BUF_SIZE)"))] pub(crate) socket_send_buf_size: ByteQty, /// The receive buffer size (`SO_RCVBUF`) of proxy sockets. #[deftly(tor_config(default = "ByteQty(DEFAULT_RECV_BUF_SIZE)"))] pub(crate) socket_recv_buf_size: ByteQty, } impl ProxyConfig { Loading Loading @@ -561,6 +587,8 @@ mod test { "use_obsolete_software", "circuit_timing.disused_circuit_timeout", "storage.port_info_file", "proxy.socket_send_buf_size", "proxy.socket_recv_buf_size", ], ); Loading
crates/arti/src/proxy.rs +2 −20 Original line number Diff line number Diff line Loading @@ -17,7 +17,7 @@ use futures::stream::StreamExt; use std::net::IpAddr; use std::sync::Arc; use tor_basic_utils::error_sources::ErrorSources; use tor_rtcompat::{NetStreamProvider, SpawnExt}; use tor_rtcompat::{NetStreamProvider, SpawnExt, TcpListenOptions}; use tracing::{debug, error, info, instrument, warn}; #[allow(unused)] Loading Loading @@ -386,6 +386,7 @@ pub(crate) async fn bind_proxy<R: Runtime>( runtime: R, tor_client: TorClient<R>, listen: Listen, listen_options: TcpListenOptions, protocols: ListenProtocols, rpc_mgr: Option<Arc<RpcMgr>>, ) -> Result<StreamProxy<R>> { Loading @@ -396,25 +397,6 @@ pub(crate) async fn bind_proxy<R: Runtime>( ); } // Our proxy sockets will use a small-ish fixed kernel socket buffer size. // Tor streams are slow relative to a pair of loopback sockets, // so don't need socket buffers as large as what Linux provides by default // (sometimes several MBs). // // This has a few advantages over the defaults: // - Less buffer bloat. // - Better ability to make congestion/flow control decisions. // - Disables TCP autotuning, which means behaviour will better match Shadow sims. // - Easier to reason about stream performance when the buffer size isn't dynamic. // // See https://gitlab.torproject.org/tpo/core/arti/-/work_items/2500. let mut listen_options = tor_rtcompat::TcpListenOptions::builder(); listen_options .common() .send_buffer_size(Some(128_000)) .recv_buffer_size(Some(128_000)); let listen_options = listen_options.build()?; let mut listeners = Vec::new(); // Try to bind to the listener ports. Loading
crates/arti/src/subcommands/proxy.rs +18 −3 Original line number Diff line number Diff line Loading @@ -185,6 +185,14 @@ async fn run_proxy<R: ToplevelRuntime>( } } // The options that we'll use for our listening proxy sockets. let mut listen_options = tor_rtcompat::TcpListenOptions::builder(); listen_options .common() .send_buffer_size(Some(arti_config.proxy().socket_send_buf_size.as_usize())) .recv_buffer_size(Some(arti_config.proxy().socket_recv_buf_size.as_usize())); let listen_options = listen_options.build()?; let mut proxy: Vec<PinnedFuture<Result<()>>> = Vec::new(); let mut ports = Vec::new(); if !socks_listen.is_empty() { Loading @@ -193,7 +201,14 @@ async fn run_proxy<R: ToplevelRuntime>( let socks_listen = socks_listen.clone(); let listener_type = protocols.to_string(); let stream_proxy = proxy::bind_proxy(runtime, client, socks_listen, protocols, rpc_mgr) let stream_proxy = proxy::bind_proxy( runtime, client, socks_listen, listen_options, protocols, rpc_mgr, ) .await .with_context(|| format!("Unable to launch {listener_type} proxy"))?; let port_info = stream_proxy.port_info()?; Loading