Class: ReDNS::Resolver
- Inherits:
-
Object
- Object
- ReDNS::Resolver
- Defined in:
- lib/redns/resolver.rb
Class Method Summary collapse
-
.in_resolv_conf ⇒ Object
Class Methods ========================================================.
- .servers ⇒ Object
- .servers=(list) ⇒ Object
- .timeout ⇒ Object
- .timeout=(secs) ⇒ Object
Instance Method Summary collapse
- #a_for(name) ⇒ Object
- #bulk_query(type, names) ⇒ Object
-
#initialize(options = { }) {|_self| ... } ⇒ Resolver
constructor
Instance Methods =====================================================.
- #mx_for(name) ⇒ Object
- #ns_for(name) ⇒ Object
- #ptr_for(name) ⇒ Object
- #ptr_for_list(name) ⇒ Object
- #query(message = nil, server = nil, async = false) {|| ... } ⇒ Object
- #random_server ⇒ Object
- #response_for(id) ⇒ Object
- #responses ⇒ Object
- #reverse_addresses(ips) ⇒ Object
- #send_message(message, server = nil) ⇒ Object
- #servers ⇒ Object
- #servers=(list) ⇒ Object
- #simple_query(type, name) ⇒ Object
- #soa_for(name) ⇒ Object
- #timeout ⇒ Object
- #timeout=(secs) ⇒ Object
- #wait(_timeout = nil, &block) ⇒ Object
- #wait_for_responses(_timeout = nil, &block) ⇒ Object
Constructor Details
#initialize(options = { }) {|_self| ... } ⇒ Resolver
Instance Methods =====================================================
48 49 50 51 52 53 54 55 56 |
# File 'lib/redns/resolver.rb', line 48 def initialize( = { }, &block) @servers = self.class.servers.dup @responses = { } @socket = UDPSocket.new ReDNS::Support.io_set_nonblock(@socket) yield(self) if (block) end |
Class Method Details
.in_resolv_conf ⇒ Object
Class Methods ========================================================
14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 |
# File 'lib/redns/resolver.rb', line 14 def self.in_resolv_conf list = [ ] File.open("/etc/resolv.conf") do |fh| list = fh.readlines.collect { |l| l.chomp }.collect { |l| l.sub(/#.*/, '') } list.reject!{ |l| !l.sub!(/^\s*nameserver\s+/, '') } end list rescue Errno::ENOENT # /etc/resolv.conf may not be present on misconfigured or offline systems [ ] end |
.servers ⇒ Object
30 31 32 |
# File 'lib/redns/resolver.rb', line 30 def self.servers @servers ||= in_resolv_conf end |
.servers=(list) ⇒ Object
34 35 36 |
# File 'lib/redns/resolver.rb', line 34 def self.servers=(list) @servers = list end |
.timeout ⇒ Object
38 39 40 |
# File 'lib/redns/resolver.rb', line 38 def self.timeout @timeout end |
.timeout=(secs) ⇒ Object
42 43 44 |
# File 'lib/redns/resolver.rb', line 42 def self.timeout=(secs) @timeout = secs end |
Instance Method Details
#a_for(name) ⇒ Object
94 95 96 |
# File 'lib/redns/resolver.rb', line 94 def a_for(name) simple_query(:a, name) end |
#bulk_query(type, names) ⇒ Object
67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 |
# File 'lib/redns/resolver.rb', line 67 def bulk_query(type, names) results = { } ids = [ ] ||= ReDNS::Message.new q = (.questions[0] ||= ReDNS::Question.new) q.qtype = type names.each do |name| q.name = name.to_s .increment_id! ids.push(.id) () end wait_for_responses do |response, addr| results[response.questions[0].name.to_s] = response ids.delete(response.id) return results if (ids.empty?) end results end |
#mx_for(name) ⇒ Object
106 107 108 |
# File 'lib/redns/resolver.rb', line 106 def mx_for(name) simple_query(:mx, name) end |
#ns_for(name) ⇒ Object
98 99 100 101 102 103 104 |
# File 'lib/redns/resolver.rb', line 98 def ns_for(name) if (name.match(/^(\d+\.\d+\.\d+)\.\d+$/)) return simple_query(:ns, ReDNS::Support.addr_to_arpa($1)) end simple_query(:ns, name) end |
#ptr_for(name) ⇒ Object
110 111 112 |
# File 'lib/redns/resolver.rb', line 110 def ptr_for(name) simple_query(:ptr, ReDNS::Support.addr_to_arpa(name)) end |
#ptr_for_list(name) ⇒ Object
114 115 116 117 118 |
# File 'lib/redns/resolver.rb', line 114 def ptr_for_list(name) ips = [ ips ].flatten bulk_query(:ptr, ips.collect { |ip| ReDNS::Support.addr_to_arpa(ip) }) end |
#query(message = nil, server = nil, async = false) {|| ... } ⇒ Object
157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 |
# File 'lib/redns/resolver.rb', line 157 def query( = nil, server = nil, async = false, &block) # FUTURE: Fix the duplication here and in query_async ||= ReDNS::Message.new .questions[0] ||= ReDNS::Question.new yield(.questions[0]) if (block) (, server) unless (async) wait_for_responses do |r, addr| return r if (r.id == .id) end end end |
#random_server ⇒ Object
149 150 151 |
# File 'lib/redns/resolver.rb', line 149 def random_server @servers[rand(@servers.length)] end |
#response_for(id) ⇒ Object
174 175 176 |
# File 'lib/redns/resolver.rb', line 174 def response_for(id) @responses[id] end |
#responses ⇒ Object
178 179 180 |
# File 'lib/redns/resolver.rb', line 178 def responses @responses end |
#reverse_addresses(ips) ⇒ Object
124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 |
# File 'lib/redns/resolver.rb', line 124 def reverse_addresses(ips) map = ips.inject({ }) do |h, ip| h[ReDNS::Support.addr_to_arpa(ip)] = ip h end list = bulk_query(:ptr, map.keys) list.values.inject({ }) do |h, r| if (ip = map[r.questions[0].name.to_s]) h[ip] = (r.answers[0] and r.answers[0].rdata.to_s) end h end end |
#send_message(message, server = nil) ⇒ Object
153 154 155 |
# File 'lib/redns/resolver.rb', line 153 def (, server = nil) @socket.send(.serialize.to_s, 0, (server or random_server), 53) end |
#servers ⇒ Object
141 142 143 |
# File 'lib/redns/resolver.rb', line 141 def servers @servers end |
#servers=(list) ⇒ Object
145 146 147 |
# File 'lib/redns/resolver.rb', line 145 def servers=(list) @servers = list end |
#simple_query(type, name) ⇒ Object
58 59 60 61 62 63 64 65 |
# File 'lib/redns/resolver.rb', line 58 def simple_query(type, name) r = query do |q| q.qtype = type q.name = name.to_s end (r) end |
#soa_for(name) ⇒ Object
120 121 122 |
# File 'lib/redns/resolver.rb', line 120 def soa_for(name) simple_query(:soa, name) end |
#timeout ⇒ Object
182 183 184 |
# File 'lib/redns/resolver.rb', line 182 def timeout @timeout or self.class.timeout end |
#timeout=(secs) ⇒ Object
186 187 188 |
# File 'lib/redns/resolver.rb', line 186 def timeout=(secs) @timeout = secs end |
#wait(_timeout = nil, &block) ⇒ Object
190 191 192 |
# File 'lib/redns/resolver.rb', line 190 def wait(_timeout = nil, &block) wait_for_response(nil, _timeout, &block) end |
#wait_for_responses(_timeout = nil, &block) ⇒ Object
194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 |
# File 'lib/redns/resolver.rb', line 194 def wait_for_responses(_timeout = nil, &block) start = Time.now _timeout ||= timeout left = _timeout - Time.now.to_f + start.to_f while (left > 0) if (ready = IO.select([ @socket ], nil, nil, left)) ready[0].each do |socket| data = socket.recvfrom(1524) r = ReDNS::Message.new(ReDNS::Buffer.new(data[0])) yield(r, data[1]) if (block) @responses[r.id] = [ r, data[1] ] end end left = _timeout - Time.now.to_f + start.to_f end end |