pNet-DNS 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (71) hide show
  1. data/README +68 -0
  2. data/lib/Net/DNS.rb +879 -0
  3. data/lib/Net/DNS/Header.rb +303 -0
  4. data/lib/Net/DNS/Nameserver.rb +601 -0
  5. data/lib/Net/DNS/Packet.rb +851 -0
  6. data/lib/Net/DNS/Question.rb +117 -0
  7. data/lib/Net/DNS/RR.rb +630 -0
  8. data/lib/Net/DNS/RR/A.rb +103 -0
  9. data/lib/Net/DNS/RR/AAAA.rb +147 -0
  10. data/lib/Net/DNS/RR/AFSDB.rb +114 -0
  11. data/lib/Net/DNS/RR/CERT.rb +191 -0
  12. data/lib/Net/DNS/RR/CNAME.rb +89 -0
  13. data/lib/Net/DNS/RR/DNAME.rb +84 -0
  14. data/lib/Net/DNS/RR/EID.rb +70 -0
  15. data/lib/Net/DNS/RR/HINFO.rb +108 -0
  16. data/lib/Net/DNS/RR/ISDN.rb +118 -0
  17. data/lib/Net/DNS/RR/LOC.rb +341 -0
  18. data/lib/Net/DNS/RR/MB.rb +92 -0
  19. data/lib/Net/DNS/RR/MG.rb +96 -0
  20. data/lib/Net/DNS/RR/MINFO.rb +109 -0
  21. data/lib/Net/DNS/RR/MR.rb +92 -0
  22. data/lib/Net/DNS/RR/MX.rb +124 -0
  23. data/lib/Net/DNS/RR/NAPTR.rb +182 -0
  24. data/lib/Net/DNS/RR/NIMLOC.rb +70 -0
  25. data/lib/Net/DNS/RR/NS.rb +100 -0
  26. data/lib/Net/DNS/RR/NSAP.rb +273 -0
  27. data/lib/Net/DNS/RR/NULL.rb +68 -0
  28. data/lib/Net/DNS/RR/OPT.rb +251 -0
  29. data/lib/Net/DNS/RR/PTR.rb +93 -0
  30. data/lib/Net/DNS/RR/PX.rb +131 -0
  31. data/lib/Net/DNS/RR/RP.rb +108 -0
  32. data/lib/Net/DNS/RR/RT.rb +115 -0
  33. data/lib/Net/DNS/RR/SOA.rb +195 -0
  34. data/lib/Net/DNS/RR/SPF.rb +46 -0
  35. data/lib/Net/DNS/RR/SRV.rb +153 -0
  36. data/lib/Net/DNS/RR/SSHFP.rb +190 -0
  37. data/lib/Net/DNS/RR/TKEY.rb +219 -0
  38. data/lib/Net/DNS/RR/TSIG.rb +358 -0
  39. data/lib/Net/DNS/RR/TXT.rb +162 -0
  40. data/lib/Net/DNS/RR/UNKNOWN.rb +76 -0
  41. data/lib/Net/DNS/RR/X25.rb +90 -0
  42. data/lib/Net/DNS/Resolver.rb +2090 -0
  43. data/lib/Net/DNS/Resolver/Recurse.rb +478 -0
  44. data/lib/Net/DNS/Update.rb +189 -0
  45. data/test/custom.txt +4 -0
  46. data/test/resolv.conf +4 -0
  47. data/test/tc_escapedchars.rb +498 -0
  48. data/test/tc_header.rb +91 -0
  49. data/test/tc_inet6.rb +169 -0
  50. data/test/tc_misc.rb +137 -0
  51. data/test/tc_online.rb +236 -0
  52. data/test/tc_packet.rb +174 -0
  53. data/test/tc_packet_unique_push.rb +126 -0
  54. data/test/tc_question.rb +49 -0
  55. data/test/tc_recurse.rb +69 -0
  56. data/test/tc_res_env.rb +59 -0
  57. data/test/tc_res_file.rb +55 -0
  58. data/test/tc_res_opt.rb +135 -0
  59. data/test/tc_resolver.rb +102 -0
  60. data/test/tc_rr-opt.rb +40 -0
  61. data/test/tc_rr-rrsort.rb +116 -0
  62. data/test/tc_rr-txt.rb +138 -0
  63. data/test/tc_rr-unknown.rb +95 -0
  64. data/test/tc_rr.rb +246 -0
  65. data/test/tc_tcp.rb +34 -0
  66. data/test/tc_tkey.rb +115 -0
  67. data/test/tc_update.rb +226 -0
  68. data/test/ts_netdns.rb +17 -0
  69. data/test/ts_offline.rb +32 -0
  70. data/test/ts_online.rb +33 -0
  71. metadata +119 -0
