Class: Resolve::Hostname
- Inherits:
-
Object
show all
- Defined in:
- lib/resolve/hostname.rb,
lib/resolve/hostname.rb,
lib/resolve/hostname/version.rb
Defined Under Namespace
Classes: CachedValue, NotFoundError
Constant Summary
collapse
- DEFAULT_EXPIRATION_SECONDS =
60
- DEFAULT_RESOLVER_TTL =
for rereading of /etc/resolve.conf
1800
- DEFAULT_ENABLE_SYSTEM_RESOLVER =
false
- DEFAULT_PRIMARY_ADDRESS_VERSION =
:ipv4
- DEFAULT_PERMIT_SECONDARY_ADDRESS_VERSION =
true
- ADDRESS_VERSIONS =
[:ipv4, :ipv6]
- DEFAULT_RAISE_NOTFOUND =
true
- VERSION =
"0.0.3"
Instance Attribute Summary collapse
Instance Method Summary
collapse
Constructor Details
#initialize(opts = {}) ⇒ Hostname
TODO: DNS RoundRobin with resolv DEFAULT_SUPPORTS_DNS_RR = false
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
|
# 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
end
|
Instance Attribute Details
#cache ⇒ Object
16
17
18
|
# File 'lib/resolve/hostname.rb', line 16
def cache
@cache
end
|
#resolver_expires ⇒ Object
Returns the value of attribute resolver_expires.
15
16
17
|
# File 'lib/resolve/hostname.rb', line 15
def resolver_expires
@resolver_expires
end
|
#resolver_ttl ⇒ Object
Returns the value of attribute resolver_ttl.
15
16
17
|
# File 'lib/resolve/hostname.rb', line 15
def resolver_ttl
@resolver_ttl
end
|
#ttl ⇒ Object
Returns the value of attribute ttl.
15
16
17
|
# File 'lib/resolve/hostname.rb', line 15
def ttl
@ttl
end
|
Instance Method Details
#getaddress(name) ⇒ Object
55
56
57
58
59
60
61
62
|
# File 'lib/resolve/hostname.rb', line 55
def getaddress(name)
unless @cache[name]
@mutex.synchronize do
@cache[name] ||= CachedValue.new(@ttl)
end
end
@cache[name].get_or_refresh{ resolve(name) }
end
|
#primary_ip_version ⇒ Object
64
65
66
|
# File 'lib/resolve/hostname.rb', line 64
def primary_ip_version
@primary_ip_version
end
|
#primary_version_address?(str) ⇒ Boolean
72
73
74
75
76
77
78
|
# File 'lib/resolve/hostname.rb', line 72
def primary_version_address?(str)
if @primary_ip_version == :ipv4
IPAddr.new(str).ipv4?
else
IPAddr.new(str).ipv6?
end
end
|
#resolv_instance ⇒ Object
123
124
125
126
127
128
129
130
|
# File 'lib/resolve/hostname.rb', line 123
def resolv_instance
return @resolver if @resolver && @resolver_expires >= Time.now
@resolver_expires = Time.now + @resolver_ttl
@resolver = Resolv::DNS.new
@resolver
end
|
#resolve(name) ⇒ Object
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
|
# File 'lib/resolve/hostname.rb', line 80
def resolve(name)
secondary = nil
is_address = false
begin
IPAddr.new(name)
is_address = true
rescue IPAddr::InvalidAddressError
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
|
#resolve_builtin(name) ⇒ Object
149
150
151
152
153
154
155
156
|
# File 'lib/resolve/hostname.rb', line 149
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
|
#resolve_magic(name) ⇒ Object
158
159
160
161
162
163
|
# File 'lib/resolve/hostname.rb', line 158
def resolve_magic(name)
if name =~ /^localhost$/i
return @primary_ip_version == :ipv4 ? '127.0.0.1' : '::1'
end
nil
end
|
#resolve_resolv(name, version) ⇒ Object
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
|
# File 'lib/resolve/hostname.rb', line 132
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
|
#secondary_ip_version ⇒ Object
68
69
70
|
# File 'lib/resolve/hostname.rb', line 68
def secondary_ip_version
@primary_ip_version == :ipv4 ? :ipv6 : :ipv4
end
|