diff --git a/lib/fluent/plugin_helper/server.rb b/lib/fluent/plugin_helper/server.rb index f99a64e0cb..a5cb65f001 100644 --- a/lib/fluent/plugin_helper/server.rb +++ b/lib/fluent/plugin_helper/server.rb @@ -370,10 +370,9 @@ def server_create_udp_socket(shared, bind, port) sock = if shared server_socket_manager_client.listen_udp(bind, port) else - family = IPAddr.new(IPSocket.getaddress(bind)).ipv4? ? ::Socket::AF_INET : ::Socket::AF_INET6 - usock = UDPSocket.new(family) - usock.bind(bind, port) - usock + usock = Addrinfo.udp(bind, port).bind + usock.autoclose = false + UDPSocket.for_fd(usock.fileno) end # close-on-exec is set by default in Ruby 2.0 or later (, and it's unavailable on Windows) sock.fcntl(Fcntl::F_SETFL, Fcntl::O_NONBLOCK) # nonblock diff --git a/test/plugin_helper/test_server.rb b/test/plugin_helper/test_server.rb index d71dc5788e..261a00d95f 100644 --- a/test/plugin_helper/test_server.rb +++ b/test/plugin_helper/test_server.rb @@ -751,6 +751,19 @@ class Dummy < Fluent::Plugin::TestBase assert_equal 1, errors.size assert_equal "BUG: this event is disabled for udp: close", errors.first.message end + + test 'can bind IPv4 / IPv6 together' do + omit "IPv6 unavailable here" unless ipv6_enabled? + + assert_nothing_raised do + @d.server_create_udp(:s_ipv4_udp, PORT, bind: '0.0.0.0', shared: false, max_bytes: 128) do |data, sock| + # ... + end + @d.server_create_udp(:s_ipv6_udp, PORT, bind: '::', shared: false, max_bytes: 128) do |data, sock| + # ... + end + end + end end module CertUtil