aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorLaurent Bercot <ska-skaware@skarnet.org>2024-09-28 13:58:46 +0000
committerLaurent Bercot <ska@appnovation.com>2024-09-28 13:58:46 +0000
commit645894afb11a4c5d60b4d4f6b55ba3c2f764d1c7 (patch)
treeb79811926d0ea6fd3aea534b155723288db4c5d0 /src
parent36aac3b7052792acd25aceeb7d0498474988a197 (diff)
downloaddnsfunnel-645894afb11a4c5d60b4d4f6b55ba3c2f764d1c7.tar.gz
Prepare for 0.0.2.0; make it work on ipv6
Signed-off-by: Laurent Bercot <ska@appnovation.com>
Diffstat (limited to 'src')
-rw-r--r--src/dnsfunnel/dnsfunneld.c42
-rw-r--r--src/dnsfunnel/dnsfunneld.h10
-rw-r--r--src/dnsfunnel/dnsfunneld_answer.c14
-rw-r--r--src/dnsfunnel/dnsfunneld_process.c2
4 files changed, 32 insertions, 36 deletions
diff --git a/src/dnsfunnel/dnsfunneld.c b/src/dnsfunnel/dnsfunneld.c
index 61e2cc1..f57b265 100644
--- a/src/dnsfunnel/dnsfunneld.c
+++ b/src/dnsfunnel/dnsfunneld.c
@@ -31,6 +31,7 @@
#include <skalibs/iopause.h>
#include <skalibs/selfpipe.h>
#include <skalibs/gensetdyn.h>
+#include <skalibs/ip46.h>
#include <s6-dns/s6dns.h>
@@ -42,6 +43,8 @@
#define DNSFUNNELD_INPUT_MAX 64
unsigned int verbosity = 1 ;
+unsigned int ipsz = 4 ;
+
static tain globaltto ;
static int cont = 1 ;
static s6dns_ip46list_t cachelist ;
@@ -110,14 +113,13 @@ static uint32_t sentinel ;
#define inflight (gensetdyn_n(&queries) - 1)
#define QUERY(i) GENSETDYN_P(dfquery_t, &queries, i)
-void query_new (s6dns_domain_t const *d, uint16_t qtype, uint16_t id, uint32_t ip, uint16_t port, uint32_t procid)
+void query_new (s6dns_domain_t const *d, uint16_t qtype, uint16_t id, char const *ip, uint16_t port, uint32_t procid)
{
dfquery_t q =
{
.next = QUERY(sentinel)->next,
.xindex = 0,
.procid = procid,
- .ip = ip,
.port = port,
.id = id,
.dt = S6DNS_ENGINE_ZERO
@@ -125,6 +127,7 @@ void query_new (s6dns_domain_t const *d, uint16_t qtype, uint16_t id, uint32_t i
s6dns_domain_t dd = *d ;
tain deadline ;
uint32_t i ;
+ memcpy(q.ip, ip, ipsz) ;
if (!gensetdyn_new(&queries, &i))
strerr_diefu1sys(111, "create new query") ;
s6dns_domain_encode(&dd) ;
@@ -135,10 +138,9 @@ void query_new (s6dns_domain_t const *d, uint16_t qtype, uint16_t id, uint32_t i
QUERY(sentinel)->next = i ;
}
-static inline void sanitize_and_new (char const *buf, unsigned int len, char const *ippack, uint16_t port)
+static inline void sanitize_and_new (char const *buf, unsigned int len, char const *ip, uint16_t port)
{
s6dns_domain_t d ;
- uint32_t ip ;
unsigned int pos ;
s6dns_message_header_t hdr ;
s6dns_message_counts_t counts ;
@@ -150,20 +152,10 @@ static inline void sanitize_and_new (char const *buf, unsigned int len, char con
|| hdr.counts.qd != 1 || hdr.counts.an || hdr.counts.ns || hdr.counts.nr
|| !s6dns_message_parse_question(&counts, &d, &qtype, buf, len, &pos))
return ;
- uint32_unpack_big(ippack, &ip) ;
if (ops) query_process_question(ops, &d, qtype, hdr.id, ip, port) ;
else query_new(&d, qtype, hdr.id, ip, port, 0) ;
}
-static inline size_t ip40_scan (char const *s, char *ip)
-{
- char t[4] ;
- size_t l = ip4_scan(s, t) ;
- if (!l || s[l]) return 0 ;
- memcpy(ip, t, 4) ;
- return l ;
-}
-
int main (int argc, char const *const *argv)
{
int spfd = -1 ;
@@ -178,9 +170,10 @@ int main (int argc, char const *const *argv)
int notif = 0 ;
int fd ;
unsigned int t = 0 ;
- char ip[4] = { 127, 0, 0, 1 } ;
- uint16_t port = 53 ;
subgetopt l = SUBGETOPT_ZERO ;
+ uint16_t port = 53 ;
+ ip46 ip ;
+ (void)ip46_from_ip4(&ip, IP4_LOCAL) ;
for (;;)
{
@@ -193,7 +186,7 @@ int main (int argc, char const *const *argv)
case 'U' : flagU = 1 ; break ;
case 'u' : if (!uid0_scan(l.arg, &uid)) dieusage() ; break ;
case 'g' : if (!gid0_scan(l.arg, &gid)) dieusage() ; break ;
- case 'i' : if (!ip40_scan(l.arg, ip)) dieusage() ; break ;
+ case 'i' : if (!ip46_scan(l.arg, &ip)) dieusage() ; break ;
case 'p' : if (!uint160_scan(l.arg, &port)) dieusage() ; break ;
case 'R' : root = l.arg ; break ;
case 'b' : if (!uint0_scan(l.arg, &bufsize)) dieusage() ; break ;
@@ -214,13 +207,14 @@ int main (int argc, char const *const *argv)
if (notif) strerr_dief1sys(100, "option -1 given but stdout unavailable") ;
}
else if (!notif) close(1) ;
- fd = socket_udp4() ;
+ ipsz = ip46_is6(&ip) ? 16 : 4 ;
+ fd = socket_udp46(ip46_is6(&ip)) ;
if (fd < 0) strerr_diefu1sys(111, "create UDP socket") ;
- if (socket_bind4_reuse(fd, ip, port) < 0)
+ if (socket_bind46_reuse(fd, &ip, port) < 0)
{
- char fmti[IP4_FMT] ;
+ char fmti[IP46_FMT] ;
char fmtp[UINT16_FMT] ;
- fmti[ip4_fmt(fmti, ip)] = 0 ;
+ fmti[ip46_fmt(fmti, &ip)] = 0 ;
fmtp[uint16_fmt(fmtp, port)] = 0 ;
strerr_diefu4sys(111, "bind on ip ", fmti, " port ", fmtp) ;
}
@@ -383,10 +377,10 @@ int main (int argc, char const *const *argv)
uint32_t n = DNSFUNNELD_INPUT_MAX ;
while (n--)
{
- char ip[4] ;
- uint16_t port ;
char buf[512] ;
- ssize_t r = socket_recv4(0, buf, 512, ip, &port) ;
+ char ip[16] ;
+ uint16_t port ;
+ ssize_t r = ipsz == 16 ? socket_recv6(0, buf, 512, ip, &port) : socket_recv4(0, buf, 512, ip, &port) ;
if (r < 0)
if (error_isagain(errno)) break ;
else strerr_diefu1sys(111, "socket_recv") ;
diff --git a/src/dnsfunnel/dnsfunneld.h b/src/dnsfunnel/dnsfunneld.h
index 4b9acd3..e4d5d64 100644
--- a/src/dnsfunnel/dnsfunneld.h
+++ b/src/dnsfunnel/dnsfunneld.h
@@ -7,6 +7,7 @@
#include <stdint.h>
#include <skalibs/gensetdyn.h>
+#include <skalibs/ip46.h>
#include <s6-dns/s6dns-domain.h>
#include <s6-dns/s6dns-engine.h>
@@ -17,14 +18,15 @@ struct dfquery_s
uint32_t next ;
uint32_t xindex ;
uint32_t procid ;
- uint32_t ip ;
+ char ip[SKALIBS_IP_SIZE] ;
uint16_t port ;
uint16_t id ;
s6dns_engine_t dt ;
} ;
-#define DFQUERY_ZERO { .next = 0, .xindex = 0, .procid = 0, .ip = 0, .port = 0, .id = 0, .dt = S6DNS_ENGINE_ZERO }
+#define DFQUERY_ZERO { .next = 0, .xindex = 0, .procid = 0, .ip = { 0 }, .port = 0, .id = 0, .dt = S6DNS_ENGINE_ZERO }
extern unsigned int verbosity ;
+extern unsigned int ipsz ;
extern size_t dfanswer_pending (void) ;
extern int dfanswer_flush (void) ;
extern void dfanswer_fail (dfquery_t const *, int) ;
@@ -33,11 +35,11 @@ extern void dfanswer_nodata (dfquery_t const *, int) ;
extern void dfanswer_pass (dfquery_t const *, char *, unsigned int) ;
-extern void query_new (s6dns_domain_t const *, uint16_t, uint16_t, uint32_t, uint16_t, uint32_t) ;
+extern void query_new (s6dns_domain_t const *, uint16_t, uint16_t, char const *, uint16_t, uint32_t) ;
extern int query_process_init (void) ;
extern void query_process_reload (void) ;
-extern void query_process_question (uint32_t, s6dns_domain_t const *, uint16_t, uint16_t, uint32_t, uint16_t) ;
+extern void query_process_question (uint32_t, s6dns_domain_t const *, uint16_t, uint16_t, char const *, uint16_t) ;
extern void query_process_response_failure (uint32_t, dfquery_t const *) ;
extern void query_process_response_success (uint32_t, dfquery_t const *) ;
diff --git a/src/dnsfunnel/dnsfunneld_answer.c b/src/dnsfunnel/dnsfunneld_answer.c
index 4266089..c16c280 100644
--- a/src/dnsfunnel/dnsfunneld_answer.c
+++ b/src/dnsfunnel/dnsfunneld_answer.c
@@ -24,7 +24,7 @@ size_t dfanswer_pending ()
return q.len - head ;
}
-static void dfanswer_push (char const *s, size_t len, uint32_t ip, uint16_t port)
+static void dfanswer_push (char const *s, size_t len, char const *ip, uint16_t port)
{
if (len > 512)
{
@@ -33,10 +33,10 @@ static void dfanswer_push (char const *s, size_t len, uint32_t ip, uint16_t port
}
else
{
- if (!stralloc_readyplus(&q, len + 8)) strerr_diefu1sys(111, "queue answer to client") ;
- uint32_pack_big(q.s + q.len, ip) ; q.len += 4 ;
+ if (!stralloc_readyplus(&q, len + 4 + ipsz)) strerr_diefu1sys(111, "queue answer to client") ;
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, ip, ipsz) ; q.len += ipsz ;
memcpy(q.s + q.len, s, len) ; q.len += len ;
}
}
@@ -46,11 +46,11 @@ int dfanswer_flush ()
while (dfanswer_pending())
{
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)
+ uint16_unpack_big(q.s + head, &port) ;
+ uint16_unpack_big(q.s + head + 2, &len) ;
+ if ((ipsz == 16 ? socket_send6(0, q.s + head + 20, len, q.s + head + 4, port) : socket_send4(0, q.s + head + 8, len, q.s + head + 4, port)) < 0)
return error_isagain(errno) ? (errno = 0, 0) : -1 ;
- head += len + 8 ;
+ head += 4 + ipsz + len ;
if ((q.len - head) >> 2 <= q.len)
{
memmove(q.s, q.s + head, q.len - head) ;
diff --git a/src/dnsfunnel/dnsfunneld_process.c b/src/dnsfunnel/dnsfunneld_process.c
index 5f28a37..9ccdf2e 100644
--- a/src/dnsfunnel/dnsfunneld_process.c
+++ b/src/dnsfunnel/dnsfunneld_process.c
@@ -25,7 +25,7 @@ void query_process_reload ()
{
}
-void query_process_question (uint32_t ops, s6dns_domain_t const *d, uint16_t qtype, uint16_t id, uint32_t ip, uint16_t port)
+void query_process_question (uint32_t ops, s6dns_domain_t const *d, uint16_t qtype, uint16_t id, char const *ip, uint16_t port)
{
if (ops & 2 && (qtype == S6DNS_T_A || qtype == S6DNS_T_AAAA))
{