From 0e2cd38135166d64dbf1bdd2d771ac138882a4df Mon Sep 17 00:00:00 2001 From: whitequark Date: Tue, 4 Oct 2016 06:40:38 +0000 Subject: [PATCH] Rust: set the SOF_KEEPALIVE flag on session sockets. --- artiq/runtime.rs/liblwip-sys/lib.rs | 5 +++++ artiq/runtime.rs/liblwip/lib.rs | 12 ++++++++++++ artiq/runtime.rs/src/sched.rs | 8 ++++++++ artiq/runtime.rs/src/session.rs | 1 + artiq/runtime/main.c | 4 ++++ 5 files changed, 30 insertions(+) diff --git a/artiq/runtime.rs/liblwip-sys/lib.rs b/artiq/runtime.rs/liblwip-sys/lib.rs index 5ea2e7d1e..82a7c5bcf 100644 --- a/artiq/runtime.rs/liblwip-sys/lib.rs +++ b/artiq/runtime.rs/liblwip-sys/lib.rs @@ -103,6 +103,10 @@ pub struct udp_pcb { pub const TCP_WRITE_FLAG_COPY: u8 = 0x01; pub const TCP_WRITE_FLAG_MORE: u8 = 0x02; +pub const SOF_REUSEADDR: u8 = 0x04; +pub const SOF_KEEPALIVE: u8 = 0x08; +pub const SOF_BROADCAST: u8 = 0x20; + extern { pub fn pbuf_alloc(l: pbuf_layer, length: u16, type_: pbuf_type) -> *mut pbuf; pub fn pbuf_realloc(p: *mut pbuf, length: u16); @@ -144,6 +148,7 @@ extern { // nonstandard pub fn tcp_sndbuf_(pcb: *mut tcp_pcb) -> u16; + pub fn tcp_so_options_(pcb: *mut tcp_pcb) -> *mut u8; pub fn udp_new() -> *mut udp_pcb; pub fn udp_new_ip_type(type_: ip_addr_type) -> *mut udp_pcb; diff --git a/artiq/runtime.rs/liblwip/lib.rs b/artiq/runtime.rs/liblwip/lib.rs index c996074f0..4a6e1b3c1 100644 --- a/artiq/runtime.rs/liblwip/lib.rs +++ b/artiq/runtime.rs/liblwip/lib.rs @@ -397,6 +397,18 @@ impl TcpListener { pub fn try_accept(&self) -> Option { self.state.borrow_mut().backlog.pop_front() } + + pub fn keepalive(&self) -> bool { + unsafe { *lwip_sys::tcp_so_options_(self.raw) & lwip_sys::SOF_KEEPALIVE != 0 } + } + + pub fn set_keepalive(&self, keepalive: bool) { + if keepalive { + unsafe { *lwip_sys::tcp_so_options_(self.raw) |= lwip_sys::SOF_KEEPALIVE } + } else { + unsafe { *lwip_sys::tcp_so_options_(self.raw) &= !lwip_sys::SOF_KEEPALIVE } + } + } } impl Drop for TcpListener { diff --git a/artiq/runtime.rs/src/sched.rs b/artiq/runtime.rs/src/sched.rs index 34dd5bc8c..4737ee0c6 100644 --- a/artiq/runtime.rs/src/sched.rs +++ b/artiq/runtime.rs/src/sched.rs @@ -391,6 +391,14 @@ impl<'a> TcpListener<'a> { pub fn acceptable(&self) -> bool { self.lower.state().borrow().acceptable() } + + pub fn keepalive(&self) -> bool { + self.lower.keepalive() + } + + pub fn set_keepalive(&self, keepalive: bool) { + self.lower.set_keepalive(keepalive) + } } pub use lwip::Shutdown; diff --git a/artiq/runtime.rs/src/session.rs b/artiq/runtime.rs/src/session.rs index e4fdf2924..879ad159d 100644 --- a/artiq/runtime.rs/src/session.rs +++ b/artiq/runtime.rs/src/session.rs @@ -396,6 +396,7 @@ pub fn thread(waiter: Waiter, spawner: Spawner) { let addr = SocketAddr::new(IP_ANY, 1381); let listener = TcpListener::bind(waiter, addr).expect("cannot bind socket"); + listener.set_keepalive(true); info!("accepting network sessions in Rust"); let mut kernel_thread = None; diff --git a/artiq/runtime/main.c b/artiq/runtime/main.c index c2460b32a..bf1091526 100644 --- a/artiq/runtime/main.c +++ b/artiq/runtime/main.c @@ -237,6 +237,10 @@ u16_t tcp_sndbuf_(struct tcp_pcb *pcb) { return tcp_sndbuf(pcb); } +u8_t* tcp_so_options_(struct tcp_pcb *pcb) { + return &pcb->so_options; +} + int main(void) { irq_setmask(0);