From 604885b1fe2b4d2be0658c78914ebf16c13fb173 Mon Sep 17 00:00:00 2001 From: Evan Phoenix Date: Tue, 14 Mar 2017 09:09:39 -0700 Subject: [PATCH] Deal with unsupported sockopts. Fixes #1241 Seems that the ability to extract the TCP_INFO is a conditional capability, with it failing in some common situations. So if it works, great, but as soon as it stops working, disable it entirely. --- lib/puma/server.rb | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/lib/puma/server.rb b/lib/puma/server.rb index 1e377067..17290117 100644 --- a/lib/puma/server.rb +++ b/lib/puma/server.rb @@ -78,6 +78,8 @@ module Puma ENV['RACK_ENV'] ||= "development" @mode = :http + + @precheck_closing = true end attr_accessor :binder, :leak_stack_on_error @@ -121,10 +123,18 @@ module Puma def closed_socket?(socket) return false unless socket.kind_of? TCPSocket - tcp_info = socket.getsockopt(Socket::SOL_TCP, Socket::TCP_INFO) - state = tcp_info.unpack(UNPACK_TCP_STATE_FROM_TCP_INFO)[0] - # TIME_WAIT: 6, CLOSE: 7, CLOSE_WAIT: 8, LAST_ACK: 9, CLOSING: 11 - (state >= 6 && state <= 9) || state == 11 + return false unless @precheck_closing + + begin + tcp_info = socket.getsockopt(Socket::SOL_TCP, Socket::TCP_INFO) + rescue IOError, SystemCallError + @precheck_closing = false + false + else + state = tcp_info.unpack(UNPACK_TCP_STATE_FROM_TCP_INFO)[0] + # TIME_WAIT: 6, CLOSE: 7, CLOSE_WAIT: 8, LAST_ACK: 9, CLOSING: 11 + (state >= 6 && state <= 9) || state == 11 + end end else def cork_socket(socket)