diff options
| author | Laurent Bercot <ska-skaware@skarnet.org> | 2024-09-28 13:58:46 +0000 |
|---|---|---|
| committer | Laurent Bercot <ska@appnovation.com> | 2024-09-28 13:58:46 +0000 |
| commit | 645894afb11a4c5d60b4d4f6b55ba3c2f764d1c7 (patch) | |
| tree | b79811926d0ea6fd3aea534b155723288db4c5d0 /src | |
| parent | 36aac3b7052792acd25aceeb7d0498474988a197 (diff) | |
| download | dnsfunnel-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.c | 42 | ||||
| -rw-r--r-- | src/dnsfunnel/dnsfunneld.h | 10 | ||||
| -rw-r--r-- | src/dnsfunnel/dnsfunneld_answer.c | 14 | ||||
| -rw-r--r-- | src/dnsfunnel/dnsfunneld_process.c | 2 |
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)) { |
