dnsruby 1.40 → 1.41
Sign up to get free protection for your applications and to get access to all the features.
- 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
|