aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHimbeerserverDE <himbeerserverde@gmail.com>2023-11-22 15:40:34 +0100
committerHimbeerserverDE <himbeerserverde@gmail.com>2023-11-22 15:40:34 +0100
commit2ad617298b114dedf4cb5b209f6923d63063deb4 (patch)
tree7c5123682dc3c6646ea42d8bc0b1a9b9905d407e
parent800d2b21c116a8b7de6a289b769745027e6983a8 (diff)
adaptive lcp echo (only send requests if there is no recv activity on the link)
-rw-r--r--src/ioctls.rs7
-rw-r--r--src/supervisor.rs55
2 files changed, 40 insertions, 22 deletions
diff --git a/src/ioctls.rs b/src/ioctls.rs
index 1a58c1f..344165e 100644
--- a/src/ioctls.rs
+++ b/src/ioctls.rs
@@ -1,6 +1,13 @@
use ioctl_sys::ioctl;
+#[repr(C, packed)]
+pub struct ppp_idle64 {
+ pub xmit_idle: i64,
+ pub recv_idle: i64,
+}
+
ioctl!(write pppiocattchan with b't', 56; ::std::os::raw::c_int);
ioctl!(write pppiocconnect with b't', 58; ::std::os::raw::c_int);
ioctl!(read pppiocgchan with b't', 55; ::std::os::raw::c_int);
ioctl!(readwrite pppiocnewunit with b't', 62; ::std::os::raw::c_int);
+ioctl!(read pppiocgidle64 with b't', 63; ppp_idle64);
diff --git a/src/supervisor.rs b/src/supervisor.rs
index ec2a0ed..aa7ecd6 100644
--- a/src/supervisor.rs
+++ b/src/supervisor.rs
@@ -11,7 +11,6 @@ use std::{io, mem};
use tokio::io::unix::AsyncFd;
use tokio::signal::unix::{signal, SignalKind};
use tokio::sync::mpsc;
-use tokio::time::Interval;
use async_io::Async;
use ppproperly::*;
@@ -97,8 +96,6 @@ pub struct Client {
ipv6cp_id_term: u8,
ipv6cp_id_remote: u8,
- timeout: Interval,
-
pppoe: PppoeClient,
lcp: NegotiationProtocol<LcpOpt>,
pap: PapClient,
@@ -163,8 +160,6 @@ impl Client {
ipv6cp_id_term: 0,
ipv6cp_id_remote: 0,
- timeout: tokio::time::interval(Duration::from_secs(30)),
-
pppoe: PppoeClient::new(None, None),
lcp: NegotiationProtocol::new(ProtocolConfig {
require: vec![LcpOpt::Mru(1492), LcpOpt::MagicNumber(peer_magic)],
@@ -281,6 +276,8 @@ impl Client {
let mut echo_timeout = tokio::time::interval(Duration::from_secs(12));
let mut ncp_check = tokio::time::interval(Duration::from_secs(20));
+ let mut echo_reqs = 0;
+
let mut pppoe_rx = self.pppoe.active();
let mut lcp_rx = self.lcp.opened();
let mut pap_rx = self.pap.opened();
@@ -538,24 +535,39 @@ impl Client {
_ = echo_timeout.tick() => {
if *lcp_rx.borrow() {
- // Send an LCP Echo-Request every 12 seconds.
- self.send_lcp(
- session_fds.as_mut().map(|fds| fds.link()),
- Packet {
- ty: PacketType::EchoRequest,
- options: Vec::default(),
- rejected_code: PacketType::Unknown(0),
- rejected_protocol: 0,
+ if let Some(ctl) = ctl {
+ // Send an LCP Echo-Request every 12 seconds
+ // if no data traffic has been received for 30 seconds.
+
+ let mut idle = ioctls::ppp_idle64 {
+ xmit_idle: 0,
+ recv_idle: 0,
+ };
+
+ if unsafe { ioctls::pppiocgidle64(ctl.as_raw_fd(), &mut idle) } < 0 {
+ os_err!();
}
- ).await?;
- }
- }
- _ = self.timeout.tick() => {
- if *lcp_rx.borrow() {
- // No LCP traffic has been received for 30 seconds, terminate the link.
- self.lcp.close();
- println!("[info] -> timeout");
+ if idle.recv_idle >= 30 {
+ if echo_reqs >= 5 {
+ self.lcp.close();
+ println!("[info] -> timeout");
+ } else {
+ self.send_lcp(
+ session_fds.as_mut().map(|fds| fds.link()),
+ Packet {
+ ty: PacketType::EchoRequest,
+ options: Vec::default(),
+ rejected_code: PacketType::Unknown(0),
+ rejected_protocol: 0,
+ }
+ ).await?;
+ echo_reqs += 1;
+ }
+ } else {
+ echo_reqs = 0;
+ }
+ }
}
}
_ = ncp_check.tick() => {
@@ -1101,7 +1113,6 @@ impl Client {
};
if let Some(packet) = packet {
- self.timeout.reset();
self.lcp.from_recv(packet);
}