dnsruby 1.49 → 1.50
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/lib/Dnsruby/PacketSender.rb +12 -6
- data/lib/Dnsruby/Recursor.rb +87 -91
- data/lib/Dnsruby/Resolver.rb +1 -1
- data/lib/Dnsruby/resource/resource.rb +18 -2
- data/lib/Dnsruby/zone_transfer.rb +6 -5
- data/lib/dnsruby.rb +1 -1
- metadata +2 -2
data/lib/Dnsruby/PacketSender.rb
CHANGED
@@ -321,10 +321,10 @@ module Dnsruby
|
|
321
321
|
if (udp_packet_size < query_packet.length)
|
322
322
|
if (@no_tcp)
|
323
323
|
# Can't send the message - abort!
|
324
|
-
|
325
|
-
|
326
|
-
|
327
|
-
|
324
|
+
err=IOError.new("Can't send message - too big for UDP and no_tcp=true")
|
325
|
+
Dnsruby.log.error{"#{err}"}
|
326
|
+
st.push_exception_to_select(client_query_id, client_queue, err, nil)
|
327
|
+
return
|
328
328
|
end
|
329
329
|
Dnsruby.log.debug{"Query packet length exceeds max UDP packet size - using TCP"}
|
330
330
|
use_tcp = true
|
@@ -372,7 +372,10 @@ module Dnsruby
|
|
372
372
|
runnextportloop = false
|
373
373
|
rescue Exception => e
|
374
374
|
if (socket!=nil)
|
375
|
-
|
375
|
+
begin
|
376
|
+
socket.close
|
377
|
+
rescue Exception
|
378
|
+
end
|
376
379
|
end
|
377
380
|
# Try again if the error was EADDRINUSE and a random source port is used
|
378
381
|
# Maybe try a max number of times?
|
@@ -409,7 +412,10 @@ module Dnsruby
|
|
409
412
|
err=IOError.new("Send failed to #{@server}:#{@port} from #{@src_address}:#{src_port}, use_tcp=#{use_tcp}, exception : #{e}")
|
410
413
|
Dnsruby.log.error{"#{err}"}
|
411
414
|
st.push_exception_to_select(client_query_id, client_queue, err, nil)
|
412
|
-
|
415
|
+
begin
|
416
|
+
socket.close
|
417
|
+
rescue Exception
|
418
|
+
end
|
413
419
|
return
|
414
420
|
end
|
415
421
|
|
data/lib/Dnsruby/Recursor.rb
CHANGED
@@ -293,7 +293,7 @@ module Dnsruby
|
|
293
293
|
@@zones_cache = Hash.new # key zone_name, values Hash of servers and AddressCaches
|
294
294
|
@@zones_cache["."] = @@hints
|
295
295
|
|
296
|
-
|
296
|
+
@@authority_cache = Hash.new
|
297
297
|
end
|
298
298
|
|
299
299
|
def query_no_validation_or_recursion(name, type=Types.A, klass=Classes.IN) # :nodoc: all
|
@@ -358,10 +358,10 @@ module Dnsruby
|
|
358
358
|
zone = nil
|
359
359
|
@@mutex.synchronize{
|
360
360
|
zone = @@zones_cache[name]
|
361
|
+
if (zone != nil)
|
362
|
+
return name
|
363
|
+
end
|
361
364
|
}
|
362
|
-
if (zone != nil)
|
363
|
-
return name
|
364
|
-
end
|
365
365
|
return false if name=="."
|
366
366
|
# strip the name up to the first dot
|
367
367
|
first_dot = name.index(".")
|
@@ -398,11 +398,7 @@ module Dnsruby
|
|
398
398
|
end
|
399
399
|
|
400
400
|
def _dorecursion(name, type, klass, known_zone, known_authorities, depth, no_validation) # :nodoc:
|
401
|
-
|
402
|
-
@@mutex.synchronize{
|
403
|
-
cache = @@authority_cache # this acts as a store of known server_names - NOT zones
|
404
|
-
}
|
405
|
-
|
401
|
+
|
406
402
|
if ( depth > 255 )
|
407
403
|
TheLog.debug(";; _dorecursion() Recursion too deep, aborting...\n")
|
408
404
|
@errorstring="Recursion too deep, aborted"
|
@@ -411,110 +407,110 @@ module Dnsruby
|
|
411
407
|
|
412
408
|
known_zone.sub!(/\.*$/, ".")
|
413
409
|
|
414
|
-
# Get IPs from authorities
|
415
410
|
ns = [] # Array of AddressCaches (was array of array of addresses)
|
416
|
-
|
417
|
-
|
418
|
-
|
419
|
-
|
420
|
-
|
421
|
-
|
422
|
-
|
411
|
+
@@mutex.synchronize{
|
412
|
+
# Get IPs from authorities
|
413
|
+
known_authorities.keys.each do |ns_rec|
|
414
|
+
if (known_authorities[ns_rec] != nil && known_authorities[ns_rec] != [] )
|
415
|
+
@@authority_cache[ns_rec] = known_authorities[ns_rec]
|
416
|
+
ns.push(@@authority_cache[ns_rec])
|
417
|
+
elsif (@@authority_cache[ns_rec]!=nil && @@authority_cache[ns_rec]!=[])
|
418
|
+
known_authorities[ns_rec] = @@authority_cache[ns_rec]
|
419
|
+
ns.push(@@authority_cache[ns_rec])
|
420
|
+
end
|
423
421
|
end
|
424
|
-
end
|
425
422
|
|
426
|
-
|
427
|
-
|
428
|
-
|
429
|
-
|
430
|
-
|
431
|
-
|
432
|
-
|
433
|
-
TheLog.debug(";; _dorecursion() Manual lookup for authority [#{ns_rec}]")
|
423
|
+
if (ns.length == 0)
|
424
|
+
found_auth = 0
|
425
|
+
TheLog.debug(";; _dorecursion() Failed to extract nameserver IPs:")
|
426
|
+
TheLog.debug(known_authorities.inspect + @@authority_cache.inspect)
|
427
|
+
known_authorities.keys.each do |ns_rec|
|
428
|
+
if (known_authorities[ns_rec]==nil || known_authorities[ns_rec]==[])
|
429
|
+
TheLog.debug(";; _dorecursion() Manual lookup for authority [#{ns_rec}]")
|
434
430
|
|
435
|
-
|
436
|
-
|
431
|
+
auth_packet=nil
|
432
|
+
ans=[]
|
437
433
|
|
438
|
-
|
439
|
-
|
440
|
-
|
441
|
-
|
442
|
-
|
443
|
-
|
434
|
+
# Don't query for V6 if its not there.
|
435
|
+
# Do this in parallel
|
436
|
+
ip_mutex = Mutex.new
|
437
|
+
ip6_thread = Thread.start {
|
438
|
+
if ( @ipv6_ok)
|
439
|
+
auth_packet = _dorecursion(ns_rec,"AAAA", klass, # packet
|
440
|
+
".", # known_zone
|
441
|
+
@@hints, # known_authorities
|
442
|
+
depth+1); # depth
|
443
|
+
ip_mutex.synchronize {
|
444
|
+
ans.push(auth_packet.answer) if auth_packet
|
445
|
+
}
|
446
|
+
end
|
447
|
+
}
|
448
|
+
|
449
|
+
ip4_thread = Thread.start {
|
450
|
+
auth_packet = _dorecursion(ns_rec,"A",klass, # packet
|
444
451
|
".", # known_zone
|
445
452
|
@@hints, # known_authorities
|
446
453
|
depth+1); # depth
|
454
|
+
|
447
455
|
ip_mutex.synchronize {
|
448
|
-
ans.push(auth_packet.answer) if auth_packet
|
456
|
+
ans.push(auth_packet.answer ) if auth_packet
|
449
457
|
}
|
450
|
-
end
|
451
|
-
}
|
452
|
-
|
453
|
-
ip4_thread = Thread.start {
|
454
|
-
auth_packet = _dorecursion(ns_rec,"A",klass, # packet
|
455
|
-
".", # known_zone
|
456
|
-
@@hints, # known_authorities
|
457
|
-
depth+1); # depth
|
458
|
-
|
459
|
-
ip_mutex.synchronize {
|
460
|
-
ans.push(auth_packet.answer ) if auth_packet
|
461
458
|
}
|
462
|
-
|
463
|
-
|
464
|
-
ip4_thread.join
|
459
|
+
ip6_thread.join
|
460
|
+
ip4_thread.join
|
465
461
|
|
466
|
-
|
467
|
-
|
468
|
-
|
469
|
-
|
470
|
-
|
471
|
-
|
472
|
-
|
473
|
-
|
474
|
-
|
475
|
-
|
476
|
-
|
477
|
-
|
478
|
-
|
479
|
-
|
480
|
-
|
481
|
-
|
482
|
-
|
462
|
+
if ( ans.length > 0 )
|
463
|
+
TheLog.debug(";; _dorecursion() Answers found for [#{ns_rec}]")
|
464
|
+
# foreach my $rr (@ans) {
|
465
|
+
ans.each do |rr_arr|
|
466
|
+
rr_arr.each do |rr|
|
467
|
+
TheLog.debug(";; RR:" + rr.inspect + "")
|
468
|
+
if (rr.type == Types::CNAME)
|
469
|
+
# Follow CNAME
|
470
|
+
server = rr.name.to_s.downcase
|
471
|
+
if (server)
|
472
|
+
server.sub!(/\.*$/, ".")
|
473
|
+
if (server == ns_rec)
|
474
|
+
cname = rr.cname.downcase
|
475
|
+
cname.sub!(/\.*$/, ".")
|
476
|
+
TheLog.debug(";; _dorecursion() Following CNAME ns [#{ns_rec}] -> [#{cname}]")
|
477
|
+
if (!(known_authorities[cname]))
|
478
|
+
known_authorities[cname] = AddressCache.new
|
479
|
+
end
|
480
|
+
known_authorities.delete(ns_rec)
|
481
|
+
next
|
483
482
|
end
|
484
|
-
known_authorities.delete(ns_rec)
|
485
|
-
next
|
486
483
|
end
|
487
|
-
|
488
|
-
|
489
|
-
|
490
|
-
|
491
|
-
|
492
|
-
|
493
|
-
|
494
|
-
|
495
|
-
|
496
|
-
|
497
|
-
|
498
|
-
|
484
|
+
elsif (rr.type == Types::A || rr.type == Types::AAAA )
|
485
|
+
server = rr.name.to_s.downcase
|
486
|
+
if (server)
|
487
|
+
server.sub!(/\.*$/, ".")
|
488
|
+
if (known_authorities[server]!=nil)
|
489
|
+
ip = rr.address.to_s
|
490
|
+
TheLog.debug(";; _dorecursion() Found ns: #{server} IN A #{ip}")
|
491
|
+
@@authority_cache[server] = known_authorities[server]
|
492
|
+
@@authority_cache[ns_rec].push([ip, rr.ttl])
|
493
|
+
found_auth+=1
|
494
|
+
next
|
495
|
+
end
|
499
496
|
end
|
500
497
|
end
|
498
|
+
TheLog.debug(";; _dorecursion() Ignoring useless answer: " + rr.inspect + "")
|
501
499
|
end
|
502
|
-
TheLog.debug(";; _dorecursion() Ignoring useless answer: " + rr.inspect + "")
|
503
500
|
end
|
501
|
+
else
|
502
|
+
TheLog.debug(";; _dorecursion() Could not find A records for [#{ns_rec}]")
|
504
503
|
end
|
505
|
-
else
|
506
|
-
TheLog.debug(";; _dorecursion() Could not find A records for [#{ns_rec}]")
|
507
504
|
end
|
508
505
|
end
|
506
|
+
if (found_auth > 0)
|
507
|
+
TheLog.debug(";; _dorecursion() Found #{found_auth} new NS authorities...")
|
508
|
+
return _dorecursion( name, type, klass, known_zone, known_authorities, depth+1)
|
509
|
+
end
|
510
|
+
TheLog.debug(";; _dorecursion() No authority information could be obtained.")
|
511
|
+
return nil
|
509
512
|
end
|
510
|
-
|
511
|
-
TheLog.debug(";; _dorecursion() Found #{found_auth} new NS authorities...")
|
512
|
-
return _dorecursion( name, type, klass, known_zone, known_authorities, depth+1)
|
513
|
-
end
|
514
|
-
TheLog.debug(";; _dorecursion() No authority information could be obtained.")
|
515
|
-
return nil
|
516
|
-
# }
|
517
|
-
end
|
513
|
+
}
|
518
514
|
|
519
515
|
# Cut the deck of IPs in a random place.
|
520
516
|
TheLog.debug(";; _dorecursion() cutting deck of (" + ns.length.to_s + ") authorities...")
|
data/lib/Dnsruby/Resolver.rb
CHANGED
@@ -1013,7 +1013,7 @@ module Dnsruby
|
|
1013
1013
|
event_type == Resolver::EventType::ERROR)
|
1014
1014
|
if (!outstanding.include?id)
|
1015
1015
|
Dnsruby.log.error{"Query id not on outstanding list! #{outstanding.length} items. #{id} not on #{outstanding}"}
|
1016
|
-
raise RuntimeError.new("Query id not on outstanding!")
|
1016
|
+
# raise RuntimeError.new("Query id not on outstanding!")
|
1017
1017
|
end
|
1018
1018
|
outstanding.delete(id)
|
1019
1019
|
end
|
@@ -213,7 +213,23 @@ module Dnsruby
|
|
213
213
|
# rr_again = Dnsruby::RR.create(s)
|
214
214
|
#
|
215
215
|
class RR
|
216
|
+
|
217
|
+
include Comparable
|
216
218
|
|
219
|
+
def <=>(other)
|
220
|
+
# return 1 if ((!other) || !(other.name) || !(other.type))
|
221
|
+
# return -1 if (!@name)
|
222
|
+
if (@name.canonical == other.name.canonical)
|
223
|
+
if (@type.code == other.type.code)
|
224
|
+
return (@rdata <=> other.rdata)
|
225
|
+
else
|
226
|
+
return @type.code <=> other.type.code
|
227
|
+
end
|
228
|
+
else
|
229
|
+
return @name <=> other.name
|
230
|
+
end
|
231
|
+
end
|
232
|
+
|
217
233
|
# A regular expression which catches any valid resource record.
|
218
234
|
@@RR_REGEX = Regexp.new("^\\s*(\\S+)\\s*(\\d+)?\\s*(#{Classes.regexp +
|
219
235
|
"|CLASS\\d+"})?\\s*(#{Types.regexp + '|TYPE\\d+'})?\\s*([\\s\\S]*)\$") #:nodoc: all
|
@@ -412,8 +428,8 @@ module Dnsruby
|
|
412
428
|
if ((rrtype == "NAPTR") || (rrtype == "TXT"))
|
413
429
|
else
|
414
430
|
if (rdata)
|
415
|
-
|
416
|
-
|
431
|
+
rdata.gsub!("(", "")
|
432
|
+
rdata.gsub!(")", "")
|
417
433
|
end
|
418
434
|
end
|
419
435
|
|
@@ -298,9 +298,10 @@ module Dnsruby
|
|
298
298
|
# Old BINDs sent cross class A records for non IN classes.
|
299
299
|
if (type == Types.A && rec.klass() != @klass)
|
300
300
|
else
|
301
|
-
@axfr << rec
|
302
301
|
if (type == Types.SOA)
|
303
302
|
@state = :End
|
303
|
+
else
|
304
|
+
@axfr << rec
|
304
305
|
end
|
305
306
|
end
|
306
307
|
when :End
|
@@ -340,10 +341,10 @@ module Dnsruby
|
|
340
341
|
buf = tcp_read(socket, answersize)
|
341
342
|
msg = Message.decode(buf)
|
342
343
|
if (@tsig)
|
343
|
-
|
344
|
-
|
345
|
-
|
346
|
-
|
344
|
+
if !@tsig.verify_envelope(msg, buf)
|
345
|
+
Dnsruby.log.error("Bad signature on zone transfer - closing connection")
|
346
|
+
raise ResolvError.new("Bad signature on zone transfer")
|
347
|
+
end
|
347
348
|
end
|
348
349
|
return msg
|
349
350
|
end
|
data/lib/dnsruby.rb
CHANGED
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: dnsruby
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: "1.
|
4
|
+
version: "1.50"
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- AlexD
|
@@ -9,7 +9,7 @@ autorequire: dnsruby
|
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
11
|
|
12
|
-
date: 2010-
|
12
|
+
date: 2010-09-15 00:00:00 +01:00
|
13
13
|
default_executable:
|
14
14
|
dependencies: []
|
15
15
|
|