summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--README3
-rw-r--r--configure.ac4
-rw-r--r--src/Makefile.am9
-rw-r--r--src/rexmpp.c33
-rw-r--r--src/rexmpp.h2
-rw-r--r--src/rexmpp_dns.c36
-rw-r--r--src/rexmpp_dns.h31
7 files changed, 83 insertions, 35 deletions
diff --git a/README b/README
index 75f202d..75a326d 100644
--- a/README
+++ b/README
@@ -14,8 +14,7 @@ rely on any particular UI, should be flexible and not stay in the way
of implementing additional XEPs on top of it, and should try to make
it easy to implement a decent client application using it.
-Current dependencies: libunbound, c-ares, libxml2, gnutls,
-gnutls-dane, gsasl.
+Current dependencies: libunbound, libxml2, gnutls, gnutls-dane, gsasl.
A rough roadmap:
diff --git a/configure.ac b/configure.ac
index 8fd21d6..b8e3786 100644
--- a/configure.ac
+++ b/configure.ac
@@ -32,10 +32,6 @@ PKG_CHECK_MODULES([GSASL], [libgsasl])
AC_SUBST(GSASL_CFLAGS)
AC_SUBST(GSASL_LIBS)
-PKG_CHECK_MODULES([CARES], [libcares])
-AC_SUBST(CARES_CFLAGS)
-AC_SUBST(CARES_LIBS)
-
PKG_CHECK_MODULES([UNBOUND], [libunbound])
AC_SUBST(UNBOUND_CFLAGS)
AC_SUBST(UNBOUND_LIBS)
diff --git a/src/Makefile.am b/src/Makefile.am
index f3cd9c0..6ee0e82 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -11,7 +11,8 @@ lib_LTLIBRARIES = librexmpp.la
librexmpp_la_SOURCES = rexmpp_roster.h rexmpp_roster.c \
rexmpp_tcp.h rexmpp_tcp.c \
rexmpp_socks.h rexmpp_socks.c \
- rexmpp.h rexmpp.c
-include_HEADERS = rexmpp_roster.h rexmpp_tcp.h rexmpp_socks.h rexmpp.h
-librexmpp_la_CFLAGS = $(AM_CFLAGS) $(LIBXML_CFLAGS) $(GNUTLS_CFLAGS) $(LIBDANE_CFLAGS) $(GSASL_CFLAGS) $(CARES_CFLAGS) $(UNBOUND_CFLAGS)
-librexmpp_la_LIBADD = $(LIBXML_LIBS) $(GNUTLS_LIBS) $(LIBDANE_LIBS) $(GSASL_LIBS) $(CARES_LIBS) $(UNBOUND_LIBS)
+ rexmpp.h rexmpp.c \
+ rexmpp_dns.h rexmpp_dns.c
+include_HEADERS = rexmpp_roster.h rexmpp_tcp.h rexmpp_socks.h rexmpp.h rexmpp_dns.h
+librexmpp_la_CFLAGS = $(AM_CFLAGS) $(LIBXML_CFLAGS) $(GNUTLS_CFLAGS) $(LIBDANE_CFLAGS) $(GSASL_CFLAGS) $(UNBOUND_CFLAGS)
+librexmpp_la_LIBADD = $(LIBXML_LIBS) $(GNUTLS_LIBS) $(LIBDANE_LIBS) $(GSASL_LIBS) $(UNBOUND_LIBS)
diff --git a/src/rexmpp.c b/src/rexmpp.c
index 59059a2..7068270 100644
--- a/src/rexmpp.c
+++ b/src/rexmpp.c
@@ -26,6 +26,7 @@
#include "rexmpp_tcp.h"
#include "rexmpp_socks.h"
#include "rexmpp_roster.h"
+#include "rexmpp_dns.h"
void rexmpp_sax_start_elem_ns (rexmpp_t *s,
const char *localname,
@@ -317,19 +318,10 @@ rexmpp_err_t rexmpp_init (rexmpp_t *s, const char *jid)
ub_strerror(err));
}
- err = ares_library_init(ARES_LIB_INIT_ALL);
- if (err != 0) {
- rexmpp_log(s, LOG_CRIT, "ares library initialisation error: %s",
- ares_strerror(err));
- xmlFreeParserCtxt(s->xml_parser);
- return REXMPP_E_DNS;
- }
-
err = gnutls_certificate_allocate_credentials(&(s->gnutls_cred));
if (err) {
rexmpp_log(s, LOG_CRIT, "gnutls credentials allocation error: %s",
gnutls_strerror(err));
- ares_library_cleanup();
xmlFreeParserCtxt(s->xml_parser);
return REXMPP_E_TLS;
}
@@ -337,7 +329,6 @@ rexmpp_err_t rexmpp_init (rexmpp_t *s, const char *jid)
if (err < 0) {
rexmpp_log(s, LOG_CRIT, "Certificates loading error: %s",
gnutls_strerror(err));
- ares_library_cleanup();
xmlFreeParserCtxt(s->xml_parser);
return REXMPP_E_TLS;
}
@@ -347,7 +338,6 @@ rexmpp_err_t rexmpp_init (rexmpp_t *s, const char *jid)
rexmpp_log(s, LOG_CRIT, "gsasl initialisation error: %s",
gsasl_strerror(err));
gnutls_certificate_free_credentials(s->gnutls_cred);
- ares_library_cleanup();
xmlFreeParserCtxt(s->xml_parser);
return REXMPP_E_SASL;
}
@@ -430,7 +420,6 @@ void rexmpp_done (rexmpp_t *s) {
ub_ctx_delete(s->resolver_ctx);
s->resolver_ctx = NULL;
}
- ares_library_cleanup();
xmlFreeParserCtxt(s->xml_parser);
if (s->initial_jid != NULL) {
free(s->initial_jid);
@@ -974,8 +963,6 @@ void rexmpp_start_connecting (rexmpp_t *s) {
}
void rexmpp_try_next_host (rexmpp_t *s) {
- long enclen;
- char *cur_data;
struct ub_result *cur_result;
int cur_number;
/* todo: check priorities and weights */
@@ -1013,21 +1000,17 @@ void rexmpp_try_next_host (rexmpp_t *s) {
rexmpp_schedule_reconnect(s);
return;
}
- if (cur_result->len[cur_number] < 7) {
- rexmpp_log(s, LOG_ERR, "An SRV record is too short.");
+
+ if (rexmpp_parse_srv(cur_result->data[cur_number],
+ cur_result->len[cur_number],
+ &(s->server_active_srv))) {
+ rexmpp_log(s, LOG_DEBUG, "Failed to parse an SRV record");
rexmpp_cleanup(s);
rexmpp_schedule_reconnect(s);
return;
}
- cur_data = cur_result->data[cur_number];
- /* TODO: replace the following with a custom function, to remove the
- c-ares dependency. */
- ares_expand_name(cur_data + 6,
- cur_data,
- cur_result->len[cur_number],
- (char**)&(s->server_host),
- &enclen);
- s->server_port = cur_data[4] * 0x100 + cur_data[5];
+ s->server_host = s->server_active_srv.target;
+ s->server_port = s->server_active_srv.port;
rexmpp_start_connecting(s);
}
diff --git a/src/rexmpp.h b/src/rexmpp.h
index 78ec5a6..e826099 100644
--- a/src/rexmpp.h
+++ b/src/rexmpp.h
@@ -16,6 +16,7 @@
#include <libxml/tree.h>
#include "rexmpp_tcp.h"
#include "rexmpp_socks.h"
+#include "rexmpp_dns.h"
typedef struct rexmpp rexmpp_t;
@@ -288,6 +289,7 @@ struct rexmpp
int server_srv_cur;
struct ub_result *server_srv_tls;
int server_srv_tls_cur;
+ struct rexmpp_dns_srv server_active_srv;
/* The XMPP server we are connecting to. */
const char *server_host;
diff --git a/src/rexmpp_dns.c b/src/rexmpp_dns.c
new file mode 100644
index 0000000..6a8e743
--- /dev/null
+++ b/src/rexmpp_dns.c
@@ -0,0 +1,36 @@
+/**
+ @file rexmpp_dns.c
+ @brief DNS helper functions
+ @author defanor <defanor@uberspace.net>
+ @date 2020
+ @copyright MIT license.
+*/
+
+#include "rexmpp_dns.h"
+#include <memory.h>
+
+/* https://tools.ietf.org/html/rfc1035#section-3.1 */
+int rexmpp_parse_srv (char *in, int in_len, struct rexmpp_dns_srv *out) {
+ int i;
+ char *name;
+ if (in_len < 7 || in_len > 255 + 6) {
+ return -1;
+ }
+ out->priority = in[0] * 0x100 + in[1];
+ out->weight = in[2] * 0x100 + in[3];
+ out->port = in[4] * 0x100 + in[5];
+ name = in + 6;
+ i = 0;
+ while (name[i]) {
+ if (i + name[i] < 255) {
+ memcpy(out->target + i, name + i + 1, name[i]);
+ i += name[i];
+ out->target[i] = '.';
+ i++;
+ out->target[i] = '\0';
+ } else {
+ return -1;
+ }
+ }
+ return 0;
+}
diff --git a/src/rexmpp_dns.h b/src/rexmpp_dns.h
new file mode 100644
index 0000000..f9c8b81
--- /dev/null
+++ b/src/rexmpp_dns.h
@@ -0,0 +1,31 @@
+/**
+ @file rexmpp_dns.h
+ @brief DNS helper functions
+ @author defanor <defanor@uberspace.net>
+ @date 2020
+ @copyright MIT license.
+*/
+
+
+#ifndef REXMPP_DNS_H
+#define REXMPP_DNS_H
+
+#include <stdint.h>
+
+struct rexmpp_dns_srv {
+ uint16_t priority;
+ uint16_t weight;
+ uint16_t port;
+ char target[256];
+};
+
+/**
+ @brief Parses an SRV DNS RR's RDATA.
+ @param[in] in SRV record's RDATA.
+ @param[in] in_len Length of the input data in octets.
+ @param[out] out A structure to fill with data.
+ @returns 0 on success, non-zero on parsing failure.
+*/
+int rexmpp_parse_srv (char *in, int in_len, struct rexmpp_dns_srv *out);
+
+#endif