When making an outgoing TCP or UDP connection, set AI_ADDRCONFIG in the
hints we send to getaddrinfo(3) (if supported). This will prompt the
resolver to _NOT_ issue A or AAAA queries if the system does not
actually have an IPv4 or IPv6 address (respectively).
This makes outgoing connections marginally more efficient on
non-dual-stack systems, since we don't have to try connecting to an
address which can't possibly work.
More importantly, however, this works around a race condition present
in some older versions of glibc on aarch64 where it could accidently
send the two outgoing DNS queries with the same DNS txnid, and get
confused when receiving the responses. This manifests as outgoing
connections sometimes taking 5 seconds (the DNS timeout before retry) to
be made.
Fixes#19144
This is analogous to functionality found in IO#read_nonblock and
IO#wait_nonblock. Raising exceptions for common failures on
non-blocking servers is expensive and makes $DEBUG too noisy.
Benchmark results:
user system total real
default 2.790000 0.870000 3.660000 ( 3.671597)
exception: false 1.120000 0.800000 1.920000 ( 1.922032)
exception: false (cached arg) 0.820000 0.770000 1.590000 ( 1.589267)
--------------------- benchmark script ------------------------
require 'socket'
require 'benchmark'
require 'tmpdir'
nr = 1000000
Dir.mktmpdir('nb_bench') do |path|
sock_path = "#{path}/test.sock"
s = UNIXServer.new(sock_path)
Benchmark.bmbm do |x|
x.report("default") do
nr.times do
begin
s.accept_nonblock
rescue IO::WaitReadable
end
end
end
x.report("exception: false") do
nr.times do
begin
s.accept_nonblock(exception: false)
rescue IO::WaitReadable
abort "should not raise"
end
end
end
x.report("exception: false (cached arg)") do
arg = { exception: false }
nr.times do
begin
s.accept_nonblock(arg)
rescue IO::WaitReadable
abort "should not raise"
end
end
end
end
end
* ext/socket/init.c (rsock_s_accept_nonblock):
support exception: false
[ruby-core:66385] [Feature #10532]
* ext/socket/init.c (rsock_init_socket_init): define new symbols
* ext/socket/rubysocket.h: adjust prototype
* ext/socket/socket.c (sock_accept_nonblock): support exception: false
* ext/openssl/ossl_ssl.c (ossl_ssl_accept_nonblock): ditto
* ext/socket/socket.c (Init_socket): adjust accept_nonblock definition
* ext/openssl/ossl_ssl.c (Init_ossl_ssl): ditto
* ext/socket/tcpserver.c (rsock_init_tcpserver): ditto
* ext/socket/unixserver.c (rsock_init_unixserver): ditto
* ext/socket/tcpserver.c (tcp_accept_nonblock): adjust
rsock_s_accept_nonblock call
* ext/socket/unixserver.c (unix_accept_nonblock): ditto
* ext/openssl/ossl_ssl.c (ossl_start_ssl): support no_exception
* ext/openssl/ossl_ssl.c (ossl_ssl_connect): adjust ossl_start_ssl call
* ext/openssl/ossl_ssl.c (ossl_ssl_connect_nonblock): ditto
* ext/openssl/ossl_ssl.c (ossl_ssl_accept): ditto
* test/socket/test_nonblock.rb (test_accept_nonblock): test for
"exception :false"
* test/socket/test_tcp.rb (test_accept_nonblock): new test
* test/socket/test_unix.rb (test_accept_nonblock): ditto
* test/openssl/test_pair.rb (test_accept_nonblock_no_exception): ditto
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@49948 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
after path length check.
This fixes a fd leak by TestSocket_UNIXSocket#test_too_long_path.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@46218 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
addresses which address family is different to remote address.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@41686 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
* test/socket/test_tcp.rb (test_recvfrom, test_encoding): use IP address instead
of host name.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@20442 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
fixed. [ruby-dev:27123]
* string.c (rb_str_substr): should propagate taintness even for
empty strings. [ruby-dev:27121]
* string.c (rb_str_aref): should infect result if range argument
is tainted. [ruby-dev:27121]
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@9199 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
operation ignores EAGAIN.
* test/ruby/test_super.rb (TestSuper#test_define_method): test for
super from proc. [ruby-core:03856]
* test/socket/test_tcp.rb (TestTCPSocket#test_recvfrom): make
execution order more precise.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@7496 b2dd03c8-39d4-4d8f-98ff-823fe69b080e