From eae4e5d518d8b258d87f54c3cd35f6d111b42579 Mon Sep 17 00:00:00 2001 From: Rene Treffer Date: Thu, 3 Apr 2014 11:01:20 +0200 Subject: [PATCH] Add ability to use a provided ipv4 address on connect --- libs/minidns | 2 +- .../siacs/conversations/utils/DNSHelper.java | 58 +++++++++++++++---- .../conversations/xmpp/XmppConnection.java | 12 +++- 3 files changed, 59 insertions(+), 13 deletions(-) diff --git a/libs/minidns b/libs/minidns index d5cca3b3a..921674b3f 160000 --- a/libs/minidns +++ b/libs/minidns @@ -1 +1 @@ -Subproject commit d5cca3b3a48cfaed3008050fcab9574d97d771cc +Subproject commit 921674b3f1585dde76d13f181abcfc6d49bd737d diff --git a/src/eu/siacs/conversations/utils/DNSHelper.java b/src/eu/siacs/conversations/utils/DNSHelper.java index c5a3eeb09..bfab73e02 100644 --- a/src/eu/siacs/conversations/utils/DNSHelper.java +++ b/src/eu/siacs/conversations/utils/DNSHelper.java @@ -6,7 +6,10 @@ 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.A; +import de.measite.minidns.record.AAAA; import de.measite.minidns.record.Data; +import de.measite.minidns.util.NameUtil; import java.io.IOException; import java.net.InetAddress; @@ -42,12 +45,13 @@ public class DNSHelper { public static Bundle queryDNS(String host, InetAddress dnsServer) { Bundle namePort = new Bundle(); try { + String qname = "_xmpp-client._tcp." + host; Log.d("xmppService", "using dns server: " + dnsServer.getHostAddress() + " to look up " + host); DNSMessage message = client.query( - "_xmpp-client._tcp." + host, - TYPE.SRV, + qname, + TYPE.ANY, CLASS.IN, dnsServer.getHostAddress()); @@ -61,15 +65,36 @@ public class DNSHelper { TreeMap> priorities = new TreeMap>(); + TreeMap> ips4 = + new TreeMap>(); + TreeMap> ips6 = + new TreeMap>(); - for (Record rr : message.getAnswers()) { - Data d = rr.getPayload(); - if (d instanceof SRV) { - SRV srv = (SRV) d; - if (!priorities.containsKey(srv.getPriority())) { - priorities.put(srv.getPriority(), new ArrayList(2)); + for (Record[] rrset : new Record[][]{ message.getAnswers(), + message.getAdditionalResourceRecords()}) { + for (Record rr : rrset) { + Data d = rr.getPayload(); + if (d instanceof SRV && NameUtil.idnEquals(qname,rr.getName())) { + SRV srv = (SRV) d; + if (!priorities.containsKey(srv.getPriority())) { + priorities.put(srv.getPriority(), new ArrayList(2)); + } + priorities.get(srv.getPriority()).add(srv); + } + if (d instanceof A) { + A arecord = (A) d; + if (!ips4.containsKey(rr.getName())) { + ips4.put(rr.getName(), new ArrayList(3)); + } + ips4.get(rr.getName()).add(arecord.toString()); + } + if (d instanceof AAAA) { + AAAA aaaa = (AAAA) d; + if (!ips6.containsKey(rr.getName())) { + ips6.put(rr.getName(), new ArrayList(3)); + } + ips6.get(rr.getName()).add("[" + aaaa.toString() + "]"); } - priorities.get(srv.getPriority()).add(srv); } } @@ -113,9 +138,22 @@ public class DNSHelper { // we now have a list of servers to try :-) // classic name/port pair - namePort.putString("name", result.get(0).getName()); + String resultName = result.get(0).getName(); + namePort.putString("name", resultName); namePort.putInt("port", result.get(0).getPort()); + if (ips4.containsKey(resultName)) { + // we have an ip! + ArrayList ip = ips4.get(resultName); + Collections.shuffle(ip, rnd); + namePort.putString("ipv4", ip.get(0)); + } + if (ips6.containsKey(resultName)) { + ArrayList ip = ips6.get(resultName); + Collections.shuffle(ip, rnd); + namePort.putString("ipv6", ip.get(0)); + } + // add all other records int i = 0; for (SRV srv : result) { diff --git a/src/eu/siacs/conversations/xmpp/XmppConnection.java b/src/eu/siacs/conversations/xmpp/XmppConnection.java index 4baf5fae0..3a4668f44 100644 --- a/src/eu/siacs/conversations/xmpp/XmppConnection.java +++ b/src/eu/siacs/conversations/xmpp/XmppConnection.java @@ -129,11 +129,19 @@ public class XmppConnection implements Runnable { return; } String srvRecordServer = namePort.getString("name"); + String srvIpServer = namePort.getString("ipv4"); int srvRecordPort = namePort.getInt("port"); if (srvRecordServer != null) { - Log.d(LOGTAG, account.getJid() + ": using values from dns " + if (srvIpServer != null) { + Log.d(LOGTAG, account.getJid() + ": using values from dns " + + srvRecordServer + "[" + srvIpServer + "]:" + + srvRecordPort); + socket = new Socket(srvIpServer, srvRecordPort); + } else { + Log.d(LOGTAG, account.getJid() + ": using values from dns " + srvRecordServer + ":" + srvRecordPort); - socket = new Socket(srvRecordServer, srvRecordPort); + socket = new Socket(srvRecordServer, srvRecordPort); + } } else { socket = new Socket(account.getServer(), 5222); }