1
0

add max UDP relay packet size option on server

This commit is contained in:
EAimTY 2022-06-25 20:37:14 +09:00
parent 850e3f91e5
commit 083adca141
5 changed files with 53 additions and 8 deletions

View File

@ -19,6 +19,7 @@ pub struct Config {
pub port: u16,
pub token: HashSet<[u8; 32]>,
pub authentication_timeout: Duration,
pub max_udp_relay_packet_size: usize,
pub log_level: LevelFilter,
}
@ -76,6 +77,7 @@ impl Config {
.collect();
let authentication_timeout = Duration::from_secs(raw.authentication_timeout);
let max_udp_relay_packet_size = raw.max_udp_relay_packet_size;
let log_level = raw.log_level;
Ok(Self {
@ -83,6 +85,7 @@ impl Config {
port,
token,
authentication_timeout,
max_udp_relay_packet_size,
log_level,
})
}
@ -111,6 +114,9 @@ struct RawConfig {
#[serde(default = "default::alpn")]
alpn: Vec<String>,
#[serde(default = "default::max_udp_relay_packet_size")]
max_udp_relay_packet_size: usize,
#[serde(default = "default::log_level")]
log_level: LevelFilter,
}
@ -126,6 +132,7 @@ impl Default for RawConfig {
max_idle_time: default::max_idle_time(),
authentication_timeout: default::authentication_timeout(),
alpn: default::alpn(),
max_udp_relay_packet_size: default::max_udp_relay_packet_size(),
log_level: default::log_level(),
}
}
@ -193,6 +200,13 @@ impl RawConfig {
"ALPN_PROTOCOL",
);
opts.optopt(
"",
"max-udp-relay-packet-size",
"UDP relay mode QUIC can transmit UDP packets larger than the MTU. Set this to a higher value allows outbound to receive larger UDP packet. Default: 1500",
"MAX_UDP_RELAY_PACKET_SIZE",
);
opts.optopt(
"",
"log-level",
@ -274,6 +288,10 @@ impl RawConfig {
raw.authentication_timeout = timeout.parse()?;
};
if let Some(size) = matches.opt_str("max-udp-relay-packet-size") {
raw.max_udp_relay_packet_size = size.parse()?;
};
let alpn = matches.opt_strs("alpn");
if !alpn.is_empty() {
@ -345,6 +363,10 @@ mod default {
Vec::new()
}
pub(super) const fn max_udp_relay_packet_size() -> usize {
1500
}
pub(super) const fn log_level() -> LevelFilter {
LevelFilter::Info
}

View File

@ -38,7 +38,12 @@ pub struct Connection {
}
impl Connection {
pub async fn handle(conn: Connecting, token: Arc<HashSet<[u8; 32]>>, auth_timeout: Duration) {
pub async fn handle(
conn: Connecting,
token: Arc<HashSet<[u8; 32]>>,
auth_timeout: Duration,
max_pkt_size: usize,
) {
let rmt_addr = conn.remote_address().restore_ipv4();
match conn.await {
@ -51,7 +56,7 @@ impl Connection {
}) => {
log::debug!("[{rmt_addr}] [establish]");
let (udp_sessions, recv_pkt_rx) = UdpSessionMap::new();
let (udp_sessions, recv_pkt_rx) = UdpSessionMap::new(max_pkt_size);
let is_closed = IsClosed::new();
let is_authed = IsAuthenticated::new(is_closed.clone());

View File

@ -52,16 +52,18 @@ pub type RecvPacketReceiver = Receiver<(u32, Bytes, Address)>;
pub struct UdpSessionMap {
map: Mutex<HashMap<u32, UdpSession>>,
recv_pkt_tx_for_clone: RecvPacketSender,
max_pkt_size: usize,
}
impl UdpSessionMap {
pub fn new() -> (Self, RecvPacketReceiver) {
pub fn new(max_pkt_size: usize) -> (Self, RecvPacketReceiver) {
let (recv_pkt_tx, recv_pkt_rx) = mpsc::channel(1);
(
Self {
map: Mutex::new(HashMap::new()),
recv_pkt_tx_for_clone: recv_pkt_tx,
max_pkt_size,
},
recv_pkt_rx,
)
@ -85,8 +87,13 @@ impl UdpSessionMap {
log::info!("[{src_addr}] [associate] [{assoc_id}]");
drop(map);
let assoc =
UdpSession::new(assoc_id, self.recv_pkt_tx_for_clone.clone(), src_addr).await?;
let assoc = UdpSession::new(
assoc_id,
self.recv_pkt_tx_for_clone.clone(),
src_addr,
self.max_pkt_size,
)
.await?;
let send_pkt_tx = assoc.0.clone();
@ -114,6 +121,7 @@ impl UdpSession {
assoc_id: u32,
recv_pkt_tx: RecvPacketSender,
src_addr: SocketAddr,
max_pkt_size: usize,
) -> Result<Self, IoError> {
let socket = Arc::new(UdpSocket::bind(SocketAddr::from((Ipv6Addr::UNSPECIFIED, 0))).await?);
let (send_pkt_tx, send_pkt_rx) = mpsc::channel(1);
@ -121,7 +129,7 @@ impl UdpSession {
tokio::spawn(async move {
match tokio::select!(
res = Self::listen_send_packet(socket.clone(), send_pkt_rx) => res,
res = Self::listen_receive_packet(socket, assoc_id, recv_pkt_tx) => res,
res = Self::listen_receive_packet(socket, assoc_id, recv_pkt_tx,max_pkt_size) => res,
) {
Ok(()) => (),
Err(err) => log::warn!("[{src_addr}] [udp-session] [{assoc_id}] {err}"),
@ -153,9 +161,10 @@ impl UdpSession {
socket: Arc<UdpSocket>,
assoc_id: u32,
recv_pkt_tx: RecvPacketSender,
max_pkt_size: usize,
) -> Result<(), IoError> {
loop {
let mut buf = vec![0; 65535];
let mut buf = vec![0; max_pkt_size];
let (len, addr) = socket.recv_from(&mut buf).await?;
buf.truncate(len);

View File

@ -37,6 +37,7 @@ async fn main() {
config.port,
config.token,
config.authentication_timeout,
config.max_udp_relay_packet_size,
) {
Ok(server) => server,
Err(err) => {

View File

@ -15,6 +15,7 @@ pub struct Server {
port: u16,
token: Arc<HashSet<[u8; 32]>>,
authentication_timeout: Duration,
max_pkt_size: usize,
}
impl Server {
@ -23,6 +24,7 @@ impl Server {
port: u16,
token: HashSet<[u8; 32]>,
auth_timeout: Duration,
max_pkt_size: usize,
) -> Result<Self, IoError> {
let socket = Socket::new(Domain::IPV6, Type::DGRAM, Some(Protocol::UDP))?;
socket.set_only_v6(false)?;
@ -39,6 +41,7 @@ impl Server {
port,
token: Arc::new(token),
authentication_timeout: auth_timeout,
max_pkt_size,
})
}
@ -48,7 +51,12 @@ impl Server {
while let Some(conn) = self.incoming.next().await {
let token = self.token.clone();
tokio::spawn(Connection::handle(conn, token, self.authentication_timeout));
tokio::spawn(Connection::handle(
conn,
token,
self.authentication_timeout,
self.max_pkt_size,
));
}
}
}