From 37e8a87ea675b1708d854d39839ee02fcbb9f3aa Mon Sep 17 00:00:00 2001 From: defanor Date: Sat, 14 Nov 2020 15:23:22 +0300 Subject: Remove the c-ares dependency --- README | 3 +-- configure.ac | 4 ---- src/Makefile.am | 9 +++++---- src/rexmpp.c | 33 ++++++++------------------------- src/rexmpp.h | 2 ++ src/rexmpp_dns.c | 36 ++++++++++++++++++++++++++++++++++++ src/rexmpp_dns.h | 31 +++++++++++++++++++++++++++++++ 7 files changed, 83 insertions(+), 35 deletions(-) create mode 100644 src/rexmpp_dns.c create mode 100644 src/rexmpp_dns.h 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 #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 + @date 2020 + @copyright MIT license. +*/ + +#include "rexmpp_dns.h" +#include + +/* 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 + @date 2020 + @copyright MIT license. +*/ + + +#ifndef REXMPP_DNS_H +#define REXMPP_DNS_H + +#include + +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 -- cgit v1.2.3