Looking Up the SMTP Server for a Domain

Typically, users configure their mail programs to send all mail through a single SMTP server set up by the network administrator. This server is sometimes referred to as a smart host because it has the ability to look at an email address, query the Domain Name System (DNS) enough to find out which mail server handles mail for that domain, and then deliver the message.

The server that accepts mail for a domain is sometimes at an obvious location, like mail.domain.com, but it can be any server, even one in a different domain. Domain administrators list their mail servers in their public DNS information by adding MX (short for Mail Exchange) records that list the SMTP servers that will accept mail addressed to that domain. For example, the DNS records for oreilly.com list two MX records, smtp1.oreilly.com and smtp2.oreilly.com. So when you want to send an email to somebody@oreilly.com, it must be delivered to one of those two servers.

Typically, programs that send mail using SMTP are configured to use a smart host. The hostname of the outgoing SMTP server is stored in a configuration file, and all mail, regardless of the domain, is sent through that server. However, there are times when you might want to write a program that doesn't rely on a smart host. For example, you might want your application to be able to move between networks without having to be told where the local SMTP server is. Or you could actually be developing your own mail server. (For much more on mail servers, see Chapter 8.) In these cases, you'll need to query the DNS system to find the appropriate server to use for each address.

7.3.1. How Do I Do That?

Create a twisted.mail.relaymanager.MXCalculator object. Use its getMX method to look up the appropriate mail server for each address to which you need to deliver mail, as shown in Example 7-4.

Example 7-4. smtplookup.py

from twisted.mail import relaymanager

mxCalc = relaymanager.MXCalculator( )

def getSMTPServer(emailAddress):

 username, domain = emailAddress.split("@")

 return mxCalc.getMX(domain).addCallback(_gotMXRecord)

def _gotMXRecord(mxRecord):

 return mxRecord.exchange

if __name__ == "_ _main_ _":

 from twisted.internet import reactor

 import sys

 address = sys.argv[1]

 def printServer(server):

 print server

 reactor.stop( )

 def handleError(error):

 print >> sys.stderr, error.getErrorMessage( )

 reactor.stop( )


 reactor.run( )

Run smtplookup.py with an email address as its only argument. It will print out the name of a server that accepts mail for the address's domain:

 $ python smtplookup.py user@oreilly.com


 $ python smtplookup.py abe@fettig.net



7.3.2. How Does That Work?

smtplookup.py creates a twisted.mail.relaymanager.MXCalculator object called mxCalc. Note that it is created at the module level, instead of inside the getSMTPServer function; this will allow for the MXCalculator to use cached results if the same domain is looked up more than once.

The getSMTPServer function extracts the domain from the email address, and then returns the Deferred result of mxCalc.getMX(domain), while adding _gotMXRecord as a callback handler. The _gotMXRecord function does some simple filtering on the result of getMX, taking the result (a twisted.protocols.dns.Record_MX object) and returning just the exchange attribute, which contains the hostname of the mail server. This technique of adding an extra callback handler up front can be quite useful, enabling you to process or transform the result of a deferred function.

Getting Started

Building Simple Clients and Servers

Web Clients

Web Servers

Web Services and RPC


Mail Clients

Mail Servers

NNTP Clients and Servers


Services, Processes, and Logging

Twisted Network Programming Essentials
Twisted Network Programming Essentials
ISBN: 0596100329
EAN: 2147483647
Year: 2004
Pages: 107
Authors: Abe Fettig

Flylib.com © 2008-2020.
If you may any questions please contact us: flylib@qtcs.net