summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorLaurent Bercot <ska-skaware@skarnet.org>2021-01-15 02:04:18 +0000
committerLaurent Bercot <ska-skaware@skarnet.org>2021-01-15 02:04:18 +0000
commitc47e30d38e6815174ddfc0fa0d718da18849db75 (patch)
tree9009dd8417d575c608e7c56b3cd4e2f2c1a0d2e1 /src
parent066056c64a7fee4ecf1f442e80984523aa7d600a (diff)
downloaddnsfunnel-c47e30d38e6815174ddfc0fa0d718da18849db75.tar.xz
Bugfixes. Store less empty space in dfanswer.
Diffstat (limited to 'src')
-rw-r--r--src/dnsfunnel/dnsfunneld.c4
-rw-r--r--src/dnsfunnel/dnsfunneld_answer.c53
-rw-r--r--src/dnsfunnel/dnsfunneld_process.c4
3 files changed, 31 insertions, 30 deletions
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) ;