Class Resolv::DNS
In: 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 resolv.rb, line 381
    def initialize(config_info=nil)
      @mutex = Mutex.new
      @config = Config.new(config_info)
      @initialized = nil
    end

[Source]

# File resolv.rb, line 371
    def self.open(*args)
      dns = new(*args)
      return dns unless block_given?
      begin
        yield dns
      ensure
        dns.close
      end
    end

Public Instance methods

[Source]

# File resolv.rb, line 404
    def close
      @mutex.synchronize {
        if @initialized
          @requester.close if @requester
          @requester = nil
          @initialized = false
        end
      }
    end

[Source]

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

[Source]

# File resolv.rb, line 440
    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

[Source]

# File resolv.rb, line 465
    def each_resource(name, typeclass, &proc)
      lazy_initialize
      q = Queue.new
      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, q, nameserver)
          end
          sender.send
          reply = reply_name = nil
          timeout(tout, ResolvTimeout) { reply, reply_name = q.pop }
          case reply.rcode
          when RCode::NoError
            extract_resources(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.delete(q)
      end
    end

[Source]

# File resolv.rb, line 496
    def extract_resources(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

[Source]

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

[Source]

# File resolv.rb, line 419
    def getaddresses(name)
      ret = []
      each_address(name) {|address| ret << address}
      return ret
    end

[Source]

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

[Source]

# File resolv.rb, line 434
    def getnames(address)
      ret = []
      each_name(address) {|name| ret << name}
      return ret
    end

[Source]

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

[Source]

# File resolv.rb, line 459
    def getresources(name, typeclass)
      ret = []
      each_resource(name, typeclass) {|resource| ret << resource}
      return ret
    end

[Source]

# File resolv.rb, line 387
    def lazy_initialize
      @mutex.synchronize {
        unless @initialized
          @config.lazy_initialize

          if nameserver = @config.single?
            @requester = Requester::ConnectedUDP.new(nameserver)
          else
            @requester = Requester::UnconnectedUDP.new
          end

          @initialized = true
        end
      }
      self
    end

[Validate]