Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

net: expose TCP keep alive socket option #6214

Closed
carllerche opened this issue Dec 12, 2023 · 1 comment · Fixed by #6311
Closed

net: expose TCP keep alive socket option #6214

carllerche opened this issue Dec 12, 2023 · 1 comment · Fixed by #6311
Labels
A-tokio Area: The main tokio crate C-feature-request Category: A feature request. E-help-wanted Call for participation: Help is requested to fix this issue. M-net Module: tokio/net

Comments

@carllerche
Copy link
Member

Currently, Tokio does not expose the keep-alive socket option. There have been attempts (#3082, #3146) but they have not succeeded because keep-alive behavior is not consistent between *nix and windows (possibly others) platforms.

That said, setting the keep-alive option is still a common operation. Today, work arounds exist by using libraries like socket2, nix, or libc directly, but we should still add an easier API.

Because there is no consistent behavior across platforms, we should consider adding this feature on a platform-by-platform basis. The biggest challenge for doing this is that I am not sure what the best API would be to add platform-specific methods that have the same name but different arguments. E.g. set_keep_alive on linux would probably take different arguments than on windows.

To move forward with this issue, we would need a proposal for how to add an API with a similar name, but different arguments and behavior based on the platform. This proposal should consider Tokio's existing platform-specific APIs and prior-art within the Rust ecosystem.

@carllerche carllerche added E-help-wanted Call for participation: Help is requested to fix this issue. A-tokio Area: The main tokio crate M-net Module: tokio/net C-feature-request Category: A feature request. labels Dec 12, 2023
@maminrayej
Copy link
Member

To my understanding, the point of difference is setting idle_time and interval which is done atomically in windows, but requires two calls to setsockopt in unix. This means that setting the keep_alive on or off is consistent across different platforms. Also, setting retries is only possible in unix. Instead of calling set_keep_alive once with a struct that is platform dependent, we could provide three different methods:

  • set_keep_alive(enabled: bool): This is a pass-through to a syscall, and is consistent across platforms.
  • set_idle_and_interval(idle_time: Option<Duration>, interval: Option<Duration>): This is the tricky method that I'm going to try to justify.
  • set_retry(count: usize): This is only available in unix, and is a simple pass-through to a syscall.

The issue with set_idle_and_interval is that it is not atomic in unix, but its implementation will be as good as a handwritten solution by user. What I mean is a user have to set these two socket options separately on unix and handle the failures:

fn set_idle_and_interval(socket, idle: Duration, interval: Duration) {
    let _ = socket.set_idle(idle)?;

    if let Err(_) = socket.set_interval(interval) {
        // handle failure and reach a consistent state
    }
}

This would be using the hypothetical API of tokio:

fn set_idle_and_interval(socket: TcpSocket, idle: Duration, interval: Duration) {    
    if let Err(e) = socket.set_idle_and_interval(idle, interval) {
        match e {
            Error::Failed => { return; } // This is only returned on Windows
            Error::IdleFailed => { return; }
            Error::IntervalFailed => { /* handle failure and reach a consistent state */ }
        }
    }
}

It's ugly at the moment and could be further improved, but I think it gets my point across.

This way we have two methods that we can use without worry, and one method which isn't ideal, but it's as good as a handwritten solution.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-tokio Area: The main tokio crate C-feature-request Category: A feature request. E-help-wanted Call for participation: Help is requested to fix this issue. M-net Module: tokio/net
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants