Dmytro Shteflyuk created THRIFT-6112:
----------------------------------------
Summary: Ruby Socket should reject duplicate opens
Key: THRIFT-6112
URL: https://issues.apache.org/jira/browse/THRIFT-6112
Project: Thrift
Issue Type: Bug
Components: Ruby - Library
Reporter: Dmytro Shteflyuk
Assignee: Dmytro Shteflyuk
h3. Problem
Calling {{Thrift::Socket#open}} on an already-open transport creates a second
TCP connection and replaces the transport's {{@handle}}. The first connection
is not closed before its handle becomes unreachable through the transport.
As a result, {{close}} only closes the replacement connection. The original
connection remains open until some other owner closes it or Ruby eventually
reclaims it.
This ticket is scoped to the TCP {{Thrift::Socket}} transport. Transports that
override {{open}} have separate lifecycle implementations and are not changed
here.
h3. Client impact
Applications that accidentally open the same transport twice—for example,
through overlapping connection setup or retry paths—can leave an unused TCP
connection open on both the client and server. This consumes a file descriptor
and may leave an unexpected server-side session active even after the transport
itself is closed.
h3. Reproduction
>From the repository root:
{code:bash}
ruby -Ilib/rb/lib /tmp/thrift_double_open.rb
{code}
With {{/tmp/thrift_double_open.rb}} containing:
{code:ruby}
require 'socket'
require 'thrift'
server = TCPServer.new('127.0.0.1', 0)
transport = Thrift::Socket.new('127.0.0.1', server.local_address.ip_port)
transport.open
first_peer = server.accept
first_handle = transport.handle
transport.open
second_peer = server.accept
puts "first_handle_closed=#{first_handle.closed?}"
puts "second_handle_same=#{transport.handle.equal?(first_handle)}"
transport.close
first_handle.close
first_peer.close
second_peer.close
server.close
{code}
The current output is:
{code}
first_handle_closed=false
second_handle_same=false
{code}
The transport has replaced its handle while leaving the first connection open.
h3. Expected behavior
Opening an already-open TCP transport should raise
{{Thrift::TransportException}} with type {{ALREADY_OPEN}}. The existing live
connection and handle should remain unchanged so the caller can continue using
or explicitly close that transport.
--
This message was sent by Atlassian Jira
(v8.20.10#820010)