|
AXL MXLookup DNS API | |||||||||
| PREV CLASS NEXT CLASS | FRAMES NO FRAMES | |||||||||
| SUMMARY: NESTED | FIELD | CONSTR | METHOD | DETAIL: FIELD | CONSTR | METHOD | |||||||||
ObjectMXLookup
Looks up MX (Mail Exchange) records for a given host.
MX records are used to determine the SMTP server addresses for a give email address. For example, mail to mjl@theorem.com will actually go to a machine named mail.theorem.com, or a secondary (overflow or backup) server mail.cooldog.com. Typically a SMTP client will either use a "Smart Host" which can do MX record lookups on a "dumb host's" behalf or will use it's own internal MX record lookup. This class allows your SMTP client to become a Smart Host.
Note: The MX record for domain.com, a real domain, will return the name loopback which generally translates to your own IP address. This can cause mail loops. MXLookup returns a successful, but empty result to prevent this problem.
Although the example program below illustrates how to use a single thread performing a single lookup MXLookup can use one constructor with multiple .mxGet() methods, either sequentially in a single thread or concurrently by multiple threads. By default MXLookup can handle fifty concurrent lookups.
MXLookup class.
You can use MXLookup manually from the command line: java com.theorem.smtp.MXLookup acm.org
This uses the name server ns1.bellatlantic.net. You may wish
to write your own main() to use a closer name server.
For systems with multiple threads, first create a new instance of MXLookup()
and read the cache file in. Discard this instance.
Each thread requires a new instance of MXLookup() to keep the
DNS connections straight. The disk version of the cache should be saved
periodically and certainly before the program terminates.
Here is an example of how to perform the lookups (the main of MXLookup, in fact).
/**
* Tests MX lookup.
* Lists the mail hosts from the domain names the command line.
* Eg: java com.theorem.smtp.MXLookup compuserve.com aol.com theorem.com
* Reads and writes the file savemx in the current directory.
* This file contains the cached lookups.
*
* @param args hosts for which we want MX records.
*/
public static void main(String[] args)
{
if (args.length < 2)
{
System.err.println("Usage: java -jar mxlookup.jar [nameserver] [hostname] ...");
System.exit(1);
}
String nameServer = args[0];
MXLookup mx = null;
try {
mx = new MXLookup(nameServer);
} catch (UnknownHostException uhne) { System.err.println("Can't find host " + nameServer + " " + uhne); }
catch (SocketException see) { System.err.println("Socket error " + see); }
if (new File("savemx").exists() && mx.readCache("savemx") == false)
{
System.out.println("savemx file had a problem being read");
new File("savemx").delete();
}
for (int j = 1; j < args.length; j++)
{
String mxlist[] = null;
try {
mxlist = mx.getMX(args[j]);
} catch (IOException ioe)
{
// DNS must have timed out quit often.
System.err.println("DNS timed out quite often");
}
if (mxlist == null)
{
System.out.println("Lookup failed for " + args[j]);
continue;
}
System.out.println();
for (int i = 0; i < mxlist.length; i++)
{
System.out.print(mxlist[i]);
try {
System.out.println(", IP address is " + InetAddress.getByName(mxlist[i]).getHostAddress());
mx.addIP(args[j], mxlist[i], InetAddress.getByName(mxlist[i]));
} catch (UnknownHostException uhne1) { System.err.println("Can't find host " + mxlist[i] + " " + uhne1); }
}
}
mx.close();
if (mx.writeCache("savemx") == false)
{
System.out.println("savemx file had a problem being written");
}
}
| Field Summary | |
static String |
copyright
"Copyright 1998 Michael Lecuyer. All rights reserved"; |
static String |
Version
"2.26". |
| Constructor Summary | |
MXLookup()
Constructor to get at the internals of MXLookup without doing a lookup. |
|
MXLookup(String nameServer)
Connects to name server. |
|
MXLookup(String nameServer,
int port)
Connects to name a server on a particular port. |
|
MXLookup(String nameServer,
int port,
int timeout,
int retries)
Connects to name server on a particular port with settable timeout and retry values. |
|
| Method Summary | |
void |
addIP(String host,
String mxHost,
InetAddress ip)
Adds an IP address to the cache. |
void |
clearStats()
Clear statistics. |
void |
close()
Closes down the MXLookup system. |
static long |
elapsedTime(Date start)
Get elapsed time. |
static String |
elapsedTimeToString(Date start)
Get elapsed time of an event. |
void |
finalize()
Cleans up after the constructor. |
int |
getARecordLookups()
Return total number of successful A record (hostname) lookups. |
int |
getCacheHits()
Return total number of cache hits. |
int |
getFailedLookups()
Return total number of successful lookups. |
int |
getLookups()
Return total number of lookups. |
String[] |
getMX(String host)
|
MXData[] |
getMXFull(String host)
Get an array of MXData objects describing the full MX records. |
int |
getRetries()
Return total number of retries. |
int |
getSuccessfulLookups()
Return total number of successful lookups. |
static void |
main(String[] args)
Tests MX lookup. |
void |
merge(MXLookup mx)
Merge another MX cache list with the current one. |
boolean |
readCache(String fName)
Read MX cache records from a file. |
void |
setCacheSize(int cacheSize)
Sets cache size. |
void |
setMaximumRequests(int maxRequests)
Set the maximum concurrent outstanding requests the MXLookup class may handle. |
static Date |
startTime()
Start timing an event. |
String |
toString()
Return the string representation of MXLookup. |
void |
useMXOnly(boolean enable)
Do not fetch A records when performing a lookup. |
boolean |
writeCache(String fName)
Write MX cache records to a file. |
| Methods inherited from class Object |
equals, getClass, hashCode, notify, notifyAll, wait, wait, wait |
| Field Detail |
public static final String Version
public static final String copyright
| Constructor Detail |
public MXLookup()
public MXLookup(String nameServer,
int port)
throws SocketException,
UnknownHostException
nameServer - namer server host as a domain name or IP address string.port - Name server port. Uses default port 53 if port = 0
SocketException - Socket creation error
UnknownHostException - Unknown name server
public MXLookup(String nameServer,
int port,
int timeout,
int retries)
throws SocketException,
UnknownHostException
nameServer - Namer server host as a domain name or IP address string.port - Name server port. Uses default port 53 if port = 0timeout - Time out in seconds for a packet. The default is 5 seconds.
A value of 0 uses the default.retries - Maximum number of retries allowed. The default is 3, the maximum is 16
A value of 0 uses the default number of retries..
SocketException - Socket creation error
UnknownHostException - Unknown name server
public MXLookup(String nameServer)
throws SocketException,
UnknownHostException
nameServer - namer server host as a domain name or IP address string.
SocketException - Socket creation error
UnknownHostException - Unknown name server| Method Detail |
public static void main(String[] args)
args - hosts for which we want MX records.public void setCacheSize(int cacheSize)
cacheSize - number of entries in cache (default is 1024).public void useMXOnly(boolean enable)
When a domain does not return a valid MX record MXLookup attempts to resolve the full domain name. While this can properly resolve improper email addresses like @mail.theorem.com, the proper mailing address is @theorem.com. Some misconfigured systems don't use an MX record and this resolution is helpful.
When testing for a spam address from an ISP's dailup's and cable connections it's clear that the given address is certainly not a mail server because it doesn't have an MX record for itself, but does have one for the real SMPT server.
Warning: Before enabling this be aware that large ISP's mail sender machines are often not their mail receiver machines.
enable - True if MX records are the only valid records, false if the A records for the
raw domain is to be resolved. The default is false.
This should only be set once as it will affect all threads using the same MXLookup instance.
.
public MXData[] getMXFull(String host)
throws IOException
host - Host to look up.
IOException
public String[] getMX(String host)
throws IOException
IOExceptionpublic String toString()
public void addIP(String host,
String mxHost,
InetAddress ip)
host - original host name for lookup.mxHost - mx host actually looked up.ip - InetAddress object returned by InetAddress.getByName()public void finalize()
public void close()
public boolean writeCache(String fName)
fName - name of file to write.
true if all went well, false if there was an error.
public boolean readCache(String fName)
throws Exception
fName - name of file containing cache records to read.
true if all went well, false if there was an error.
Exceptionpublic int getRetries()
public int getLookups()
public int getCacheHits()
public int getSuccessfulLookups()
public int getFailedLookups()
public int getARecordLookups()
A records are lookups of last resort when MX records cannot be found. This usually occurs when a host has no MX records (rare), the DNS lookup timed out (sometimes happens), and most commonly when someone mistakenly uses their mail server for the email address.
public void clearStats()
public void merge(MXLookup mx)
This would appear in a globally available static class available to all threads created in the main thread:
public class GLOBAL {
static MXLookup masterLookup = new MXLookup();
}
Start a new MXLookup in each send mail thread.
Merge the current cache with the master cache periodically:
MXLookup mx = new MXLookup(nameServer);
...
mx.lookup("site.com");
...
GLOBAL.masterLookup.merge(mx);
GLOBAL.masterLookup.writeCache();
The thread's MXLookup simply reads the master MX cache file to preload it's cache.
readCache(java.lang.String)public void setMaximumRequests(int maxRequests)
This method can only increase the queue size. Attempts to shrink the queue size are ignored.
maxRequests - Maximum number of requests allowed in request queue.
This is the maximum number of concurrent outstanding requests. The default is 50.public static Date startTime()
elapsedTime(java.util.Date start),
elapsedTimeToString(java.util.Date start)public static long elapsedTime(Date start)
start - The time the clock started running.
elapsedTimeToString(java.util.Date),
startTime()public static String elapsedTimeToString(Date start)
start - The time the clock started running.
elapsedTime(java.util.Date start),
startTime()
|
AXL MXLookup DNS API | |||||||||
| PREV CLASS NEXT CLASS | FRAMES NO FRAMES | |||||||||
| SUMMARY: NESTED | FIELD | CONSTR | METHOD | DETAIL: FIELD | CONSTR | METHOD | |||||||||