set reasonable TCP keepalive timeout

This commit is contained in:
Dietmar Maurer 2020-10-19 13:59:33 +02:00
parent 9809772b23
commit 97168f920e
4 changed files with 52 additions and 3 deletions

View File

@ -1,5 +1,6 @@
use std::sync::{Arc}; use std::sync::{Arc};
use std::path::{Path, PathBuf}; use std::path::{Path, PathBuf};
use std::os::unix::io::AsRawFd;
use anyhow::{bail, format_err, Error}; use anyhow::{bail, format_err, Error};
use futures::*; use futures::*;
@ -16,7 +17,16 @@ use proxmox_backup::server;
use proxmox_backup::tools::daemon; use proxmox_backup::tools::daemon;
use proxmox_backup::server::{ApiConfig, rest::*}; use proxmox_backup::server::{ApiConfig, rest::*};
use proxmox_backup::auth_helpers::*; use proxmox_backup::auth_helpers::*;
use proxmox_backup::tools::disks::{ DiskManage, zfs_pool_stats }; use proxmox_backup::tools::{
disks::{
DiskManage,
zfs_pool_stats,
},
socket::{
set_tcp_keepalive,
PROXMOX_BACKUP_TCP_KEEPALIVE_TIME,
},
};
use proxmox_backup::api2::pull::do_sync_job; use proxmox_backup::api2::pull::do_sync_job;
@ -89,6 +99,9 @@ async fn run() -> Result<(), Error> {
let acceptor = Arc::clone(&acceptor); let acceptor = Arc::clone(&acceptor);
async move { async move {
sock.set_nodelay(true).unwrap(); sock.set_nodelay(true).unwrap();
let _ = set_tcp_keepalive(sock.as_raw_fd(), PROXMOX_BACKUP_TCP_KEEPALIVE_TIME);
Ok(tokio_openssl::accept(&acceptor, sock) Ok(tokio_openssl::accept(&acceptor, sock)
.await .await
.ok() // handshake errors aren't be fatal, so return None to filter .ok() // handshake errors aren't be fatal, so return None to filter

View File

@ -2,6 +2,7 @@ use std::io::Write;
use std::task::{Context, Poll}; use std::task::{Context, Poll};
use std::sync::{Arc, Mutex, RwLock}; use std::sync::{Arc, Mutex, RwLock};
use std::time::Duration; use std::time::Duration;
use std::os::unix::io::AsRawFd;
use anyhow::{bail, format_err, Error}; use anyhow::{bail, format_err, Error};
use futures::*; use futures::*;
@ -26,7 +27,15 @@ use proxmox::{
use super::pipe_to_stream::PipeToSendStream; use super::pipe_to_stream::PipeToSendStream;
use crate::api2::types::Userid; use crate::api2::types::Userid;
use crate::tools::async_io::EitherStream; use crate::tools::async_io::EitherStream;
use crate::tools::{self, BroadcastFuture, DEFAULT_ENCODE_SET}; use crate::tools::{
self,
BroadcastFuture,
DEFAULT_ENCODE_SET,
socket::{
set_tcp_keepalive,
PROXMOX_BACKUP_TCP_KEEPALIVE_TIME,
},
};
#[derive(Clone)] #[derive(Clone)]
pub struct AuthInfo { pub struct AuthInfo {
@ -608,7 +617,7 @@ impl HttpClient {
.await?; .await?;
let connection = connection let connection = connection
.map_err(|_| panic!("HTTP/2.0 connection failed")); .map_err(|_| eprintln!("HTTP/2.0 connection failed"));
let (connection, abort) = futures::future::abortable(connection); let (connection, abort) = futures::future::abortable(connection);
// A cancellable future returns an Option which is None when cancelled and // A cancellable future returns an Option which is None when cancelled and
@ -969,6 +978,9 @@ impl hyper::service::Service<Uri> for HttpsConnector {
let config = this.ssl_connector.configure(); let config = this.ssl_connector.configure();
let conn = this.http.call(dst).await?; let conn = this.http.call(dst).await?;
let _ = set_tcp_keepalive(conn.as_raw_fd(), PROXMOX_BACKUP_TCP_KEEPALIVE_TIME);
if is_https { if is_https {
let conn = tokio_openssl::connect(config?, &host, conn).await?; let conn = tokio_openssl::connect(config?, &host, conn).await?;
Ok(MaybeTlsStream::Right(conn)) Ok(MaybeTlsStream::Right(conn))

View File

@ -35,6 +35,7 @@ pub mod nom;
pub mod logrotate; pub mod logrotate;
pub mod loopdev; pub mod loopdev;
pub mod fuse_loop; pub mod fuse_loop;
pub mod socket;
mod parallel_handler; mod parallel_handler;
pub use parallel_handler::*; pub use parallel_handler::*;

23
src/tools/socket.rs Normal file
View File

@ -0,0 +1,23 @@
use std::os::unix::io::RawFd;
use nix::sys::socket::sockopt::{KeepAlive, TcpKeepIdle};
use nix::sys::socket::setsockopt;
pub const PROXMOX_BACKUP_TCP_KEEPALIVE_TIME: u32 = 120;
/// Set TCP keepalive time on a socket
///
/// See "man 7 tcp" for details.
///
/// The default on Linix is 7200 (2 hours) which is much too long for
/// our backup tools.
pub fn set_tcp_keepalive(
socket_fd: RawFd,
tcp_keepalive_time: u32,
) -> nix::Result<()> {
setsockopt(socket_fd, KeepAlive, &true)?;
setsockopt(socket_fd, TcpKeepIdle, &tcp_keepalive_time)?;
Ok(())
}