mirror of
https://codeberg.org/Mercury-IM/Smack
synced 2024-11-30 10:12:06 +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:
parent
ac2c9b09dc
commit
fdca9b339d
1 changed files with 49 additions and 13 deletions
|
@ -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;
|
||||||
|
|
Loading…
Reference in a new issue