I am aware of bind: cannot assign requested address and Cannot assign requested address - possible causes?, I have not been able to derive a solution from these.
I am trying to create a TCP stream (specifically here a std::net::TcpListener) directly with libc. I am encountering the error Cannot assign requested address and error code: 99 when running my code.
The exact output being:
error message: error code: : Cannot assign requested address
thread 'main' panicked at 'error code: 99', src/main.rs:43:13
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
My code (playground):
use libc; // 0.2.136
use std::mem::{size_of, transmute};
fn main() {
    // Create socket
    let socket_fd = unsafe {
        let socket = libc::socket(libc::AF_INET6, libc::SOCK_STREAM | libc::SOCK_NONBLOCK, 0);
        assert_ne!(socket, -1);
        let optval = 1i32;
        let res = libc::setsockopt(
            socket,
            libc::SOL_SOCKET,
            libc::SO_REUSEPORT,
            (&optval as *const i32).cast(),
            4,
        );
        assert_eq!(res, 0);
        socket
    };
    // Bind socket
    
    // decimal 127.0.0.1 -> hexadecimal 007f.0000.0000.0001
    let sin6_addr = unsafe { transmute::<_, libc::in6_addr>(*b"007f000000000001") };
    let socket_address = libc::sockaddr_in6 {
        sin6_family: libc::AF_INET6 as u16,
        sin6_port: 8080,
        sin6_flowinfo: u32::default(),
        sin6_addr,
        sin6_scope_id: u32::default(),
    };
    let socket_address_length = size_of::<libc::sockaddr_in6>() as u32;
    unsafe {
        let res = libc::bind(
            socket_fd,
            (&socket_address as *const libc::sockaddr_in6).cast(),
            socket_address_length,
        );
        if res == -1 {
            let err = errno();
            print_error("error message: ");
            panic!("error code: {err}");
        }
    }
    
    assert_eq!(unsafe { libc::close(socket_fd) },0);
}
fn print_error(s: &str) {
    unsafe {
        libc::perror(s.as_ptr().cast());
    }
}
fn errno() -> i32 {
    unsafe { *libc::__errno_location() }
}
I set the option SO_REUSEPORT here as I need to create a stream that multiple processes can listen to.
https://lwn.net/Articles/542629/:
The basic concept of SO_REUSEPORT is simple enough. Multiple servers (processes or threads) can bind to the same port
The port does not appear to be in use:
jonathan@jonathan-pc:~$ sudo lsof -i -P -n
COMMAND    PID            USER   FD   TYPE DEVICE SIZE/OFF NODE NAME
systemd-r  793 systemd-resolve   13u  IPv4  19452      0t0  UDP 127.0.0.53:53 
systemd-r  793 systemd-resolve   14u  IPv4  19453      0t0  TCP 127.0.0.53:53 (LISTEN)
avahi-dae  855           avahi   12u  IPv4  31377      0t0  UDP *:5353 
avahi-dae  855           avahi   13u  IPv6  31378      0t0  UDP *:5353 
avahi-dae  855           avahi   14u  IPv4  31379      0t0  UDP *:49594 
avahi-dae  855           avahi   15u  IPv6  31380      0t0  UDP *:58397 
NetworkMa  859            root   36u  IPv4  36212      0t0  UDP 192.168.0.22:68->192.168.0.1:67 
NetworkMa  859            root   37u  IPv4 110801      0t0  UDP 192.168.0.17:68->192.168.0.1:67 
tor       1038      debian-tor    6u  IPv4  31407      0t0  TCP 127.0.0.1:9050 (LISTEN)
rust-anal 4117        jonathan   46u  IPv4  33176      0t0  UDP 127.0.0.1:35972->127.0.0.53:53 
rust-anal 4189        jonathan   46u  IPv4  33176      0t0  UDP 127.0.0.1:35972->127.0.0.53:53 
firefox   4297        jonathan    3u  IPv4 112786      0t0  TCP 192.168.0.22:46702->151.101.1.69:443 (ESTABLISHED)
firefox   4297        jonathan   29u  IPv4 100032      0t0  TCP 192.168.0.22:55828->34.120.208.123:443 (ESTABLISHED)
firefox   4297        jonathan   56u  IPv4 115182      0t0  TCP 192.168.0.22:50798->52.51.190.37:443 (ESTABLISHED)
firefox   4297        jonathan   75u  IPv4  95741      0t0  TCP 192.168.0.22:48466->142.250.200.10:443 (ESTABLISHED)
firefox   4297        jonathan   81u  IPv4  67879      0t0  TCP 192.168.0.22:55638->34.214.17.205:443 (ESTABLISHED)
firefox   4297        jonathan  116u  IPv4 111739      0t0  TCP 192.168.0.22:37986->172.217.169.68:443 (ESTABLISHED)
firefox   4297        jonathan  121u  IPv4  95751      0t0  TCP 192.168.0.22:46054->198.252.206.25:443 (ESTABLISHED)
firefox   4297        jonathan  129u  IPv4 102073      0t0  TCP 192.168.0.22:51478->34.120.237.76:443 (ESTABLISHED)
firefox   4297        jonathan  136u  IPv4  96742      0t0  TCP 192.168.0.22:36606->34.120.115.102:443 (ESTABLISHED)
firefox   4297        jonathan  139u  IPv4  97943      0t0  TCP 192.168.0.22:36626->172.217.169.68:443 (ESTABLISHED)
firefox   4297        jonathan  144u  IPv4  99520      0t0  TCP 192.168.0.22:49264->198.252.206.25:443 (ESTABLISHED)
firefox   4297        jonathan  157u  IPv4 104859      0t0  TCP 192.168.0.22:58042->93.184.220.29:80 (ESTABLISHED)
jonathan@jonathan-pc:~$