1
0
Fork 0
mirror of https://github.com/vanitasvitae/Smack.git synced 2024-11-23 04:22:05 +01:00

Fix Smack-225

git-svn-id: http://svn.igniterealtime.org/svn/repos/smack/trunk@10961 b35dd754-fafc-0310-a699-88a17e54d16e
This commit is contained in:
Jeff Williams 2009-02-24 00:24:06 +00:00 committed by jeff.williams
parent ac2c9b09dc
commit fdca9b339d

View file

@ -19,11 +19,14 @@
package org.jivesoftware.smack.util; package org.jivesoftware.smack.util;
import java.util.Hashtable;
import java.util.Map;
import javax.naming.NamingEnumeration;
import javax.naming.directory.Attribute;
import javax.naming.directory.Attributes; import javax.naming.directory.Attributes;
import javax.naming.directory.DirContext; import javax.naming.directory.DirContext;
import javax.naming.directory.InitialDirContext; import javax.naming.directory.InitialDirContext;
import java.util.Hashtable;
import java.util.Map;
/** /**
* Utilty class to perform DNS lookups for XMPP services. * Utilty class to perform DNS lookups for XMPP services.
@ -64,6 +67,13 @@ public class DNSUtil {
* *
* As an example, a lookup for "example.com" may return "im.example.com:5269". * As an example, a lookup for "example.com" may return "im.example.com:5269".
* *
* Note on SRV record selection.
* We now check priority and weight, but we still don't do this correctly.
* The missing behavior is this: if we fail to reach a host based on its SRV
* record then we need to select another host from the other SRV records.
* In Smack 3.1.1 we're not going to be able to do the major system redesign to
* correct this.
*
* @param domain the domain. * @param domain the domain.
* @return a HostAddress, which encompasses the hostname and port that the XMPP * @return a HostAddress, which encompasses the hostname and port that the XMPP
* server can be reached at for the specified domain. * server can be reached at for the specified domain.
@ -80,24 +90,50 @@ public class DNSUtil {
return address; return address;
} }
} }
String host = domain; String bestHost = domain;
int port = 5222; int bestPort = 5222;
int bestPriority = 0;
int bestWeight = 0;
try { try {
Attributes dnsLookup = Attributes dnsLookup = context.getAttributes("_xmpp-client._tcp." + domain, new String[]{"SRV"});
context.getAttributes("_xmpp-client._tcp." + domain, new String[]{"SRV"}); Attribute srvAttribute = dnsLookup.get("SRV");
String srvRecord = (String)dnsLookup.get("SRV").get(); NamingEnumeration srvRecords = srvAttribute.getAll();
while(srvRecords.hasMore()) {
String srvRecord = (String) srvRecords.next();
String [] srvRecordEntries = srvRecord.split(" "); String [] srvRecordEntries = srvRecord.split(" ");
port = Integer.parseInt(srvRecordEntries[srvRecordEntries.length-2]); int priority = Integer.parseInt(srvRecordEntries[srvRecordEntries.length - 4]);
host = srvRecordEntries[srvRecordEntries.length-1]; int port = Integer.parseInt(srvRecordEntries[srvRecordEntries.length-2]);
int weight = Integer.parseInt(srvRecordEntries[srvRecordEntries.length - 3]);
String host = srvRecordEntries[srvRecordEntries.length-1];
// Randomize the weight.
weight *= Math.random() * weight;
if ((bestPriority == 0) || (priority < bestPriority)) {
// Choose a server with the lowest priority.
bestPriority = priority;
bestWeight = weight;
bestHost = host;
bestPort = port;
} else if (priority == bestPriority) {
// When we have like priorities then randomly choose a server based on its weight
// The weights were randomized above.
if (weight > bestWeight) {
bestWeight = weight;
bestHost = host;
bestPort = port;
}
}
}
} }
catch (Exception e) { catch (Exception e) {
// Ignore. // Ignore.
} }
// Host entries in DNS should end with a ".". // Host entries in DNS should end with a ".".
if (host.endsWith(".")) { if (bestHost.endsWith(".")) {
host = host.substring(0, host.length()-1); bestHost = bestHost.substring(0, bestHost.length()-1);
} }
HostAddress address = new HostAddress(host, port); HostAddress address = new HostAddress(bestHost, bestPort);
// Add item to cache. // Add item to cache.
cache.put(key, address); cache.put(key, address);
return address; return address;