New in Whois: #nameservers are now Nameserver

It's time for another update on Ruby Whois library. Let's talk about name servers.

The most part of WHOIS servers follow the "convention" to include the name server list of a domain in the WHOIS record.

A name server is represented by a DNS name, which is a string.

ns1.google.com
ns2.google.com

The DNS name resolves to an IPv4 IP address.

ns1.google.com => 216.239.32.10
ns2.google.com => 216.239.34.10

Optionally, the DNS name can resolve to an IPv6 IP address.git

ns1.nic.fr => 2001:660:3003:2::4:1
ns2.nic.fr => 2001:660:3005:1::1:2

Each WHOIS server arbitrary choses the amount of information to store and return in a WHOIS record. Some registries returns only the DNS name, other registries include IP addresses as well.

In the current WHOIS version, the list of name servers is accessible through the #nameservers property.

r = Whois.query "google.com"
r.nameservers
# => ["ns1.google.com", "ns2.google.com"]

The method returns an Array of String. This is a lossy implementation because it completely ignores the IPv4 and IPv6 details.

The new Whois version solves this problem by introducing a new Whois::Answer::Nameserver object. This object is a Struct composed by three attributes: name, ipv4 and ipv6.

ns = Nameserver.new(
    :name => "ns1.nic.fr",
    :ipv4 => "192.134.4.1",
    :ipv6 => "2001:660:3003:2::4:1"
  )

ns.name
# => "ns1.nic.fr"
ns.ipv4
# => "192.134.4.1"
ns.ipv6
# => "2001:660:3003:2::4:1"

In the new Whois version, the #nameservers implementation has been changed to return an array of Nameserver instead of a simple String.

r = Whois.query "nic.fr"
r.nameservers
# => [
#     #<struct Whois::Answer::Nameserver name="ns1.nic.fr", ipv4="192.134.4.1", ipv6="2001:660:3003:2::4:1">,
#     #<struct Whois::Answer::Nameserver name="ns2.nic.fr", ipv4="192.93.0.4", ipv6="2001:660:3005:1::1:2">,
#     ...
#    ]

It's important to know that this change can break backwards compatibility. In order to minimize the impact, Nameserver#to_s returns the String value of the name attribute.

Nameserver.new(:name => "ns1.nic.fr", :ipv4 => "192.134.4.1").to_s
# => "ns1.nic.fr"