diff options
author | Laurent Bercot <ska-skaware@skarnet.org> | 2023-07-06 11:00:58 +0000 |
---|---|---|
committer | Laurent Bercot <ska@appnovation.com> | 2023-07-06 11:00:58 +0000 |
commit | cfe4051aaffd4ff5e7a1b55b023840042896dbd6 (patch) | |
tree | 254e4ba0b8d5e1fd2286ad562518f65aba5df07e /src/libs6dns | |
parent | ad7f496c36025a4177e061bbf7d1205d38685316 (diff) | |
download | s6-dns-cfe4051aaffd4ff5e7a1b55b023840042896dbd6.tar.xz |
Add s6dns_hosts reading functions
Signed-off-by: Laurent Bercot <ska@appnovation.com>
Diffstat (limited to 'src/libs6dns')
-rw-r--r-- | src/libs6dns/deps-lib/s6dns | 6 | ||||
-rw-r--r-- | src/libs6dns/s6dns_hosts_aaaaa_q.c | 37 | ||||
-rw-r--r-- | src/libs6dns/s6dns_hosts_aaaaa_string.c | 40 | ||||
-rw-r--r-- | src/libs6dns/s6dns_hosts_compile.c | 84 | ||||
-rw-r--r-- | src/libs6dns/s6dns_hosts_ip_q.c | 36 | ||||
-rw-r--r-- | src/libs6dns/s6dns_hosts_ip_string.c | 36 | ||||
-rw-r--r-- | src/libs6dns/s6dns_hosts_name.c | 43 |
7 files changed, 224 insertions, 58 deletions
diff --git a/src/libs6dns/deps-lib/s6dns b/src/libs6dns/deps-lib/s6dns index 7ade4f4..6eaf610 100644 --- a/src/libs6dns/deps-lib/s6dns +++ b/src/libs6dns/deps-lib/s6dns @@ -25,6 +25,12 @@ s6dns_fmt_soa.o s6dns_fmt_srv.o s6dns_fmt_caa.o s6dns_hosts_compile.o +s6dns_hosts_aaaaa_q.o +s6dns_hosts_aaaaa_string.o +s6dns_hosts_ip_q.o +s6dns_hosts_ip_string.o +s6dns_hosts_name.o +s6dns_hosts_here.o s6dns_message_counts_next.o s6dns_message_counts_pack.o s6dns_message_counts_unpack.o diff --git a/src/libs6dns/s6dns_hosts_aaaaa_q.c b/src/libs6dns/s6dns_hosts_aaaaa_q.c new file mode 100644 index 0000000..765433a --- /dev/null +++ b/src/libs6dns/s6dns_hosts_aaaaa_q.c @@ -0,0 +1,37 @@ +/* ISC license. */ + +#include <string.h> + +#include <skalibs/ip46.h> +#include <skalibs/genalloc.h> + +#include <s6-dns/s6dns-domain.h> +#include <s6-dns/hosts.h> + +extern int s6dns_hosts_aaaaa_q_r (cdb const *c, char const *name, genalloc *ga, char const *rules, unsigned int rulesnum) +{ + int r ; + int gawn = !genalloc_s(ip46full, ga) ; + size_t gabase = genalloc_len(ip46full, ga) ; + s6dns_domain_t d[rulesnum + 1] ; + if (!c->map) return 0 ; + r = s6dns_hosts_aaaaa_unq_r(c, name, ga) ; + if (r == -1) return -1 ; + if (!s6dns_domain_fromstring(d + rulesnum, name, strlen(name))) goto err ; + if (!s6dns_domain_qualify(d, d + rulesnum, rules, rulesnum)) goto err ; + for (unsigned int i = 0 ; i < rulesnum ; i++) + { + char tmp[256] ; + r = s6dns_domain_tostring(tmp, 256, d + i) ; + if (!r) goto err ; + tmp[r] = 0 ; + r = s6dns_hosts_aaaaa_noq_r(c, tmp, ga) ; + if (r == -1) goto err ; + if (r) break ; + } + return genalloc_len(ip46full, ga) - gabase ; + + err: + if (gawn) genalloc_free(ip46full, ga) ; else genalloc_setlen(ip46full, ga, gabase) ; + return -1 ; +} diff --git a/src/libs6dns/s6dns_hosts_aaaaa_string.c b/src/libs6dns/s6dns_hosts_aaaaa_string.c new file mode 100644 index 0000000..f4b00f0 --- /dev/null +++ b/src/libs6dns/s6dns_hosts_aaaaa_string.c @@ -0,0 +1,40 @@ +/* ISC license. */ + +#include <errno.h> +#include <string.h> + +#include <skalibs/ip46.h> +#include <skalibs/stralloc.h> +#include <skalibs/genalloc.h> + +#include <s6-dns/hosts.h> + +extern int s6dns_hosts_aaaaa_string_r (cdb const *c, char const *name, genalloc *ga, int isunq) +{ + stralloc sa = STRALLOC_ZERO ; + int gawn = !genalloc_s(ip46full, ga) ; + size_t gabase = genalloc_len(ip46full, ga) ; + int r = s6dns_hosts_a_string_r(c, name, &sa, isunq) ; + if (r <= 0) return r ; + if (!genalloc_readyplus(ip46full, ga, r)) return -1 ; + for (size_t i = 0 ; i < r ; i++) + ip46full_from_ip4(genalloc_s(ip46full, ga) + i, sa.s + (i << 2)) ; + genalloc_setlen(ip46full, ga, gabase + r) ; + sa.len = 0 ; + r = s6dns_hosts_aaaa_string_r(c, name, &sa, isunq) ; + if (r == -1) goto err ; + if (r) + { + if (!genalloc_readyplus(ip46full, ga, r)) goto err ; + for (size_t i = 0 ; i < r ; i++) + ip46full_from_ip6(genalloc_s(ip46full, ga) + i, sa.s + (i << 4)) ; + genalloc_setlen(ip46full, ga, genalloc_len(ip46full, ga) + r) ; + } + stralloc_free(&sa) ; + return genalloc_len(ip46full, ga) - gabase ; + + err: + if (gawn) genalloc_free(ip46full, ga) ; else genalloc_setlen(ip46full, ga, gabase) ; + stralloc_free(&sa) ; + return -1 ; +} diff --git a/src/libs6dns/s6dns_hosts_compile.c b/src/libs6dns/s6dns_hosts_compile.c index d4fc184..c0bba5b 100644 --- a/src/libs6dns/s6dns_hosts_compile.c +++ b/src/libs6dns/s6dns_hosts_compile.c @@ -5,6 +5,7 @@ #include <errno.h> #include <sys/uio.h> +#include <skalibs/bytestr.h> #include <skalibs/buffer.h> #include <skalibs/fmtscan.h> #include <skalibs/cdbmake.h> @@ -12,7 +13,6 @@ #include <skalibs/genalloc.h> #include <skalibs/gensetdyn.h> #include <skalibs/avltree.h> -#include <skalibs/lolstdio.h> #include <s6-dns/hosts.h> @@ -38,11 +38,11 @@ typedef struct hostdata_s hostdata, *hostdata_ref ; struct hostdata_s { stralloc storage ; - gensetdyn alias ; + gensetdyn unq ; gensetdyn fqdn ; gensetdyn ipv4 ; gensetdyn ipv6 ; - avltree byalias ; + avltree byunq ; avltree byfqdn ; avltree byipv4 ; avltree byipv6 ; @@ -50,11 +50,11 @@ struct hostdata_s #define HOSTDATA_ZERO \ { \ .storage = STRALLOC_ZERO, \ - .alias = GENSETDYN_INIT(node_name, 3, 3, 8), \ + .unq = GENSETDYN_INIT(node_name, 3, 3, 8), \ .fqdn = GENSETDYN_INIT(node_name, 3, 3, 8), \ .ipv4 = GENSETDYN_INIT(node_ip, 3, 3, 8), \ .ipv6 = GENSETDYN_INIT(node_ip, 3, 3, 8), \ - .byalias = AVLTREE_ZERO, \ + .byunq = AVLTREE_ZERO, \ .byfqdn = AVLTREE_ZERO, \ .byipv4 = AVLTREE_ZERO, \ .byipv6 = AVLTREE_ZERO \ @@ -86,14 +86,14 @@ static void node_ip_free (void *data) static void hostdata_free (hostdata *hd) { - gensetdyn_deepfree(&hd->alias, &node_name_free) ; - gensetdyn_deepfree(&hd->fqdn, &node_name_free) ; - gensetdyn_deepfree(&hd->ipv4, &node_ip_free) ; - gensetdyn_deepfree(&hd->ipv6, &node_ip_free) ; - avltree_free(&hd->byalias) ; + avltree_free(&hd->byunq) ; avltree_free(&hd->byfqdn) ; avltree_free(&hd->byipv4) ; avltree_free(&hd->byipv6) ; + gensetdyn_deepfree(&hd->unq, &node_name_free) ; + gensetdyn_deepfree(&hd->fqdn, &node_name_free) ; + gensetdyn_deepfree(&hd->ipv4, &node_ip_free) ; + gensetdyn_deepfree(&hd->ipv6, &node_ip_free) ; stralloc_free(&hd->storage) ; } @@ -103,10 +103,10 @@ static int name_cmp (void const *a, void const *b, void *aux) return strcmp((char const *)a, (char const *)b) ; } -static void *byalias_dtok (uint32_t d, void *aux) +static void *byunq_dtok (uint32_t d, void *aux) { hostdata *hd = aux ; - return hd->storage.s + GENSETDYN_P(node_name, &hd->alias, d)->pos ; + return hd->storage.s + GENSETDYN_P(node_name, &hd->unq, d)->pos ; } static void *byfqdn_dtok (uint32_t d, void *aux) @@ -177,7 +177,6 @@ static int s6dns_hosts_parse (buffer *b, hostdata *hd) if (r == -1) goto err ; if (!r) cur = 0 ; c = table[state][cclass(cur)] ; - LOLDEBUG("parse: state: %hhu, event: %c, newstate: %hhu, actions: %s%s%s%s", state, cur, c & 0x07, c & 0x08 ? "p" : "", c & 0x10 ? "s" : "", c & 0x20 ? "f" : "", c & 0x40 ? "n" : "") ; state = c & 0x07 ; if (c & 0x08) if (!stralloc_catb(&hd->storage, &cur, 1)) goto err ; if (c & 0x10) @@ -187,9 +186,6 @@ static int s6dns_hosts_parse (buffer *b, hostdata *hd) if (ip6_scan(hd->storage.s + mark, ip)) { uint32_t d ; -#ifdef DEBUG - LOLDEBUG("parse: ipv6 found: %s", hd->storage.s + mark) ; -#endif if (!avltree_search(&hd->byipv6, ip, &d)) { if (!gensetdyn_new(&hd->ipv6, &d)) goto err ; @@ -202,9 +198,6 @@ static int s6dns_hosts_parse (buffer *b, hostdata *hd) } else if (ip4_scan(hd->storage.s + mark, ip)) { -#ifdef DEBUG - LOLDEBUG("parse: ipv4 found: %s", hd->storage.s + mark) ; -#endif uint32_t d ; if (!avltree_search(&hd->byipv4, ip, &d)) { @@ -217,7 +210,6 @@ static int s6dns_hosts_parse (buffer *b, hostdata *hd) node = GENSETDYN_P(node_ip, &hd->ipv4, d) ; } else goto err ; - LOLDEBUG("parse: %s has %zu names so far", hd->storage.s + mark, genalloc_len(size_t, &node->names)) ; hd->storage.len = mark ; flags &= ~2 ; } @@ -225,27 +217,26 @@ static int s6dns_hosts_parse (buffer *b, hostdata *hd) { node_name *noden ; size_t i = 0 ; + case_lowerb(hd->storage.s + mark, hd->storage.len - mark) ; if (flags & 2) { uint32_t d ; if (!stralloc_0(&hd->storage)) goto err ; - LOLDEBUG("parse: alias found: %s", hd->storage.s + mark) ; - if (!avltree_search(&hd->byalias, hd->storage.s + mark, &d)) + if (!avltree_search(&hd->byunq, hd->storage.s + mark, &d)) { - if (!gensetdyn_new(&hd->alias, &d)) goto err ; - GENSETDYN_P(node_name, &hd->alias, d)->pos = mark ; - GENSETDYN_P(node_name, &hd->alias, d)->ipv4 = stralloc_zero ; - GENSETDYN_P(node_name, &hd->alias, d)->ipv6 = stralloc_zero ; - if (!avltree_insert(&hd->byalias, d)) goto err ; + if (!gensetdyn_new(&hd->unq, &d)) goto err ; + GENSETDYN_P(node_name, &hd->unq, d)->pos = mark ; + GENSETDYN_P(node_name, &hd->unq, d)->ipv4 = stralloc_zero ; + GENSETDYN_P(node_name, &hd->unq, d)->ipv6 = stralloc_zero ; + if (!avltree_insert(&hd->byunq, d)) goto err ; } else hd->storage.len = mark ; - noden = GENSETDYN_P(node_name, &hd->alias, d) ; + noden = GENSETDYN_P(node_name, &hd->unq, d) ; } else { uint32_t d ; if (!stralloc_catb(&hd->storage, ".", 2)) goto err ; - LOLDEBUG("parse: fqdn found: %s", hd->storage.s + mark) ; if (!avltree_search(&hd->byfqdn, hd->storage.s + mark, &d)) { if (!gensetdyn_new(&hd->fqdn, &d)) goto err ; @@ -257,33 +248,23 @@ static int s6dns_hosts_parse (buffer *b, hostdata *hd) else hd->storage.len = mark ; noden = GENSETDYN_P(node_name, &hd->fqdn, d) ; } - LOLDEBUG("parse: %s has %zu ipv4 and %zu ipv6 so far", hd->storage.s + noden->pos, noden->ipv4.len >> 2, noden->ipv6.len >> 4) ; for (; i < genalloc_len(size_t, &node->names) ; i++) if (!strcmp(hd->storage.s + noden->pos, hd->storage.s + genalloc_s(size_t, &node->names)[i])) break ; if (i >= genalloc_len(size_t, &node->names)) - { - LOLDEBUG("parse: adding it to current ipv%s", flags & 1 ? "6" : "4") ; if (!genalloc_catb(size_t, &node->names, &noden->pos, 1)) goto err ; - } if (flags & 1) { for (i = 0 ; i < noden->ipv6.len ; i += 16) if (!memcmp(node->addr, noden->ipv6.s + i, 16)) break ; if (i >= noden->ipv6.len) - { - LOLDEBUG("parse: adding current ipv6 to address list for %s", hd->storage.s + noden->pos) ; if (!stralloc_catb(&noden->ipv6, node->addr, 16)) goto err ; - } } else { for (i = 0 ; i < noden->ipv4.len ; i += 4) if (!memcmp(node->addr, noden->ipv4.s + i, 4)) break ; if (i >= noden->ipv4.len) - { - LOLDEBUG("parse: adding current ipv4 to address list for %s", hd->storage.s + noden->pos) ; if (!stralloc_catb(&noden->ipv4, node->addr, 4)) goto err ; - } } mark = hd->storage.len ; } @@ -303,16 +284,15 @@ static int name_write_iter (void *data, void *aux) { node_name *node = data ; hdcm *blah = aux ; - char keybase[4] = "q4:" ; - struct iovec kv[2] = { { .iov_base = keybase, .iov_len = 3 }, { .iov_base = blah->hd->storage.s + node->pos, .iov_len = strlen(blah->hd->storage.s + node->pos) + 1 } } ; + struct iovec kv[3] = { { .iov_base = blah->key, .iov_len = 2 }, { .iov_base = ":", .iov_len = 1 }, { .iov_base = blah->hd->storage.s + node->pos, .iov_len = strlen(blah->hd->storage.s + node->pos) } } ; struct iovec dv = { .iov_base = node->ipv4.s, .iov_len = node->ipv4.len } ; - LOLDEBUG("name_write_iter: name: %s, ipv4.len: %zu, ipv6.len: %zu", blah->hd->storage.s + node->pos, node->ipv4.len, node->ipv6.len) ; if (node->ipv4.len && !cdbmake_addv(blah->cm, kv, 2, &dv, 1)) return 0 ; if (node->ipv6.len) { - keybase[1] = '6' ; + blah->key[1] = '6' ; dv.iov_base = node->ipv6.s ; dv.iov_len = node->ipv6.len ; if (!cdbmake_addv(blah->cm, kv, 2, &dv, 1)) return 0 ; + blah->key[1] = '4' ; } return 1 ; } @@ -322,14 +302,6 @@ static int ip_write_iter (void *data, void *aux) node_ip *node = data ; hdcm *blah = aux ; size_t n = genalloc_len(size_t, &node->names) ; -#ifdef DEBUG - { - char fmt[IP6_FMT] ; - if (blah->key[1] == '6') fmt[ip6_fmt(fmt, node->addr)] = 0 ; - else fmt[ip4_fmt(fmt, node->addr)] = 0 ; - LOLDEBUG("ip_write_iter: %s: names: %zu", fmt, n) ; - } -#endif if (n) { size_t const *p = genalloc_s(size_t, &node->names) ; @@ -347,17 +319,13 @@ static int ip_write_iter (void *data, void *aux) static int s6dns_hosts_write (hostdata *hd, cdbmaker *cm) { - hdcm blah = { .hd = hd, .cm = cm, .key = { 'q', '4' } } ; - LOLDEBUG("writing alias") ; - if (gensetdyn_iter(&hd->alias, &name_write_iter, &blah) < gensetdyn_n(&hd->alias)) return 0 ; + hdcm blah = { .hd = hd, .cm = cm, .key = { 'u', '4' } } ; + if (gensetdyn_iter(&hd->unq, &name_write_iter, &blah) < gensetdyn_n(&hd->unq)) return 0 ; blah.key[0] = 'a' ; - LOLDEBUG("writing fqdn") ; if (gensetdyn_iter(&hd->fqdn, &name_write_iter, &blah) < gensetdyn_n(&hd->fqdn)) return 0 ; blah.key[0] = 'p' ; - LOLDEBUG("writing ipv4") ; if (gensetdyn_iter(&hd->ipv4, &ip_write_iter, &blah) < gensetdyn_n(&hd->ipv4)) return 0 ; blah.key[1] = '6' ; - LOLDEBUG("writing ipv6") ; if (gensetdyn_iter(&hd->ipv6, &ip_write_iter, &blah) < gensetdyn_n(&hd->ipv6)) return 0 ; return 1 ; } @@ -371,7 +339,7 @@ int s6dns_hosts_compile (int fdr, int fdw) { char buf[BUFFER_INSIZE] ; buffer b = BUFFER_INIT(&buffer_read, fdr, buf, BUFFER_INSIZE) ; - avltree_init(&hd.byalias, 3, 3, 8, &byalias_dtok, &name_cmp, &hd) ; + avltree_init(&hd.byunq, 3, 3, 8, &byunq_dtok, &name_cmp, &hd) ; avltree_init(&hd.byfqdn, 3, 3, 8, &byfqdn_dtok, &name_cmp, &hd) ; avltree_init(&hd.byipv4, 3, 3, 8, &byipv4_dtok, &ipv4_cmp, &hd) ; avltree_init(&hd.byipv6, 3, 3, 8, &byipv6_dtok, &ipv6_cmp, &hd) ; diff --git a/src/libs6dns/s6dns_hosts_ip_q.c b/src/libs6dns/s6dns_hosts_ip_q.c new file mode 100644 index 0000000..f6bc573 --- /dev/null +++ b/src/libs6dns/s6dns_hosts_ip_q.c @@ -0,0 +1,36 @@ +/* ISC license. */ + +#include <string.h> + +#include <skalibs/stralloc.h> + +#include <s6-dns/s6dns-domain.h> +#include <s6-dns/hosts.h> + +extern int s6dns_hosts_ip_q_r (cdb const *c, char const *name, stralloc *sa, char const *rules, unsigned int rulesnum, int is6) +{ + int r ; + int sawn = !sa->s ; + size_t sabase = sa->len ; + s6dns_domain_t d[rulesnum + 1] ; + if (!c->map) return 0 ; + r = s6dns_hosts_ip_unq_r(c, name, sa, is6) ; + if (r == -1) return -1 ; + if (!s6dns_domain_fromstring(d + rulesnum, name, strlen(name))) goto err ; + if (!s6dns_domain_qualify(d, d + rulesnum, rules, rulesnum)) goto err ; + for (unsigned int i = 0 ; i < rulesnum ; i++) + { + char tmp[256] ; + r = s6dns_domain_tostring(tmp, 256, d + i) ; + if (!r) goto err ; + tmp[r] = 0 ; + r = s6dns_hosts_ip_noq_r(c, tmp, sa, is6) ; + if (r == -1) goto err ; + if (r) break ; + } + return (sa->len - sabase) >> (is6 ? 4 : 2) ; + + err: + if (sawn) stralloc_free(sa) ; else sa->len = sabase ; + return -1 ; +} diff --git a/src/libs6dns/s6dns_hosts_ip_string.c b/src/libs6dns/s6dns_hosts_ip_string.c new file mode 100644 index 0000000..430f7d3 --- /dev/null +++ b/src/libs6dns/s6dns_hosts_ip_string.c @@ -0,0 +1,36 @@ +/* ISC license. */ + +#include <errno.h> +#include <string.h> + +#include <skalibs/cdb.h> +#include <skalibs/stralloc.h> + +#include <s6-dns/s6dns-domain.h> +#include <s6-dns/hosts.h> + +#include <skalibs/posixishard.h> + +extern int s6dns_hosts_ip_string_r (cdb const *c, char const *name, stralloc *sa, unsigned int flags) +{ + s6dns_domain_t d ; + int r ; + cdb_data data ; + if (!c->map) return 0 ; + if (!s6dns_domain_fromstring(&d, name, strlen(name)) + || !s6dns_domain_noqualify(&d)) return -1 ; + + { + char tmp[3 + d.len] ; + tmp[0] = flags & 2 ? 'u' : 'a' ; + tmp[1] = flags & 1 ? '6' : '4' ; + tmp[2] = ':' ; + memcpy(tmp + 3, d.s, d.len) ; + r = cdb_find(c, &data, tmp, 3 + d.len) ; + } + if (r <= 0) return r ; + if (!data.len) return 0 ; + if (data.len & (flags & 1 ? 15 : 3)) return (errno = EPROTO, -1) ; + if (!stralloc_catb(sa, data.s, data.len)) return -1 ; + return data.len >> (flags & 1 ? 4 : 2) ; +} diff --git a/src/libs6dns/s6dns_hosts_name.c b/src/libs6dns/s6dns_hosts_name.c new file mode 100644 index 0000000..af2030b --- /dev/null +++ b/src/libs6dns/s6dns_hosts_name.c @@ -0,0 +1,43 @@ +/* ISC license. */ + +#include <errno.h> +#include <string.h> + +#include <skalibs/cdb.h> +#include <skalibs/stralloc.h> +#include <skalibs/genalloc.h> + +#include <s6-dns/hosts.h> + +#include <skalibs/posixishard.h> + +int s6dns_hosts_name_r (cdb const *c, char const *ip, stralloc *sa, genalloc *ga, int is6) +{ + int r ; + cdb_data data ; + int sawn = !sa->s ; + int gawn = !genalloc_s(size_t, ga) ; + size_t sabase = sa->len ; + size_t gabase = genalloc_len(size_t, ga) ; + size_t i = sabase ; + char tmp[19] = "p4:" ; + if (!c->map) return 0 ; + if (is6) tmp[1] = '6' ; + memcpy(tmp + 3, ip, is6 ? 16 : 4) ; + r = cdb_find(c, &data, tmp, 7) ; + if (r <= 0) return r ; + if (!data.len) return 0 ; + if (data.s[data.len - 1]) return (errno = EPROTO, -1) ; + if (!stralloc_catb(sa, data.s, data.len)) return -1 ; + while (i < sa->len) + { + if (!genalloc_catb(size_t, ga, &i, 1)) goto err ; + i += strlen(sa->s + i) + 1 ; + } + return genalloc_len(size_t, ga) - gabase ; + + err: + if (gawn) genalloc_free(size_t, ga) ; else genalloc_setlen(size_t, ga, 0) ; + if (sawn) stralloc_free(sa) ; else sa->len = 0 ; + return -1 ; +} |