summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-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
5 files changed, 82 insertions, 29 deletions
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