Skip to content

Commit 961a4d5

Browse files
committed
fix: handle libc errors
1 parent 317b3cd commit 961a4d5

File tree

11 files changed

+248
-68
lines changed

11 files changed

+248
-68
lines changed

Cargo.lock

Lines changed: 66 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

crates/rproxy/Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@ sysctl = "0.7.1"
5959
thiserror = "2.0.16"
6060
time = { version = "0.3.43", features = ["formatting"] }
6161
tokio = { version = "1.47.1", features = ["macros", "rt", "rt-multi-thread", "signal"] }
62-
tokio-tungstenite = "0.27.0"
62+
tokio-tungstenite = {version = "0.27.0", features = ["rustls-tls-native-roots"] }
6363
tokio-util = "0.7.16"
6464
tracing = { version = "0.1.41", features = ["valuable"] }
6565
tracing-subscriber = { version = "0.3.20", features = ["env-filter", "json", "valuable"] }

crates/rproxy/src/server/proxy/config/authrpc.rs

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,18 @@ pub(crate) struct ConfigAuthrpc {
8484
)]
8585
pub(crate) idle_connection_timeout: Duration,
8686

87+
/// interval between tcp keepalive packets on authrpc connections
88+
#[arg(
89+
default_value = "5s",
90+
env = "RPROXY_AUTHRPC_KEEPALIVE_INTERVAL",
91+
help_heading = "authrpc",
92+
long("authrpc-keepalive-interval"),
93+
name("authrpc_keepalive_interval"),
94+
value_name = "duration",
95+
value_parser = humantime::parse_duration
96+
)]
97+
pub(crate) keepalive_interval: Duration,
98+
8799
/// host:port for authrpc proxy
88100
#[arg(
89101
default_value = "0.0.0.0:8651",
@@ -353,6 +365,11 @@ impl ConfigProxyHttp for ConfigAuthrpc {
353365
self.idle_connection_timeout
354366
}
355367

368+
#[inline]
369+
fn keepalive_interval(&self) -> Duration {
370+
self.keepalive_interval
371+
}
372+
356373
#[inline]
357374
fn listen_address(&self) -> SocketAddr {
358375
self.listen_address.parse::<SocketAddr>().expect(ALREADY_VALIDATED)

crates/rproxy/src/server/proxy/config/flashblocks.rs

Lines changed: 24 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,19 @@ use crate::{config::ALREADY_VALIDATED, server::proxy::ws::config::ConfigProxyWs}
1010

1111
#[derive(Args, Clone, Debug)]
1212
pub(crate) struct ConfigFlashblocks {
13+
/// timeout to establish backend connections of to receive pong
14+
/// websocket response
15+
#[arg(
16+
default_value = "30s",
17+
env = "RPROXY_FLASHBLOCKS_BACKEND_TIMEOUT",
18+
help_heading = "flashblocks",
19+
long("flashblocks-backend-timeout"),
20+
name("flashblocks_backend_timeout"),
21+
value_name = "duration",
22+
value_parser = humantime::parse_duration
23+
)]
24+
pub(crate) backend_timeout: Duration,
25+
1326
/// url of flashblocks backend
1427
#[arg(
1528
default_value = "ws://127.0.0.1:11111",
@@ -29,19 +42,17 @@ pub(crate) struct ConfigFlashblocks {
2942
name("flashblocks_enabled")
3043
)]
3144
pub(crate) enabled: bool,
32-
33-
/// timeout to establish backend connections of to receive pong
34-
/// websocket response
45+
/// interval between tcp keepalive packets on flashblocks connections
3546
#[arg(
36-
default_value = "30s",
37-
env = "RPROXY_FLASHBLOCKS_BACKEND_TIMEOUT",
47+
default_value = "5s",
48+
env = "RPROXY_FLASHBLOCKS_KEEPALIVE_INTERVAL",
3849
help_heading = "flashblocks",
39-
long("flashblocks-backend-timeout"),
40-
name("flashblocks_backend_timeout"),
50+
long("flashblocks-keepalive-interval"),
51+
name("flashblocks_keepalive_interval"),
4152
value_name = "duration",
4253
value_parser = humantime::parse_duration
4354
)]
44-
pub(crate) backend_timeout: Duration,
55+
pub(crate) keepalive_interval: Duration,
4556

4657
/// host:port for flashblocks proxy
4758
#[arg(
@@ -212,6 +223,11 @@ impl ConfigProxyWs for ConfigFlashblocks {
212223
self.backend_url.parse::<tungstenite::http::Uri>().expect(ALREADY_VALIDATED)
213224
}
214225

226+
#[inline]
227+
fn keep_alive_interval(&self) -> Duration {
228+
self.keepalive_interval
229+
}
230+
215231
#[inline]
216232
fn listen_address(&self) -> SocketAddr {
217233
self.listen_address.parse::<SocketAddr>().expect(ALREADY_VALIDATED)

crates/rproxy/src/server/proxy/config/rpc.rs

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,18 @@ pub(crate) struct ConfigRpc {
7373
)]
7474
pub(crate) idle_connection_timeout: Duration,
7575

