-
-
Notifications
You must be signed in to change notification settings - Fork 5.7k
Description
With bind(::UDPSocket; reuseaddr=true), it's possible to bind the same address multiple times, with only the last bind receiving any traffic. On macOS, that fails for specific addresses, such as 0.0.0.0. This does not cause any errors (I expected -EADDRINUSE) while causing subsequent recvs to hang.
MWE:
using Sockets
const ip = IPv4("0.0.0.0")
let sock = UDPSocket()
bind(sock, ip, 12345; reuseaddr=true)
println("Waiting...")
@show data = recv(sock)
println("Received ", Base.format_bytes(length(data)))
end
println()
let sock = UDPSocket()
bind(sock, ip, 12345; reuseaddr=true)
println("Waiting...")
@show data = recv(sock)
println("Received ", Base.format_bytes(length(data)))
endMeanwhile, in a different terminal, run echo -n test | nc -u 127.0.0.1 12345 or so twice. On macOS, this will result in the second recv call never returning, while on Linux everything works fine.
I haven't looked in the platform specifics of SO_REUSEADDR/SO_REUSEPORT yet -- it seems like quite a mess -- so this may be a platform limitation (as the libuv docs suggest). However, if possible I think we should detect an impossible reuseaddr request and throw an error. If that's not possible, at the very least the docs should warn about it.
Changing the address to 127.0.0.1 works around the issue.