Skip to content

Commit 76e25af

Browse files
committed
server plugin helper: accept ipv4 and ipv6 both with one interface for TCP
Signed-off-by: Shizuo Fujita <fujita@clear-code.com>
1 parent cefbc62 commit 76e25af

File tree

1 file changed

+17
-14
lines changed

1 file changed

+17
-14
lines changed

lib/fluent/plugin_helper/server.rb

Lines changed: 17 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,7 @@ def server_wait_until_stop
6767
# conn.close
6868
# end
6969
# end
70-
def server_create_connection(title, port, proto: nil, bind: '0.0.0.0', shared: true, backlog: nil, tls_options: nil, **socket_options, &block)
70+
def server_create_connection(title, port, proto: nil, bind: '0.0.0.0', shared: true, bind_ipv6_only: true, backlog: nil, tls_options: nil, **socket_options, &block)
7171
proto ||= (@transport_config && @transport_config.protocol == :tls) ? :tls : :tcp
7272

7373
raise ArgumentError, "BUG: title must be a symbol" unless title && title.is_a?(Symbol)
@@ -91,7 +91,7 @@ def server_create_connection(title, port, proto: nil, bind: '0.0.0.0', shared: t
9191

9292
case proto
9393
when :tcp
94-
server = server_create_for_tcp_connection(shared, bind, port, backlog, socket_option_setter, &block)
94+
server = server_create_for_tcp_connection(shared, bind, port, backlog, socket_option_setter, bind_ipv6_only: bind_ipv6_only, &block)
9595
when :tls
9696
transport_config = if tls_options
9797
server_create_transport_section_object(tls_options)
@@ -100,7 +100,7 @@ def server_create_connection(title, port, proto: nil, bind: '0.0.0.0', shared: t
100100
else
101101
raise ArgumentError, "BUG: TLS transport specified, but certification options are not specified"
102102
end
103-
server = server_create_for_tls_connection(shared, bind, port, transport_config, backlog, socket_option_setter, &block)
103+
server = server_create_for_tls_connection(shared, bind, port, transport_config, backlog, socket_option_setter, bind_ipv6_only: bind_ipv6_only, &block)
104104
when :unix
105105
raise "not implemented yet"
106106
else
@@ -121,7 +121,7 @@ def server_create_connection(title, port, proto: nil, bind: '0.0.0.0', shared: t
121121
# sock.remote_port
122122
# # ...
123123
# end
124-
def server_create(title, port, proto: nil, bind: '0.0.0.0', shared: true, socket: nil, backlog: nil, tls_options: nil, max_bytes: nil, flags: 0, **socket_options, &callback)
124+
def server_create(title, port, proto: nil, bind: '0.0.0.0', shared: true, socket: nil, bind_ipv6_only: true, backlog: nil, tls_options: nil, max_bytes: nil, flags: 0, **socket_options, &callback)
125125
proto ||= (@transport_config && @transport_config.protocol == :tls) ? :tls : :tcp
126126

127127
raise ArgumentError, "BUG: title must be a symbol" unless title && title.is_a?(Symbol)
@@ -155,7 +155,7 @@ def server_create(title, port, proto: nil, bind: '0.0.0.0', shared: true, socket
155155

156156
case proto
157157
when :tcp
158-
server = server_create_for_tcp_connection(shared, bind, port, backlog, socket_option_setter) do |conn|
158+
server = server_create_for_tcp_connection(shared, bind, port, backlog, socket_option_setter, bind_ipv6_only: bind_ipv6_only) do |conn|
159159
conn.data(&callback)
160160
end
161161
when :tls
@@ -166,7 +166,7 @@ def server_create(title, port, proto: nil, bind: '0.0.0.0', shared: true, socket
166166
else
167167
raise ArgumentError, "BUG: TLS transport specified, but certification options are not specified"
168168
end
169-
server = server_create_for_tls_connection(shared, bind, port, transport_config, backlog, socket_option_setter) do |conn|
169+
server = server_create_for_tls_connection(shared, bind, port, transport_config, backlog, socket_option_setter, bind_ipv6_only: bind_ipv6_only) do |conn|
170170
conn.data(&callback)
171171
end
172172
when :udp
@@ -212,8 +212,8 @@ def server_attach(title, proto, port, bind, shared, server)
212212
event_loop_attach(server)
213213
end
214214

215-
def server_create_for_tcp_connection(shared, bind, port, backlog, socket_option_setter, &block)
216-
sock = server_create_tcp_socket(shared, bind, port)
215+
def server_create_for_tcp_connection(shared, bind, port, backlog, socket_option_setter, bind_ipv6_only: true, &block)
216+
sock = server_create_tcp_socket(shared, bind, port, bind_ipv6_only: bind_ipv6_only)
217217
socket_option_setter.call(sock)
218218
close_callback = ->(conn){ @_server_mutex.synchronize{ @_server_connections.delete(conn) } }
219219
server = Coolio::TCPServer.new(sock, nil, EventHandler::TCPServer, socket_option_setter, close_callback, @log, @under_plugin_development, block) do |conn|
@@ -227,9 +227,9 @@ def server_create_for_tcp_connection(shared, bind, port, backlog, socket_option_
227227
server
228228
end
229229

230-
def server_create_for_tls_connection(shared, bind, port, conf, backlog, socket_option_setter, &block)
230+
def server_create_for_tls_connection(shared, bind, port, conf, backlog, socket_option_setter, bind_ipv6_only: true, &block)
231231
context = cert_option_create_context(conf.version, conf.insecure, conf.ciphers, conf)
232-
sock = server_create_tcp_socket(shared, bind, port)
232+
sock = server_create_tcp_socket(shared, bind, port, bind_ipv6_only: bind_ipv6_only)
233233
socket_option_setter.call(sock)
234234
close_callback = ->(conn){ @_server_mutex.synchronize{ @_server_connections.delete(conn) } }
235235
server = Coolio::TCPServer.new(sock, nil, EventHandler::TLSServer, context, socket_option_setter, close_callback, @log, @under_plugin_development, block) do |conn|
@@ -379,13 +379,16 @@ def server_socket_manager_client
379379
ServerEngine::SocketManager::Client.new(socket_manager_path)
380380
end
381381

382-
def server_create_tcp_socket(shared, bind, port)
382+
def server_create_tcp_socket(shared, bind, port, bind_ipv6_only: true)
383383
sock = if shared
384384
server_socket_manager_client.listen_tcp(bind, port)
385385
else
386-
# TCPServer.new doesn't set IPV6_V6ONLY flag, so use Addrinfo class instead.
387-
# backlog will be set by the caller, we don't need to set backlog here
388-
tsock = Addrinfo.tcp(bind, port).listen
386+
addrinfo = Addrinfo.tcp(bind, port)
387+
tsock = ::Socket.new(addrinfo.pfamily, addrinfo.socktype, addrinfo.protocol)
388+
tsock.ipv6only! if addrinfo.ipv6? && bind_ipv6_only
389+
tsock.setsockopt(::Socket::SOL_SOCKET, ::Socket::SO_REUSEADDR, 1)
390+
tsock.bind(addrinfo)
391+
tsock.listen(::Socket::SOMAXCONN)
389392
tsock.autoclose = false
390393
TCPServer.for_fd(tsock.fileno)
391394
end

0 commit comments

Comments
 (0)