Skip to content

Commit eb286ff

Browse files
committed
vey-daemon: add offline wait time limit for ListenUdpRuntime
1 parent 73cdff9 commit eb286ff

4 files changed

Lines changed: 107 additions & 3 deletions

File tree

lib/vey-daemon/src/listen/udp/listen.rs

Lines changed: 43 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ use smallvec::SmallVec;
3232
use tokio::net::UdpSocket;
3333
use tokio::runtime::Handle;
3434
use tokio::sync::{broadcast, mpsc};
35+
use tokio::time::Instant;
3536

3637
use vey_io_ext::{UdpMoveRecv, UdpMoveSend, UdpSocketExt};
3738
use vey_io_sys::udp::{RecvMsgHdr, SendMsgHdr};
@@ -96,7 +97,10 @@ impl UdpMoveRecv for AcceptedUdpPacketReceiver {
9697
fn poll_recv_packet(&mut self, cx: &mut Context<'_>) -> Poll<Result<Bytes, Self::RecvError>> {
9798
match self.inner.poll_recv(cx) {
9899
Poll::Ready(Some(packet)) => Poll::Ready(Ok(packet)),
99-
Poll::Ready(None) => Poll::Ready(Ok(Bytes::new())),
100+
Poll::Ready(None) => Poll::Ready(Err(io::Error::new(
101+
io::ErrorKind::UnexpectedEof,
102+
"packet receiver closed",
103+
))),
100104
Poll::Pending => Poll::Pending,
101105
}
102106
}
@@ -816,6 +820,16 @@ where
816820
mut rt_state: RuntimeState,
817821
mut ct_table: LruCache<ClientConnectionKey, StreamDispatcher, FixedState>,
818822
) {
823+
let mut wait_sleep = Box::pin(tokio::time::sleep(self.conn_track.offline_wait_time()));
824+
let mut allow_new = true;
825+
826+
info!(
827+
"SRT[{}_v{}#{}] enters offline-wait mode",
828+
self.server.name(),
829+
self.server_version,
830+
self.instance_id
831+
);
832+
819833
loop {
820834
tokio::select! {
821835
biased;
@@ -825,14 +839,32 @@ where
825839
self.handle_events(&mut event_recv_buf, &mut ct_table).await;
826840
event_recv_buf.clear();
827841
if ct_table.is_empty() {
828-
break;
842+
return;
829843
}
830844
}
831845
r = self.recv_packets(&rt_state.socket) => {
832846
match r {
833847
Ok(packets) => {
834848
for (cc_info, data) in packets {
835-
self.handle_packet(cc_info, data, &rt_state, &mut ct_table);
849+
if allow_new {
850+
self.handle_packet(cc_info, data, &rt_state, &mut ct_table);
851+
} else {
852+
let key = cc_info.connection_key();
853+
if let Some(dispatcher) = ct_table.get(&key) {
854+
match dispatcher.sender.try_send(data) {
855+
Ok(_) => {}
856+
Err(mpsc::error::TrySendError::Full(_)) => {
857+
dispatcher.state.add_recv_dropped();
858+
}
859+
Err(mpsc::error::TrySendError::Closed(_)) => {
860+
dispatcher.state.add_recv_dropped();
861+
ct_table.pop(&key);
862+
}
863+
}
864+
} else {
865+
self.listen_stats.add_dropped();
866+
}
867+
}
836868
}
837869
}
838870
Err(e) => {
@@ -842,6 +874,14 @@ where
842874
}
843875
}
844876
}
877+
_ = &mut wait_sleep => {
878+
if !allow_new {
879+
break;
880+
}
881+
info!("SRT[{}_v{}#{}] enters offline-quit mode", self.server.name(), self.server_version, self.instance_id);
882+
allow_new = false;
883+
wait_sleep.as_mut().reset(Instant::now() + self.conn_track.offline_quit_time());
884+
}
845885
}
846886
}
847887
}

lib/vey-types/src/net/udp/listen.rs

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66

77
use std::net::{IpAddr, Ipv6Addr, SocketAddr};
88
use std::num::{NonZeroU32, NonZeroUsize};
9+
use std::time::Duration;
910