76+
/// interval between tcp keepalive packets on rpc connections
77+
#[arg(
78+
default_value = "5s",
79+
env = "RPROXY_RPC_KEEPALIVE_INTERVAL",
80+
help_heading = "rpc",
81+
long("rpc-keepalive-interval"),
82+
name("rpc_keepalive_interval"),
83+
value_name = "duration",
84+
value_parser = humantime::parse_duration
85+
)]
86+
pub(crate) keepalive_interval: Duration,
87+
7688
/// host:port for rpc proxy
7789
#[arg(
7890
default_value = "0.0.0.0:8645",
@@ -349,6 +361,11 @@ impl ConfigProxyHttp for ConfigRpc {
349361
self.idle_connection_timeout
350362
}
351363

364+
#[inline]
365+
fn keepalive_interval(&self) -> Duration {
366+
self.keepalive_interval
367+
}
368+
352369
#[inline]
353370
fn listen_address(&self) -> SocketAddr {
354371
self.listen_address.parse::<SocketAddr>().expect(ALREADY_VALIDATED)

crates/rproxy/src/server/proxy/connection_guard.rs

Lines changed: 14 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
use std::{
22
any::Any,
3-
os::fd::{AsFd, AsRawFd},
43
sync::{
54
Arc,
65
LazyLock,
@@ -14,7 +13,10 @@ use sysctl::Sysctl;
1413
use tracing::{debug, warn};
1514
use uuid::Uuid;
1615

17-
use crate::server::metrics::{LabelsProxy, Metrics};
16+
use crate::{
17+
server::metrics::{LabelsProxy, Metrics},
18+
utils::setup_keepalive,
19+
};
1820

1921
pub(crate) static TCP_KEEPALIVE_ATTEMPTS: LazyLock<libc::c_int> = LazyLock::new(|| {
2022
#[cfg(target_os = "linux")]
@@ -81,12 +83,8 @@ impl ConnectionGuard {
8183
proxy: &'static str,
8284
metrics: Arc<Metrics>,
8385
client_connections_count: Arc<AtomicI64>,
84-
keep_alive_timeout: Duration,
86+
keep_alive_interval: Duration,
8587
) -> impl Fn(&dyn Any, &mut Extensions) {
86-
let keep_alive_attempts: libc::c_int = *TCP_KEEPALIVE_ATTEMPTS;
87-
let keep_alive_interval: libc::c_int =
88-
keep_alive_timeout.div_f64(f64::from(keep_alive_attempts)).as_secs_f64().ceil() as i32;
89-
9088
move |connection, extensions| {
9189
{
9290
let val = client_connections_count.fetch_add(1, Ordering::Relaxed) + 1;
@@ -103,48 +101,21 @@ impl ConnectionGuard {
103101
Some(stream)
104102
} else {
105103
warn!(
104+
proxy = proxy,
106105
connection_type = std::any::type_name_of_val(connection),
107106
"Unexpected connection type",
108107
);
109108
None
110109
};
111110

112-
if let Some(stream) = stream {
113-
#[cfg(target_os = "linux")]
114-
unsafe {
115-
libc::setsockopt(
116-
stream.as_fd().as_raw_fd(),
117-
libc::IPPROTO_TCP,
118-
libc::TCP_KEEPIDLE,
119-
&keep_alive_interval as *const _ as *const libc::c_void,
120-
size_of_val(&keep_alive_interval) as libc::socklen_t,
121-
);
122-
libc::setsockopt(
123-
stream.as_fd().as_raw_fd(),
124-
libc::IPPROTO_TCP,
125-
libc::TCP_KEEPINTVL,
126-
&keep_alive_interval as *const _ as *const libc::c_void,
127-
size_of_val(&keep_alive_interval) as libc::socklen_t,
128-
);
129-
libc::setsockopt(
130-
stream.as_fd().as_raw_fd(),
131-
libc::IPPROTO_TCP,
132-
libc::TCP_KEEPCNT,
133-
&keep_alive_attempts as *const _ as *const libc::c_void,
134-
size_of_val(&keep_alive_attempts) as libc::socklen_t,
135-
);
136-
}
137-
138-
#[cfg(target_os = "macos")]
139-
unsafe {
140-
libc::setsockopt(
141-
stream.as_fd().as_raw_fd(),
142-
libc::IPPROTO_TCP,
143-
libc::TCP_KEEPALIVE,
144-
&keep_alive_interval as *const _ as *const _,
145-
std::mem::size_of_val(&keep_alive_interval) as libc::socklen_t,
146-
);
147-
}
111+
if let Some(stream) = stream &&
112+
let Err(err) = setup_keepalive(stream, keep_alive_interval)
113+
{
114+
warn!(
115+
proxy = proxy,
116+
error = ?err,
117+
"Failed to set keepalive interval",
118+
);
148119
}
149120

150121
if let Some(stream) = stream {

crates/rproxy/src/server/proxy/http/config.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ pub(crate) trait ConfigProxyHttp: Clone + Send + Unpin + 'static {
99
fn backend_timeout(&self) -> Duration;
1010
fn backend_url(&self) -> Url;
1111
fn idle_connection_timeout(&self) -> Duration;
12+
fn keepalive_interval(&self) -> Duration;
1213
fn listen_address(&self) -> SocketAddr;
1314
fn log_mirrored_requests(&self) -> bool;
1415
fn log_mirrored_responses(&self) -> bool;

0 commit comments

Comments
 (0)