rkvm-{server,client}: Remove dead peers quickly

I use rkvm on a machine which hangs multiple times a day, leaving no
TCP FIN or RSTs behind.

Previously, the UX got very confusing once I rebooted the machine, because
it captured inputs without forwarding them anywhere live.

It's unfortunate that the TCP settings aren't shared between the client
& server because keepalive settings should be consistent to avoid one
peer disconnecting and the other waiting longer before timing out.
This commit is contained in:
ckie 2023-08-21 21:07:37 +03:00
parent 0b57699313
commit c4ff4232ae
No known key found for this signature in database
GPG key ID: 13E79449C0525215
5 changed files with 34 additions and 1 deletions

14
Cargo.lock generated
View file

@ -778,6 +778,7 @@ dependencies = [
"rkvm-net",
"rustls-pemfile",
"serde",
"socket2 0.5.3",
"thiserror",
"tokio",
"tokio-rustls",
@ -829,6 +830,7 @@ dependencies = [
"rustls-pemfile",
"serde",
"slab",
"socket2 0.5.3",
"thiserror",
"tokio",
"tokio-rustls",
@ -970,6 +972,16 @@ dependencies = [
"winapi",
]
[[package]]
name = "socket2"
version = "0.5.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2538b18701741680e0322a2302176d3253a35388e2e62f172f64f4f16605f877"
dependencies = [
"libc",
"windows-sys 0.48.0",
]
[[package]]
name = "spin"
version = "0.5.2"
@ -1054,7 +1066,7 @@ dependencies = [
"num_cpus",
"pin-project-lite",
"signal-hook-registry",
"socket2",
"socket2 0.4.9",
"tokio-macros",
"windows-sys 0.48.0",
]

View file

@ -19,6 +19,7 @@ clap = { version = "4.2.2", features = ["derive"] }
thiserror = "1.0.40"
tokio-rustls = "0.24.0"
rustls-pemfile = "1.0.2"
socket2 = { version = "0.5.3", features = ["all"] }
[package.metadata.rpm]
package = "rkvm-client"

View file

@ -3,9 +3,11 @@ use rkvm_net::auth::{AuthChallenge, AuthStatus};
use rkvm_net::message::Message;
use rkvm_net::version::Version;
use rkvm_net::Update;
use socket2::{SockRef, TcpKeepalive};
use std::collections::hash_map::Entry;
use std::collections::HashMap;
use std::io;
use std::time::Duration;
use thiserror::Error;
use tokio::io::{AsyncWriteExt, BufStream};
use tokio::net::TcpStream;
@ -43,6 +45,15 @@ pub async fn run(
stream.set_linger(None).map_err(Error::Network)?;
stream.set_nodelay(false).map_err(Error::Network)?;
SockRef::from(&stream)
.set_tcp_keepalive(
&TcpKeepalive::new()
.with_time(Duration::from_secs(1))
.with_interval(Duration::from_secs(10))
.with_retries(1),
)
.map_err(Error::Network)?;
log::info!("Connected to server");
let stream = connector

View file

@ -21,6 +21,7 @@ rustls-pemfile = "1.0.2"
thiserror = "1.0.40"
slab = "0.4.8"
rand = "0.8.5"
socket2 = { version = "0.5.3", features = ["all"] }
[package.metadata.rpm]
package = "rkvm-server"

View file

@ -8,6 +8,7 @@ use rkvm_net::message::Message;
use rkvm_net::version::Version;
use rkvm_net::Update;
use slab::Slab;
use socket2::{SockRef, TcpKeepalive};
use std::collections::{HashMap, HashSet, VecDeque};
use std::ffi::CString;
use std::io::{self, ErrorKind};
@ -267,6 +268,13 @@ async fn client(
stream.set_linger(None)?;
stream.set_nodelay(false)?;
SockRef::from(&stream).set_tcp_keepalive(
&TcpKeepalive::new()
.with_time(Duration::from_secs(1))
.with_interval(Duration::from_secs(10))
.with_retries(1),
)?;
let stream = acceptor.accept(stream).await?;
log::info!("{}: TLS connected", addr);