From 7d16531c0fdf05763f25efb4b1cdb4314b1b1f70 Mon Sep 17 00:00:00 2001 From: Hiroshi Hatake Date: Thu, 5 Mar 2020 15:52:30 +0900 Subject: [PATCH] test: Correct linger option related type In Winsock, linger related struct's menber types are not `int` but `u_short` (unsigned short). `linger_timeout` also should be set up when linger_timeout > 0. Signed-off-by: Hiroshi Hatake --- lib/fluent/plugin_helper/socket_option.rb | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/lib/fluent/plugin_helper/socket_option.rb b/lib/fluent/plugin_helper/socket_option.rb index 6e357c1741..5bfe303cab 100644 --- a/lib/fluent/plugin_helper/socket_option.rb +++ b/lib/fluent/plugin_helper/socket_option.rb @@ -21,6 +21,8 @@ module Fluent module PluginHelper module SocketOption + # ref: https://docs.microsoft.com/en-us/windows/win32/api/winsock/ns-winsock-linger + FORMAT_STRUCT_LINGER_WINDOWS = 'S!S!' # { u_short l_onoff; u_short l_linger; } FORMAT_STRUCT_LINGER = 'I!I!' # { int l_onoff; int l_linger; } FORMAT_STRUCT_TIMEVAL = 'L!L!' # { time_t tv_sec; suseconds_t tv_usec; } @@ -49,9 +51,21 @@ def socket_option_set(sock, resolve_name: nil, nonblock: false, linger_timeout: if nonblock sock.fcntl(Fcntl::F_SETFL, Fcntl::O_NONBLOCK) end - if linger_timeout + if Fluent.windows? + # To prevent closing socket forcibly on Windows, + # this options shouldn't be set up when linger_timeout equals to 0 (including nil). + # This unintended behavior always ocurrs on Windows when linger_timeout.to_i == 0. + # This unintented behavior causes "Errno::ECONNRESET: An existing connection was forcibly + # closed by the remote host." on Windows. + if linger_timeout.to_i > 0 + optval = [1, linger_timeout.to_i].pack(FORMAT_STRUCT_LINGER_WINDOWS) + socket_option_set_one(sock, :SO_LINGER, optval) + end + else + if linger_timeout optval = [1, linger_timeout.to_i].pack(FORMAT_STRUCT_LINGER) socket_option_set_one(sock, :SO_LINGER, optval) + end end if recv_timeout optval = [recv_timeout.to_i, 0].pack(FORMAT_STRUCT_TIMEVAL)