Class: MailResolver::Resolver

Inherits:
Object
  • Object
show all
Defined in:
lib/mailresolver/resolver.rb

Overview

DNS for mail. Built on dnsruby rather than Resolv, which collapses SERVFAIL/REFUSED into the same empty answer as NXDOMAIN.

Constant Summary collapse

TIMEOUTS =

One attempt per element: the first element is how long the first packet gets before the first retry, dnsruby doubles the interval for each retry after that, and the sum is the hard deadline. Default: attempts at 0s, 5s, and 10s, all of it over at 11s.

[ 5, 3, 3 ].freeze

Instance Method Summary collapse

Constructor Details

#initialize(timeouts: TIMEOUTS) ⇒ Resolver

Returns a new instance of Resolver.



26
27
28
29
# File 'lib/mailresolver/resolver.rb', line 26

def initialize(timeouts: TIMEOUTS)
  @timeouts = timeouts
  @lock = Mutex.new
end

Instance Method Details

#a(name) ⇒ Object



36
37
38
# File 'lib/mailresolver/resolver.rb', line 36

def a(name)
  records("A", name).map { |record| record.address.to_s }
end

#aaaa(name) ⇒ Object

Dnsruby prints IPv6 in capitals; RFC 5952 §4.3 asks for lower case.



41
42
43
# File 'lib/mailresolver/resolver.rb', line 41

def aaaa(name)
  records("AAAA", name).map { |record| record.address.to_s.downcase }
end

#addresses(name) ⇒ Object

A missing family contributes nothing; a name that doesn't exist at all, or a nameserver failure, still raises.



47
48
49
# File 'lib/mailresolver/resolver.rb', line 47

def addresses(name)
  %w[ A AAAA ].flat_map { |type| family(type, name) }
end

#cname(name) ⇒ Object



63
64
65
# File 'lib/mailresolver/resolver.rb', line 63

def cname(name)
  records("CNAME", name).map { |record| record.domainname.to_s }
end

#mx(name) ⇒ Object

Equal preferences tie-break on the exchange name: sort_by is not stable, and callers walking MX hosts in order deserve the same order every time.



53
54
55
56
# File 'lib/mailresolver/resolver.rb', line 53

def mx(name)
  records("MX", name).sort_by { |record| [ record.preference, record.exchange.to_s ] }
    .map { |record| record.exchange.to_s }
end

#ptr(address) ⇒ Object

Dnsruby puts the question name in name and the host in domainname.



59
60
61
# File 'lib/mailresolver/resolver.rb', line 59

def ptr(address)
  records("PTR", IPAddr.new(address.to_s).reverse).map { |record| record.domainname.to_s }
end

#txt(name) ⇒ Object

TXT character-strings are joined into one value (RFC 7208 §3.3).



32
33
34
# File 'lib/mailresolver/resolver.rb', line 32

def txt(name)
  records("TXT", name).map { |record| record.strings.join }
end