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

Setting TCP_NODELAY does not work using std::net::TcpStream #218

Open
jothan opened this issue Apr 15, 2024 · 3 comments
Open

Setting TCP_NODELAY does not work using std::net::TcpStream #218

jothan opened this issue Apr 15, 2024 · 3 comments

Comments

@jothan
Copy link

jothan commented Apr 15, 2024

I tried this code:

// Wi-Fi setup, etc....

let s = std::net::TcpStream::connect(("example.com", 80))?;
log::info!("socket connected");
if let Err(e) = s.set_nodelay(true) {
    log::error!("nodelay error: {e:?}");
};

I expected to see this happen: the socket should have been put in nodelay mode without issue.

Instead, this happened:

I (5067) myproject: socket connected
E (5067) myproject: nodelay error: Os { code: 109, kind: Uncategorized, message: "Protocol not available" }

The TCP_NODELAY option should be supported: https://docs.espressif.com/projects/esp-idf/en/v5.2.1/esp32/api-guides/lwip.html#tcp-options

Meta

rustc --version --verbose:

rustc 1.77.0-nightly (424037dcb 2024-03-18) (1.77.0.0)
binary: rustc
commit-hash: 424037dcb6937656992747c4bbff310c40061498
commit-date: 2024-03-18
host: x86_64-unknown-linux-gnu
release: 1.77.0-nightly
LLVM version: 17.0.1
  • ESP-IDF 5.2.1
  • esp-idf-sys 0.34.1
  • esp-idf-svc 0.48.1
  • esp-idf-hal 0.43.1
@jothan
Copy link
Author

jothan commented Apr 15, 2024

I think I found the bug.

LWIP defines TCP_NODELAY as 1 in esp-idf/components/lwip/lwip/src/include/lwip/sockets.h:

#define TCP_NODELAY    0x01    /* don't delay send to coalesce packets */

While Rust uses the libc::TCP_NODELAY with a value of 8193 defined by the libc crate in src/unix/newlib/mod.rs:

cfg_if! {
    if #[cfg(target_os = "vita")] {
        pub const TCP_NODELAY: ::c_int = 1;
        pub const TCP_MAXSEG: ::c_int = 2;
    } else {
        pub const TCP_NODELAY: ::c_int = 8193;
        pub const TCP_MAXSEG: ::c_int = 8194;
    }
}

@jothan
Copy link
Author

jothan commented Apr 15, 2024

I found this pull request that would fix this issue on the libc crate repository: rust-lang/libc#3345

@DavidVentura
Copy link

I've hit the same, for now I've done this as a workaround

extern "C" {                                                                                                                                        
    fn lwip_setsockopt(fd: i32, level: i32, optname: i32);                                                                                          
}   
unsafe {                                                                                                                                    
    lwip_setsockopt(                                                                                                                        
              conn.as_raw_fd(),                                                                                                                   
              6, // tcp https://github.com/stm32duino/LwIP/blob/main/src/lwip/sockets.h#L250                                               
              1, // nodelay https://github.com/stm32duino/LwIP/blob/main/src/lwip/sockets.h#L279                                         
      )
};  

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
Status: Todo
Development

No branches or pull requests

2 participants