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/
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
|