aquatic_ws: set so_reuseport on socket, with new create_listener fn

This commit is contained in:
Joakim Frostegård 2020-05-12 15:23:25 +02:00
parent 21048727db
commit e4bdfd06fb
3 changed files with 36 additions and 25 deletions

View file

@ -2,17 +2,18 @@
## aquatic_ws ## aquatic_ws
* network * network
* open socket with so_reuseport and nonblocking
* native_tls for wss support * native_tls for wss support
* handshake: deregister stream when applicable * handshake: deregister stream when applicable
* connection cleaning: shrink to fit * connection cleaning: shrink to fit
* test * test
* test full torrent transfer (offer-answer exchange) * test full torrent transfer (offer-answer exchange)
* torrent state cleaning * torrent state cleaning
* log crate instead of println/eprintln * log crate instead of println/eprintln?
* privdrop * privdrop
* some config.network fields are actually used in handler. maybe they should * config
be checked while parsing? not completely clear * 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 ## aquatic_udp
* mio: set oneshot for epoll and kqueue? otherwise, stop reregistering? * mio: set oneshot for epoll and kqueue? otherwise, stop reregistering?

View file

@ -30,21 +30,6 @@ pub struct NetworkConfig {
pub max_offers: usize, // FIXME: should this really be in NetworkConfig? pub max_offers: usize, // FIXME: should this really be in NetworkConfig?
/// Ask peers to announce this often (seconds) /// Ask peers to announce this often (seconds)
pub peer_announce_interval: usize, // FIXME: should this really be in NetworkConfig? 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_event_capacity: usize,
pub poll_timeout_milliseconds: u64, pub poll_timeout_milliseconds: u64,
} }
@ -102,12 +87,11 @@ impl Default for NetworkConfig {
fn default() -> Self { fn default() -> Self {
Self { Self {
address: SocketAddr::from(([127, 0, 0, 1], 3000)), address: SocketAddr::from(([127, 0, 0, 1], 3000)),
max_scrape_torrents: 255, max_scrape_torrents: 255, // FIXME: what value is reasonable?
max_offers: 10, max_offers: 10,
peer_announce_interval: 60 * 15, peer_announce_interval: 120,
poll_event_capacity: 4096, poll_event_capacity: 4096,
poll_timeout_milliseconds: 50, poll_timeout_milliseconds: 50,
socket_recv_buffer_size: 4096 * 128,
} }
} }
} }
@ -127,8 +111,8 @@ impl Default for CleaningConfig {
fn default() -> Self { fn default() -> Self {
Self { Self {
interval: 30, interval: 30,
max_peer_age: 60 * 20, max_peer_age: 180,
max_connection_age: 60 * 5, max_connection_age: 180,
} }
} }
} }

View file

@ -5,6 +5,7 @@ use std::io::ErrorKind;
use tungstenite::WebSocket; use tungstenite::WebSocket;
use tungstenite::handshake::{MidHandshake, HandshakeError, server::{ServerHandshake, NoCallback}}; use tungstenite::handshake::{MidHandshake, HandshakeError, server::{ServerHandshake, NoCallback}};
use hashbrown::HashMap; use hashbrown::HashMap;
use net2::{TcpBuilder, unix::UnixTcpBuilderExt};
use mio::{Events, Poll, Interest, Token}; use mio::{Events, Poll, Interest, Token};
use mio::net::{TcpListener, TcpStream}; 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( pub fn run_socket_worker(
config: Config, config: Config,
socket_worker_index: usize, socket_worker_index: usize,
@ -110,7 +136,7 @@ pub fn run_socket_worker(
config.network.poll_timeout_milliseconds 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 poll = Poll::new().expect("create poll");
let mut events = Events::with_capacity(config.network.poll_event_capacity); let mut events = Events::with_capacity(config.network.poll_event_capacity);