# File lib/resolve/hostname.rb, line 70 def primary_ip_version @primary_ip_version end
TODO: DNS RoundRobin with resolv
DEFAULT_SUPPORTS_DNS_RR = false
# File lib/resolve/hostname.rb, line 35 def initialize(opts={}) @primary_ip_version = opts[:version] || DEFAULT_PRIMARY_ADDRESS_VERSION unless ADDRESS_VERSIONS.include? @primary_ip_version raise ArgumentError, "unknown version of ip address: #{opts[:version]}" end @ttl = opts[:ttl] || DEFAULT_EXPIRATION_SECONDS @resolver_ttl = opts[:resolver_ttl] || DEFAULT_RESOLVER_TTL @system_resolver_enabled = opts.fetch(:system_resolver, DEFAULT_ENABLE_SYSTEM_RESOLVER) @permit_secondary_address_version = opts.fetch(:permit_other_version, DEFAULT_PERMIT_SECONDARY_ADDRESS_VERSION) @raise_notfound = opts.fetch(:raise_notfound, DEFAULT_RAISE_NOTFOUND) @cache = {} @mutex = Mutex.new @resolver = nil @resolver_expires = nil @invalid_address_error = if IPAddr.const_defined?('InvalidAddressError') IPAddr::InvalidAddressError else ArgumentError end end
# File lib/resolve/hostname.rb, line 61 def getaddress(name) unless @cache[name] @mutex.synchronize do @cache[name] ||= CachedValue.new(@ttl) end end @cache[name].get_or_refresh{ resolve(name) } end
# File lib/resolve/hostname.rb, line 70 def primary_ip_version @primary_ip_version end
# File lib/resolve/hostname.rb, line 78 def primary_version_address?(str) if @primary_ip_version == :ipv4 IPAddr.new(str).ipv4? else IPAddr.new(str).ipv6? end end
# File lib/resolve/hostname.rb, line 129 def resolv_instance return @resolver if @resolver && @resolver_expires >= Time.now @resolver_expires = Time.now + @resolver_ttl @resolver = Resolv::DNS.new @resolver end
# File lib/resolve/hostname.rb, line 86 def resolve(name) secondary = nil is_address = false begin IPAddr.new(name) is_address = true rescue @invalid_address_error => e # ignore end return name if is_address if @system_resolver_enabled addr = resolve_builtin(name) if addr return addr if primary_version_address?(addr) secondary = addr end end addr = resolve_resolv(name, primary_ip_version) if addr return addr if primary_version_address?(addr) secondary ||= addr end if secondary.nil? && @permit_secondary_address_version secondary = resolve_resolv(name, secondary_ip_version) end addr = resolve_magic(name) if addr return addr if primary_version_address?(addr) secondary ||= addr end return secondary if secondary && @permit_secondary_address_version raise NotFoundError, "cannot resolve hostname #{name}" if @raise_notfound nil end
# File lib/resolve/hostname.rb, line 155 def resolve_builtin(name) begin IPSocket.getaddress(name) rescue SocketError => e raise unless e.message.start_with?('getaddrinfo: nodename nor servname provided, or not known') nil end end
# File lib/resolve/hostname.rb, line 164 def resolve_magic(name) if name =~ /^localhost$/ return @primary_ip_version == :ipv4 ? '127.0.0.1' : '::1' end nil end
# File lib/resolve/hostname.rb, line 138 def resolve_resolv(name, version) t = case version when :ipv4 Resolv::DNS::Resource::IN::A when :ipv6 Resolv::DNS::Resource::IN::AAAA else raise ArgumentError, "invalid ip address version:#{version}" end begin resolv_instance.getresource(name, t).address.to_s rescue Resolv::ResolvError => e raise unless e.message.start_with?('DNS result has no information for') nil end end
# File lib/resolve/hostname.rb, line 74 def secondary_ip_version @primary_ip_version == :ipv4 ? :ipv6 : :ipv4 end