Class: StunClient::RFC3489LifetimeDiscovery

Inherits:
Object
  • Object
show all
Defined in:
lib/stun-client/rfc3489/discovery/lifetime.rb

Overview

Helper to determine the Binding Lifetime of a NAT.

Note: This helper has not been tested yet. The reason is that I have not found a STUN server that supports the Response Address Attribute.

Instance Method Summary collapse

Constructor Details

#initialize(host = nil, port = nil, protocol = :IPv4) ⇒ RFC3489LifetimeDiscovery

Creates a new object for NAT lifetime discovery.

Raises:

  • (ArgumentError)


22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
# File 'lib/stun-client/rfc3489/discovery/lifetime.rb', line 22

def initialize host = nil, port = nil, protocol = :IPv4
  raise ArgumentError, 'Host must be a string' if host && (! host.is_a? String)
  raise ArgumentError, 'Port must be a integer' if port && (! host.is_a? Integer)

  case protocol
  when :IPv6
    @inet = Socket::AF_INET6
    @addr = '::'
  when :IPv4
    @inet = Socket::AF_INET
    @addr = '0.0.0.0'
  else
    raise ArgumentError, 'Unknown protocol'
  end

  @host = host
  @port = port
end

Instance Method Details

#alive_in_time?(time) ⇒ TrueClass, FalseClass

Checks if the NAT Binding Lifetime is less than the specified time.

For this, a STUN server is contacted to determine its own host and port. Afterwards it is waited accordingly. Then the STUN server is contacted again from another socket and instructed to send a STUN binding response to the previous socket. If the response arrives, the binding lifetime has not been exceeded. If no response is received, the binding lifetime is exceeded.

Raises:



85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
# File 'lib/stun-client/rfc3489/discovery/lifetime.rb', line 85

def alive_in_time? time
  raise 'The waiting time must be an integer.' if ! time.is_a? Integer

  socket_a = create_socket
  resp = do_query socket_a
  raise TimeoutError, 'UDP blocked.' if ! resp

  host = resp[:host]
  port = resp[:port].to_i

  # rubocop:disable Style/NumericLiterals
  raise 'The server has returned an invalid port.' if port.zero? || port > 65535
  # rubocop:enable Style/NumericLiterals

  sleep time

  socket_b = create_socket
  resp = do_query socket_b, response_ip: host, response_port: port

  return ( resp ? true : false )
end

#detect_binding_lifetime(max = 1200, min = 0) ⇒ Integer

Measures the Binding Lifetime of a NAT.



57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
# File 'lib/stun-client/rfc3489/discovery/lifetime.rb', line 57

def detect_binding_lifetime max = 1200, min = 0
  raise 'STUN server does not support response address.' if ! alive_in_time?(0)

  while min < max
    mid = (min + max) / 2

    if alive_in_time? mid
      min = mid + 1
    else
      max = mid - 1
    end
  end

  return max
end