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