Skip to content

Duplicate UDP source ports allocated #13

@seandilda

Description

@seandilda

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions