add option binding server to a specified IP
This commit is contained in:
parent
3929af931b
commit
d1d61cf762
@ -9,14 +9,22 @@ use rustls::{version::TLS13, Error as RustlsError, ServerConfig as RustlsServerC
|
|||||||
use serde::{de::Error as DeError, Deserialize, Deserializer};
|
use serde::{de::Error as DeError, Deserialize, Deserializer};
|
||||||
use serde_json::Error as JsonError;
|
use serde_json::Error as JsonError;
|
||||||
use std::{
|
use std::{
|
||||||
collections::HashSet, env::ArgsOs, fmt::Display, fs::File, io::Error as IoError,
|
collections::HashSet,
|
||||||
num::ParseIntError, str::FromStr, sync::Arc, time::Duration,
|
env::ArgsOs,
|
||||||
|
fmt::Display,
|
||||||
|
fs::File,
|
||||||
|
io::Error as IoError,
|
||||||
|
net::{AddrParseError, IpAddr, Ipv4Addr, SocketAddr},
|
||||||
|
num::ParseIntError,
|
||||||
|
str::FromStr,
|
||||||
|
sync::Arc,
|
||||||
|
time::Duration,
|
||||||
};
|
};
|
||||||
use thiserror::Error;
|
use thiserror::Error;
|
||||||
|
|
||||||
pub struct Config {
|
pub struct Config {
|
||||||
pub server_config: ServerConfig,
|
pub server_config: ServerConfig,
|
||||||
pub port: u16,
|
pub listen_addr: SocketAddr,
|
||||||
pub token: HashSet<[u8; 32]>,
|
pub token: HashSet<[u8; 32]>,
|
||||||
pub authentication_timeout: Duration,
|
pub authentication_timeout: Duration,
|
||||||
pub max_udp_relay_packet_size: usize,
|
pub max_udp_relay_packet_size: usize,
|
||||||
@ -68,7 +76,7 @@ impl Config {
|
|||||||
config
|
config
|
||||||
};
|
};
|
||||||
|
|
||||||
let port = raw.port.unwrap();
|
let listen_addr = SocketAddr::from((raw.ip, raw.port.unwrap()));
|
||||||
|
|
||||||
let token = raw
|
let token = raw
|
||||||
.token
|
.token
|
||||||
@ -82,7 +90,7 @@ impl Config {
|
|||||||
|
|
||||||
Ok(Self {
|
Ok(Self {
|
||||||
server_config,
|
server_config,
|
||||||
port,
|
listen_addr,
|
||||||
token,
|
token,
|
||||||
authentication_timeout,
|
authentication_timeout,
|
||||||
max_udp_relay_packet_size,
|
max_udp_relay_packet_size,
|
||||||
@ -99,6 +107,9 @@ struct RawConfig {
|
|||||||
certificate: Option<String>,
|
certificate: Option<String>,
|
||||||
private_key: Option<String>,
|
private_key: Option<String>,
|
||||||
|
|
||||||
|
#[serde(default = "default::ip")]
|
||||||
|
ip: IpAddr,
|
||||||
|
|
||||||
#[serde(
|
#[serde(
|
||||||
default = "default::congestion_controller",
|
default = "default::congestion_controller",
|
||||||
deserialize_with = "deserialize_from_str"
|
deserialize_with = "deserialize_from_str"
|
||||||
@ -128,6 +139,7 @@ impl Default for RawConfig {
|
|||||||
token: Vec::new(),
|
token: Vec::new(),
|
||||||
certificate: None,
|
certificate: None,
|
||||||
private_key: None,
|
private_key: None,
|
||||||
|
ip: default::ip(),
|
||||||
congestion_controller: default::congestion_controller(),
|
congestion_controller: default::congestion_controller(),
|
||||||
max_idle_time: default::max_idle_time(),
|
max_idle_time: default::max_idle_time(),
|
||||||
authentication_timeout: default::authentication_timeout(),
|
authentication_timeout: default::authentication_timeout(),
|
||||||
@ -172,6 +184,13 @@ impl RawConfig {
|
|||||||
"PRIVATE_KEY",
|
"PRIVATE_KEY",
|
||||||
);
|
);
|
||||||
|
|
||||||
|
opts.optopt(
|
||||||
|
"",
|
||||||
|
"ip",
|
||||||
|
"Set the server listening IP. Default: 0.0.0.0",
|
||||||
|
"IP",
|
||||||
|
);
|
||||||
|
|
||||||
opts.optopt(
|
opts.optopt(
|
||||||
"",
|
"",
|
||||||
"congestion-controller",
|
"congestion-controller",
|
||||||
@ -276,6 +295,10 @@ impl RawConfig {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
if let Some(ip) = matches.opt_str("ip") {
|
||||||
|
raw.ip = ip.parse()?;
|
||||||
|
};
|
||||||
|
|
||||||
if let Some(cgstn_ctrl) = matches.opt_str("congestion-controller") {
|
if let Some(cgstn_ctrl) = matches.opt_str("congestion-controller") {
|
||||||
raw.congestion_controller = cgstn_ctrl.parse()?;
|
raw.congestion_controller = cgstn_ctrl.parse()?;
|
||||||
};
|
};
|
||||||
@ -347,6 +370,10 @@ where
|
|||||||
mod default {
|
mod default {
|
||||||
use super::*;
|
use super::*;
|
||||||
|
|
||||||
|
pub(super) fn ip() -> IpAddr {
|
||||||
|
IpAddr::V4(Ipv4Addr::UNSPECIFIED)
|
||||||
|
}
|
||||||
|
|
||||||
pub(super) const fn congestion_controller() -> CongestionController {
|
pub(super) const fn congestion_controller() -> CongestionController {
|
||||||
CongestionController::Cubic
|
CongestionController::Cubic
|
||||||
}
|
}
|
||||||
@ -390,6 +417,8 @@ pub enum ConfigError {
|
|||||||
MissingOption(&'static str),
|
MissingOption(&'static str),
|
||||||
#[error(transparent)]
|
#[error(transparent)]
|
||||||
ParseInt(#[from] ParseIntError),
|
ParseInt(#[from] ParseIntError),
|
||||||
|
#[error(transparent)]
|
||||||
|
ParseAddr(#[from] AddrParseError),
|
||||||
#[error("Invalid congestion controller")]
|
#[error("Invalid congestion controller")]
|
||||||
InvalidCongestionController,
|
InvalidCongestionController,
|
||||||
#[error(transparent)]
|
#[error(transparent)]
|
||||||
|
@ -34,7 +34,7 @@ async fn main() {
|
|||||||
|
|
||||||
let server = match Server::init(
|
let server = match Server::init(
|
||||||
config.server_config,
|
config.server_config,
|
||||||
config.port,
|
config.listen_addr,
|
||||||
config.token,
|
config.token,
|
||||||
config.authentication_timeout,
|
config.authentication_timeout,
|
||||||
config.max_udp_relay_packet_size,
|
config.max_udp_relay_packet_size,
|
||||||
|
@ -4,15 +4,15 @@ use quinn::{Endpoint, EndpointConfig, Incoming, ServerConfig};
|
|||||||
use socket2::{Domain, Protocol, SockAddr, Socket, Type};
|
use socket2::{Domain, Protocol, SockAddr, Socket, Type};
|
||||||
use std::{
|
use std::{
|
||||||
collections::HashSet,
|
collections::HashSet,
|
||||||
io::Error as IoError,
|
io::Result,
|
||||||
net::{Ipv6Addr, SocketAddr, UdpSocket},
|
net::{SocketAddr, UdpSocket},
|
||||||
sync::Arc,
|
sync::Arc,
|
||||||
time::Duration,
|
time::Duration,
|
||||||
};
|
};
|
||||||
|
|
||||||
pub struct Server {
|
pub struct Server {
|
||||||
incoming: Incoming,
|
incoming: Incoming,
|
||||||
port: u16,
|
listen_addr: SocketAddr,
|
||||||
token: Arc<HashSet<[u8; 32]>>,
|
token: Arc<HashSet<[u8; 32]>>,
|
||||||
authentication_timeout: Duration,
|
authentication_timeout: Duration,
|
||||||
max_pkt_size: usize,
|
max_pkt_size: usize,
|
||||||
@ -21,24 +21,26 @@ pub struct Server {
|
|||||||
impl Server {
|
impl Server {
|
||||||
pub fn init(
|
pub fn init(
|
||||||
config: ServerConfig,
|
config: ServerConfig,
|
||||||
port: u16,
|
listen_addr: SocketAddr,
|
||||||
token: HashSet<[u8; 32]>,
|
token: HashSet<[u8; 32]>,
|
||||||
auth_timeout: Duration,
|
auth_timeout: Duration,
|
||||||
max_pkt_size: usize,
|
max_pkt_size: usize,
|
||||||
) -> Result<Self, IoError> {
|
) -> Result<Self> {
|
||||||
let socket = Socket::new(Domain::IPV6, Type::DGRAM, Some(Protocol::UDP))?;
|
let socket = match listen_addr {
|
||||||
socket.set_only_v6(false)?;
|
SocketAddr::V4(_) => UdpSocket::bind(listen_addr)?,
|
||||||
socket.bind(&SockAddr::from(SocketAddr::from((
|
SocketAddr::V6(_) => {
|
||||||
Ipv6Addr::UNSPECIFIED,
|
let socket = Socket::new(Domain::IPV6, Type::DGRAM, Some(Protocol::UDP))?;
|
||||||
port,
|
socket.set_only_v6(false)?;
|
||||||
))))?;
|
socket.bind(&SockAddr::from(listen_addr))?;
|
||||||
let socket = UdpSocket::from(socket);
|
UdpSocket::from(socket)
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
let (_, incoming) = Endpoint::new(EndpointConfig::default(), Some(config), socket)?;
|
let (_, incoming) = Endpoint::new(EndpointConfig::default(), Some(config), socket)?;
|
||||||
|
|
||||||
Ok(Self {
|
Ok(Self {
|
||||||
incoming,
|
incoming,
|
||||||
port,
|
listen_addr,
|
||||||
token: Arc::new(token),
|
token: Arc::new(token),
|
||||||
authentication_timeout: auth_timeout,
|
authentication_timeout: auth_timeout,
|
||||||
max_pkt_size,
|
max_pkt_size,
|
||||||
@ -46,7 +48,7 @@ impl Server {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub async fn run(mut self) {
|
pub async fn run(mut self) {
|
||||||
log::info!("Server started. Listening port: {}", self.port);
|
log::info!("Server started. Listening: {}", self.listen_addr);
|
||||||
|
|
||||||
while let Some(conn) = self.incoming.next().await {
|
while let Some(conn) = self.incoming.next().await {
|
||||||
let token = self.token.clone();
|
let token = self.token.clone();
|
||||||
|
Loading…
x
Reference in New Issue
Block a user