dnsruby 1.40 → 1.41
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/demo/example_recurse.rb +4 -1
- data/lib/Dnsruby/DNS.rb +1 -1
- data/lib/Dnsruby/Recursor.rb +129 -118
- data/lib/Dnsruby/Resolver.rb +83 -60
- data/lib/Dnsruby/SingleResolver.rb +1 -0
- data/lib/Dnsruby/dnssec.rb +4 -4
- data/lib/Dnsruby/resource/DNSKEY.rb +42 -7
- data/lib/Dnsruby/resource/IN.rb +40 -7
- data/lib/Dnsruby/resource/NSEC3.rb +1 -1
- data/lib/Dnsruby/resource/generic.rb +8 -0
- data/lib/Dnsruby/resource/resource.rb +17 -5
- data/lib/Dnsruby/single_verifier.rb +3 -2
- data/lib/Dnsruby/zone_reader.rb +2 -2
- data/test/tc_cache.rb +33 -11
- data/test/tc_ipseckey.rb +1 -0
- data/test/tc_naptr.rb +48 -0
- data/test/tc_resolver.rb +7 -8
- data/test/tc_rr.rb +1 -1
- data/test/tc_rrsig.rb +5 -0
- data/test/tc_update.rb +2 -2
- data/test/tc_verifier.rb +19 -2
- data/test/ts_offline.rb +1 -0
- data/test/ts_online.rb +2 -1
- metadata +7 -6
data/demo/example_recurse.rb
CHANGED
@@ -21,6 +21,9 @@ require 'dnsruby'
|
|
21
21
|
|
22
22
|
res = Dnsruby::Recursor.new
|
23
23
|
Dnsruby::TheLog.level = Logger::DEBUG
|
24
|
+
name, type, klass = ARGV
|
25
|
+
type ||= "A"
|
26
|
+
klass ||= "IN"
|
24
27
|
res.hints=("198.41.0.4") # A.ROOT-SERVER.NET.
|
25
|
-
packet = res.
|
28
|
+
packet = res.query(name, type, klass)
|
26
29
|
print packet.to_s
|
data/lib/Dnsruby/DNS.rb
CHANGED
@@ -284,7 +284,7 @@ module Dnsruby
|
|
284
284
|
msg.add_question(candidate, type, klass)
|
285
285
|
@resolver.send_async(msg, q)
|
286
286
|
id, ret, exception = q.pop
|
287
|
-
if (exception == nil && ret.rcode == RCode.NOERROR)
|
287
|
+
if (exception == nil && ret && ret.rcode == RCode.NOERROR)
|
288
288
|
return ret, ret.question[0].qname
|
289
289
|
end
|
290
290
|
end
|
data/lib/Dnsruby/Recursor.rb
CHANGED
@@ -14,102 +14,102 @@
|
|
14
14
|
#limitations under the License.
|
15
15
|
#++
|
16
16
|
module Dnsruby
|
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
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
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
|
-
|
111
|
-
|
112
|
-
|
17
|
+
#Dnsruby::Recursor - Perform recursive dns lookups
|
18
|
+
#
|
19
|
+
# require 'Dnsruby'
|
20
|
+
# rec = Dnsruby::Recursor.new()
|
21
|
+
# answer = rec.recurse("rob.com.au")
|
22
|
+
#
|
23
|
+
#This module uses a Dnsruby::Resolver to perform recursive queries.
|
24
|
+
#
|
25
|
+
#=== AUTHOR
|
26
|
+
#
|
27
|
+
#Rob Brown, bbb@cpan.org
|
28
|
+
#Alex Dalitz, alexd@nominet.org.uk
|
29
|
+
#
|
30
|
+
#=== SEE ALSO
|
31
|
+
#
|
32
|
+
#Dnsruby::Resolver,
|
33
|
+
#
|
34
|
+
#=== COPYRIGHT
|
35
|
+
#
|
36
|
+
#Copyright (c) 2002, Rob Brown. All rights reserved.
|
37
|
+
#Portions Copyright (c) 2005, Olaf M Kolkman.
|
38
|
+
#Ruby version with caching and validation Copyright (c) 2008, AlexD (Nominet UK)
|
39
|
+
#
|
40
|
+
#Example lookup process:
|
41
|
+
#
|
42
|
+
#[root@box root]# dig +trace www.rob.com.au.
|
43
|
+
#
|
44
|
+
#; <<>> DiG 9.2.0 <<>> +trace www.rob.com.au.
|
45
|
+
#;; global options: printcmd
|
46
|
+
#. 507343 IN NS C.ROOT-SERVERS.NET.
|
47
|
+
#. 507343 IN NS D.ROOT-SERVERS.NET.
|
48
|
+
#. 507343 IN NS E.ROOT-SERVERS.NET.
|
49
|
+
#. 507343 IN NS F.ROOT-SERVERS.NET.
|
50
|
+
#. 507343 IN NS G.ROOT-SERVERS.NET.
|
51
|
+
#. 507343 IN NS H.ROOT-SERVERS.NET.
|
52
|
+
#. 507343 IN NS I.ROOT-SERVERS.NET.
|
53
|
+
#. 507343 IN NS J.ROOT-SERVERS.NET.
|
54
|
+
#. 507343 IN NS K.ROOT-SERVERS.NET.
|
55
|
+
#. 507343 IN NS L.ROOT-SERVERS.NET.
|
56
|
+
#. 507343 IN NS M.ROOT-SERVERS.NET.
|
57
|
+
#. 507343 IN NS A.ROOT-SERVERS.NET.
|
58
|
+
#. 507343 IN NS B.ROOT-SERVERS.NET.
|
59
|
+
#;; Received 436 bytes from 127.0.0.1#53(127.0.0.1) in 9 ms
|
60
|
+
# ;;; But these should be hard coded as the hints
|
61
|
+
#
|
62
|
+
# ;;; Ask H.ROOT-SERVERS.NET gave:
|
63
|
+
#au. 172800 IN NS NS2.BERKELEY.EDU.
|
64
|
+
#au. 172800 IN NS NS1.BERKELEY.EDU.
|
65
|
+
#au. 172800 IN NS NS.UU.NET.
|
66
|
+
#au. 172800 IN NS BOX2.AUNIC.NET.
|
67
|
+
#au. 172800 IN NS SEC1.APNIC.NET.
|
68
|
+
#au. 172800 IN NS SEC3.APNIC.NET.
|
69
|
+
#;; Received 300 bytes from 128.63.2.53#53(H.ROOT-SERVERS.NET) in 322 ms
|
70
|
+
# ;;; A little closer than before
|
71
|
+
#
|
72
|
+
# ;;; Ask NS2.BERKELEY.EDU gave:
|
73
|
+
#com.au. 259200 IN NS ns4.ausregistry.net.
|
74
|
+
#com.au. 259200 IN NS dns1.telstra.net.
|
75
|
+
#com.au. 259200 IN NS au2ld.CSIRO.au.
|
76
|
+
#com.au. 259200 IN NS audns01.syd.optus.net.
|
77
|
+
#com.au. 259200 IN NS ns.ripe.net.
|
78
|
+
#com.au. 259200 IN NS ns1.ausregistry.net.
|
79
|
+
#com.au. 259200 IN NS ns2.ausregistry.net.
|
80
|
+
#com.au. 259200 IN NS ns3.ausregistry.net.
|
81
|
+
#com.au. 259200 IN NS ns3.melbourneit.com.
|
82
|
+
#;; Received 387 bytes from 128.32.206.12#53(NS2.BERKELEY.EDU) in 10312 ms
|
83
|
+
# ;;; A little closer than before
|
84
|
+
#
|
85
|
+
# ;;; Ask ns4.ausregistry.net gave:
|
86
|
+
#com.au. 259200 IN NS ns1.ausregistry.net.
|
87
|
+
#com.au. 259200 IN NS ns2.ausregistry.net.
|
88
|
+
#com.au. 259200 IN NS ns3.ausregistry.net.
|
89
|
+
#com.au. 259200 IN NS ns4.ausregistry.net.
|
90
|
+
#com.au. 259200 IN NS ns3.melbourneit.com.
|
91
|
+
#com.au. 259200 IN NS dns1.telstra.net.
|
92
|
+
#com.au. 259200 IN NS au2ld.CSIRO.au.
|
93
|
+
#com.au. 259200 IN NS ns.ripe.net.
|
94
|
+
#com.au. 259200 IN NS audns01.syd.optus.net.
|
95
|
+
#;; Received 259 bytes from 137.39.1.3#53(ns4.ausregistry.net) in 606 ms
|
96
|
+
# ;;; Uh... yeah... I already knew this
|
97
|
+
# ;;; from what NS2.BERKELEY.EDU told me.
|
98
|
+
# ;;; ns4.ausregistry.net must have brain damage
|
99
|
+
#
|
100
|
+
# ;;; Ask ns1.ausregistry.net gave:
|
101
|
+
#rob.com.au. 86400 IN NS sy-dns02.tmns.net.au.
|
102
|
+
#rob.com.au. 86400 IN NS sy-dns01.tmns.net.au.
|
103
|
+
#;; Received 87 bytes from 203.18.56.41#53(ns1.ausregistry.net) in 372 ms
|
104
|
+
# ;;; Ah, much better. Something more useful.
|
105
|
+
#
|
106
|
+
# ;;; Ask sy-dns02.tmns.net.au gave:
|
107
|
+
#www.rob.com.au. 7200 IN A 139.134.5.123
|
108
|
+
#rob.com.au. 7200 IN NS sy-dns01.tmns.net.au.
|
109
|
+
#rob.com.au. 7200 IN NS sy-dns02.tmns.net.au.
|
110
|
+
#;; Received 135 bytes from 139.134.2.18#53(sy-dns02.tmns.net.au) in 525 ms
|
111
|
+
# ;;; FINALLY, THE ANSWER!
|
112
|
+
# Now,DNSSEC validation is performed (unless disabled).
|
113
113
|
class Recursor
|
114
114
|
class AddressCache # :nodoc: all
|
115
115
|
# Like an array, but stores the expiration of each record.
|
@@ -196,7 +196,7 @@ module Dnsruby
|
|
196
196
|
# Nice idea.
|
197
197
|
|
198
198
|
resolver.recurse=(1)
|
199
|
-
packet=resolver.
|
199
|
+
packet=resolver.query_no_validation_or_recursion(".", "NS", "IN")
|
200
200
|
hints = Hash.new
|
201
201
|
if (packet)
|
202
202
|
if (ans = packet.answer)
|
@@ -289,9 +289,9 @@ module Dnsruby
|
|
289
289
|
end
|
290
290
|
|
291
291
|
def Recursor.clear_caches(resolver = Resolver.new)
|
292
|
-
|
293
|
-
|
294
|
-
|
292
|
+
Recursor.set_hints(Hash.new, resolver)
|
293
|
+
@@zones_cache = Hash.new # key zone_name, values Hash of servers and AddressCaches
|
294
|
+
@@zones_cache["."] = @@hints
|
295
295
|
end
|
296
296
|
|
297
297
|
def query_no_validation_or_recursion(name, type=Types.A, klass=Classes.IN) # :nodoc: all
|
@@ -423,7 +423,7 @@ module Dnsruby
|
|
423
423
|
|
424
424
|
if (ns.length == 0)
|
425
425
|
found_auth = 0
|
426
|
-
# @@mutex.synchronize { # @TODO@ Lock access to @@known_authorities
|
426
|
+
# @@mutex.synchronize { # @TODO@ Lock access to @@known_authorities
|
427
427
|
TheLog.debug(";; _dorecursion() Failed to extract nameserver IPs:")
|
428
428
|
TheLog.debug(known_authorities.inspect + cache.inspect)
|
429
429
|
known_authorities.keys.each do |ns_rec|
|
@@ -434,20 +434,32 @@ module Dnsruby
|
|
434
434
|
ans=[]
|
435
435
|
|
436
436
|
# Don't query for V6 if its not there.
|
437
|
-
|
438
|
-
|
437
|
+
# Do this in parallel
|
438
|
+
ip_mutex = Mutex.new
|
439
|
+
ip6_thread = Thread.start {
|
440
|
+
if ( @ipv6_ok)
|
441
|
+
auth_packet = _dorecursion(ns_rec,"AAAA", klass, # packet
|
442
|
+
".", # known_zone
|
443
|
+
@@hints, # known_authorities
|
444
|
+
depth+1); # depth
|
445
|
+
ip_mutex.synchronize {
|
446
|
+
ans.push(auth_packet.answer) if auth_packet
|
447
|
+
}
|
448
|
+
end
|
449
|
+
}
|
450
|
+
|
451
|
+
ip4_thread = Thread.start {
|
452
|
+
auth_packet = _dorecursion(ns_rec,"A",klass, # packet
|
439
453
|
".", # known_zone
|
440
454
|
@@hints, # known_authorities
|
441
455
|
depth+1); # depth
|
442
|
-
ans = auth_packet.answer if auth_packet
|
443
|
-
end
|
444
456
|
|
445
|
-
|
446
|
-
|
447
|
-
|
448
|
-
|
449
|
-
|
450
|
-
|
457
|
+
ip_mutex.synchronize {
|
458
|
+
ans.push(auth_packet.answer ) if auth_packet
|
459
|
+
}
|
460
|
+
}
|
461
|
+
ip6_thread.join
|
462
|
+
ip4_thread.join
|
451
463
|
|
452
464
|
if ( ans.length > 0 )
|
453
465
|
TheLog.debug(";; _dorecursion() Answers found for [#{ns_rec}]")
|
@@ -499,7 +511,7 @@ module Dnsruby
|
|
499
511
|
end
|
500
512
|
TheLog.debug(";; _dorecursion() No authority information could be obtained.")
|
501
513
|
return nil
|
502
|
-
# }
|
514
|
+
# }
|
503
515
|
end
|
504
516
|
|
505
517
|
# Cut the deck of IPs in a random place.
|
@@ -513,8 +525,7 @@ module Dnsruby
|
|
513
525
|
ns.each do |nss|
|
514
526
|
nss.each {|n| nameservers.push(n)}
|
515
527
|
end
|
516
|
-
resolver = Resolver.new(
|
517
|
-
resolver.nameserver = nameservers
|
528
|
+
resolver = Resolver.new({:nameserver=>nameservers})
|
518
529
|
servers = []
|
519
530
|
resolver.single_resolvers.each {|s|
|
520
531
|
servers.push(s.server)
|
@@ -573,7 +584,7 @@ module Dnsruby
|
|
573
584
|
TheLog.debug(";; _dorecursion() FOUND closer authority for [#{of}] at [#{server}].")
|
574
585
|
auth[server] ||= AddressCache.new #[] @TODO@ If there is no additional record for this, then we want to use the authority!
|
575
586
|
if ((packet.additional.rrset(rr.nsdname, Types::A).length == 0) &&
|
576
|
-
|
587
|
+
(packet.additional.rrset(rr.nsdname, Types::AAAA).length == 0))
|
577
588
|
auth[server].push([rr.nsdname, rr.ttl])
|
578
589
|
end
|
579
590
|
else
|
@@ -654,9 +665,9 @@ module Dnsruby
|
|
654
665
|
if ((n.to_s == zone) || (n.to_s == Name.create(zone).to_s) ||
|
655
666
|
(n.subdomain_of?(Name.create(zone))) ||
|
656
667
|
(rrset.type == Types::OPT))
|
657
|
-
# # @TODO@ Leave in the response if it is an SOA, NSEC or RRSIGfor the parent zone
|
658
|
-
## elsif ((query_name.subdomain_of?rrset.name) &&
|
659
|
-
# elsif ((rrset.type == Types.SOA) || (rrset.type == Types.NSEC) || (rrset.type == Types.NSEC3)) #)
|
668
|
+
# # @TODO@ Leave in the response if it is an SOA, NSEC or RRSIGfor the parent zone
|
669
|
+
## elsif ((query_name.subdomain_of?rrset.name) &&
|
670
|
+
# elsif ((rrset.type == Types.SOA) || (rrset.type == Types.NSEC) || (rrset.type == Types.NSEC3)) #)
|
660
671
|
else
|
661
672
|
TheLog.debug"Removing #{rrset.name}, #{rrset.type} from response from server for #{zone}"
|
662
673
|
packet.send(section).remove_rrset(rrset.name, rrset.type)
|
data/lib/Dnsruby/Resolver.rb
CHANGED
@@ -103,9 +103,9 @@ module Dnsruby
|
|
103
103
|
# attr_accessor :single_resolvers # :nodoc:
|
104
104
|
def single_resolvers=(s) # :nodoc:
|
105
105
|
@configured = true
|
106
|
-
# @single_res_mutex.synchronize {
|
106
|
+
# @single_res_mutex.synchronize {
|
107
107
|
@single_resolvers = s
|
108
|
-
# }
|
108
|
+
# }
|
109
109
|
end
|
110
110
|
def single_resolvers # :nodoc:
|
111
111
|
if (!@configured)
|
@@ -139,6 +139,11 @@ module Dnsruby
|
|
139
139
|
# requirements.
|
140
140
|
attr_accessor :do_validation
|
141
141
|
|
142
|
+
# Defines whether we will cache responses, or pass every request to the
|
143
|
+
# upstream resolver. This is only really useful when querying authoritative
|
144
|
+
# servers (as the upstream recursive resolver is likely to cache)
|
145
|
+
attr_accessor :do_caching
|
146
|
+
|
142
147
|
#--
|
143
148
|
#@TODO@ add load_balance? i.e. Target nameservers in a random, rather than pre-determined, order?
|
144
149
|
#This is best done when configuring the Resolver, as it will re-order servers based on their response times.
|
@@ -156,6 +161,7 @@ module Dnsruby
|
|
156
161
|
# response = res.query("208.77.188.166", Types.PTR)
|
157
162
|
def query(name, type=Types.A, klass=Classes.IN, set_cd=@dnssec)
|
158
163
|
msg = Message.new
|
164
|
+
msg.do_caching = @do_caching
|
159
165
|
msg.header.rd = 1
|
160
166
|
msg.add_question(name, type, klass)
|
161
167
|
msg.do_validation = @do_validation
|
@@ -167,6 +173,7 @@ module Dnsruby
|
|
167
173
|
|
168
174
|
def query_no_validation_or_recursion(name, type=Types.A, klass=Classes.IN) # :nodoc: all
|
169
175
|
msg = Message.new
|
176
|
+
msg.do_caching = @do_caching
|
170
177
|
msg.header.rd = false
|
171
178
|
msg.do_validation = false
|
172
179
|
msg.add_question(name, type, klass)
|
@@ -315,12 +322,19 @@ module Dnsruby
|
|
315
322
|
if (!@configured)
|
316
323
|
add_config_nameservers
|
317
324
|
end
|
318
|
-
# @single_res_mutex.synchronize {
|
325
|
+
# @single_res_mutex.synchronize {
|
319
326
|
if (!@resolver_ruby) # @TODO@ Synchronize this?
|
320
327
|
@resolver_ruby = ResolverRuby.new(self)
|
321
328
|
end
|
322
|
-
# }
|
323
|
-
|
329
|
+
# }
|
330
|
+
client_query_id = @resolver_ruby.send_async(*args)
|
331
|
+
if (@single_resolvers.length == 0)
|
332
|
+
Thread.start {
|
333
|
+
sleep(@query_timeout == 0 ? 1 : @query_timeout)
|
334
|
+
args[1].push([client_query_id, nil, ResolvTimeout.new])
|
335
|
+
}
|
336
|
+
end
|
337
|
+
return client_query_id
|
324
338
|
end
|
325
339
|
|
326
340
|
# Close the Resolver. Unfinished queries are terminated with OtherResolvError.
|
@@ -347,12 +361,14 @@ module Dnsruby
|
|
347
361
|
# * :query_timeout
|
348
362
|
# * :retry_times
|
349
363
|
# * :retry_delay
|
364
|
+
# * :do_caching
|
350
365
|
def initialize(*args)
|
351
366
|
# @TODO@ Should we allow :namesver to be an RRSet of NS records? Would then need to randomly order them?
|
352
367
|
@resolver_ruby = nil
|
353
368
|
@src_address = nil
|
354
369
|
@single_res_mutex = Mutex.new
|
355
370
|
@configured = false
|
371
|
+
@do_caching = true
|
356
372
|
@config = Config.new()
|
357
373
|
reset_attributes
|
358
374
|
|
@@ -396,14 +412,15 @@ module Dnsruby
|
|
396
412
|
end
|
397
413
|
@configured = true
|
398
414
|
@single_res_mutex.synchronize {
|
399
|
-
|
400
|
-
|
401
|
-
|
402
|
-
|
403
|
-
|
404
|
-
|
405
|
-
|
406
|
-
|
415
|
+
# Add the Config nameservers
|
416
|
+
@config.nameserver.each do |ns|
|
417
|
+
@single_resolvers.push(PacketSender.new({:server=>ns, :dnssec=>@dnssec,
|
418
|
+
:use_tcp=>@use_tcp, :packet_timeout=>@packet_timeout,
|
419
|
+
:tsig => @tsig, :ignore_truncation=>@ignore_truncation,
|
420
|
+
:src_address=>@src_address, :src_port=>@src_port,
|
421
|
+
:do_caching=>@do_caching,
|
422
|
+
:recurse=>@recurse, :udp_size=>@udp_size}))
|
423
|
+
end
|
407
424
|
}
|
408
425
|
end
|
409
426
|
|
@@ -435,6 +452,7 @@ module Dnsruby
|
|
435
452
|
@port = DefaultPort
|
436
453
|
@udp_size = DefaultUDPSize
|
437
454
|
@dnssec = DefaultDnssec
|
455
|
+
@do_caching= true
|
438
456
|
@use_tcp = false
|
439
457
|
@tsig = nil
|
440
458
|
@ignore_truncation = false
|
@@ -443,7 +461,7 @@ module Dnsruby
|
|
443
461
|
@src_port = [0]
|
444
462
|
@recurse = true
|
445
463
|
@single_res_mutex.synchronize {
|
446
|
-
|
464
|
+
@single_resolvers=[]
|
447
465
|
}
|
448
466
|
@configured = false
|
449
467
|
end
|
@@ -487,9 +505,9 @@ module Dnsruby
|
|
487
505
|
end
|
488
506
|
def nameserver=(n)
|
489
507
|
@configured = true
|
490
|
-
|
491
|
-
|
492
|
-
|
508
|
+
@single_res_mutex.synchronize {
|
509
|
+
@single_resolvers=[]
|
510
|
+
}
|
493
511
|
set_config_nameserver(n)
|
494
512
|
add_config_nameservers
|
495
513
|
end
|
@@ -661,6 +679,11 @@ module Dnsruby
|
|
661
679
|
@persistent_udp = on
|
662
680
|
update
|
663
681
|
end
|
682
|
+
|
683
|
+
def do_caching=(on)
|
684
|
+
@do_caching=on
|
685
|
+
update
|
686
|
+
end
|
664
687
|
|
665
688
|
def recurse=(a)
|
666
689
|
@recurse = a
|
@@ -692,29 +715,29 @@ module Dnsruby
|
|
692
715
|
# e.g. timeouts[timeout1]=nameserver
|
693
716
|
timeouts = {}
|
694
717
|
retry_delay = @retry_delay
|
695
|
-
# @single_res_mutex.synchronize {
|
696
|
-
|
697
|
-
|
698
|
-
|
699
|
-
|
700
|
-
# servers=[]
|
701
|
-
# @single_resolvers.each do |r| servers.push(r.server) end
|
702
|
-
|
703
|
-
|
704
|
-
|
705
|
-
|
706
|
-
|
707
|
-
|
708
|
-
|
709
|
-
|
710
|
-
|
711
|
-
|
712
|
-
end
|
713
|
-
timeouts[base+retry_delay+offset]=[res, retry_count]
|
718
|
+
# @single_res_mutex.synchronize {
|
719
|
+
@retry_times.times do |retry_count|
|
720
|
+
if (retry_count>0)
|
721
|
+
retry_delay *= 2
|
722
|
+
end
|
723
|
+
# servers=[]
|
724
|
+
# @single_resolvers.each do |r| servers.push(r.server) end
|
725
|
+
@single_resolvers.each_index do |i|
|
726
|
+
res= @single_resolvers[i]
|
727
|
+
next if !res # @TODO@ WHY?1
|
728
|
+
offset = (i*@retry_delay.to_f/@single_resolvers.length)
|
729
|
+
if (retry_count==0)
|
730
|
+
timeouts[base+offset]=[res, retry_count]
|
731
|
+
else
|
732
|
+
if (timeouts.has_key?(base+retry_delay+offset))
|
733
|
+
Dnsruby.log.error{"Duplicate timeout key!"}
|
734
|
+
raise RuntimeError.new("Duplicate timeout key!")
|
714
735
|
end
|
736
|
+
timeouts[base+retry_delay+offset]=[res, retry_count]
|
715
737
|
end
|
716
738
|
end
|
717
|
-
|
739
|
+
end
|
740
|
+
# }
|
718
741
|
return timeouts
|
719
742
|
end
|
720
743
|
end
|
@@ -729,7 +752,7 @@ module Dnsruby
|
|
729
752
|
end
|
730
753
|
def reset_attributes #:nodoc: all
|
731
754
|
# data structures
|
732
|
-
# @mutex=Mutex.new
|
755
|
+
# @mutex=Mutex.new
|
733
756
|
@query_list = {}
|
734
757
|
@timeouts = {}
|
735
758
|
end
|
@@ -773,7 +796,7 @@ module Dnsruby
|
|
773
796
|
|
774
797
|
tick_needed=false
|
775
798
|
# add to our data structures
|
776
|
-
# @mutex.synchronize{
|
799
|
+
# @mutex.synchronize{
|
777
800
|
@parent.single_res_mutex.synchronize {
|
778
801
|
tick_needed = true if @query_list.empty?
|
779
802
|
if (@query_list.has_key?client_query_id)
|
@@ -813,7 +836,7 @@ module Dnsruby
|
|
813
836
|
|
814
837
|
# Close the Resolver. Unfinished queries are terminated with OtherResolvError.
|
815
838
|
def close
|
816
|
-
# @mutex.synchronize {
|
839
|
+
# @mutex.synchronize {
|
817
840
|
@parent.single_res_mutex.synchronize {
|
818
841
|
@query_list.each do |client_query_id, values|
|
819
842
|
msg, client_queue, q, outstanding = values
|
@@ -867,7 +890,7 @@ module Dnsruby
|
|
867
890
|
def tick #:nodoc: all
|
868
891
|
# Handle the tick
|
869
892
|
# Do we have any retries due to be sent yet?
|
870
|
-
# @mutex.synchronize{
|
893
|
+
# @mutex.synchronize{
|
871
894
|
@parent.single_res_mutex.synchronize {
|
872
895
|
time_now = Time.now
|
873
896
|
@timeouts.keys.each do |client_query_id|
|
@@ -949,7 +972,7 @@ module Dnsruby
|
|
949
972
|
Dnsruby.log.error{"Serious internal error!! #{id} expected, #{event_id} received"}
|
950
973
|
raise RuntimeError.new("Serious internal error!! #{id} expected, #{event_id} received")
|
951
974
|
end
|
952
|
-
# @mutex.synchronize{
|
975
|
+
# @mutex.synchronize{
|
953
976
|
@parent.single_res_mutex.synchronize {
|
954
977
|
if (@query_list[client_query_id]==nil)
|
955
978
|
# print "Dead query response - ignoring\n"
|
@@ -1047,34 +1070,34 @@ module Dnsruby
|
|
1047
1070
|
# TO BE CALLED IN A SYNCHRONIZED BLOCK
|
1048
1071
|
def increment_resolver_priority(res)
|
1049
1072
|
TheLog.debug("Incrementing resolver priority for #{res.server}\n")
|
1050
|
-
# @parent.single_res_mutex.synchronize {
|
1051
|
-
|
1052
|
-
|
1053
|
-
|
1054
|
-
|
1055
|
-
|
1056
|
-
# }
|
1073
|
+
# @parent.single_res_mutex.synchronize {
|
1074
|
+
index = @parent.single_resolvers.index(res)
|
1075
|
+
if (index > 0)
|
1076
|
+
@parent.single_resolvers.delete(res)
|
1077
|
+
@parent.single_resolvers.insert(index-1,res)
|
1078
|
+
end
|
1079
|
+
# }
|
1057
1080
|
end
|
1058
1081
|
|
1059
1082
|
# TO BE CALLED IN A SYNCHRONIZED BLOCK
|
1060
1083
|
def decrement_resolver_priority(res)
|
1061
1084
|
TheLog.debug("Decrementing resolver priority for #{res.server}\n")
|
1062
|
-
# @parent.single_res_mutex.synchronize {
|
1063
|
-
|
1064
|
-
|
1065
|
-
|
1066
|
-
|
1067
|
-
|
1068
|
-
# }
|
1085
|
+
# @parent.single_res_mutex.synchronize {
|
1086
|
+
index = @parent.single_resolvers.index(res)
|
1087
|
+
if (index < @parent.single_resolvers.length)
|
1088
|
+
@parent.single_resolvers.delete(res)
|
1089
|
+
@parent.single_resolvers.insert(index+1,res)
|
1090
|
+
end
|
1091
|
+
# }
|
1069
1092
|
end
|
1070
1093
|
|
1071
1094
|
# TO BE CALLED IN A SYNCHRONIZED BLOCK
|
1072
1095
|
def demote_resolver(res)
|
1073
1096
|
TheLog.debug("Demoting resolver priority for #{res.server} to bottom\n")
|
1074
|
-
# @parent.single_res_mutex.synchronize {
|
1075
|
-
|
1076
|
-
|
1077
|
-
# }
|
1097
|
+
# @parent.single_res_mutex.synchronize {
|
1098
|
+
@parent.single_resolvers.delete(res)
|
1099
|
+
@parent.single_resolvers.push(res)
|
1100
|
+
# }
|
1078
1101
|
end
|
1079
1102
|
|
1080
1103
|
def handle_response(select_queue, query_id, response) #:nodoc: all
|