File: test_tfo.rb

package info (click to toggle)
ruby-kgio 2.11.2-2
  • links: PTS, VCS
  • area: main
  • in suites: bookworm, bullseye, forky, sid, trixie
  • size: 504 kB
  • sloc: ruby: 2,779; ansic: 2,017; sh: 32; makefile: 5
file content (70 lines) | stat: -rw-r--r-- 1,887 bytes parent folder | download | duplicates (3)
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