Foundations of Python Network Programming

(WallPaper) #1
Chapter 4 ■ SoCket NameS aNd dNS

63

This can be useful if you are not going to try to use the addresses yourself but if you are providing some sort of
directory information to other hosts or programs.


Asking getaddrinfo() for a Canonical Hostname

One last circumstance that you will commonly encounter is that you either are making a new connection or maybe
have just accepted an incoming connection on one of your own server sockets and you want to know the hostname
that belongs officially to the IP address at the other end of your socket.
Although this desire is understandable, please note that it comes with a grave danger: the fact that the owner of
an IP address can, when your machine performs the reverse lookup, have their DNS server return anything they want
as the canonical name! They can claim to be google.com or python.org or whomever they want. They are in complete
control of the string of characters parroted back to you when you ask them what hostname belongs to one of their IP
addresses.
Before trusting a canonical name lookup—also known as a reverse DNS lookup, because it maps an IP address
to a hostname instead of the other way around—you will therefore probably want to look up the name that has been
returned and see whether it really resolves to the original IP address. If not, then either the hostname is deliberately
misleading or it was a well intentioned answer from a domain whose forward and reverse names and IP addresses
have not been correctly configured so that they match.
Canonical name lookups are costly. They incur an extra round-trip through the worldwide DNS service and are
therefore often skipped when doing logging. Services that stop to reverse-lookup every single IP address that makes
a connection tend to be slow and lumbering, and a classic move by system administrators trying to make a system
respond better is to log bare IP addresses. If one of them is causing a problem, you can always look it up by hand later
when you see it in the log file.
But if you have a good use for the canonical name of a host and want to attempt the lookup, then simply run
getaddrinfo() with the AI_CANONNAME flag turned on, and the fourth item of any of the tuples that it returns—an item
that was the empty string in the foregoing examples—will contain the canonical name:





getaddrinfo('iana.org', 'www', 0, socket.SOCK_STREAM, 0,
... socket.AI_ADDRCONFIG | socket.AI_V4MAPPED | socket.AI_CANONNAME)
[(2, 1, 6, '43-8.any.icann.org', ('192.0.43.8', 80))]





You can also supply getaddrinfo() with the name of a socket that is already connected to a remote peer and get
a canonical name in return.





mysock = server_sock.accept()
addr, port = mysock.getpeername()
getaddrinfo(addr, port, mysock.family, mysock.type, mysock.proto,
... socket.AI_CANONNAME)
[(2, 1, 6, 'rr.pmtpa.wikimedia.org', ('208.80.152.2', 80))]





Again, this will work only if the owner of the IP address happens to have a name defined for it. Many IP addresses
on the Internet do not provide a useful reverse name, so you have no way of knowing what host has really contacted
you unless you use encryption to verify the peer with which you are communicating.

Free download pdf