ravi861 / nperf-rs

iperf3 in Rust
Apache License 2.0
7 stars 2 forks source link

"libc::TCP_INFO not found in libc" error while trying to install on MacOS (arm64) #5

Open ksa-real opened 10 months ago

ksa-real commented 10 months ago

Not sure if this is expected but I failed to install nparse on MacOS (Sonoma 14.2.1, M1 Max)

$ cargo install nperf
    Updating crates.io index
  Installing nperf v0.3.0
    Updating crates.io index
   Compiling cfg-if v1.0.0
   Compiling libc v0.2.151
...
error[E0425]: cannot find value `TCP_INFO` in crate `libc`
   --> /Users/USER/.cargo/registry/src/index.crates.io-6f17d22bba15001f/nperf-0.3.0/src/tcp.rs:328:15
    |
328 |         libc::TCP_INFO,
    |               ^^^^^^^^ not found in `libc`

For more information about this error, try `rustc --explain E0425`.
error: could not compile `nperf` (bin "nperf") due to previous error
error: failed to compile `nperf v0.3.0`, intermediate artifacts can be found at `/var/folders/qj/4kbgnk3n34x3prbjz6mqtssw0000gn/T/cargo-installAp7LIe`.
To reuse those artifacts with a future compilation, set the environment variable `CARGO_TARGET_DIR` to that path.

Fresh rust / cargo install with curl https://sh.rustup.rs -sSf | sh

mdean75 commented 1 week ago

Mac doesn't have TCP_INFO defined so this would need to use TCP_CONNECTION_INFO. I have tested with just that modification and while it will now compile, the test exists immediately. I am probably still missing something, but i'm optimistic i'm on the right track because you can see in the output below that the test did report the tcp information before exiting.

I accomplished this by changing the cfg attribute for fn tcp_info on tcp.rs:320 to target the os specifically instead of just unix family and provided a new implementation for mac.

#[cfg(target_os = "linux")]
pub fn tcp_info(sck: &Socket) -> io::Result<TcpInfo> {
    let mut payload = TcpInfo::default();
    let payload_ptr: *mut TcpInfo = &mut payload;
    let mut len = size_of::<TcpInfo>() as libc::socklen_t;
    syscall!(getsockopt(
        sck.as_raw_fd(),
        libc::IPPROTO_TCP,
        libc::TCP_INFO,
        payload_ptr.cast(),
        &mut len,
    ))
        .map(|_| payload.clone())
}

#[cfg(target_os = "macos")]
pub fn tcp_info(sck: &Socket) -> io::Result<TcpInfo> {
    let mut payload = TcpInfo::default();
    let payload_ptr: *mut TcpInfo = &mut payload;
    let mut len = size_of::<TcpInfo>() as libc::socklen_t;
    syscall!(getsockopt(
        sck.as_raw_fd(),
        libc::IPPROTO_TCP,
        libc::TCP_CONNECTION_INFO,
        payload_ptr.cast(),
        &mut len,
    ))
    .map(|_| payload.clone())
}
==========================================
Server listening on 127.0.0.1:8080
==========================================
Accepted ctrl connection from 127.0.0.1:54953
[  7] local 127.0.0.1:8080, peer 127.0.0.1:54954 sndbuf 146988 rcvbuf 408300 mss 16332
Starting Test: protocol: TCP, 1 streams, 131072 byte blocks, 10 seconds test
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
[ FD]  Time  Transfer         Rate              
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- - - - - - - - - - - - - Results Per Stream- - - - - - - - - - - - - - - -
[  7]    0s     0.0     bits/sec                              receiver
- - - - - - - - - - - - - - - All Streams - - - - - - - - - - - - - - - - -
[Sum]    0s     0.0     bits/sec                              receiver