diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/Makefile.am | 9 | ||||
-rw-r--r-- | src/rexmpp.c | 33 | ||||
-rw-r--r-- | src/rexmpp.h | 2 | ||||
-rw-r--r-- | src/rexmpp_dns.c | 36 | ||||
-rw-r--r-- | src/rexmpp_dns.h | 31 |
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 |