1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70
|
require 'test/unit'
require 'kgio'
class TestTFO < Test::Unit::TestCase
def test_constants
if `uname -s`.chomp == "Linux" && `uname -r`.to_f >= 3.7
assert_equal 23, Kgio::TCP_FASTOPEN
assert_equal 0x20000000, Kgio::MSG_FASTOPEN
end
end
def fastopen_ok?
if RUBY_PLATFORM =~ /linux/ && File.exist?("/proc/sys/net/ipv4/tcp_fastopen")
tfo = File.read("/proc/sys/net/ipv4/tcp_fastopen").to_i
client_enable = 1
server_enable = 2
enable = client_enable | server_enable
(tfo & enable) == enable
else
false
end
end
def test_tfo_client_server
unless fastopen_ok?
warn "TCP Fast Open not enabled on this system (check kernel docs)"
return
end
addr = '127.0.0.1'
qlen = 1024
s = Kgio::TCPServer.new(addr, 0)
s.setsockopt(:TCP, Kgio::TCP_FASTOPEN, qlen)
port = s.local_address.ip_port
addr = Socket.pack_sockaddr_in(port, addr)
c = Kgio::Socket.new(:INET, :STREAM)
assert_nil c.kgio_fastopen("HELLO", addr)
a = s.accept
assert_equal "HELLO", a.read(5)
c.close
a.close
# ensure empty sends work
c = Kgio::Socket.new(:INET, :STREAM)
assert_nil c.kgio_fastopen("", addr)
a = s.accept
Thread.new { c.close }
assert_nil a.read(1)
a.close
# try a monster packet
buf = 'x' * (1024 * 1024 * 320)
c = Kgio::Socket.new(:INET, :STREAM)
thr = Thread.new do
a = s.accept
assert_equal buf.size, a.read(buf.size).size
a.close
end
assert_nil c.kgio_fastopen(buf, addr)
thr.join
c.close
# allow timeouts
c = Kgio::Socket.new(:INET, :STREAM)
c.setsockopt(:SOCKET, :SNDTIMEO, [ 0, 10 ].pack("l_l_"))
unsent = c.kgio_fastopen(buf, addr)
c.close
assert_equal s.accept.read.size + unsent.size, buf.size
end if defined?(Addrinfo) && defined?(Kgio::TCP_FASTOPEN)
end
|