1
0
Fork 0
mirror of https://codeberg.org/Mercury-IM/Smack synced 2024-11-29 17:52:06 +01:00

Support for International Domain Names in DNSUtil

This commit is contained in:
Florian Schmaus 2014-09-13 09:27:55 +02:00
parent f2718c2d76
commit d3cea48c0d
2 changed files with 78 additions and 9 deletions

View file

@ -39,6 +39,23 @@ public class DNSUtil {
private static final Logger LOGGER = Logger.getLogger(DNSUtil.class.getName()); private static final Logger LOGGER = Logger.getLogger(DNSUtil.class.getName());
private static DNSResolver dnsResolver = null; private static DNSResolver dnsResolver = null;
/**
* International Domain Name transformer.
* <p>
* Used to transform Unicode representations of the Domain Name to ASCII in
* order to perform a DNS request with the ASCII representation.
* 'java.net.IDN' is available since Android API 9, but as long as Smack
* requires API 8, we are going to need this. This part is going to get
* removed once Smack depends on Android API 9 or higher.
* </p>
*/
private static StringTransformer idnaTransformer = new StringTransformer() {
@Override
public String transform(String string) {
return string;
}
};
/** /**
* Set the DNS resolver that should be used to perform DNS lookups. * Set the DNS resolver that should be used to perform DNS lookups.
* *
@ -57,6 +74,27 @@ public class DNSUtil {
return dnsResolver; return dnsResolver;
} }
/**
* Set the IDNA (Internatiionalizing Domain Names in Applications, RFC 3490) transformer.
* <p>
* You usually want to wrap 'java.net.IDN.toASCII()' into a StringTransformer here.
* </p>
* @param idnaTransformer
*/
public static void setIdnaTransformer(StringTransformer idnaTransformer) {
if (idnaTransformer == null) {
throw new NullPointerException();
}
DNSUtil.idnaTransformer = idnaTransformer;
}
private static enum DomainType {
Server,
Client,
;
}
/** /**
* Returns a list of HostAddresses under which the specified XMPP server can be * Returns a list of HostAddresses under which the specified XMPP server can be
* reached at for client-to-server communication. A DNS lookup for a SRV * reached at for client-to-server communication. A DNS lookup for a SRV
@ -75,13 +113,15 @@ public class DNSUtil {
* XMPP server can be reached at for the specified domain. * XMPP server can be reached at for the specified domain.
* @throws Exception * @throws Exception
*/ */
public static List<HostAddress> resolveXMPPDomain(final String domain) throws Exception { public static List<HostAddress> resolveXMPPDomain(String domain) throws Exception {
domain = idnaTransformer.transform(domain);
if (dnsResolver == null) { if (dnsResolver == null) {
LOGGER.warning("No DNS Resolver active in Smack, will be unable to perform DNS SRV lookups");
List<HostAddress> addresses = new ArrayList<HostAddress>(1); List<HostAddress> addresses = new ArrayList<HostAddress>(1);
addresses.add(new HostAddress(domain, 5222)); addresses.add(new HostAddress(domain, 5222));
return addresses; return addresses;
} }
return resolveDomain(domain, 'c'); return resolveDomain(domain, DomainType.Client);
} }
/** /**
@ -102,26 +142,31 @@ public class DNSUtil {
* XMPP server can be reached at for the specified domain. * XMPP server can be reached at for the specified domain.
* @throws Exception * @throws Exception
*/ */
public static List<HostAddress> resolveXMPPServerDomain(final String domain) throws Exception { public static List<HostAddress> resolveXMPPServerDomain(String domain) throws Exception {
domain = idnaTransformer.transform(domain);
if (dnsResolver == null) { if (dnsResolver == null) {
LOGGER.warning("No DNS Resolver active in Smack, will be unable to perform DNS SRV lookups");
List<HostAddress> addresses = new ArrayList<HostAddress>(1); List<HostAddress> addresses = new ArrayList<HostAddress>(1);
addresses.add(new HostAddress(domain, 5269)); addresses.add(new HostAddress(domain, 5269));
return addresses; return addresses;
} }
return resolveDomain(domain, 's'); return resolveDomain(domain, DomainType.Server);
} }
private static List<HostAddress> resolveDomain(String domain, char keyPrefix) throws Exception { private static List<HostAddress> resolveDomain(String domain, DomainType domainType) throws Exception {
List<HostAddress> addresses = new ArrayList<HostAddress>(); List<HostAddress> addresses = new ArrayList<HostAddress>();
// Step one: Do SRV lookups // Step one: Do SRV lookups
String srvDomain; String srvDomain;
if (keyPrefix == 's') { switch (domainType) {
case Server:
srvDomain = "_xmpp-server._tcp." + domain; srvDomain = "_xmpp-server._tcp." + domain;
} else if (keyPrefix == 'c') { break;
case Client:
srvDomain = "_xmpp-client._tcp." + domain; srvDomain = "_xmpp-client._tcp." + domain;
} else { break;
srvDomain = domain; default:
throw new AssertionError();
} }
try { try {
List<SRVRecord> srvRecords = dnsResolver.lookupSRVRecords(srvDomain); List<SRVRecord> srvRecords = dnsResolver.lookupSRVRecords(srvDomain);
@ -225,4 +270,5 @@ public class DNSUtil {
} }
return pos; return pos;
} }
} }

View file

@ -0,0 +1,23 @@
/**
*
* Copyright 2014 Florian Schmaus
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jivesoftware.smack.util;
public interface StringTransformer {
public String transform(String string);
}