connection log query

This commit is contained in:
rustdesk
2026-01-06 23:59:47 +08:00
parent 7e921be539
commit 5d1b4ba78a

View File

@@ -61,6 +61,14 @@ type RelayServers = Vec<String>;
const CHECK_RELAY_TIMEOUT: u64 = 3_000;
static ALWAYS_USE_RELAY: AtomicBool = AtomicBool::new(false);
// Store punch hole requests
use once_cell::sync::Lazy;
use tokio::sync::Mutex as TokioMutex; // differentiate if needed
#[derive(Clone)]
struct PunchReqEntry { tm: Instant, from_ip: String, to_ip: String, to_id: String }
static PUNCH_REQS: Lazy<TokioMutex<Vec<PunchReqEntry>>> = Lazy::new(|| TokioMutex::new(Vec::new()));
const PUNCH_REQ_DEDUPE_SEC: u64 = 60;
#[derive(Clone)]
struct Inner {
serial: i32,
@@ -707,6 +715,23 @@ impl RendezvousServer {
});
return Ok((msg_out, None));
}
// record punch hole request (from addr -> peer id/peer_addr)
{
let from_ip = try_into_v4(addr).ip().to_string();
let to_ip = try_into_v4(peer_addr).ip().to_string();
let to_id_clone = id.clone();
let mut lock = PUNCH_REQS.lock().await;
let mut dup = false;
for e in lock.iter().rev().take(30) { // only check recent tail subset for speed
if e.from_ip == from_ip && e.to_id == to_id_clone {
if e.tm.elapsed().as_secs() < PUNCH_REQ_DEDUPE_SEC { dup = true; }
break;
}
}
if !dup { lock.push(PunchReqEntry { tm: Instant::now(), from_ip, to_ip, to_id: to_id_clone }); }
}
let mut msg_out = RendezvousMessage::new();
let peer_is_lan = self.is_lan(peer_addr);
let is_lan = self.is_lan(addr);
@@ -917,11 +942,12 @@ impl RendezvousServer {
match fds.next() {
Some("h") => {
res = format!(
"{}\n{}\n{}\n{}\n{}\n{}\n",
"{}\n{}\n{}\n{}\n{}\n{}\n{}\n",
"relay-servers(rs) <separated by ,>",
"reload-geo(rg)",
"ip-blocker(ib) [<ip>|<number>] [-]",
"ip-changes(ic) [<id>|<number>] [-]",
"punch-requests(pr) [<number>] [-]",
"always-use-relay(aur)",
"test-geo(tg) <ip1> <ip2>"
)
@@ -1021,6 +1047,27 @@ impl RendezvousServer {
}
}
}
Some("punch-requests" | "pr") => {
use std::fmt::Write as _;
let mut lock = PUNCH_REQS.lock().await;
// retain only recent (optional cleanup older than a day)
lock.retain(|e| e.tm.elapsed().as_secs() < 24*3600);
let arg = fds.next();
if let Some("-") = arg { lock.clear(); }
else {
let mut start = arg.and_then(|x| x.parse::<usize>().ok()).unwrap_or(0);
let mut page_size = fds.next().and_then(|x| x.parse::<usize>().ok()).unwrap_or(10);
if page_size == 0 { page_size = 10; }
if start >= lock.len() { start = 0; }
for (_, e) in lock.iter().enumerate().skip(start).take(page_size) {
let age = e.tm.elapsed();
let event_system = std::time::SystemTime::now() - age;
let event_iso = chrono::DateTime::<chrono::Utc>::from(event_system)
.to_rfc3339_opts(chrono::SecondsFormat::Secs, true);
let _ = writeln!(res, "{} {} -> {}@{}", event_iso, e.from_ip, e.to_id, e.to_ip);
}
}
}
Some("always-use-relay" | "aur") => {
if let Some(rs) = fds.next() {
if rs.to_uppercase() == "Y" {