From 280b55e644d6cefcdd175c604fadf43d96295d5e Mon Sep 17 00:00:00 2001 From: Masahiro Nakagawa Date: Thu, 14 Nov 2019 15:30:23 +0900 Subject: [PATCH 1/4] server helper: Fix IPv6 dual stack mode issue for tcp socket. fix #2682 Signed-off-by: Masahiro Nakagawa --- lib/fluent/plugin_helper/server.rb | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/lib/fluent/plugin_helper/server.rb b/lib/fluent/plugin_helper/server.rb index 3ac8ec251b..0a5f86f9e5 100644 --- a/lib/fluent/plugin_helper/server.rb +++ b/lib/fluent/plugin_helper/server.rb @@ -355,7 +355,10 @@ def server_create_tcp_socket(shared, bind, port) sock = if shared server_socket_manager_client.listen_tcp(bind, port) else - TCPServer.new(bind, port) # this method call can create sockets for AF_INET6 + # TCPServer.new doesn't set IPV6_V6ONLY flag, so use tcp_server_sockets instead. + tsock = ::Socket.tcp_server_sockets(bind, port).first + tsock.autoclose = false + TCPServer.for_fd(tsock.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 From a34c06bb3d7ba5a2580c42e75d4e11e81131f8d1 Mon Sep 17 00:00:00 2001 From: Masahiro Nakagawa Date: Fri, 15 Nov 2019 11:06:48 +0900 Subject: [PATCH 2/4] Use Addrinfo class Signed-off-by: Masahiro Nakagawa --- lib/fluent/plugin_helper/server.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/fluent/plugin_helper/server.rb b/lib/fluent/plugin_helper/server.rb index 0a5f86f9e5..be83dadc15 100644 --- a/lib/fluent/plugin_helper/server.rb +++ b/lib/fluent/plugin_helper/server.rb @@ -356,7 +356,7 @@ def server_create_tcp_socket(shared, bind, port) server_socket_manager_client.listen_tcp(bind, port) else # TCPServer.new doesn't set IPV6_V6ONLY flag, so use tcp_server_sockets instead. - tsock = ::Socket.tcp_server_sockets(bind, port).first + tsock = Addrinfo.tcp(bind, port).listen(::Socket::SOMAXCONN) tsock.autoclose = false TCPServer.for_fd(tsock.fileno) end From b54697c615c8b0687ea6f375c01fc9d21c9c8d94 Mon Sep 17 00:00:00 2001 From: Masahiro Nakagawa Date: Fri, 15 Nov 2019 11:19:15 +0900 Subject: [PATCH 3/4] server helper: Add test to IPv4/IPv6 listen at same port Signed-off-by: Masahiro Nakagawa --- test/plugin_helper/test_server.rb | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/test/plugin_helper/test_server.rb b/test/plugin_helper/test_server.rb index e54c20c8e5..d71dc5788e 100644 --- a/test/plugin_helper/test_server.rb +++ b/test/plugin_helper/test_server.rb @@ -538,6 +538,19 @@ class Dummy < Fluent::Plugin::TestBase assert_equal ["yayfoo\n", "yayfoo\n", "yayfoo\n"], lines assert_equal ["closed", "closed", "closed"], callback_results end + + test 'can listen IPv4 / IPv6 together' do + omit "IPv6 unavailable here" unless ipv6_enabled? + + assert_nothing_raised do + @d.server_create_tcp(:s_ipv4, PORT, bind: '0.0.0.0', shared: false) do |data, conn| + # ... + end + @d.server_create_tcp(:s_ipv6, PORT, bind: '::', shared: false) do |data, conn| + # ... + end + end + end end sub_test_case '#server_create_udp' do From 29b51764662c31cebcbfd417b3282e52c0e1fa8f Mon Sep 17 00:00:00 2001 From: Masahiro Nakagawa Date: Fri, 15 Nov 2019 11:23:42 +0900 Subject: [PATCH 4/4] server helper: Update comment and code Signed-off-by: Masahiro Nakagawa --- lib/fluent/plugin_helper/server.rb | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/lib/fluent/plugin_helper/server.rb b/lib/fluent/plugin_helper/server.rb index be83dadc15..7b9cea0649 100644 --- a/lib/fluent/plugin_helper/server.rb +++ b/lib/fluent/plugin_helper/server.rb @@ -355,8 +355,9 @@ def server_create_tcp_socket(shared, bind, port) sock = if shared server_socket_manager_client.listen_tcp(bind, port) else - # TCPServer.new doesn't set IPV6_V6ONLY flag, so use tcp_server_sockets instead. - tsock = Addrinfo.tcp(bind, port).listen(::Socket::SOMAXCONN) + # TCPServer.new doesn't set IPV6_V6ONLY flag, so use Addrinfo class instead. + # backlog will be set by the caller, we don't need to set backlog here + tsock = Addrinfo.tcp(bind, port).listen tsock.autoclose = false TCPServer.for_fd(tsock.fileno) end