summaryrefslogtreecommitdiff
path: root/src/rexmpp_dns.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/rexmpp_dns.c')
-rw-r--r--src/rexmpp_dns.c137
1 files changed, 110 insertions, 27 deletions
diff --git a/src/rexmpp_dns.c b/src/rexmpp_dns.c
index 5c3f4f6..d56aa10 100644
--- a/src/rexmpp_dns.c
+++ b/src/rexmpp_dns.c
@@ -7,6 +7,7 @@
*/
#include <memory.h>
+#include <stdlib.h>
#include <syslog.h>
#include "config.h"
@@ -64,6 +65,7 @@ int rexmpp_parse_srv (char *in, int in_len, struct rexmpp_dns_srv *out) {
}
+#ifndef USE_RUST
void rexmpp_dns_result_free (rexmpp_dns_result_t *result) {
if (result->data != NULL) {
int i;
@@ -79,20 +81,37 @@ void rexmpp_dns_result_free (rexmpp_dns_result_t *result) {
}
free(result);
}
+#endif
rexmpp_dns_result_t *result_from_hostent (struct hostent *hostinfo) {
rexmpp_dns_result_t *r = malloc(sizeof(rexmpp_dns_result_t));
+ if (r == NULL) {
+ return NULL;
+ }
r->secure = 0;
int i, size = 0;
while (hostinfo->h_addr_list[size] != NULL) {
size++;
}
r->data = malloc(sizeof(void *) * (size + 1));
+ if (r->data == NULL) {
+ free(r);
+ return NULL;
+ }
r->len = malloc(sizeof(int) * size);
+ if (r->len == NULL) {
+ free(r->data);
+ free(r);
+ return NULL;
+ }
for (i = 0; i < size; i++) {
r->len[i] = hostinfo->h_length;
r->data[i] = malloc(r->len[i]);
- memcpy(r->data[i], hostinfo->h_addr_list[i], hostinfo->h_length);
+ if (r->data[i] != NULL) {
+ memcpy(r->data[i], hostinfo->h_addr_list[i], hostinfo->h_length);
+ } else {
+ return r;
+ }
}
r->data[size] = NULL;
return r;
@@ -102,22 +121,22 @@ rexmpp_dns_result_t *result_from_hostent (struct hostent *hostinfo) {
int rexmpp_dns_ctx_init (rexmpp_t *s) {
#if defined(USE_UNBOUND)
int err;
- s->resolver.ctx = ub_ctx_create();
- if (s->resolver.ctx == NULL) {
+ s->resolver = ub_ctx_create();
+ if (s->resolver == NULL) {
rexmpp_log(s, LOG_CRIT, "Failed to create resolver context");
return 1;
}
- err = ub_ctx_resolvconf(s->resolver.ctx, NULL);
+ err = ub_ctx_resolvconf(s->resolver, NULL);
if (err != 0) {
rexmpp_log(s, LOG_WARNING, "Failed to read resolv.conf: %s",
ub_strerror(err));
}
- err = ub_ctx_hosts(s->resolver.ctx, NULL);
+ err = ub_ctx_hosts(s->resolver, NULL);
if (err != 0) {
rexmpp_log(s, LOG_WARNING, "Failed to read hosts file: %s",
ub_strerror(err));
}
- err = ub_ctx_add_ta_file(s->resolver.ctx, DNSSEC_TRUST_ANCHOR_FILE);
+ err = ub_ctx_add_ta_file(s->resolver, DNSSEC_TRUST_ANCHOR_FILE);
if (err != 0) {
rexmpp_log(s, LOG_WARNING, "Failed to set root key file for DNSSEC: %s",
ub_strerror(err));
@@ -130,7 +149,7 @@ int rexmpp_dns_ctx_init (rexmpp_t *s) {
ares_strerror(err));
return 1;
}
- err = ares_init(&(s->resolver.channel));
+ err = ares_init(&(s->resolver));
if (err) {
rexmpp_log(s, LOG_CRIT, "ares channel initialisation error: %s",
ares_strerror(err));
@@ -139,7 +158,7 @@ int rexmpp_dns_ctx_init (rexmpp_t *s) {
}
return 0;
#else
- (void)s;
+ s->resolver = NULL;
return 0;
#endif
}
@@ -151,12 +170,15 @@ void rexmpp_dns_ctx_cleanup (rexmpp_t *s) {
void rexmpp_dns_ctx_deinit (rexmpp_t *s) {
#if defined(USE_UNBOUND)
- if (s->resolver.ctx != NULL) {
- ub_ctx_delete(s->resolver.ctx);
- s->resolver.ctx = NULL;
+ if (s->resolver != NULL) {
+ ub_ctx_delete(s->resolver);
+ s->resolver = NULL;
}
#elif defined(USE_CARES)
- ares_destroy(s->resolver.channel);
+ if (s->resolver != NULL) {
+ ares_destroy(s->resolver);
+ s->resolver = NULL;
+ }
ares_library_cleanup();
#else
(void)s;
@@ -166,13 +188,13 @@ void rexmpp_dns_ctx_deinit (rexmpp_t *s) {
int rexmpp_dns_fds (rexmpp_t *s, fd_set *read_fds, fd_set *write_fds) {
#if defined(USE_UNBOUND)
(void)write_fds;
- int max_fd = ub_fd(s->resolver.ctx) + 1;
+ int max_fd = ub_fd(s->resolver) + 1;
if (max_fd != 0) {
FD_SET(max_fd - 1, read_fds);
}
return max_fd;
#elif defined(USE_CARES)
- return ares_fds(s->resolver.channel, read_fds, write_fds);
+ return ares_fds(s->resolver, read_fds, write_fds);
#else
(void)s;
(void)read_fds;
@@ -181,16 +203,30 @@ int rexmpp_dns_fds (rexmpp_t *s, fd_set *read_fds, fd_set *write_fds) {
#endif
}
-struct timeval * rexmpp_dns_timeout (rexmpp_t *s,
- struct timeval *max_tv,
- struct timeval *tv)
+struct timespec * rexmpp_dns_timeout (rexmpp_t *s,
+ struct timespec *max_tv,
+ struct timespec *tv)
{
#if defined(USE_UNBOUND)
(void)s;
(void)tv;
return max_tv;
#elif defined(USE_CARES)
- return ares_timeout(s->resolver.channel, max_tv, tv);
+ struct timeval tv_ms;
+ struct timeval *max_tv_ms = NULL;
+ if (max_tv != NULL) {
+ max_tv_ms = &tv_ms;
+ tv_ms.tv_sec = tv->tv_sec;
+ tv_ms.tv_usec = tv->tv_nsec / 1000;
+ }
+ struct timeval *ret_ms = ares_timeout(s->resolver, max_tv_ms, &tv_ms);
+ if (ret_ms == max_tv_ms) {
+ return max_tv;
+ } else {
+ tv->tv_sec = tv_ms.tv_sec;
+ tv->tv_nsec = tv_ms.tv_usec * 1000;
+ return tv;
+ }
#else
(void)s;
(void)max_tv;
@@ -237,20 +273,54 @@ void rexmpp_dns_cb (void *ptr,
size++;
}
rexmpp_dns_result_t *res = malloc(sizeof(rexmpp_dns_result_t));
- res->data = malloc(sizeof(void *) * (size + 1));
+ if (res == NULL) {
+ rexmpp_log(s, LOG_DEBUG,
+ "Failed to allocate memory for a DNS resolution result");
+ ub_resolve_free(result);
+ d->cb(s, d->ptr, NULL);
+ free(d);
+ return;
+ }
+ res->data = calloc((size + 1), sizeof(void *));
+ if (res->data == NULL) {
+ rexmpp_log(s, LOG_DEBUG,
+ "Failed to allocate memory for a DNS resolution result's data");
+ free(res);
+ ub_resolve_free(result);
+ d->cb(s, d->ptr, NULL);
+ free(d);
+ return;
+ }
res->len = malloc(sizeof(int) * size);
+ if (res->len == NULL) {
+ rexmpp_log(s, LOG_DEBUG,
+ "Failed to allocate memory for a DNS resolution result's len");
+ free(res->data);
+ free(res);
+ ub_resolve_free(result);
+ d->cb(s, d->ptr, NULL);
+ free(d);
+ return;
+ }
for (i = 0; i < size; i++) {
if (result->qtype == 33) {
/* SRV */
res->len[i] = sizeof(rexmpp_dns_srv_t);
res->data[i] = malloc(res->len[i]);
+ if (res->data[i] == NULL) {
+ rexmpp_log(s, LOG_ERR,
+ "Failed to allocate memory for an SRV record");
+ d->cb(s, d->ptr, res);
+ rexmpp_dns_result_free(res);
+ free(d);
+ return;
+ }
int err = rexmpp_parse_srv(result->data[i], result->len[i],
(rexmpp_dns_srv_t*)res->data[i]);
if (err) {
rexmpp_log(s, LOG_WARNING, "Failed to parse an SRV record");
- res->data[i + 1] = NULL;
+ d->cb(s, d->ptr, res);
rexmpp_dns_result_free(res);
- d->cb(s, d->ptr, NULL);
free(d);
return;
}
@@ -258,7 +328,12 @@ void rexmpp_dns_cb (void *ptr,
/* Non-SRV, for now that's just A or AAAA */
res->len[i] = result->len[i];
res->data[i] = malloc(res->len[i]);
- memcpy(res->data[i], result->data[i], res->len[i]);
+ if (res->data[i] == NULL) {
+ rexmpp_log(s, LOG_WARNING,
+ "Failed to allocate memory for a DNS result's data record");
+ } else {
+ memcpy(res->data[i], result->data[i], res->len[i]);
+ }
}
}
res->data[size] = NULL;
@@ -332,10 +407,14 @@ int rexmpp_dns_resolve (rexmpp_t *s,
#if defined(USE_UNBOUND)
struct rexmpp_dns_query_cb_data *d =
malloc(sizeof(struct rexmpp_dns_query_cb_data));
+ if (d == NULL) {
+ rexmpp_log(s, LOG_ERR, "Failed to allocate memory for a DNS query");
+ return 1;
+ }
d->s = s;
d->cb = callback;
d->ptr = ptr;
- int err = ub_resolve_async(s->resolver.ctx, query, rrtype, rrclass,
+ int err = ub_resolve_async(s->resolver, query, rrtype, rrclass,
d, rexmpp_dns_cb, NULL);
if (err) {
rexmpp_log(s, LOG_ERR, "Failed to query %s: %s",
@@ -345,10 +424,14 @@ int rexmpp_dns_resolve (rexmpp_t *s,
#elif defined(USE_CARES)
struct rexmpp_dns_query_cb_data *d =
malloc(sizeof(struct rexmpp_dns_query_cb_data));
+ if (d == NULL) {
+ rexmpp_log(s, LOG_ERR, "Failed to allocate memory for a DNS query");
+ return 1;
+ }
d->s = s;
d->cb = callback;
d->ptr = ptr;
- ares_query(s->resolver.channel, query, rrclass, rrtype, rexmpp_dns_cb, d);
+ ares_query(s->resolver, query, rrclass, rrtype, rexmpp_dns_cb, d);
#else
if (rrclass == 1) {
if (rrtype == 1 || rrtype == 28) {
@@ -381,8 +464,8 @@ int rexmpp_dns_process (rexmpp_t *s, fd_set *read_fds, fd_set *write_fds) {
#if defined(USE_UNBOUND)
(void)read_fds;
(void)write_fds;
- if (ub_poll(s->resolver.ctx)) {
- int err = ub_process(s->resolver.ctx);
+ if (ub_poll(s->resolver)) {
+ int err = ub_process(s->resolver);
if (err != 0) {
rexmpp_log(s, LOG_ERR, "DNS query processing error: %s",
ub_strerror(err));
@@ -391,7 +474,7 @@ int rexmpp_dns_process (rexmpp_t *s, fd_set *read_fds, fd_set *write_fds) {
}
return 0;
#elif defined(USE_CARES)
- ares_process(s->resolver.channel, read_fds, write_fds);
+ ares_process(s->resolver, read_fds, write_fds);
return 0;
#else
(void)s;