Skip to content

The runtime does not allow to reuse socket address for UDP connections #5247

Open
@rodjjo

Description

@rodjjo

Describe the bug

The runtime exposes functions to allow us to set SO_REUSEADDR and SO_REUSEPORT, however it's not working:

wasmer run --net examples/rust_udp/target/wasm32-wasmer-wasi/debug/udp_example.rustc.wasm
Starting UDP server
Binding to 0.0.0.0:8080
Error: Os { code: 3, kind: AddrInUse, message: "Address in use" }

The example code:

use tokio::net::UdpSocket;
use std::io;
use std::net::{SocketAddr};
use socket2::{Socket, Domain, Type};


#[tokio::main]
async fn main() -> io::Result<()> {
    println!("Starting UDP server");
    let std_sock = Socket::new(Domain::IPV4, Type::DGRAM, None)?;
    std_sock.set_reuse_address(true)?;

    println!("Binding to 0.0.0.0:8080");

    let address: SocketAddr = "0.0.0.0:8080".parse().unwrap();
    let address = address.into();
    std_sock.bind(&address)?;
    println!("Binding to 0.0.0.0:8080");
   
    let sock = UdpSocket::from_std(std_sock.into())?;

    let mut buf = [0; 1024];
    loop {
        let (len, addr) = sock.recv_from(&mut buf).await?;
        println!("{:?} bytes received from {:?}", len, addr);

        let len = sock.send_to(&buf[..len], addr).await?;
        println!("{:?} bytes sent", len);
    }
}

Libraries in use (cargo.toml):

[package]
name = "udp_example"
version = "0.1.0"
edition = "2021"

[dependencies]
 
socket2 = { git = "https://github.com/wasix-org/socket2.git", branch = "master" }
tokio = { git = "https://github.com/wasix-org/tokio.git", branch = "wasix-1.35.1", version = "=1.35.1", features = ["fs", "io-util", "io-std","net", "rt",  "signal", "macros", "rt", "rt-multi-thread", "signal", "sync", "time", "socket2" ] }

Steps to reproduce

Compile the application and try to open two instances of it using wasmer.

Expected behavior

Actual behavior

It shows an error:

Starting UDP server
Binding to 0.0.0.0:8080
Error: Os { code: 3, kind: AddrInUse, message: "Address in use" }

Additional context

Journal report:

init-module (hash=[cc, 76, 0, fc, cb, e3, 44, c8])
thread-update (id=1, call-stack.len=108, mem-stack.len=16, store-size=136
memory-update (start=0, end=1114112, data.len=1114112, compressed.len=32190)
snapshot (when=SystemTime { tv_sec: 1731589610, tv_nsec: 148723631 }, trigger=FirstEnviron)
epoll-create (fd=6)
fd-event (fd=7, initial=0)
fd-set-flags (fd=7, flags=NONBLOCK)
epoll-ctl (epfd=6, op=EPOLL_CTL_ADD, fd=7)
fd-duplicate (original=6, copied=8)
fd-write (fd=1, offset=0, data.len=20)
sock-open (fd=9, af=Addressfamily::Inet4, ty=Socktype::Dgram, pt=SockProto::Udp)
sock-set-opt (fd=9, opt=Sockoption::ReuseAddr, flag=true)
fd-write (fd=1, offset=0, data.len=24)
fd-close (fd=9)
fd-close (fd=9)
fd-write (fd=7, offset=0, data.len=8)
fd-close (fd=6)
fd-close (fd=8)
fd-close (fd=7)
fd-write (fd=2, offset=0, data.len=7)
thread-close (id=2, code=Some(ExitCode::success (error 0)))
fd-write (fd=2, offset=0, data.len=2)
fd-write (fd=2, offset=0, data.len=3)
fd-write (fd=2, offset=0, data.len=4)
fd-write (fd=2, offset=0, data.len=2)
fd-write (fd=2, offset=0, data.len=1)
fd-write (fd=2, offset=0, data.len=2)
fd-write (fd=2, offset=0, data.len=4)
fd-write (fd=2, offset=0, data.len=2)
fd-write (fd=2, offset=0, data.len=9)
fd-write (fd=2, offset=0, data.len=2)
fd-write (fd=2, offset=0, data.len=7)
fd-write (fd=2, offset=0, data.len=2)
fd-write (fd=2, offset=0, data.len=1)
fd-write (fd=2, offset=0, data.len=14)
fd-write (fd=2, offset=0, data.len=1)
fd-write (fd=2, offset=0, data.len=2)
fd-write (fd=2, offset=0, data.len=1)
thread-close (id=1, code=Some(ExitCode::toobig (error 1)))
process-exit (code=Some(ExitCode::toobig (error 1)))

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions