@@ -263,6 +263,7 @@ def initialize(address, port = nil, tls: false, starttls: :auto, tls_verify: tru
263263 @tls_verify = tls_verify
264264 @tls_hostname = tls_hostname
265265 @ssl_context_params = ssl_context_params
266+ @tcp_socket_supports_open_timeout = nil
266267 end
267268
268269 # If +true+, verify th server's certificate.
@@ -659,17 +660,43 @@ def finish
659660
660661 private
661662
662- def tcp_socket ( address , port )
663- TCPSocket . open address , port
663+ def tcp_socket ( address , port , open_timeout : nil )
664+ if open_timeout
665+ TCPSocket . open ( address , port , nil , nil , open_timeout : open_timeout )
666+ else
667+ TCPSocket . open ( address , port )
668+ end
664669 end
665670
666671 def do_start ( helo_domain , user , secret , authtype )
667672 raise IOError , 'SMTP session already started' if @started
668673 if user || secret || authtype
669674 check_auth_args authtype , user , secret
670675 end
671- s = Timeout . timeout ( @open_timeout , Net ::OpenTimeout ) do
672- tcp_socket ( @address , @port )
676+ begin
677+ s =
678+ case @tcp_socket_supports_open_timeout
679+ when nil , true
680+ begin
681+ sock = tcp_socket ( @address , @port , open_timeout : @open_timeout )
682+ @tcp_socket_supports_open_timeout = true
683+ sock
684+ rescue ArgumentError => e
685+ raise unless e . message . include? ( 'unknown keyword: :open_timeout' ) || e . message . include? ( 'wrong number of arguments (given 5, expected 2..4)' )
686+ @tcp_socket_supports_open_timeout = false
687+
688+ Timeout . timeout ( @open_timeout , Net ::OpenTimeout ) do
689+ tcp_socket ( @address , @port )
690+ end
691+ end
692+ when false
693+ Timeout . timeout ( @open_timeout , Net ::OpenTimeout ) do
694+ tcp_socket ( @address , @port )
695+ end
696+ end
697+ rescue => e
698+ e = Net ::OpenTimeout . new ( e ) if e . is_a? ( Errno ::ETIMEDOUT ) # for compatibility with previous versions
699+ raise e
673700 end
674701 logging "Connection opened: #{ @address } :#{ @port } "
675702 @socket = new_internet_message_io ( tls? ? tlsconnect ( s , @ssl_context_tls ) : s )
0 commit comments