In Files

  • resolv.rb

Resolv::DNS::Config

Constants

InitialTimeout

Public Class Methods

default_config_hash(filename="/etc/resolv.conf") click to toggle source
 
               # File resolv.rb, line 802
def Config.default_config_hash(filename="/etc/resolv.conf")
  if File.exist? filename
    config_hash = Config.parse_resolv_conf(filename)
  else
    if /mswin32|cygwin|mingw|bccwin/ =~ RUBY_PLATFORM
      require 'win32/resolv'
      search, nameserver = Win32::Resolv.get_resolv_info
      config_hash = {}
      config_hash[:nameserver] = nameserver if nameserver
      config_hash[:search] = [search].flatten if search
    end
  end
  config_hash
end
            
new(config_info=nil) click to toggle source
 
               # File resolv.rb, line 762
def initialize(config_info=nil)
  @mutex = Mutex.new
  @config_info = config_info
  @initialized = nil
end
            
parse_resolv_conf(filename) click to toggle source
 
               # File resolv.rb, line 768
def Config.parse_resolv_conf(filename)
  nameserver = []
  search = nil
  ndots = 1
  open(filename) {|f|
    f.each {|line|
      line.sub!(/[#;].*/, '')
      keyword, *args = line.split(/\s+/)
      args.each { |arg|
        arg.untaint
      }
      next unless keyword
      case keyword
      when 'nameserver'
        nameserver += args
      when 'domain'
        next if args.empty?
        search = [args[0]]
      when 'search'
        next if args.empty?
        search = args
      when 'options'
        args.each {|arg|
          case arg
          when /\Andots:(\d+)\z/
            ndots = $1.to_i
          end
        }
      end
    }
  }
  return { :nameserver => nameserver, :search => search, :ndots => ndots }
end
            

Public Instance Methods

generate_candidates(name) click to toggle source
 
               # File resolv.rb, line 884
def generate_candidates(name)
  candidates = nil
  name = Name.create(name)
  if name.absolute?
    candidates = [name]
  else
    if @ndots <= name.length - 1
      candidates = [Name.new(name.to_a)]
    else
      candidates = []
    end
    candidates.concat(@search.map {|domain| Name.new(name.to_a + domain)})
  end
  return candidates
end
            
generate_timeouts() click to toggle source
 
               # File resolv.rb, line 902
def generate_timeouts
  ts = [InitialTimeout]
  ts << ts[-1] * 2 / @nameserver.length
  ts << ts[-1] * 2
  ts << ts[-1] * 2
  return ts
end
            
lazy_initialize() click to toggle source
 
               # File resolv.rb, line 817
def lazy_initialize
  @mutex.synchronize {
    unless @initialized
      @nameserver = []
      @search = nil
      @ndots = 1
      case @config_info
      when nil
        config_hash = Config.default_config_hash
      when String
        config_hash = Config.parse_resolv_conf(@config_info)
      when Hash
        config_hash = @config_info.dup
        if String === config_hash[:nameserver]
          config_hash[:nameserver] = [config_hash[:nameserver]]
        end
        if String === config_hash[:search]
          config_hash[:search] = [config_hash[:search]]
        end
      else
        raise ArgumentError.new("invalid resolv configuration: #{@config_info.inspect}")
      end
      @nameserver = config_hash[:nameserver] if config_hash.include? :nameserver
      @search = config_hash[:search] if config_hash.include? :search
      @ndots = config_hash[:ndots] if config_hash.include? :ndots

      @nameserver = ['0.0.0.0'] if @nameserver.empty?
      if @search
        @search = @search.map {|arg| Label.split(arg) }
      else
        hostname = Socket.gethostname
        if /\./ =~ hostname
          @search = [Label.split($')]
        else
          @search = [[]]
        end
      end

      if !@nameserver.kind_of?(Array) ||
         !@nameserver.all? {|ns| String === ns }
        raise ArgumentError.new("invalid nameserver config: #{@nameserver.inspect}")
      end

      if !@search.kind_of?(Array) ||
         !@search.all? {|ls| ls.all? {|l| Label::Str === l } }
        raise ArgumentError.new("invalid search config: #{@search.inspect}")
      end

      if !@ndots.kind_of?(Integer)
        raise ArgumentError.new("invalid ndots config: #{@ndots.inspect}")
      end

      @initialized = true
    end
  }
  self
end
            
resolv(name) click to toggle source
 
               # File resolv.rb, line 910
def resolv(name)
  candidates = generate_candidates(name)
  timeouts = generate_timeouts
  begin
    candidates.each {|candidate|
      begin
        timeouts.each {|tout|
          @nameserver.each {|nameserver|
            begin
              yield candidate, tout, nameserver
            rescue ResolvTimeout
            end
          }
        }
        raise ResolvError.new("DNS resolv timeout: #{name}")
      rescue NXDomain
      end
    }
  rescue ResolvError
  end
end
            
single?() click to toggle source
 
               # File resolv.rb, line 875
def single?
  lazy_initialize
  if @nameserver.length == 1
    return @nameserver[0]
  else
    return nil
  end
end