/** * Returns an ordered host name list based on the MX records of the domain. * The first has the highest priority. If the domain has no MX records, then * it returns the host itself. Records with the same priority are shuffled * randomly. * * @see <a href="http://tools.ietf.org/html/rfc5321#section-5.1">RFC 5321 * Simple Mail Transfer Protocol - Locating the Target Host</a> */ public Name[] queryMxTargets(Domain domain) throws MxLookupException { MXRecord[] records = queryMxRecords(domain); if (records.length == 0) { logger.debug("Domain {} has no MX records, using an implicit " + "MX record targetting the host", domain); return implicitMxTargetForDomain(domain); } else { // ArrayList<MXRecord> list = new ArrayList<MXRecord>(Arrays.asList(records)); Collections.shuffle(list); // This sort is guaranteed to be stable: equal elements will not be // reordered as a result of the sort, so shuffle remains in effect Collections.sort(list, mxRecordPriorityComparator); list.toArray(records); return convertMxRecordsToHostNames(records); } }
@Test() public void testSamePriorityReallyShuffled() throws MxLookupException { new Expectations() { { lookup.run(); result = new MXRecord[] { HOST1_PRIORITY10, HOST2_PRIORITY10, HOST3_PRIORITY10, HOST4_PRIORITY10 }; } }; final int COUNT_OF_TEST_RUNS = 4; List<Name[]> listOfResults = new ArrayList<Name[]>(); for (int i = 0; i < COUNT_OF_TEST_RUNS; i++) { listOfResults.add(mxLookup.queryMxTargets(EXAMPLE_COM_DOMAIN)); } assertTrue(reallyShuffled(listOfResults)); }
@Override public int compare(MXRecord o1, MXRecord o2) { int p1 = o1.getPriority(); int p2 = o2.getPriority(); if (p1 < p2) return -1; else if (p1 > p2) return +1; else return 0; }
@Test() public void testDifferentPriority() throws MxLookupException { new Expectations() { { lookup.run(); result = new MXRecord[] { HOST2_PRIORITY20, HOST1_PRIORITY10 }; } }; Name[] targets = mxLookup.queryMxTargets(EXAMPLE_COM_DOMAIN); assertArrayEquals(new Name[] { HOST1_EXAMPLE_COM_NAME, HOST2_EXAMPLE_COM_NAME }, targets); }
public static ArrayList<MXRecord> mxLookup(String server) throws Exception { ArrayList<MXRecord> mxServers = new ArrayList<MXRecord>(); Lookup lookup = new Lookup(server, Type.MX); Record[] records = lookup.run(); for (int i = 0; i < records.length; i++) { mxServers.add((MXRecord)records[i]); } Collections.sort(mxServers, new MXCompare()); return mxServers; }
public static String getMxServer(String server) throws Exception { ArrayList<MXRecord> servers = MXExchange.mxLookup(server); if (servers.isEmpty()) { return null; } String serverName = servers.get(0).getTarget().toString(); return serverName.substring(0, serverName.length() - 1); }
private Name[] convertMxRecordsToHostNames(MXRecord[] records) { Name[] result = new Name[records.length]; for (int i = result.length; --i >= 0;) result[i] = records[i].getTarget(); return result; }
@Override public int compare(Object arg0, Object arg1) { return Integer.compare(((MXRecord) arg0).getPriority(), ((MXRecord) arg1).getPriority()); }
public static MXRecord getMXRecord(String domainName) { return null; }
public MXRecord getMXRecord(String domainName) { return null; }
/** * Return a prioritized unmodifiable list of MX records obtained from the * server. * * @param hostname * domain name to look up * * @return a list of MX records corresponding to this mail domain * @throws TemporaryResolutionException * get thrown on temporary problems */ private List<String> findMXRecordsRaw(String hostname) throws TemporaryResolutionException { Record answers[] = lookup(hostname, Type.MX, "MX"); List<String> servers = new ArrayList<String>(); if (answers == null) { return servers; } MXRecord[] mxAnswers = new MXRecord[answers.length]; for (int i = 0; i < answers.length; i++) { mxAnswers[i] = (MXRecord) answers[i]; } // just sort for now.. This will ensure that mx records with same prio // are in sequence Arrays.sort(mxAnswers, mxComparator); // now add the mx records to the right list and take care of shuffle // mx records with the same priority int currentPrio = -1; List<String> samePrio = new ArrayList<String>(); for (int i = 0; i < mxAnswers.length; i++) { boolean same = false; boolean lastItem = i + 1 == mxAnswers.length; MXRecord mx = mxAnswers[i]; if (i == 0) { currentPrio = mx.getPriority(); } else { if (currentPrio == mx.getPriority()) { same = true; } else { same = false; } } String mxRecord = mx.getTarget().toString(); if (same) { samePrio.add(mxRecord); } else { // shuffle entries with same prio // JAMES-913 Collections.shuffle(samePrio); servers.addAll(samePrio); samePrio.clear(); samePrio.add(mxRecord); } if (lastItem) { // shuffle entries with same prio // JAMES-913 Collections.shuffle(samePrio); servers.addAll(samePrio); } logger.debug(new StringBuffer("Found MX record ").append(mxRecord).toString()); } return servers; }
public int compare(MXRecord a, MXRecord b) { int pa = a.getPriority(); int pb = b.getPriority(); return pa - pb; }