Class Resolv::DNS
In: lib/resolv.rb
Parent: Object

Methods

Classes and Modules

Module Resolv::DNS::Label
Module Resolv::DNS::OpCode
Module Resolv::DNS::RCode
Class Resolv::DNS::Config
Class Resolv::DNS::DecodeError
Class Resolv::DNS::EncodeError
Class Resolv::DNS::Message
Class Resolv::DNS::Name
Class Resolv::DNS::Query
Class Resolv::DNS::Requester
Class Resolv::DNS::Resource

Constants

Port = 53   STD0013 (RFC 1035, etc.) ftp.isi.edu/in-notes/iana/assignments/dns-parameters
UDPSize = 512
DNSThreadGroup = ThreadGroup.new

Public Class methods

[Source]

     # File lib/resolv.rb, line 381
381:     def initialize(config_info=nil)
382:       @mutex = Mutex.new
383:       @config = Config.new(config_info)
384:       @initialized = nil
385:     end

[Source]

     # File lib/resolv.rb, line 371
371:     def self.open(*args)
372:       dns = new(*args)
373:       return dns unless block_given?
374:       begin
375:         yield dns
376:       ensure
377:         dns.close
378:       end
379:     end

Public Instance methods

[Source]

     # File lib/resolv.rb, line 404
404:     def close
405:       @mutex.synchronize {
406:         if @initialized
407:           @requester.close if @requester
408:           @requester = nil
409:           @initialized = false
410:         end
411:       }
412:     end

[Source]

     # File lib/resolv.rb, line 425
425:     def each_address(name)
426:       each_resource(name, Resource::IN::A) {|resource| yield resource.address}
427:     end

[Source]

     # File lib/resolv.rb, line 440
440:     def each_name(address)
441:       case address
442:       when Name
443:         ptr = address
444:       when IPv4::Regex
445:         ptr = IPv4.create(address).to_name
446:       when IPv6::Regex
447:         ptr = IPv6.create(address).to_name
448:       else
449:         raise ResolvError.new("cannot interpret as address: #{address}")
450:       end
451:       each_resource(ptr, Resource::IN::PTR) {|resource| yield resource.name}
452:     end

[Source]

     # File lib/resolv.rb, line 465
465:     def each_resource(name, typeclass, &proc)
466:       lazy_initialize
467:       q = Queue.new
468:       senders = {}
469:       begin
470:         @config.resolv(name) {|candidate, tout, nameserver|
471:           msg = Message.new
472:           msg.rd = 1
473:           msg.add_question(candidate, typeclass)
474:           unless sender = senders[[candidate, nameserver]]
475:             sender = senders[[candidate, nameserver]] =
476:               @requester.sender(msg, candidate, q, nameserver)
477:           end
478:           sender.send
479:           reply = reply_name = nil
480:           timeout(tout, ResolvTimeout) { reply, reply_name = q.pop }
481:           case reply.rcode
482:           when RCode::NoError
483:             extract_resources(reply, reply_name, typeclass, &proc)
484:             return
485:           when RCode::NXDomain
486:             raise Config::NXDomain.new(reply_name.to_s)
487:           else
488:             raise Config::OtherResolvError.new(reply_name.to_s)
489:           end
490:         }
491:       ensure
492:         @requester.delete(q)
493:       end
494:     end

[Source]

     # File lib/resolv.rb, line 496
496:     def extract_resources(msg, name, typeclass)
497:       if typeclass < Resource::ANY
498:         n0 = Name.create(name)
499:         msg.each_answer {|n, ttl, data|
500:           yield data if n0 == n
501:         }
502:       end
503:       yielded = false
504:       n0 = Name.create(name)
505:       msg.each_answer {|n, ttl, data|
506:         if n0 == n
507:           case data
508:           when typeclass
509:             yield data
510:             yielded = true
511:           when Resource::CNAME
512:             n0 = data.name
513:           end
514:         end
515:       }
516:       return if yielded
517:       msg.each_answer {|n, ttl, data|
518:         if n0 == n
519:           case data
520:           when typeclass
521:             yield data
522:           end
523:         end
524:       }
525:     end

[Source]

     # File lib/resolv.rb, line 414
414:     def getaddress(name)
415:       each_address(name) {|address| return address}
416:       raise ResolvError.new("DNS result has no information for #{name}")
417:     end

[Source]

     # File lib/resolv.rb, line 419
419:     def getaddresses(name)
420:       ret = []
421:       each_address(name) {|address| ret << address}
422:       return ret
423:     end

[Source]

     # File lib/resolv.rb, line 429
429:     def getname(address)
430:       each_name(address) {|name| return name}
431:       raise ResolvError.new("DNS result has no information for #{address}")
432:     end

[Source]

     # File lib/resolv.rb, line 434
434:     def getnames(address)
435:       ret = []
436:       each_name(address) {|name| ret << name}
437:       return ret
438:     end

[Source]

     # File lib/resolv.rb, line 454
454:     def getresource(name, typeclass)
455:       each_resource(name, typeclass) {|resource| return resource}
456:       raise ResolvError.new("DNS result has no information for #{name}")
457:     end

[Source]

     # File lib/resolv.rb, line 459
459:     def getresources(name, typeclass)
460:       ret = []
461:       each_resource(name, typeclass) {|resource| ret << resource}
462:       return ret
463:     end

[Source]

     # File lib/resolv.rb, line 387
387:     def lazy_initialize
388:       @mutex.synchronize {
389:         unless @initialized
390:           @config.lazy_initialize
391: 
392:           if nameserver = @config.single?
393:             @requester = Requester::ConnectedUDP.new(nameserver)
394:           else
395:             @requester = Requester::UnconnectedUDP.new
396:           end
397: 
398:           @initialized = true
399:         end
400:       }
401:       self
402:     end

[Validate]