From 86dbb2f411c28a5eaae207caf1e6bcd1e56503b0 Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Fri, 7 Feb 2014 06:52:09 +0100 Subject: [PATCH] wrote the scariest code ever to fetch srv records from dns. todo use real dns servers and dont hard code 8.8.8.8 --- .../chat/services/XmppConnectionService.java | 2 +- src/de/gultsch/chat/utils/DNSHelper.java | 93 +++++++++++++++++++ src/de/gultsch/chat/xmpp/XmppConnection.java | 13 ++- 3 files changed, 106 insertions(+), 2 deletions(-) create mode 100644 src/de/gultsch/chat/utils/DNSHelper.java diff --git a/src/de/gultsch/chat/services/XmppConnectionService.java b/src/de/gultsch/chat/services/XmppConnectionService.java index 457c06b67..43be24c31 100644 --- a/src/de/gultsch/chat/services/XmppConnectionService.java +++ b/src/de/gultsch/chat/services/XmppConnectionService.java @@ -132,7 +132,7 @@ public class XmppConnectionService extends Service { String jid = packet.getAttribute("from"); String type = packet.getAttribute("type"); if (type==null) { - Log.d(LOGTAG,"online presence from "+jid); + //Log.d(LOGTAG,"online presence from "+jid); } } }; diff --git a/src/de/gultsch/chat/utils/DNSHelper.java b/src/de/gultsch/chat/utils/DNSHelper.java new file mode 100644 index 000000000..f19b1b6f0 --- /dev/null +++ b/src/de/gultsch/chat/utils/DNSHelper.java @@ -0,0 +1,93 @@ +package de.gultsch.chat.utils; + +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.net.DatagramPacket; +import java.net.DatagramSocket; +import java.net.InetAddress; +import java.util.Random; + +import android.os.Bundle; +import android.util.Log; + +public class DNSHelper { + public static Bundle getSRVRecord(String host) { + Bundle namePort = new Bundle(); + try { + String[] hostParts = host.split("\\."); + byte[] transId = new byte[2]; + Random random = new Random(); + random.nextBytes(transId); + byte[] header = { 0x01, 0x20, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x01, 0x0c, 0x5f, 0x78, 0x6d, 0x70, 0x70, 0x2d, 0x63, + 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x04, 0x5f, 0x74, 0x63, 0x70 }; + byte[] rest = { 0x00, 0x00, 0x21, 0x00, 0x01, 0x00, 0x00, 0x29, + 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; + ByteArrayOutputStream output = new ByteArrayOutputStream(); + output.write(transId); + output.write(header); + for (int i = 0; i < hostParts.length; ++i) { + char[] tmpChars = hostParts[i].toCharArray(); + byte[] tmp = new byte[tmpChars.length]; + for (int j = 0; j < tmpChars.length; ++j) { + tmp[j] = (byte) tmpChars[j]; + } + output.write(tmp.length); + output.write(tmp); + } + output.write(rest); + byte[] sendPaket = output.toByteArray(); + byte[] addr = { 0x8, 0x8, 0x8, 0x8 }; + int realLenght = sendPaket.length - 11; + DatagramPacket packet = new DatagramPacket(sendPaket, + sendPaket.length, InetAddress.getByAddress(addr), 53); + DatagramSocket datagramSocket = new DatagramSocket(); + datagramSocket.send(packet); + byte[] receiveData = new byte[1024]; + + DatagramPacket receivePacket = new DatagramPacket(receiveData, + receiveData.length); + datagramSocket.setSoTimeout(2000); + datagramSocket.receive(receivePacket); + if (receiveData[3]!=-128) { + namePort.putString("error", "nosrv"); + return namePort; + } + namePort.putInt("port",calcPort(receiveData[realLenght + 16], + receiveData[realLenght + 17])); + int i = realLenght + 18; + int wordLenght = 0; + StringBuilder builder = new StringBuilder(); + while (receiveData[i] != 0) { + if (wordLenght > 0) { + builder.append((char) receiveData[i]); + --wordLenght; + } else { + wordLenght = receiveData[i]; + builder.append("."); + } + ++i; + } + builder.replace(0, 1, ""); + namePort.putString("name",builder.toString()); + } catch (IOException e) { + Log.d("xmppService","gut" + e.getMessage()); + } + return namePort; + } + + static int calcPort(byte hb, byte lb) { + return ((int) hb << 8) | ((int) lb & 0xFF); + } + + final protected static char[] hexArray = "0123456789ABCDEF".toCharArray(); + public static String bytesToHex(byte[] bytes) { + char[] hexChars = new char[bytes.length * 2]; + for ( int j = 0; j < bytes.length; j++ ) { + int v = bytes[j] & 0xFF; + hexChars[j * 2] = hexArray[v >>> 4]; + hexChars[j * 2 + 1] = hexArray[v & 0x0F]; + } + return new String(hexChars); + } +} diff --git a/src/de/gultsch/chat/xmpp/XmppConnection.java b/src/de/gultsch/chat/xmpp/XmppConnection.java index c105bbb4b..d7443fc4e 100644 --- a/src/de/gultsch/chat/xmpp/XmppConnection.java +++ b/src/de/gultsch/chat/xmpp/XmppConnection.java @@ -14,9 +14,11 @@ import javax.net.ssl.SSLSocketFactory; import org.xmlpull.v1.XmlPullParserException; +import android.os.Bundle; import android.os.PowerManager; import android.util.Log; import de.gultsch.chat.entities.Account; +import de.gultsch.chat.utils.DNSHelper; import de.gultsch.chat.utils.SASL; import de.gultsch.chat.xml.Element; import de.gultsch.chat.xml.Tag; @@ -64,7 +66,15 @@ public class XmppConnection implements Runnable { protected void connect() { try { - socket = new Socket(account.getServer(), 5222); + Bundle namePort = DNSHelper.getSRVRecord(account.getServer()); + String srvRecordServer = namePort.getString("name"); + int srvRecordPort = namePort.getInt("port"); + if (srvRecordServer!=null) { + Log.d(LOGTAG,account.getJid()+": using values from dns "+srvRecordServer+":"+srvRecordPort); + socket = new Socket(srvRecordServer,srvRecordPort); + } else { + socket = new Socket(account.getServer(), 5222); + } OutputStream out = socket.getOutputStream(); tagWriter.setOutputStream(out); InputStream in = socket.getInputStream(); @@ -91,6 +101,7 @@ public class XmppConnection implements Runnable { } return; } catch (IOException e) { + Log.d(LOGTAG,"bla "+e.getMessage()); if (shouldConnect) { Log.d(LOGTAG,account.getJid()+": connection lost"); account.setStatus(Account.STATUS_OFFLINE);