diff options
-rw-r--r-- | INSTALL | 4 | ||||
-rw-r--r-- | doc/index.html | 4 | ||||
-rw-r--r-- | src/dnsfunnel/dnsfunneld.c | 4 | ||||
-rw-r--r-- | src/dnsfunnel/dnsfunneld_answer.c | 53 | ||||
-rw-r--r-- | src/dnsfunnel/dnsfunneld_process.c | 4 |
5 files changed, 35 insertions, 34 deletions
@@ -6,8 +6,8 @@ Build Instructions - A POSIX-compliant C development environment - GNU make version 3.81 or later - - skalibs version 2.10.0.0 or later: https://skarnet.org/software/skalibs/ - - s6-dns version 2.3.4.0 or later: https://skarnet.org/software/s6-dns/ + - skalibs version 2.10.0.1 or later: https://skarnet.org/software/skalibs/ + - s6-dns version 2.3.5.0 or later: https://skarnet.org/software/s6-dns/ This software will run on any operating system that implements POSIX.1-2008, available at: diff --git a/doc/index.html b/doc/index.html index b52f70a..e1d9a75 100644 --- a/doc/index.html +++ b/doc/index.html @@ -45,11 +45,11 @@ TCP DNS transport. It was originally written to be used in the <li> A POSIX-compliant system with a standard C development environment. </li> <li> GNU make, version 3.81 or later </li> <li> <a href="//skarnet.org/software/skalibs/">skalibs</a> version -2.10.0.0 or later. It's a build-time requirement. It's also a run-time +2.10.0.1 or later. It's a build-time requirement. It's also a run-time requirement if you link against the shared version of the skalibs library. </li> <li> <a href="//skarnet.org/software/s6-dns/">s6-dns</a> version -2.3.4.0 or later. It's a build-time requirement. It's also a run-time +2.3.5.0 or later. It's a build-time requirement. It's also a run-time requirement if you link against the shared version of the s6dns library. </li> diff --git a/src/dnsfunnel/dnsfunneld.c b/src/dnsfunnel/dnsfunneld.c index 48965f1..2beef07 100644 --- a/src/dnsfunnel/dnsfunneld.c +++ b/src/dnsfunnel/dnsfunneld.c @@ -122,12 +122,14 @@ void query_new (s6dns_domain_t const *d, uint16_t qtype, uint16_t id, uint32_t i .id = id, .dt = S6DNS_ENGINE_ZERO } ; + s6dns_domain_t dd = *d ; tain_t deadline ; uint32_t i ; if (!gensetdyn_new(&queries, &i)) strerr_diefu1sys(111, "create new query") ; + s6dns_domain_encode(&dd) ; tain_add_g(&deadline, &globaltto) ; - if (!s6dns_engine_init_g(&q.dt, &cachelist, S6DNS_O_RECURSIVE, d->s, d->len, qtype, &deadline)) + if (!s6dns_engine_init_g(&q.dt, &cachelist, S6DNS_O_RECURSIVE, dd.s, dd.len, qtype, &deadline)) strerr_diefu1sys(111, "start new query") ; *QUERY(i) = q ; QUERY(sentinel)->next = i ; diff --git a/src/dnsfunnel/dnsfunneld_answer.c b/src/dnsfunnel/dnsfunneld_answer.c index c06637f..e0fed6e 100644 --- a/src/dnsfunnel/dnsfunneld_answer.c +++ b/src/dnsfunnel/dnsfunneld_answer.c @@ -1,5 +1,7 @@ /* ISC license. */ +#define DEBUG + #include <errno.h> #include <stdint.h> #include <string.h> @@ -8,44 +10,35 @@ #include <skalibs/uint32.h> #include <skalibs/error.h> #include <skalibs/strerr2.h> -#include <skalibs/genqdyn.h> +#include <skalibs/stralloc.h> #include <skalibs/socket.h> #include <s6-dns/s6dns-message.h> #include "dnsfunneld.h" -typedef struct dfanswer_s dfanswer_t, *dfanswer_t_ref ; -struct dfanswer_s -{ - char buf[512] ; - char ip[4] ; - uint16_t port ; -} ; -#define DFANSWER_ZERO { .buf = { 0 }, .ip = "\0\0\0", .port = 0 } - -static genqdyn dfanswers = GENQDYN_INIT(dfanswer_t, 1, 8) ; +static stralloc q = STRALLOC_ZERO ; +static size_t head = 0 ; size_t dfanswer_pending () { - return (dfanswers.queue.len - dfanswers.head) / dfanswers.esize ; + return q.len - head ; } static void dfanswer_push (char const *s, size_t len, uint32_t ip, uint16_t port) { - if (len > 510) + if (len > 512) { if (verbosity) strerr_warnw1x("answer too big, dropping - enable truncation to avoid this") ; } else { - dfanswer_t ans = { .port = port } ; - uint16_pack_big(ans.buf, len) ; - memcpy(ans.buf + 2, s+2, len) ; - uint32_pack_big(ans.ip, ip) ; - if (!genqdyn_push(&dfanswers, &ans)) - strerr_diefu1sys(111, "queue answer to client") ; + if (!stralloc_readyplus(&q, len + 8)) strerr_diefu1sys(111, "queue answer to client") ; + uint32_pack_big(q.s + q.len, ip) ; q.len += 4 ; + uint16_pack_big(q.s + q.len, port) ; q.len += 2 ; + uint16_pack_big(q.s + q.len, len) ; q.len += 2 ; + memcpy(q.s + q.len, s, len) ; q.len += len ; } } @@ -53,19 +46,25 @@ int dfanswer_flush () { while (dfanswer_pending()) { - dfanswer_t *ans = GENQDYN_PEEK(dfanswer_t, &dfanswers) ; - uint16_t len ; - uint16_unpack_big(ans->buf, &len) ; - if (socket_send4(0, ans->buf, len, ans->ip, ans->port) < 0) + uint16_t port, len ; + uint16_unpack_big(q.s + head + 4, &port) ; + uint16_unpack_big(q.s + head + 6, &len) ; + if (socket_send4(0, q.s + head + 8, len, q.s + head, port) < 0) return error_isagain(errno) ? (errno = 0, 0) : -1 ; - genqdyn_pop(&dfanswers) ; + head += len + 8 ; + if ((q.len - head) >> 2 <= q.len) + { + memmove(q.s, q.s + head, q.len - head) ; + q.len -= head ; + head = 0 ; + } } return 1 ; } void dfanswer_fail (dfquery_t const *q) { - char buf[510] ; + char buf[512] ; uint16_t len ; s6dns_message_header_t hdr ; uint16_unpack_big(q->dt.sa.s, &len) ; @@ -85,7 +84,7 @@ void dfanswer_fail (dfquery_t const *q) void dfanswer_nxdomain (dfquery_t const *q) { - char buf[510] ; + char buf[512] ; uint16_t len ; s6dns_message_header_t hdr ; uint16_unpack_big(q->dt.sa.s, &len) ; @@ -105,7 +104,7 @@ void dfanswer_nxdomain (dfquery_t const *q) void dfanswer_nodata (dfquery_t const *q) { - char buf[510] ; + char buf[512] ; uint16_t len ; s6dns_message_header_t hdr ; uint16_unpack_big(q->dt.sa.s, &len) ; diff --git a/src/dnsfunnel/dnsfunneld_process.c b/src/dnsfunnel/dnsfunneld_process.c index 9d90289..8a0ffe2 100644 --- a/src/dnsfunnel/dnsfunneld_process.c +++ b/src/dnsfunnel/dnsfunneld_process.c @@ -54,7 +54,7 @@ static inline unsigned int truncate_packet (char *s, unsigned int olen) unsigned int tmp = pos ; if (!s6dns_message_parse_getrr(&rr, s, olen, &tmp)) return 0 ; section = s6dns_message_parse_next(&newcounts, &rr, s, olen, &tmp) ; - if (tmp > 510) + if (tmp > 512) { hdr.counts.qd -= counts.qd ; hdr.counts.an -= counts.an ; @@ -126,7 +126,7 @@ void query_process_response_failure (uint32_t ops, dfquery_t const *q) void query_process_response_success (uint32_t ops, dfquery_t const *q) { if (ops & 2 && q->procid && input_event(q, 1 + !isnxdomain(q))) return ; - if (ops & 1 && s6dns_engine_packetlen(&q->dt) > 510) + if (ops & 1 && s6dns_engine_packetlen(&q->dt) > 512) { unsigned int len = truncate_packet(s6dns_engine_packet(&q->dt), s6dns_engine_packetlen(&q->dt)) ; if (!len) dfanswer_fail(q) ; |