Class: Resolv::DNS
- Inherits:
-
Object
show all
- Defined in:
- lib/resolv.rb
Defined Under Namespace
Modules: Label, OpCode, RCode
Classes: Config, DecodeError, EncodeError, Message, Name, Query, Requester, Resource
Constant Summary
collapse
- Port =
53
- UDPSize =
512
- DNSThreadGroup =
ThreadGroup.new
- RequestID =
{}
- RequestIDMutex =
Mutex.new
Class Method Summary
collapse
Instance Method Summary
collapse
Constructor Details
#initialize(config_info = nil) ⇒ DNS
Returns a new instance of DNS.
386
387
388
389
390
|
# File 'lib/resolv.rb', line 386
def initialize(config_info=nil)
@mutex = Mutex.new
@config = Config.new(config_info)
@initialized = nil
end
|
Class Method Details
.allocate_request_id(host, port) ⇒ Object
555
556
557
558
559
560
561
562
563
564
565
|
# File 'lib/resolv.rb', line 555
def self.allocate_request_id(host, port) id = nil
RequestIDMutex.synchronize {
h = (RequestID[[host, port]] ||= {})
begin
id = rangerand(0x0000..0xffff)
end while h[id]
h[id] = true
}
id
end
|
.bind_random_port(udpsock) ⇒ Object
579
580
581
582
583
584
585
586
|
# File 'lib/resolv.rb', line 579
def self.bind_random_port(udpsock) begin
port = rangerand(1024..65535)
udpsock.bind("", port)
rescue Errno::EADDRINUSE
retry
end
end
|
.free_request_id(host, port, id) ⇒ Object
567
568
569
570
571
572
573
574
575
576
577
|
# File 'lib/resolv.rb', line 567
def self.free_request_id(host, port, id) RequestIDMutex.synchronize {
key = [host, port]
if h = RequestID[key]
h.delete id
if h.empty?
RequestID.delete key
end
end
}
end
|
.open(*args) ⇒ Object
376
377
378
379
380
381
382
383
384
|
# File 'lib/resolv.rb', line 376
def self.open(*args)
dns = new(*args)
return dns unless block_given?
begin
yield dns
ensure
dns.close
end
end
|
.random(arg) ⇒ Object
530
531
532
|
# File 'lib/resolv.rb', line 530
def self.random(arg) rand(arg)
end
|
.rangerand(range) ⇒ Object
543
544
545
546
547
548
549
550
|
# File 'lib/resolv.rb', line 543
def self.rangerand(range) base = range.begin
len = range.end - range.begin
if !range.exclude_end?
len += 1
end
base + random(len)
end
|
Instance Method Details
#close ⇒ Object
402
403
404
405
406
407
408
|
# File 'lib/resolv.rb', line 402
def close
@mutex.synchronize {
if @initialized
@initialized = false
end
}
end
|
#each_address(name) ⇒ Object
421
422
423
|
# File 'lib/resolv.rb', line 421
def each_address(name)
each_resource(name, Resource::IN::A) {|resource| yield resource.address}
end
|
#each_name(address) ⇒ Object
436
437
438
439
440
441
442
443
444
445
446
447
448
|
# File 'lib/resolv.rb', line 436
def each_name(address)
case address
when Name
ptr = address
when IPv4::Regex
ptr = IPv4.create(address).to_name
when IPv6::Regex
ptr = IPv6.create(address).to_name
else
raise ResolvError.new("cannot interpret as address: #{address}")
end
each_resource(ptr, Resource::IN::PTR) {|resource| yield resource.name}
end
|
#each_resource(name, typeclass, &proc) ⇒ Object
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
|
# File 'lib/resolv.rb', line 461
def each_resource(name, typeclass, &proc)
lazy_initialize
requester = make_requester
senders = {}
begin
@config.resolv(name) {|candidate, tout, nameserver|
msg = Message.new
msg.rd = 1
msg.add_question(candidate, typeclass)
unless sender = senders[[candidate, nameserver]]
sender = senders[[candidate, nameserver]] =
requester.sender(msg, candidate, nameserver)
end
reply, reply_name = requester.request(sender, tout)
case reply.rcode
when RCode::NoError
(reply, reply_name, typeclass, &proc)
return
when RCode::NXDomain
raise Config::NXDomain.new(reply_name.to_s)
else
raise Config::OtherResolvError.new(reply_name.to_s)
end
}
ensure
requester.close
end
end
|
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
|
# File 'lib/resolv.rb', line 498
def (msg, name, typeclass)
if typeclass < Resource::ANY
n0 = Name.create(name)
msg.each_answer {|n, ttl, data|
yield data if n0 == n
}
end
yielded = false
n0 = Name.create(name)
msg.each_answer {|n, ttl, data|
if n0 == n
case data
when typeclass
yield data
yielded = true
when Resource::CNAME
n0 = data.name
end
end
}
return if yielded
msg.each_answer {|n, ttl, data|
if n0 == n
case data
when typeclass
yield data
end
end
}
end
|
#getaddress(name) ⇒ Object
410
411
412
413
|
# File 'lib/resolv.rb', line 410
def getaddress(name)
each_address(name) {|address| return address}
raise ResolvError.new("DNS result has no information for #{name}")
end
|
#getaddresses(name) ⇒ Object
415
416
417
418
419
|
# File 'lib/resolv.rb', line 415
def getaddresses(name)
ret = []
each_address(name) {|address| ret << address}
return ret
end
|
#getname(address) ⇒ Object
425
426
427
428
|
# File 'lib/resolv.rb', line 425
def getname(address)
each_name(address) {|name| return name}
raise ResolvError.new("DNS result has no information for #{address}")
end
|
#getnames(address) ⇒ Object
430
431
432
433
434
|
# File 'lib/resolv.rb', line 430
def getnames(address)
ret = []
each_name(address) {|name| ret << name}
return ret
end
|
#getresource(name, typeclass) ⇒ Object
450
451
452
453
|
# File 'lib/resolv.rb', line 450
def getresource(name, typeclass)
each_resource(name, typeclass) {|resource| return resource}
raise ResolvError.new("DNS result has no information for #{name}")
end
|
#getresources(name, typeclass) ⇒ Object
455
456
457
458
459
|
# File 'lib/resolv.rb', line 455
def getresources(name, typeclass)
ret = []
each_resource(name, typeclass) {|resource| ret << resource}
return ret
end
|
#lazy_initialize ⇒ Object
392
393
394
395
396
397
398
399
400
|
# File 'lib/resolv.rb', line 392
def lazy_initialize
@mutex.synchronize {
unless @initialized
@config.lazy_initialize
@initialized = true
end
}
self
end
|