summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--INSTALL4
-rw-r--r--doc/index.html4
-rw-r--r--src/dnsfunnel/dnsfunneld.c4
-rw-r--r--src/dnsfunnel/dnsfunneld_answer.c53
-rw-r--r--src/dnsfunnel/dnsfunneld_process.c4
5 files changed, 35 insertions, 34 deletions
diff --git a/INSTALL b/INSTALL
index fa107a5..58fdf3f 100644
--- a/INSTALL
+++ b/INSTALL
@@ -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) ;