Class: ReDNS::Connection
- Inherits:
-
EventMachine::Connection
- Object
- EventMachine::Connection
- ReDNS::Connection
- Includes:
- EventMachine::Deferrable
- Defined in:
- lib/redns/connection.rb
Constant Summary collapse
- DEFAULT_TIMEOUT =
Constants ============================================================
5
- DEFAULT_ATTEMPTS =
2
- SEQUENCE_LIMIT =
0x10000
Instance Attribute Summary collapse
-
#attempts ⇒ Object
Properties ===========================================================.
-
#timeout ⇒ Object
Properties ===========================================================.
Class Method Summary collapse
-
.instance {|connection| ... } ⇒ Object
Returns a new instance of a reactor-bound resolver.
Instance Method Summary collapse
-
#nameservers ⇒ Object
Returns the configured list of nameservers as an Array.
-
#nameservers=(*list) ⇒ Object
Configure the nameservers to use.
-
#port ⇒ Object
Returns the current port in use.
-
#post_init ⇒ Object
EventMachine: Called after the connection is initialized.
-
#random_nameserver ⇒ Object
Picks a random nameserver from the configured list=.
-
#receive_data(data) ⇒ Object
EventMachine: Called when data is received on the active socket.
-
#resolve(query, type = nil, filter = true, &callback) ⇒ Object
Resolves a given query and optional type asynchronously, yielding to the callback function with either the answers or nil if a timeout or error occurred.
-
#unbind ⇒ Object
EventMachine: Called when the connection is closed.
Instance Attribute Details
#attempts ⇒ Object
Properties ===========================================================
12 13 14 |
# File 'lib/redns/connection.rb', line 12 def attempts @attempts end |
#timeout ⇒ Object
Properties ===========================================================
12 13 14 |
# File 'lib/redns/connection.rb', line 12 def timeout @timeout end |
Class Method Details
.instance {|connection| ... } ⇒ Object
Returns a new instance of a reactor-bound resolver. If a block is given, the instance is supplied for customization purposes.
22 23 24 25 26 27 28 29 30 31 32 |
# File 'lib/redns/connection.rb', line 22 def self.instance connection = EventMachine.open_datagram_socket( ReDNS::Support.bind_all_addr, 0, self ) yield(connection) if (block_given?) connection end |
Instance Method Details
#nameservers ⇒ Object
Returns the configured list of nameservers as an Array. If not configured specifically, will look in the resolver configuration file, typically /etc/resolv.conf for which servers to use.
53 54 55 |
# File 'lib/redns/connection.rb', line 53 def nameservers @nameservers ||= ReDNS::Support.default_nameservers end |
#nameservers=(*list) ⇒ Object
Configure the nameservers to use. Supplied value can be either a string containing one IP address, an Array containing multiple IP addresses, or nil which reverts to defaults.
60 61 62 63 |
# File 'lib/redns/connection.rb', line 60 def nameservers=(*list) @nameservers = list.flatten.compact @nameservers = nil if (list.empty?) end |
#port ⇒ Object
Returns the current port in use.
71 72 73 |
# File 'lib/redns/connection.rb', line 71 def port Socket.unpack_sockaddr_in(get_sockname)[0] end |
#post_init ⇒ Object
EventMachine: Called after the connection is initialized.
113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 |
# File 'lib/redns/connection.rb', line 113 def post_init # Sequence numbers do not have to be cryptographically secure, but having # a healthy amount of randomness is a good thing. @sequence = (rand(SEQUENCE_LIMIT) ^ (object_id ^ (Time.now.to_f * SEQUENCE_LIMIT).to_i)) % SEQUENCE_LIMIT # Callback tracking is done by matching response IDs in a lookup table @callback = { } @timeout ||= DEFAULT_TIMEOUT @attempts ||= DEFAULT_ATTEMPTS EventMachine.add_periodic_timer(1) do check_for_timeouts! end end |
#random_nameserver ⇒ Object
Picks a random nameserver from the configured list=
66 67 68 |
# File 'lib/redns/connection.rb', line 66 def random_nameserver nameservers[rand(nameservers.length)] end |
#receive_data(data) ⇒ Object
EventMachine: Called when data is received on the active socket.
130 131 132 133 134 135 136 137 138 139 140 141 142 |
# File 'lib/redns/connection.rb', line 130 def receive_data(data) = ReDNS::Message.new(ReDNS::Buffer.new(data)) if (callback = @callback.delete(.id)) answers = .answers if (type = callback[:filter_by_type]) answers = answers.select { |a| a.rtype == type } end callback[:callback].call(answers) end end |
#resolve(query, type = nil, filter = true, &callback) ⇒ Object
Resolves a given query and optional type asynchronously, yielding to the callback function with either the answers or nil if a timeout or error occurred. The filter option will restrict responses ot those matching the requested type if true, or return all responses if false. The default is to filter responses.
80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 |
# File 'lib/redns/connection.rb', line 80 def resolve(query, type = nil, filter = true, &callback) = ReDNS::Message.question(query, type) do |m| m.id = @sequence end = .serialize.to_s target_nameserver = random_nameserver result = send_datagram( , target_nameserver, ReDNS::Support.dns_port ) if (result > 0) @callback[@sequence] = { :serialized_message => , :type => type, :filter_by_type => (type == :any || !filter) ? false : type, :nameserver => target_nameserver, :attempts => self.attempts - 1, :callback => callback, :at => Time.now } else callback.call(nil) end @sequence += 1 @sequence %= SEQUENCE_LIMIT end |
#unbind ⇒ Object
EventMachine: Called when the connection is closed.
145 146 |
# File 'lib/redns/connection.rb', line 145 def unbind end |