aquatic/aquatic_http/src/lib/network/utils.rs

72 lines
No EOL
2 KiB
Rust

use std::time::Instant;
use anyhow::Context;
use mio::Token;
use socket2::{Socket, Domain, Type, Protocol};
use crate::config::Config;
use super::*;
// will be almost identical to ws version
pub fn create_listener(
config: &Config
) -> ::anyhow::Result<::std::net::TcpListener> {
let builder = if config.network.address.is_ipv4(){
Socket::new(Domain::ipv4(), Type::stream(), Some(Protocol::tcp()))
} else {
Socket::new(Domain::ipv6(), Type::stream(), Some(Protocol::tcp()))
}.context("Couldn't create socket2::Socket")?;
if config.network.ipv6_only {
builder.set_only_v6(true)
.context("Couldn't put socket in ipv6 only mode")?
}
builder.set_nonblocking(true)
.context("Couldn't put socket in non-blocking mode")?;
builder.set_reuse_port(true)
.context("Couldn't put socket in reuse_port mode")?;
builder.bind(&config.network.address.into()).with_context(||
format!("Couldn't bind socket to address {}", config.network.address)
)?;
builder.listen(128)
.context("Couldn't listen for connections on socket")?;
Ok(builder.into_tcp_listener())
}
/// Don't bother with deregistering from Poll. In my understanding, this is
/// done automatically when the stream is dropped, as long as there are no
/// other references to the file descriptor, such as when it is accessed
/// in multiple threads.
pub fn remove_connection_if_exists(
connections: &mut ConnectionMap,
token: Token,
){
if let Some(mut connection) = connections.remove(&token){
// connection.close(); // FIXME
}
}
// Close and remove inactive connections
pub fn remove_inactive_connections(
connections: &mut ConnectionMap,
){
let now = Instant::now();
connections.retain(|_, connection| {
if connection.valid_until.0 < now {
// connection.close(); // FIXME
false
} else {
true
}
});
connections.shrink_to_fit();
}