@@ -0,0 +1,478 @@
1
+ # The contents of this file are subject to the Mozilla
2
+ # Public Licence Version 1.1 (the "Licence"); you may
3
+ # not use this file except in compliance with the
4
+ # Licence. You may obtain a copy of the Licence at
5
+ # http://www.mozilla.org/MPL
6
+ # Software distributed under the Licence is distributed
7
+ # on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND,
8
+ # either express or implied. See the Licence of the
9
+ # specific language governing rights and limitations
10
+ # under the Licence.
11
+ # The Original Code is pNet::DNS.
12
+ # The Initial Developer of the Original Code is
13
+ # Nominet UK (www.nominet.org.uk). Portions created by
14
+ # Nominet UK are Copyright (c) Nominet UK 2006.
15
+ # All rights reserved.
16
+ module Net
17
+ module DNS
18
+ class Resolver
19
+ #= NAME
20
+ #
21
+ #Net::DNS::Resolver::Recurse - Perform recursive dns lookups
22
+ #
23
+ #= SYNOPSIS
24
+ #
25
+ # require 'Net/DNS'
26
+ # res = Net::DNS::Resolver::Recurse.new
27
+ #
28
+ #= DESCRIPTION
29
+ #
30
+ #This module is a sub class of Net::DNS::Resolver. So the methods for
31
+ #Net::DNS::Resolver still work for this module as well. There are just a
32
+ #couple methods added
33
+ #
34
+ #=head1 AUTHOR
35
+ #
36
+ #Rob Brown, bbb@cpan.org
37
+ #
38
+ #=head1 SEE ALSO
39
+ #
40
+ #L<Net::DNS::Resolver>,
41
+ #
42
+ #=head1 COPYRIGHT
43
+ #
44
+ #Copyright (c) 2002, Rob Brown. All rights reserved.
45
+ #Portions Copyright (c) 2005, Olaf M Kolkman.
46
+ #Ruby version Copyright (c) 2006, AlexD (Nominet UK)
47
+ #
48
+ #This module is free software; you can redistribute
49
+ #it and/or modify it under the same terms as Perl itself.
50
+ #
51
+ #Example lookup process:
52
+ #
53
+ #[root@box root]# dig +trace www.rob.com.au.
54
+ #
55
+ #; <<>> DiG 9.2.0 <<>> +trace www.rob.com.au.
56
+ #;; global options: printcmd
57
+ #. 507343 IN NS C.ROOT-SERVERS.NET.
58
+ #. 507343 IN NS D.ROOT-SERVERS.NET.
59
+ #. 507343 IN NS E.ROOT-SERVERS.NET.
60
+ #. 507343 IN NS F.ROOT-SERVERS.NET.
61
+ #. 507343 IN NS G.ROOT-SERVERS.NET.
62
+ #. 507343 IN NS H.ROOT-SERVERS.NET.
63
+ #. 507343 IN NS I.ROOT-SERVERS.NET.
64
+ #. 507343 IN NS J.ROOT-SERVERS.NET.
65
+ #. 507343 IN NS K.ROOT-SERVERS.NET.
66
+ #. 507343 IN NS L.ROOT-SERVERS.NET.
67
+ #. 507343 IN NS M.ROOT-SERVERS.NET.
68
+ #. 507343 IN NS A.ROOT-SERVERS.NET.
69
+ #. 507343 IN NS B.ROOT-SERVERS.NET.
70
+ #;; Received 436 bytes from 127.0.0.1#53(127.0.0.1) in 9 ms
71
+ # ;;; But these should be hard coded as the hints
72
+ #
73
+ # ;;; Ask H.ROOT-SERVERS.NET gave:
74
+ #au. 172800 IN NS NS2.BERKELEY.EDU.
75
+ #au. 172800 IN NS NS1.BERKELEY.EDU.
76
+ #au. 172800 IN NS NS.UU.NET.
77
+ #au. 172800 IN NS BOX2.AUNIC.NET.
78
+ #au. 172800 IN NS SEC1.APNIC.NET.
79
+ #au. 172800 IN NS SEC3.APNIC.NET.
80
+ #;; Received 300 bytes from 128.63.2.53#53(H.ROOT-SERVERS.NET) in 322 ms
81
+ # ;;; A little closer than before
82
+ #
83
+ # ;;; Ask NS2.BERKELEY.EDU gave:
84
+ #com.au. 259200 IN NS ns4.ausregistry.net.
85
+ #com.au. 259200 IN NS dns1.telstra.net.
86
+ #com.au. 259200 IN NS au2ld.CSIRO.au.
87
+ #com.au. 259200 IN NS audns01.syd.optus.net.
88
+ #com.au. 259200 IN NS ns.ripe.net.
89
+ #com.au. 259200 IN NS ns1.ausregistry.net.
90
+ #com.au. 259200 IN NS ns2.ausregistry.net.
91
+ #com.au. 259200 IN NS ns3.ausregistry.net.
92
+ #com.au. 259200 IN NS ns3.melbourneit.com.
93
+ #;; Received 387 bytes from 128.32.206.12#53(NS2.BERKELEY.EDU) in 10312 ms
94
+ # ;;; A little closer than before
95
+ #
96
+ # ;;; Ask ns4.ausregistry.net gave:
97
+ #com.au. 259200 IN NS ns1.ausregistry.net.
98
+ #com.au. 259200 IN NS ns2.ausregistry.net.
99
+ #com.au. 259200 IN NS ns3.ausregistry.net.
100
+ #com.au. 259200 IN NS ns4.ausregistry.net.
101
+ #com.au. 259200 IN NS ns3.melbourneit.com.
102
+ #com.au. 259200 IN NS dns1.telstra.net.
103
+ #com.au. 259200 IN NS au2ld.CSIRO.au.
104
+ #com.au. 259200 IN NS ns.ripe.net.
105
+ #com.au. 259200 IN NS audns01.syd.optus.net.
106
+ #;; Received 259 bytes from 137.39.1.3#53(ns4.ausregistry.net) in 606 ms
107
+ # ;;; Uh... yeah... I already knew this
108
+ # ;;; from what NS2.BERKELEY.EDU told me.
109
+ # ;;; ns4.ausregistry.net must have brain damage
110
+ #
111
+ # ;;; Ask ns1.ausregistry.net gave:
112
+ #rob.com.au. 86400 IN NS sy-dns02.tmns.net.au.
113
+ #rob.com.au. 86400 IN NS sy-dns01.tmns.net.au.
114
+ #;; Received 87 bytes from 203.18.56.41#53(ns1.ausregistry.net) in 372 ms
115
+ # ;;; Ah, much better. Something more useful.
116
+ #
117
+ # ;;; Ask sy-dns02.tmns.net.au gave:
118
+ #www.rob.com.au. 7200 IN A 139.134.5.123
119
+ #rob.com.au. 7200 IN NS sy-dns01.tmns.net.au.
120
+ #rob.com.au. 7200 IN NS sy-dns02.tmns.net.au.
121
+ #;; Received 135 bytes from 139.134.2.18#53(sy-dns02.tmns.net.au) in 525 ms
122
+ # ;;; FINALLY, THE ANSWER!
123
+ class Recurse < Resolver
124
+ attr_accessor :nameservers, :callback, :recurse
125
+ attr_reader :hints
126
+ #Initialize the hint servers. Recursive queries need a starting name
127
+ #server to work off of. This method takes a list of IP addresses to use
128
+ #as the starting servers. These name servers should be authoritative for
129
+ #the root (.) zone.
130
+ #
131
+ # res.hints=(ips)
132
+ #
133
+ #If no hints are passed, the default nameserver is asked for the hints.
134
+ #Normally these IPs can be obtained from the following location:
135
+ #
136
+ # ftp://ftp.internic.net/domain/named.root
137
+ #
138
+ def hints=(hints)
139
+ print ";; hints(#{hints.inspect})\n" if @debug
140
+ if (!hints && @nameservers)
141
+ @hints=(@nameservers)
142
+ else
143
+ @nameservers=(hints)
144
+ end
145
+ print ";; verifying (root) zone...\n" if @debug
146
+ # bind always asks one of the hint servers
147
+ # for who it thinks is authoritative for
148
+ # the (root) zone as a sanity check.
149
+ # Nice idea.
150
+
151
+ recurse=(1)
152
+ packet=query(".", "NS", "IN")
153
+
154
+ hints = Hash.new
155
+ if (packet)
156
+ if (ans = packet.answer)
157
+ # foreach my $rr (@ans)
158
+ ans.each do |rr|
159
+ if (rr.name =~ /^\.?$/ and
160
+ rr.type == "NS")
161
+ # Found root authority
162
+ server = rr.rdatastr.downcase
163
+ server.sub!(/\.$/,"")
164
+ print ";; FOUND HINT: #{server}\n" if @debug
165
+ hints[server] = []
166
+ end
167
+ end
168
+ # foreach my $rr ($packet->additional) {
169
+ packet.additional.each do |rr|
170
+ print ";; ADDITIONAL: ",rr.inspect,"\n" if @debug
171
+ if (server = rr.name.downcase)
172
+ if ( rr.type == "A")
173
+ #print ";; ADDITIONAL HELP: $server -> [".$rr->rdatastr."]\n" if $self->{'debug'};
174
+ if (hints[server]!=nil)
175
+ print ";; STORING IP: #{server} IN A ",rr.rdatastr,"\n" if @debug
176
+ hints[server]=rr.rdatastr
177
+ end
178
+ end
179
+ if ( rr.type == "AAAA")
180
+ #print ";; ADDITIONAL HELP: $server -> [".$rr->rdatastr."]\n" if $self->{'debug'};
181
+ if (hints[server])
182
+ print ";; STORING IP6: #{server} IN AAAA ",rr.rdatastr,"\n" if @debug
183
+ hints[server]=rr.rdatastr
184
+ end
185
+ end
186
+
187
+ end
188
+ end
189
+ end
190
+ # foreach my $server (keys %hints) {
191
+ hints.keys.each do |server|
192
+ if (!hints[server] || hints[server]==[])
193
+ # Wipe the servers without lookups
194
+ hints.delete(server)
195
+ end
196
+ end
197
+ @hints = hints
198
+ else
199
+ @hints = []
200
+ end
201
+ if (@hints.size > 0)
202
+ if (@debug)
203
+ print ";; USING THE FOLLOWING HINT IPS:\n";
204
+ # foreach my $ips (values %{ $self->{'hints'} }) {
205
+ @hints.values.each do |ips|
206
+ # foreach my $server (@{ $ips }) {
207
+ ips.each do |server|
208
+ print ";; #{server}\n";
209
+ end
210
+ end
211
+ end
212
+ else
213
+ warn "Server ["+(@nameservers)[0]+"] did not give answers"
214
+ end
215
+
216
+ # Disable recursion flag.
217
+ @recurse=(0)
218
+
219
+ # return $self->nameservers( map { @{ $_ } } values %{ $self->{'hints'} } );
220
+ @nameservers = @hints.values
221
+ return @nameservers
222
+ end
223
+
224
+
225
+ #This method is takes a code reference, which is then invoked each time a
226
+ #packet is received during the recursive lookup. For example to emulate
227
+ #dig's C<+trace> function:
228
+ #
229
+ # res.recursion_callback(Proc.new { |packet|
230
+ # print packet.additional.inspect
231
+ #
232
+ # print";; Received %d bytes from %s\n\n",
233
+ # packetanswersize,
234
+ # packet.answerfrom);
235
+ # })
236
+ #
237
+ def recursion_callback=(sub)
238
+ # if (sub && UNIVERSAL::isa(sub, 'CODE'))
239
+ @callback = sub
240
+ # end
241
+ end
242
+
243
+ def recursion_callback
244
+ return @callback
245
+ end
246
+
247
+
248
+ #
249
+ #This method is much like the normal query() method except it disables
250
+ #the recurse flag in the packet and explicitly performs the recursion.
251
+ #
252
+ # packet = res.query_dorecursion( "www.netscape.com.", "A")
253
+ #
254
+ #
255
+ def query_dorecursion(*args)
256
+
257
+ # Make sure the hint servers are initialized.
258
+ @hints=Hash.new unless @hints
259
+ @recurse=(0)
260
+ # Make sure the authority cache is clean.
261
+ # It is only used to store A and AAAA records of
262
+ # the suposedly authoritative name servers.
263
+ @authority_cache = Hash.new
264
+
265
+ # Obtain real question Net::DNS::Packet
266
+ query_packet = make_query_packet(args)
267
+
268
+ # Seed name servers with hints
269
+ return _dorecursion( query_packet, ".", @hints, 0)
270
+ end
271
+
272
+ def _dorecursion(query_packet, known_zone, known_authorities, depth)
273
+ cache = @authority_cache
274
+
275
+ # die "Recursion too deep, aborting..." if $depth > 255;
276
+ if ( depth > 255 )
277
+ print ";; _dorecursion() Recursion too deep, aborting...\n" if @debug
278
+ @errorstring="Recursion too deep, aborted"
279
+ return nil
280
+ end
281
+
282
+ known_zone.sub!(/\.*$/, ".")
283
+
284
+ # Get IPs from authorities
285
+ ns = []
286
+ # foreach my $ns (keys %{ $known_authorities }) {
287
+ known_authorities.keys.each do |ns_rec|
288
+ if (known_authorities[ns_rec] != nil && known_authorities[ns_rec] != [] )
289
+ cache[ns_rec] = known_authorities[ns_rec]
290
+ ns.push(cache[ns_rec])
291
+ elsif (cache[ns_rec]!=nil && cache[ns_rec]!=[])
292
+ known_authorities[ns_rec] = cache[ns_rec]
293
+ ns.push(cache[ns_rec])
294
+ end
295
+ end
296
+
297
+ if (ns.length == 0)
298
+ found_auth = 0
299
+ if (@debug)
300
+ print ";; _dorecursion() Failed to extract nameserver IPs:\n";
301
+ print known_authorities.inspect + cache.inspect + "\n"
302
+ end
303
+ # foreach my $ns (keys %{ $known_authorities }) {
304
+ known_authorities.keys.each do |ns_rec|
305
+ if (known_authorities[ns_rec]==nil || known_authorities[ns_rec]==[])
306
+ print ";; _dorecursion() Manual lookup for authority [#{ns_rec}]\n" if @debug
307
+
308
+ auth_packet=nil
309
+ ans=[]
310
+
311
+ # Don't query for V6 if its not there.
312
+ if (! @force_v4)
313
+ auth_packet = _dorecursion(make_query_packet([ns_rec,"AAAA"]), # packet
314
+ ".", # known_zone
315
+ @hints, # known_authorities
316
+ depth+1); # depth
317
+ ans = auth_packet.answer if auth_packet
318
+ end
319
+
320
+ auth_packet = _dorecursion(make_query_packet([ns_rec,"A"]), # packet
321
+ ".", # known_zone
322
+ @hints, # known_authorities
323
+ depth+1); # depth
324
+
325
+ ans.push(auth_packet.answer ) if auth_packet
326
+
327
+ if ( ans.length > 0 )
328
+ print ";; _dorecursion() Answers found for [#{ns_rec}]\n" if @debug
329
+ # foreach my $rr (@ans) {
330
+ ans.each do |rr_arr|
331
+ rr_arr.each do |rr|
332
+ print ";; RR:" + rr.inspect + "\n" if @debug
333
+ if (rr.type == "CNAME")
334
+ # Follow CNAME
335
+ server = rr.name.downcase
336
+ if (server)
337
+ server.sub!(/\.*$/, ".")
338
+ if (server == ns_rec)
339
+ cname = rr.rdatastr.downcase
340
+ cname.sub!(/\.*$/, ".")
341
+ print ";; _dorecursion() Following CNAME ns [#{ns_rec}] -> [#{cname}]\n" if @debug
342
+ known_authorities[cname] ||= []
343
+ known_authorities.delete[ns_rec]
344
+ next
345
+ end
346
+ end
347
+ elsif (rr.type == "A" || rr.type == "AAAA" )
348
+ server = rr.name.downcase
349
+ if (server)
350
+ server.sub!(/\.*$/, ".")
351
+ if (known_authorities[server]!=nil)
352
+ ip = rr.rdatastr
353
+ print ";; _dorecursion() Found ns: #{server} IN A #{ip}\n" if @debug
354
+ cache[server] = known_authorities[server]
355
+ cache[ns_rec].push(ip)
356
+ found_auth+=1
357
+ next
358
+ end
359
+ end
360
+ end
361
+ print ";; _dorecursion() Ignoring useless answer: " + rr.inspect + "\n" if @debug
362
+ end
363
+ end
364
+ else
365
+ print ";; _dorecursion() Could not find A records for [#{ns_rec}]\n" if @debug
366
+ end
367
+ end
368
+ end
369
+ if (found_auth > 0)
370
+ print ";; _dorecursion() Found #{found_auth} new NS authorities...\n" if @debug
371
+ return _dorecursion( query_packet, known_zone, known_authorities, depth+1)
372
+ end
373
+ print ";; _dorecursion() No authority information could be obtained.\n" if @debug
374
+ return nil
375
+ end
376
+
377
+ # Cut the deck of IPs in a random place.
378
+ print ";; _dorecursion() cutting deck of (" + ns.length.to_s + ") authorities...\n" if @debug
379
+ splitpos = rand(ns.length)
380
+ start = ns[0, splitpos]
381
+ endarr = ns[splitpos, ns.length - splitpos]
382
+ ns = endarr + start
383
+
384
+
385
+ ns.each do |levelns|
386
+ print ";; _dorecursion() Trying nameserver [#{levelns}]\n" if @debug
387
+ @nameservers=(levelns)
388
+
389
+ packet = send( query_packet )
390
+ if (packet)
391
+
392
+ if (@callback)
393
+ @callback.call(packet)
394
+ end
395
+
396
+ of = nil
397
+ print ";; _dorecursion() Response received from [" + @answerfrom + "]\n" if @debug
398
+ status = packet.header.rcode
399
+ authority = packet.authority
400
+ if (status)
401
+ if (status == "NXDOMAIN")
402
+ # I guess NXDOMAIN is the best we'll ever get
403
+ print ";; _dorecursion() returning NXDOMAIN\n" if @debug
404
+ return packet
405
+ elsif (packet.answer.length > 0)
406
+ print ";; _dorecursion() Answers were found.\n" if @debug
407
+ return packet
408
+ elsif (authority.length > 0)
409
+ auth = Hash.new
410
+ # foreach my $rr (@authority) {
411
+ authority.each do |rr|
412
+ if (rr.type =~ /^(NS|SOA)$/)
413
+ server = (rr.type == "NS" ? rr.nsdname : rr.mname).downcase
414
+ server.sub!(/\.*$/, ".")
415
+ of = rr.name.downcase
416
+ of.sub!(/\.*$/, ".")
417
+ print ";; _dorecursion() Received authority [#{of}] [" + rr.type() + "] [#{server}]\n" if @debug
418
+ if (of.length <= known_zone.length)
419
+ print ";; _dorecursion() Deadbeat name server did not provide new information.\n" if @debug
420
+ next
421
+ elsif (of =~ /#{known_zone}/)
422
+ print ";; _dorecursion() FOUND closer authority for [#{of}] at [#{server}].\n" if @debug
423
+ auth[server] ||= []
424
+ else
425
+ print ";; _dorecursion() Confused name server [" + @answerfrom + "] thinks [#{of}] is closer than [#{known_zone}]?\n" if @debug
426
+ last
427
+ end
428
+ else
429
+ print ";; _dorecursion() Ignoring NON NS entry found in authority section: " + rr.inspect + "\n" if @debug
430
+ end
431
+ end
432
+ # foreach my $rr ($packet->additional)
433
+ packet.additional.each do |rr|
434
+ if (rr.type == "CNAME")
435
+ # Store this CNAME into %auth too
436
+ server = rr.name.downcase
437
+ if (server)
438
+ server.sub!(/\.*$/, ".")
439
+ if (auth[server]!=nil && auth[server]!=[])
440
+ cname = rr.rdatastr.downcase
441
+ cname.sub!(/\.*$/, ".")
442
+ print ";; _dorecursion() FOUND CNAME authority: " + rr.string + "\n" if @debug
443
+ auth[cname] ||= []
444
+ auth[server] = auth[cname]
445
+ next
446
+ end
447
+
448
+ end
449
+ elsif (rr.type == "A" || rr.type == "AAAA")
450
+ server = rr.name.downcase
451
+ if (server)
452
+ server.sub!(/\.*$/, ".")
453
+ if (auth[server]!=nil)
454
+ print ";; _dorecursion() STORING: #{server} IN A " + rr.rdatastr + "\n" if @debug && rr.type == "A"
455
+ print ";; _dorecursion() STORING: #{server} IN AAAA " + rr.rdatastr + "\n" if @debug && rr.type == "AAAA"
456
+ auth[server].push(rr.rdatastr)
457
+ next
458
+ end
459
+ end
460
+ end
461
+ print ";; _dorecursion() Ignoring useless: " + rr.inspect + "\n" if @debug
462
+ end
463
+ if (of =~ /#{known_zone}/)
464
+ return _dorecursion( query_packet, of, auth, depth+1 )
465
+ else
466
+ return _dorecursion( query_packet, known_zone, known_authorities, depth+1 )
467
+ end
468
+ end
469
+ end
470
+ end
471
+ end
472
+
473
+ return nil
474
+ end
475
+ end
476
+ end
477
+ end
478
+ end