Set keepalive and tcp_nodelay on underlying sockets

This commit is contained in:
jiangjianfeng
2024-12-05 08:40:20 +00:00
committed by Tate, Hongliang Tian
parent 8b07a68e9e
commit 58cf8ea681
13 changed files with 293 additions and 35 deletions

View File

@ -10,12 +10,13 @@ use ostd::sync::{LocalIrqDisabled, RwLock, SpinLock, SpinLockGuard, WriteIrqDisa
use smoltcp::{
iface::Context,
socket::{tcp::State, udp::UdpMetadata, PollAt},
time::Instant,
time::{Duration, Instant},
wire::{IpAddress, IpEndpoint, IpRepr, TcpControl, TcpRepr, UdpRepr},
};
use super::{
event::{SocketEventObserver, SocketEvents},
option::RawTcpSetOption,
RawTcpSocket, RawUdpSocket, TcpStateCheck,
};
use crate::{ext::Ext, iface::Iface};
@ -251,6 +252,7 @@ pub enum ConnectState {
pub struct NeedIfacePoll(bool);
impl NeedIfacePoll {
pub const TRUE: Self = Self(true);
pub const FALSE: Self = Self(false);
}
@ -371,6 +373,25 @@ impl<E: Ext> BoundTcpSocket<E> {
}
}
impl<E: Ext> RawTcpSetOption for BoundTcpSocket<E> {
fn set_keep_alive(&mut self, interval: Option<Duration>) -> NeedIfacePoll {
let mut socket = self.0.socket.lock();
socket.set_keep_alive(interval);
if interval.is_some() {
self.0.update_next_poll_at_ms(PollAt::Now);
NeedIfacePoll::TRUE
} else {
NeedIfacePoll::FALSE
}
}
fn set_nagle_enabled(&mut self, enabled: bool) {
let mut socket = self.0.socket.lock();
socket.set_nagle_enabled(enabled);
}
}
impl<E: Ext> BoundUdpSocket<E> {
/// Binds to a specified endpoint.
///

View File

@ -2,13 +2,15 @@
mod bound;
mod event;
mod option;
mod state;
mod unbound;
pub use bound::{BoundTcpSocket, BoundUdpSocket, ConnectState, NeedIfacePoll};
pub(crate) use bound::{BoundTcpSocketInner, BoundUdpSocketInner, TcpProcessResult};
pub use event::{SocketEventObserver, SocketEvents};
pub use state::TcpStateCheck;
pub use option::RawTcpSetOption;
pub use state::{TcpState, TcpStateCheck};
pub use unbound::{
UnboundTcpSocket, UnboundUdpSocket, TCP_RECV_BUF_LEN, TCP_SEND_BUF_LEN, UDP_RECV_PAYLOAD_LEN,
UDP_SEND_PAYLOAD_LEN,

View File

@ -0,0 +1,21 @@
// SPDX-License-Identifier: MPL-2.0
use smoltcp::time::Duration;
use super::NeedIfacePoll;
/// A trait defines setting socket options on a raw socket.
///
/// TODO: When `UnboundSocket` is removed, all methods in this trait can accept
/// `&self` instead of `&mut self` as parameter.
pub trait RawTcpSetOption {
/// Sets the keep alive interval.
///
/// Polling the iface _may_ be required after this method succeeds.
fn set_keep_alive(&mut self, interval: Option<Duration>) -> NeedIfacePoll;
/// Enables or disables Nagles Algorithm.
///
/// Polling the iface is not required after this method succeeds.
fn set_nagle_enabled(&mut self, enabled: bool);
}

View File

@ -1,6 +1,6 @@
// SPDX-License-Identifier: MPL-2.0
use smoltcp::socket::tcp::State as TcpState;
pub use smoltcp::socket::tcp::State as TcpState;
use super::RawTcpSocket;

View File

@ -2,7 +2,7 @@
use alloc::{boxed::Box, vec};
use super::{RawTcpSocket, RawUdpSocket};
use super::{option::RawTcpSetOption, NeedIfacePoll, RawTcpSocket, RawUdpSocket};
pub struct UnboundSocket<T> {
socket: Box<T>,
@ -30,6 +30,17 @@ impl Default for UnboundTcpSocket {
}
}
impl RawTcpSetOption for UnboundTcpSocket {
fn set_keep_alive(&mut self, interval: Option<smoltcp::time::Duration>) -> NeedIfacePoll {
self.socket.set_keep_alive(interval);
NeedIfacePoll::FALSE
}
fn set_nagle_enabled(&mut self, enabled: bool) {
self.socket.set_nagle_enabled(enabled);
}
}
impl UnboundUdpSocket {
pub fn new() -> Self {
let raw_udp_socket = {