Skip to content

Commit 3d4ff13

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

File tree

2 files changed

+21
-15
lines changed

2 files changed

+21
-15
lines changed

lib/fluent/plugin/in_forward.rb

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,8 @@ class ForwardInput < Input
3636
config_param :port, :integer, default: LISTEN_PORT
3737
desc 'The bind address to listen to.'
3838
config_param :bind, :string, default: '0.0.0.0'
39+
desc 'Whether it accept only IPv6 connection with IPv6 bind address.'
40+
config_param :bind_ipv6_only, :bool, default: true
3941

4042
config_param :backlog, :integer, default: nil
4143
# SO_LINGER 0 to send RST rather than FIN to avoid lots of connections sitting in TIME_WAIT at src
@@ -176,6 +178,7 @@ def start
176178
resolve_name: @resolve_hostname,
177179
linger_timeout: @linger_timeout,
178180
send_keepalive_packet: @send_keepalive_packet,
181+
bind_ipv6_only: @bind_ipv6_only,
179182
backlog: @backlog,
180183
&method(:handle_connection)
181184
)

lib/fluent/plugin_helper/server.rb

Lines changed: 18 additions & 15 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, &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, &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) 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) 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)
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)
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
@@ -394,7 +397,7 @@ def server_create_tcp_socket(shared, bind, port)
394397
sock
395398
end
396399

397-
def server_create_udp_socket(shared, bind, port)
400+
def server_create_udp_socket(shared, bind, port, bind_ipv6_only = true)
398401
sock = if shared
399402
server_socket_manager_client.listen_udp(bind, port)
400403
else

0 commit comments

Comments
 (0)