diff --git a/build/Makefile.am b/build/Makefile.am
index aa004388..c2667d5d 100644
--- a/build/Makefile.am
+++ b/build/Makefile.am
@@ -5,6 +5,7 @@ noinst_bindir = $(top_builddir)/build
EXTRA_DIST=
include ../toxcore/Makefile.inc
+include ../toxdns/Makefile.inc
include ../toxav/Makefile.inc
include ../other/Makefile.inc
include ../testing/Makefile.inc
diff --git a/libtoxcore.pc.in b/libtoxcore.pc.in
index e05e51cd..a91a1fb7 100644
--- a/libtoxcore.pc.in
+++ b/libtoxcore.pc.in
@@ -7,5 +7,5 @@ Name: libtoxcore
Description: Tox protocol library
Requires:
Version: @PACKAGE_VERSION@
-Libs: @NACL_OBJECTS_PKGCONFIG@ -L${libdir} @NACL_LDFLAGS@ -ltoxcore @NACL_LIBS@ @LIBS@ @MATH_LDFLAGS@
+Libs: @NACL_OBJECTS_PKGCONFIG@ -L${libdir} @NACL_LDFLAGS@ -ltoxdns -ltoxcore @NACL_LIBS@ @LIBS@ @MATH_LDFLAGS@
Cflags: -I${includedir}
diff --git a/toxdns/Makefile.inc b/toxdns/Makefile.inc
new file mode 100644
index 00000000..1e66ab3f
--- /dev/null
+++ b/toxdns/Makefile.inc
@@ -0,0 +1,28 @@
+lib_LTLIBRARIES += libtoxdns.la
+
+libtoxdns_la_include_HEADERS = \
+ ../toxdns/toxdns.h
+
+libtoxdns_la_includedir = $(includedir)/tox
+
+libtoxdns_la_SOURCES = ../toxdns/toxdns.h \
+ ../toxdns/toxdns.c
+
+libtoxdns_la_CFLAGS = -I$(top_srcdir) \
+ -I$(top_srcdir)/toxcore \
+ $(LIBSODIUM_CFLAGS) \
+ $(NACL_CFLAGS) \
+ $(PTHREAD_CFLAGS)
+
+libtoxdns_la_LDFLAGS = $(TOXCORE_LT_LDFLAGS) \
+ $(EXTRA_LT_LDFLAGS) \
+ $(LIBSODIUM_LDFLAGS) \
+ $(NACL_LDFLAGS) \
+ $(MATH_LDFLAGS) \
+ $(RT_LIBS) \
+ $(WINSOCK2_LIBS)
+
+libtoxdns_la_LIBADD = $(LIBSODIUM_LIBS) \
+ $(NACL_OBJECTS) \
+ $(NAC_LIBS) \
+ $(PTHREAD_LIBS)
diff --git a/toxdns/toxdns.c b/toxdns/toxdns.c
new file mode 100644
index 00000000..20a4486c
--- /dev/null
+++ b/toxdns/toxdns.c
@@ -0,0 +1,224 @@
+/* toxdns.c
+ *
+ * Tox secure username DNS toxid resolving functions.
+ *
+ * Copyright (C) 2013 Tox project All Rights Reserved.
+ *
+ * This file is part of Tox.
+ *
+ * Tox is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Tox is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Tox. If not, see .
+ *
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "../toxcore/Messenger.h"
+
+static const char base32[32] = {"abcdefghijklmnopqrstuvwxyz012345"};
+
+#define _encode(a, b, c) \
+{ \
+uint8_t i = 0; \
+ while(i != c) { \
+ *a++ = base32[((b[0] >> bits) | (b[1] << (8 - bits))) & 0x1F]; \
+ bits += 5; \
+ if(bits >= 8) { \
+ bits -= 8; \
+ b++; \
+ i++; \
+ } \
+ } \
+} \
+
+typedef struct {
+ uint8_t temp_pk[crypto_box_PUBLICKEYBYTES];
+ uint8_t temp_sk[crypto_box_SECRETKEYBYTES];
+ uint8_t server_public_key[crypto_box_PUBLICKEYBYTES];
+ uint8_t shared_key[crypto_box_KEYBYTES];
+ uint32_t nonce;
+ uint32_t nonce_start;
+} DNS_Object;
+
+static void dns_new_temp_keys(DNS_Object *d)
+{
+ d->nonce = d->nonce_start = random_int();
+ crypto_box_keypair(d->temp_pk, d->temp_sk);
+ encrypt_precompute(d->server_public_key, d->temp_sk, d->shared_key);
+}
+
+/* Create a new tox_dns3 object for server with server_public_key.
+ *
+ * return Null on failure.
+ * return pointer object on success.
+ */
+void *tox_dns3_new(uint8_t *server_public_key)
+{
+ DNS_Object *d = malloc(sizeof(DNS_Object));
+
+ if (d == NULL)
+ return NULL;
+
+ memcpy(d->server_public_key, server_public_key, crypto_box_PUBLICKEYBYTES);
+ dns_new_temp_keys(d);
+ return d;
+}
+
+/* Destroy the tox dns3 object.
+ */
+void tox_dns3_kill(void *dns3_object)
+{
+ memset(dns3_object, 0, sizeof(DNS_Object));
+ free(dns3_object);
+}
+
+/* Generate a dns3 string of string_max_len used to query the dns server reffered to by to
+ * dns3_object for a tox id registered to user with name of name_len.
+ *
+ * This is what the string returned looks like:
+ * 4haaaaipr1o3mz0bxweox541airydbovqlbju51mb4p0ebxq.rlqdj4kkisbep2ks3fj2nvtmk4daduqiueabmexqva1jc
+ *
+ * returns length of string on sucess.
+ * returns -1 on failure.
+ */
+int tox_generate_dns3_string(void *dns3_object, uint8_t *string, uint16_t string_max_len, uint8_t *name,
+ uint8_t name_len)
+{
+#define DOT_INTERVAL (6 * 5)
+ int base = (sizeof(uint32_t) + crypto_box_PUBLICKEYBYTES + name_len + crypto_box_MACBYTES);
+ int end_len = ((base * 8) / 5) + (base / DOT_INTERVAL) + !!(base % 5);
+
+ if (end_len > string_max_len)
+ return -1;
+
+ DNS_Object *d = dns3_object;
+ uint8_t buffer[1024];
+ uint8_t nonce[crypto_box_NONCEBYTES] = {0};
+ memcpy(nonce, &d->nonce, sizeof(uint32_t));
+ memcpy(buffer, &d->nonce, sizeof(uint32_t));
+ memcpy(buffer + sizeof(uint32_t), d->temp_pk, crypto_box_PUBLICKEYBYTES);
+ int len = encrypt_data_symmetric(d->shared_key, nonce, name, name_len,
+ buffer + sizeof(uint32_t) + crypto_box_PUBLICKEYBYTES);
+
+ if (len == -1)
+ return -1;
+
+ int total_len = len + sizeof(uint32_t) + crypto_box_PUBLICKEYBYTES;
+ uint8_t *buff = buffer, *old_str = string;
+ buffer[total_len] = 0;
+ uint8_t bits = 0;
+ int i;
+
+ for (i = 0; i < (total_len / DOT_INTERVAL); ++i) {
+ _encode(string, buff, DOT_INTERVAL);
+ *string = '.';
+ ++string;
+ }
+
+ _encode(string, buff, total_len % DOT_INTERVAL);
+#undef DOT_INTERVAL
+ ++d->nonce;
+
+ if (d->nonce == d->nonce_start) {
+ dns_new_temp_keys(d);
+ }
+
+ if (end_len != string - old_str) {
+ printf("tox_generate_dns3_string Fail\n");
+ return -1;
+ }
+
+ return string - old_str;
+}
+
+
+static int decode(uint8_t *dest, uint8_t *src)
+{
+ uint8_t *p = src, *op = dest, bits = 0;
+ *op = 0;
+
+ while (*p) {
+ uint8_t ch = *p++;
+
+ switch (ch) {
+ case 'A' ... 'Z': {
+ ch = ch - 'A';
+ break;
+ }
+
+ case 'a' ... 'z': {
+ ch = ch - 'a';
+ break;
+ }
+
+ case '0' ... '5': {
+ ch = ch - '0' + 26;
+ break;
+ }
+
+ default: {
+ return - 1;
+ }
+ }
+
+ *op |= (ch << bits);
+ bits += 5;
+
+ if (bits >= 8) {
+ bits -= 8;
+ ++op;
+ *op = (ch >> (5 - bits));
+ }
+ }
+
+ return op - dest;
+}
+
+/* Decode and decrypt the id_record returned of length id_record_len into
+ * tox_id (needs to be at least TOX_FRIEND_ADDRESS_SIZE).
+ *
+ * the id_record passed to this function should look somewhat like this:
+ * 4haaaa2vgcxuycbuctvauik3plsv3d3aadv4zfjfhi3thaizwxinelrvigchv0ah3qjcsx5qhmaksb2lv2hm5cwbtx0yp
+ *
+ * returns -1 on failure.
+ * returns 0 on success.
+ *
+ */
+int tox_decrypt_dns3_TXT(void *dns3_object, uint8_t *tox_id, uint8_t *id_record, uint32_t id_record_len)
+{
+ DNS_Object *d = dns3_object;
+
+ if (id_record_len != 93)
+ return -1;
+
+ /*if (id_record_len > 255 || id_record_len <= (sizeof(uint32_t) + crypto_box_MACBYTES))
+ return -1;*/
+
+ uint8_t data[id_record_len];
+ int length = decode(data, id_record);
+
+ if (length == -1)
+ return -1;
+
+ uint8_t nonce[crypto_box_NONCEBYTES] = {0};
+ memcpy(nonce, data, sizeof(uint32_t));
+ nonce[sizeof(uint32_t)] = 1;
+ int len = decrypt_data_symmetric(d->shared_key, nonce, data + sizeof(uint32_t), length - sizeof(uint32_t), tox_id);
+
+ if (len != FRIEND_ADDRESS_SIZE)
+ return -1;
+
+ return 0;
+}
\ No newline at end of file
diff --git a/toxdns/toxdns.h b/toxdns/toxdns.h
new file mode 100644
index 00000000..ac84af9c
--- /dev/null
+++ b/toxdns/toxdns.h
@@ -0,0 +1,78 @@
+/* toxdns.h
+ *
+ * Tox secure username DNS toxid resolving functions.
+ *
+ * Copyright (C) 2013 Tox project All Rights Reserved.
+ *
+ * This file is part of Tox.
+ *
+ * Tox is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Tox is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Tox. If not, see .
+ *
+ */
+
+#ifndef TOXDNS_H
+#define TOXDNS_H
+
+#include
+
+/* How to use this api to make secure tox dns3 requests:
+ *
+ * 1. Get the public key of a server that supports tox dns3.
+ * 2. use tox_dns3_new() to create a new object to create DNS requests
+ * and handle responses for that server.
+ * 3. Use tox_generate_dns3_string() to generate a string based on the name we want to query.
+ * 4. take the string and use it for your DNS request like this:
+ * _4haaaaipr1o3mz0bxweox541airydbovqlbju51mb4p0ebxq.rlqdj4kkisbep2ks3fj2nvtmk4daduqiueabmexqva1jc_._tox.utox.org
+ *
+ * 5. The TXT in the DNS you recieve should look like this:
+ * v=tox3;id=4haaaa2vgcxuycbuctvauik3plsv3d3aadv4zfjfhi3thaizwxinelrvigchv0ah3qjcsx5qhmaksb2lv2hm5cwbtx0yp
+ * 6. Take the id string and use it with tox_decrypt_dns3_TXT() to get the Tox id returned by the DNS server.
+ */
+
+/* Create a new tox_dns3 object for server with server_public_key of size TOX_CLIENT_ID_SIZE.
+ *
+ * return Null on failure.
+ * return pointer object on success.
+ */
+void *tox_dns3_new(uint8_t *server_public_key);
+
+/* Destroy the tox dns3 object.
+ */
+void tox_dns3_kill(void *dns3_object);
+
+/* Generate a dns3 string of string_max_len used to query the dns server reffered to by to
+ * dns3_object for a tox id registered to user with name of name_len.
+ *
+ * This is what the string returned looks like:
+ * 4haaaaipr1o3mz0bxweox541airydbovqlbju51mb4p0ebxq.rlqdj4kkisbep2ks3fj2nvtmk4daduqiueabmexqva1jc
+ *
+ * returns length of string on sucess.
+ * returns -1 on failure.
+ */
+int tox_generate_dns3_string(void *dns3_object, uint8_t *string, uint16_t string_max_len, uint8_t *name,
+ uint8_t name_len);
+
+/* Decode and decrypt the id_record returned of length id_record_len into
+ * tox_id (needs to be at least TOX_FRIEND_ADDRESS_SIZE).
+ *
+ * the id_record passed to this function should look somewhat like this:
+ * 4haaaa2vgcxuycbuctvauik3plsv3d3aadv4zfjfhi3thaizwxinelrvigchv0ah3qjcsx5qhmaksb2lv2hm5cwbtx0yp
+ *
+ * returns -1 on failure.
+ * returns 0 on success.
+ *
+ */
+int tox_decrypt_dns3_TXT(void *dns3_object, uint8_t *tox_id, uint8_t *id_record, uint32_t id_record_len);
+
+#endif