Foundations of Python Network Programming

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

71

•    The “type” of record. Some common ones are A for an IPv4 address, AAAA for an IPv6 address,
NS for a record that lists a name server, and MX for a reply giving the mail server that should be
used for a domain.

•    Finally, the “data” provides the information you need to connect to or contact a service.

In the query just quoted, you learn three things about the python.org domain. First, the A record tells you that if
you want to connect to an actual python.org machine—to make an HTTP connection, start an SSH session, or to do
anything else because the user has supplied python.org as the machine to which he or she wants to connect—then
you should direct your packets at IP address 140.211.10.69. Second, the NS records tell you that if you want to query
the names of any hosts beneath python.org, then you should ask the name servers ns1.p11.dynect.net through
ns4.p11.dynect.net (preferably in the order given, rather than in numeric order) to resolve those names for you.
Finally, if you want to send e-mail to someone at the e-mail domain @python.org, then you will need to go look up the
hostname mail.python.org.
A DNS query can also return a record type CNAME, which indicates that the hostname about which you have
queried is actually just an alias for another hostname—that you then have to go and look up separately! Because it
often requires two round-trips, this record type is unpopular these days, but you still might run across it.


Resolving Mail Domains

I mentioned previously that resolving an e-mail domain is a legitimate use of raw DNS in most Python programs.
The rules for doing this resolution were specified most recently in RFC 5321. They are, briefly, that if MX records exist,
then you must try to contact those SMTP servers and return an error to the user (or put the message on a retry queue)
if none of them will accept the message. Attempt them in order from lowest- to highest-priority number, if their
priorities are not equal. If no MX records exist but an A or AAAA record is provided for the domain, then you are allowed
to try an SMTP connection to that address. If neither record exists but a CNAME is specified, then the domain name it
provides should be searched for MX or A records using the same rules.
Listing 4-3 shows how you might implement this algorithm. By doing a series of DNS queries, it works its way
through the possible destinations, printing its decisions as it goes. By adjusting a routine like this to return addresses
rather than just printing them, you could power a Python mail dispatcher that needed to deliver e-mail to remote hosts.


Listing 4-3. Resolving an E-mail Domain Name


#!/usr/bin/env python3


Foundations of Python Network Programming, Third Edition


https://github.com/brandon-rhodes/fopnp/blob/m/py3/chapter04/dns_mx.py


Looking up a mail domain - the part of an email address after the @


import argparse, dns.resolver


def resolve_hostname(hostname, indent=''):
"Print an A or AAAA record for hostname; follow CNAMEs if necessary."
indent = indent + ' '
answer = dns.resolver.query(hostname, 'A')
if answer.rrset is not None:
for record in answer:
print(indent, hostname, 'has A address', record.address)
return
answer = dns.resolver.query(hostname, 'AAAA')

Free download pdf