[ 
https://issues.apache.org/jira/browse/THRIFT-6112?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel
 ]

Dmytro Shteflyuk resolved THRIFT-6112.
--------------------------------------
    Fix Version/s: 0.25.0
       Resolution: Fixed

> 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
>            Priority: Major
>             Fix For: 0.25.0
>
>          Time Spent: 40m
>  Remaining Estimate: 0h
>
> 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)

Reply via email to