1011
use anyhow::anyhow;
1112
use num_traits::ToPrimitive;
@@ -260,6 +261,8 @@ pub struct UdpConnectionTrackConfig {
260261
dispatch_queue_size: NonZeroUsize,
261262
send_queue_size: NonZeroUsize,
262263
batch_recv_size: NonZeroUsize,
264+
offline_wait_time: Duration,
265+
offline_quit_time: Duration,
263266
}
264267

265268
impl Default for UdpConnectionTrackConfig {
@@ -270,6 +273,8 @@ impl Default for UdpConnectionTrackConfig {
270273
dispatch_queue_size: unsafe { NonZeroUsize::new_unchecked(32) },
271274
send_queue_size: unsafe { NonZeroUsize::new_unchecked(512) },
272275
batch_recv_size: unsafe { NonZeroUsize::new_unchecked(16) },
276+
offline_wait_time: Duration::from_secs(60),
277+
offline_quit_time: Duration::from_hours(1),
273278
}
274279
}
275280
}
@@ -324,4 +329,24 @@ impl UdpConnectionTrackConfig {
324329
pub fn set_batch_recv_size(&mut self, batch_recv_size: NonZeroUsize) {
325330
self.batch_recv_size = batch_recv_size;
326331
}
332+
333+
#[inline]
334+
pub fn offline_wait_time(&self) -> Duration {
335+
self.offline_wait_time
336+
}
337+
338+
#[inline]
339+
pub fn set_offline_wait_time(&mut self, wait_time: Duration) {
340+
self.offline_wait_time = wait_time;
341+
}
342+
343+
#[inline]
344+
pub fn offline_quit_time(&self) -> Duration {
345+
self.offline_quit_time
346+
}
347+
348+
#[inline]
349+
pub fn set_offline_quit_time(&mut self, quit_time: Duration) {
350+
self.offline_quit_time = quit_time;
351+
}
327352
}

lib/vey-yaml/src/value/net/udp.rs

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -223,6 +223,18 @@ pub fn as_udp_conn_track_config(value: &Yaml) -> anyhow::Result<UdpConnectionTra
223223
config.set_batch_recv_size(batch_size);
224224
Ok(())
225225
}
226+
"offline_wait_time" => {
227+
let wait_time = crate::humanize::as_duration(v)
228+
.context(format!("invalid humanize duration value for key {k}"))?;
229+
config.set_offline_wait_time(wait_time);
230+
Ok(())
231+
}
232+
"offline_quit_time" => {
233+
let wait_time = crate::humanize::as_duration(v)
234+
.context(format!("invalid humanize duration value for key {k}"))?;
235+
config.set_offline_quit_time(wait_time);
236+
Ok(())
237+
}
226238
_ => Err(anyhow!("invalid key {k}")),
227239
})?;
228240

sphinx/vey-values/configuration/values/network.rst

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -771,6 +771,33 @@ It consists of the following fields:
771771

772772
**default**: 16
773773

774+
* offline_wait_time
775+
776+
**option**, **type**: :ref:`humanize duration <conf_value_humanize_duration>`
777+
778+
When bpf feature is enabled, the udp socket will be in offline-wait mode, and it will still accept new connections.
779+
This config option set the total time of this offline-wait mode.
780+
781+
**default**: 60s
782+
783+
.. availability::
784+
785+
- ``vey-proxy``: available since ``1.13.9``
786+
787+
* offline_quit_time
788+
789+
**option**, **type**: :ref:`humanize duration <conf_value_humanize_duration>`
790+
791+
When bpf feature is enabled, the udp socket will be in offline-quit mode after offline-wait mode end, new connections
792+
are not allowed in this mode. This config option set the total time of this offline-quit mode. The socket will be
793+
closed after offline-quit mode.
794+
795+
**default**: 1h
796+
797+
.. availability::
798+
799+
- ``vey-proxy``: available since ``1.13.9``
800+
774801
.. availability::
775802

776803
- ``vey-proxy``: available since ``1.13.3``

0 commit comments

Comments
 (0)