You want to find the IP address corresponding to a domain name, or see whether a domain provides a certain service (such as an email server).
Use the Resolv:: DNS class in the standard resolv library to perform DNS lookups. The most commonly used method is DNS#each_address, which iterates over the IP addresses assigned to a domain name.
require esolv Resolv::DNS.new.each_address("oreilly.com") { |addr| puts addr } # 208.201.239.36 # 208.201.239.37
If you need to check the existence of a particular type of DNS record (such as a MX record for a mail server), use DNS#getresources or the iterator DNS#each_resource. Both methods take a domain name and a class denoting a type of DNS record. They perform a DNS lookup and, for each matching DNS record, return an instance of the given class.
These are the three most common classes:
DNS::Resource::IN::A
Indicates a DNS record pointing to an IP address for the domain.
DNS::RESOURCE::IN::NS
Indicates a DNS record pointing to a DNS nameserver.
DNS::Resource::IN::MX
Indicates a DNS record pointing to a mail server.
This code finds the mail servers and name servers responsible for oreilly.com:
dns = Resolv::DNS.new domain = "oreilly.com" dns.each_resource(domain, Resolv::DNS::Resource::IN::MX) do |mail_server| puts mail_server.exchange end # smtp1.oreilly.com # smtp2.oreilly.com dns.each_resource(domain, Resolv::DNS::Resource::IN::NS) do |nameserver| puts nameserver.name end # a.auth-ns.sonic.net # b.auth-ns.sonic.net # c.auth-ns.sonic.net # ns.oreilly.com
If your application needs to do a lot of DNS lookups, you can greatly speed things up by creating a separate thread for each lookup. Most of the time spent doing a DNS lookup is spent connecting to the network, so doing all the lookups in parallel can save a lot of time. If you do this, you should include the resolv-replace library along with resolv, to make sure your DNS lookups are thread-safe.
Heres some code that sees which one-letter .com domains (a.com, b.com, etc.) are mapped to IP addresses. It runs all 26 DNS queries at once, in 26 threads, and summarizes the results.
require esolv-replace def multiple_lookup(*names) dns = Resolv::DNS.new results = {} threads = [] names.each do |name| threads << Thread.new(name) do |name| begin dns.each_address(name) { |a| (results[name] ||= []) << a } rescue Resolv::ResolvError results[name] = nil end end end threads.each { |t| t.join } return results end domains = ("a".."z").collect { |l| l + .com } multiple_lookup(*domains).each do |name, addresses| if addresses puts "#{name}: #{addresses.size} address#{addresses.size == 1 ? "" : "es"}" end end # x.com: 4 addresses # z.com: 1 address # q.com: 1 address
Strings
Numbers
Date and Time
Arrays
Hashes
Files and Directories
Code Blocks and Iteration
Objects and Classes8
Modules and Namespaces
Reflection and Metaprogramming
XML and HTML
Graphics and Other File Formats
Databases and Persistence
Internet Services
Web Development Ruby on Rails
Web Services and Distributed Programming
Testing, Debugging, Optimizing, and Documenting
Packaging and Distributing Software
Automating Tasks with Rake
Multitasking and Multithreading
User Interface
Extending Ruby with Other Languages
System Administration