-
-
Notifications
You must be signed in to change notification settings - Fork 3
Description
When opening a large number of udp connections with Async::IO::Endpoint.udp, I've found that a few udp source ports will be reused. This creates an issue in async-dns where a socket will read the wrong message since there are two sockets using the same source port.
I ran into this while troubleshooting symptoms that look a lot like async-dns#29. While troubleshooting, I noticed that the conflicting message ids were sent from the same UDP source port. I confirmed this with tcpdump data as well as printing out the local_address info in a local copy of async-dns.
I can reproduce the issue with the following test code:
opts = ['8.8.8.8', 53]
async_addrs = []
tasks = []
Async::Reactor.run do
1000.times do
tasks << Async do
endpoint = Async::IO::Endpoint.udp(*opts)
endpoint.connect do |socket|
# Sleep to ensure all async sockets are open at the same time
sleep 5
async_addrs << socket.local_address.inspect_sockaddr
end
end
end
tasks.each(&:wait)
end
dup_source_ports = async_addrs.tally.select { |k, v| v > 1 }
puts "Duplicate source ports when opening async: #{dup_source_ports}"My output looks like:
Duplicate source ports when opening async: {"172.20.0.3:34947"=>2, "172.20.0.3:47288"=>2, "172.20.0.3:50770"=>2, "172.20.0.3:42735"=>2, "172.20.0.3:35920"=>2, "172.20.0.3:55178"=>2, "172.20.0.3:37292"=>3, "172.20.0.3:55541"=>2, "172.20.0.3:60046"=>2, "172.20.0.3:51284"=>2, "172.20.0.3:53503"=>2, "172.20.0.3:55538"=>2, "172.20.0.3:48124"=>2, "172.20.0.3:46663"=>2, "172.20.0.3:46927"=>2, "172.20.0.3:48047"=>2, "172.20.0.3:36643"=>2, "172.20.0.3:35810"=>2, "172.20.0.3:36384"=>2, "172.20.0.3:58197"=>2, "172.20.0.3:56768"=>2, "172.20.0.3:55430"=>2, "172.20.0.3:37374"=>2, "172.20.0.3:59022"=>2}
Ruby version: ruby 3.1.6p260 (2024-05-29 revision a777087be6) [x86_64-linux]
async-io version: 1.43.2
async version: 2.12.1
This is all running in a docker container built from ruby:3.1-slim