1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
|
package eu.siacs.conversations.utils;
import de.measite.minidns.Client;
import de.measite.minidns.DNSMessage;
import de.measite.minidns.Record;
import de.measite.minidns.Record.TYPE;
import de.measite.minidns.Record.CLASS;
import de.measite.minidns.record.SRV;
import de.measite.minidns.record.Data;
import de.measite.minidns.util.NameUtil;
import java.io.IOException;
import java.net.InetAddress;
import java.util.TreeSet;
import java.util.regex.Pattern;
import de.thedevstack.android.logcat.Logging;
import de.thedevstack.conversationsplus.dto.SrvRecord;
import eu.siacs.conversations.Config;
import eu.siacs.conversations.xmpp.jid.Jid;
public class DNSHelper {
private static final String CLIENT_SRV_PREFIX = "_xmpp-client._tcp.";
private static final Pattern PATTERN_IPV4 = Pattern.compile("\\A(25[0-5]|2[0-4]\\d|[0-1]?\\d?\\d)(\\.(25[0-5]|2[0-4]\\d|[0-1]?\\d?\\d)){3}\\z");
private static final Pattern PATTERN_IPV6_HEX4DECCOMPRESSED = Pattern.compile("\\A((?:[0-9A-Fa-f]{1,4}(?::[0-9A-Fa-f]{1,4})*)?) ::((?:[0-9A-Fa-f]{1,4}:)*)(25[0-5]|2[0-4]\\d|[0-1]?\\d?\\d)(\\.(25[0-5]|2[0-4]\\d|[0-1]?\\d?\\d)){3}\\z");
private static final Pattern PATTERN_IPV6_6HEX4DEC = Pattern.compile("\\A((?:[0-9A-Fa-f]{1,4}:){6,6})(25[0-5]|2[0-4]\\d|[0-1]?\\d?\\d)(\\.(25[0-5]|2[0-4]\\d|[0-1]?\\d?\\d)){3}\\z");
private static final Pattern PATTERN_IPV6_HEXCOMPRESSED = Pattern.compile("\\A((?:[0-9A-Fa-f]{1,4}(?::[0-9A-Fa-f]{1,4})*)?)::((?:[0-9A-Fa-f]{1,4}(?::[0-9A-Fa-f]{1,4})*)?)\\z");
private static final Pattern PATTERN_IPV6 = Pattern.compile("\\A(?:[0-9a-fA-F]{1,4}:){7}[0-9a-fA-F]{1,4}\\z");
protected static Client client = new Client();
/**
* Queries the SRV record for the server JID.
* This method uses all available Domain Name Servers.
* @param jid the server JID
* @return TreeSet with SrvRecords. If no SRV record is found for JID an empty TreeSet is returned.
*/
public static final TreeSet<SrvRecord> querySrvRecord(Jid jid) {
String host = jid.getDomainpart();
String dns[] = client.findDNS();
TreeSet<SrvRecord> result = new TreeSet<>();
if (dns != null) {
for (String dnsserver : dns) {
result = querySrvRecord(host, dnsserver);
if (!result.isEmpty()) {
break;
}
}
}
return result;
}
/**
* Queries the SRV record for an host from the given Domain Name Server.
* @param host the host to query for
* @param dnsserver the DNS to query on
* @return TreeSet with SrvRecords.
*/
private static final TreeSet<SrvRecord> querySrvRecord(String host, String dnsserver) {
TreeSet<SrvRecord> result = new TreeSet<>();
try {
InetAddress dnsServerAddress = InetAddress.getByName(dnsserver);
String qname = CLIENT_SRV_PREFIX + host;
DNSMessage message = client.query(qname, TYPE.SRV, CLASS.IN, dnsServerAddress.getHostAddress());
Record[] rrset = message.getAnswers();
for (Record rr : rrset) {
Data d = rr.getPayload();
if (d instanceof SRV && NameUtil.idnEquals(qname, rr.getName())) {
SRV srv = (SRV) d;
SrvRecord srvRecord = new SrvRecord(srv.getPriority(), srv.getName(), srv.getPort());
result.add(srvRecord);
}
}
} catch (IOException e) {
Logging.d("dns", "Error while retrieving SRV record for '" + host + "' from DNS '" + dnsserver + "': " + e.getMessage());
}
return result;
}
/**
* Checks whether the given server is an IP address or not.
* The following patterns are treated as valid IP addresses:
* <ul>
* <li>{@link #PATTERN_IPV4}</li>
* <li>{@link #PATTERN_IPV6}</li>
* <li>{@link #PATTERN_IPV6_6HEX4DEC}</li>
* <li>{@link #PATTERN_IPV6_HEX4DECCOMPRESSED}</li>
* <li>{@link #PATTERN_IPV6_HEXCOMPRESSED}</li>
* </ul>
* @param server the string to check
* @return <code>true</code> if one of the patterns is matched <code>false</code> otherwise
*/
public static boolean isIp(final String server) {
return PATTERN_IPV4.matcher(server).matches()
|| PATTERN_IPV6.matcher(server).matches()
|| PATTERN_IPV6_6HEX4DEC.matcher(server).matches()
|| PATTERN_IPV6_HEX4DECCOMPRESSED.matcher(server).matches()
|| PATTERN_IPV6_HEXCOMPRESSED.matcher(server).matches();
}
}
|