diff options
-rw-r--r-- | doc/dnsfunneld.html | 10 | ||||
-rw-r--r-- | src/dnsfunnel/dnsfunneld.c | 35 | ||||
-rw-r--r-- | src/dnsfunnel/dnsfunneld_answer.c | 15 |
3 files changed, 36 insertions, 24 deletions
diff --git a/doc/dnsfunneld.html b/doc/dnsfunneld.html index 5181db1..7fde21f 100644 --- a/doc/dnsfunneld.html +++ b/doc/dnsfunneld.html @@ -29,7 +29,7 @@ queries, the responses, or both. <h2> Interface </h2> <pre> - dnsfunneld [ -v <em>verbosity</em> ] [ -1 ] [ -U | -u <em>uid</em> -g <em>gid</em> ] [ -i <em>ip</em>:<em>port</em> ] [ -R <em>root</em> ] [ -b <em>bufsize</em> ] [ -T | -t ] [ -N | -n ] + dnsfunneld [ -v <em>verbosity</em> ] [ -1 ] [ -U | -u <em>uid</em> -g <em>gid</em> ] [ -i <em>ip</em>:<em>port</em> ] [ -R <em>root</em> ] [ -b <em>bufsize</em> ] [ -t <em>globaltimeout</em> ] [ -X | -x ] [ -N | -n ] </pre> <ul> @@ -97,6 +97,10 @@ to <tt>-R</tt>. </li> <li> <tt>-b <em>bufsize</em></tt> : try and reserve a kernel buffer size of <em>bufsize</em> bytes for the socket. The default is whatever the default is for your kernel. </li> + <li> <tt>-t <em>globaltimeout</em></tt> : maximum resolution time. +If a query takes more than <em>globaltimeout</em> milliseconds to resolve, +abandon it and return a SERVFAIL to the client. Default is 0, meaning infinite: +no global timeout is set. </li> </ul> <p> @@ -105,9 +109,9 @@ features. See below for the detail of operations. </p> <ul> - <li> <tt>-T</tt> : Do not activate truncation of responses. This is + <li> <tt>-X</tt> : Do not activate truncation of responses. This is the default. </li> - <li> <tt>-t</tt> : If a DNS response is bigger than 510 bytes, + <li> <tt>-x</tt> : If a DNS response is bigger than 510 bytes, truncate its last resource records until it fits into 510 bytes and can be sent in a UDP packet. </li> <li> <tt>-N</tt> : Do not activate NXDOMAIN workaround. This is the diff --git a/src/dnsfunnel/dnsfunneld.c b/src/dnsfunnel/dnsfunneld.c index d65cb7c..48965f1 100644 --- a/src/dnsfunnel/dnsfunneld.c +++ b/src/dnsfunnel/dnsfunneld.c @@ -36,13 +36,13 @@ #include "dnsfunneld.h" -#define USAGE "dnsfunneld [ -v verbosity ] [ -1 ] [ -U | -u uid -g gid ] [ -i ip:port ] [ -R root ] [ -b bufsize ] [ -T | -t ] [ -N | -n ]" +#define USAGE "dnsfunneld [ -v verbosity ] [ -1 ] [ -U | -u uid -g gid ] [ -i ip:port ] [ -R root ] [ -b bufsize ] [ -t globaltimeout ] [ -X | -x ] [ -N | -n ]" #define dieusage() strerr_dieusage(100, USAGE) #define DNSFUNNELD_INPUT_MAX 64 unsigned int verbosity = 1 ; -static tain_t globaltto = TAIN_INFINITE_RELATIVE ; +static tain_t globaltto ; static int cont = 1 ; static s6dns_ip46list_t cachelist ; static uint32_t ops = 0 ; @@ -169,12 +169,13 @@ int main (int argc, char const *const *argv) int fd ; char ip[4] ; size_t pos ; + unsigned int t = 0 ; uint16_t port ; subgetopt_t l = SUBGETOPT_ZERO ; for (;;) { - int opt = subgetopt_r(argc, argv, "v:1Uu:g:i:R:b:TtNn", &l) ; + int opt = subgetopt_r(argc, argv, "v:1Uu:g:i:R:b:t:XxNn", &l) ; if (opt == -1) break ; switch (opt) { @@ -186,8 +187,9 @@ int main (int argc, char const *const *argv) case 'i' : ipport = l.arg ; break ; case 'R' : root = l.arg ; break ; case 'b' : if (!uint0_scan(l.arg, &bufsize)) dieusage() ; break ; - case 'T' : ops &= ~1 ; break ; - case 't' : ops |= 1 ; break ; + case 't' : if (!uint0_scan(l.arg, &t)) dieusage() ; break ; + case 'X' : ops &= ~1 ; break ; + case 'x' : ops |= 1 ; break ; case 'N' : ops &= ~2 ; break ; case 'n' : ops |= 2 ; break ; default : dieusage() ; @@ -195,6 +197,8 @@ int main (int argc, char const *const *argv) } argc -= l.ind ; argv += l.ind ; + if (t) tain_from_millisecs(&globaltto, t) ; + else globaltto = tain_infinite_relative ; pos = ip4_scan(ipport, ip) ; if (!pos) dieusage() ; if (ipport[pos] != ':') dieusage() ; @@ -352,17 +356,20 @@ int main (int argc, char const *const *argv) { dfquery_t *q = QUERY(i) ; uint32_t k = q->next ; - int r = s6dns_engine_event_g(&q->dt) ; - if (r) + if (x[q->xindex].events && x[q->xindex].revents) { - if (r > 0) query_process_response_success(ops, q) ; - else query_process_response_failure(ops, q) ; - QUERY(j)->next = k ; - if (r > 0) s6dns_engine_free(&q->dt) ; - else stralloc_free(&q->dt.sa) ; - gensetdyn_delete(&queries, i) ; + int r = s6dns_engine_event_g(&q->dt) ; + if (r) + { + if (r > 0) query_process_response_success(ops, q) ; + else query_process_response_failure(ops, q) ; + QUERY(j)->next = k ; + if (r > 0) s6dns_engine_free(&q->dt) ; + else stralloc_free(&q->dt.sa) ; + gensetdyn_delete(&queries, i) ; + } + else j = i ; } - else j = i ; i = k ; } diff --git a/src/dnsfunnel/dnsfunneld_answer.c b/src/dnsfunnel/dnsfunneld_answer.c index a6ee526..c06637f 100644 --- a/src/dnsfunnel/dnsfunneld_answer.c +++ b/src/dnsfunnel/dnsfunneld_answer.c @@ -20,16 +20,15 @@ struct dfanswer_s { char buf[512] ; char ip[4] ; - uint16_t len ; uint16_t port ; } ; -#define DFANSWER_ZERO { .buf = { 0 }, .ip = "\0\0\0", .len = 0, .port = 0 } +#define DFANSWER_ZERO { .buf = { 0 }, .ip = "\0\0\0", .port = 0 } static genqdyn dfanswers = GENQDYN_INIT(dfanswer_t, 1, 8) ; size_t dfanswer_pending () { - return genqdyn_n(&dfanswers) ; + return (dfanswers.queue.len - dfanswers.head) / dfanswers.esize ; } static void dfanswer_push (char const *s, size_t len, uint32_t ip, uint16_t port) @@ -41,9 +40,9 @@ static void dfanswer_push (char const *s, size_t len, uint32_t ip, uint16_t port } else { - dfanswer_t ans = { .len = len, .port = port } ; - uint16_pack_big(ans.buf, ans.len) ; - memcpy(ans.buf, s+2, len) ; + 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") ; @@ -55,7 +54,9 @@ int dfanswer_flush () while (dfanswer_pending()) { dfanswer_t *ans = GENQDYN_PEEK(dfanswer_t, &dfanswers) ; - if (socket_send4(0, ans->buf, ans->len, ans->ip, ans->port) < 0) + uint16_t len ; + uint16_unpack_big(ans->buf, &len) ; + if (socket_send4(0, ans->buf, len, ans->ip, ans->port) < 0) return error_isagain(errno) ? (errno = 0, 0) : -1 ; genqdyn_pop(&dfanswers) ; } |