wrote the scariest code ever to fetch srv records from dns. todo use real dns servers and dont hard code 8.8.8.8

Daniel Gultsch created

Change summary

src/de/gultsch/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(-)

Detailed changes

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);
 			}
 		}
 	};

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);
+	}
+}

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);