From e4bdfd06fb5f80a3c1e0de9bfcf82a8090bcdfd8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Joakim=20Frosteg=C3=A5rd?= Date: Tue, 12 May 2020 15:23:25 +0200 Subject: [PATCH] aquatic_ws: set so_reuseport on socket, with new create_listener fn --- TODO.md | 9 +++++---- aquatic_ws/src/lib/config.rs | 24 ++++-------------------- aquatic_ws/src/lib/network.rs | 28 +++++++++++++++++++++++++++- 3 files changed, 36 insertions(+), 25 deletions(-) diff --git a/TODO.md b/TODO.md index cf2d0e0..501b2c8 100644 --- a/TODO.md +++ b/TODO.md @@ -2,17 +2,18 @@ ## aquatic_ws * network - * open socket with so_reuseport and nonblocking * native_tls for wss support * handshake: deregister stream when applicable * connection cleaning: shrink to fit * test * test full torrent transfer (offer-answer exchange) * torrent state cleaning -* log crate instead of println/eprintln +* log crate instead of println/eprintln? * privdrop -* some config.network fields are actually used in handler. maybe they should - be checked while parsing? not completely clear +* config + * send/recv buffer size: how does this interact with tls? + * some config.network fields are actually used in handler. maybe they should + be checked while parsing? not completely clear ## aquatic_udp * mio: set oneshot for epoll and kqueue? otherwise, stop reregistering? diff --git a/aquatic_ws/src/lib/config.rs b/aquatic_ws/src/lib/config.rs index 5458491..d251693 100644 --- a/aquatic_ws/src/lib/config.rs +++ b/aquatic_ws/src/lib/config.rs @@ -30,21 +30,6 @@ pub struct NetworkConfig { pub max_offers: usize, // FIXME: should this really be in NetworkConfig? /// Ask peers to announce this often (seconds) pub peer_announce_interval: usize, // FIXME: should this really be in NetworkConfig? - /// Size of socket recv buffer. Use 0 for OS default. - /// - /// This setting can have a big impact on dropped packages. It might - /// require changing system defaults. Some examples of commands to set - /// recommended values for different operating systems: - /// - /// macOS: - /// $ sudo sysctl net.inet.udp.recvspace=6000000 - /// $ sudo sysctl net.inet.udp.maxdgram=500000 # Not necessary, but recommended - /// $ sudo sysctl kern.ipc.maxsockbuf=8388608 # Not necessary, but recommended - /// - /// Linux: - /// $ sudo sysctl -w net.core.rmem_max=104857600 - /// $ sudo sysctl -w net.core.rmem_default=104857600 - pub socket_recv_buffer_size: usize, // FIXME: implement pub poll_event_capacity: usize, pub poll_timeout_milliseconds: u64, } @@ -102,12 +87,11 @@ impl Default for NetworkConfig { fn default() -> Self { Self { address: SocketAddr::from(([127, 0, 0, 1], 3000)), - max_scrape_torrents: 255, + max_scrape_torrents: 255, // FIXME: what value is reasonable? max_offers: 10, - peer_announce_interval: 60 * 15, + peer_announce_interval: 120, poll_event_capacity: 4096, poll_timeout_milliseconds: 50, - socket_recv_buffer_size: 4096 * 128, } } } @@ -127,8 +111,8 @@ impl Default for CleaningConfig { fn default() -> Self { Self { interval: 30, - max_peer_age: 60 * 20, - max_connection_age: 60 * 5, + max_peer_age: 180, + max_connection_age: 180, } } } diff --git a/aquatic_ws/src/lib/network.rs b/aquatic_ws/src/lib/network.rs index c536bf3..6fac768 100644 --- a/aquatic_ws/src/lib/network.rs +++ b/aquatic_ws/src/lib/network.rs @@ -5,6 +5,7 @@ use std::io::ErrorKind; use tungstenite::WebSocket; use tungstenite::handshake::{MidHandshake, HandshakeError, server::{ServerHandshake, NoCallback}}; use hashbrown::HashMap; +use net2::{TcpBuilder, unix::UnixTcpBuilderExt}; use mio::{Events, Poll, Interest, Token}; use mio::net::{TcpListener, TcpStream}; @@ -100,6 +101,31 @@ pub fn remove_inactive_connections( } +fn create_listener(config: &Config) -> ::std::net::TcpListener { + let mut builder = &{ + if config.network.address.is_ipv4(){ + TcpBuilder::new_v4().expect("socket: build") + } else { + TcpBuilder::new_v6().expect("socket: build") + } + }; + + builder = builder.reuse_port(true) + .expect("socket: set reuse port"); + + builder = builder.bind(&config.network.address) + .expect(&format!("socket: bind to {}", &config.network.address)); + + let listener = builder.listen(128) + .expect("tcpbuilder to tcp listener"); + + listener.set_nonblocking(true) + .expect("socket: set nonblocking"); + + listener +} + + pub fn run_socket_worker( config: Config, socket_worker_index: usize, @@ -110,7 +136,7 @@ pub fn run_socket_worker( config.network.poll_timeout_milliseconds ); - let mut listener = TcpListener::bind(config.network.address).unwrap(); + let mut listener = TcpListener::from_std(create_listener(&config)); let mut poll = Poll::new().expect("create poll"); let mut events = Events::with_capacity(config.network.poll_event_capacity);