From c1b02ce115e2d05b777d19e7f93e452b4c17773e Mon Sep 17 00:00:00 2001 From: Laurent Bercot Date: Thu, 28 Dec 2023 09:48:39 +0000 Subject: refactor: separate axfr into its own function Signed-off-by: Laurent Bercot --- src/server/shibari_packet_tdb_axfr.c | 86 ++++++++++++++++++++++++++++++++++++ 1 file changed, 86 insertions(+) create mode 100644 src/server/shibari_packet_tdb_axfr.c (limited to 'src/server/shibari_packet_tdb_axfr.c') diff --git a/src/server/shibari_packet_tdb_axfr.c b/src/server/shibari_packet_tdb_axfr.c new file mode 100644 index 0000000..5613b67 --- /dev/null +++ b/src/server/shibari_packet_tdb_axfr.c @@ -0,0 +1,86 @@ +/* ISC license. */ + +#include +#include + +#include +#include +#include +#include + +#include +#include + +#include +#include +#include +#include + +static int add (buffer *b, shibari_packet *pkt, shibari_tdb_entry const *entry, int prefixlen, uint16_t id, s6dns_domain_t const *zone, tain const *deadline, tain *stamp) +{ + if (!shibari_packet_add_rr(pkt, entry, prefixlen, 0, 2)) + { + shibari_packet_end(pkt) ; + if (!buffer_timed_put(b, pkt->buf - 2, pkt->pos + 2, deadline, stamp)) return 0 ; + shibari_packet_begin(pkt, id, zone, SHIBARI_T_AXFR) ; + shibari_packet_add_rr(pkt, entry, prefixlen, 0, 2) ; + } + return 1 ; +} + +#define SEPS "/,; \t\n" + +int shibari_packet_tdb_axfr (buffer *b, char const *axfrok, char const *loc, cdb const *tdb, s6dns_message_header_t const *qhdr, s6dns_domain_t const *zone, shibari_packet *pkt, tain const *deadline, tain const *wstamp, tain *stamp) +{ + shibari_tdb_entry soa ; + shibari_tdb_entry cur ; + uint32_t pos = CDB_TRAVERSE_INIT() ; + if (axfrok && axfrok[0] != '*') + { + s6dns_domain_t decoded = *zone ; + unsigned int zonelen ; + size_t len = strlen(axfrok) + 1 ; + char zbuf[256] ; + if (!s6dns_domain_decode(&decoded)) return 1 ; + zonelen = s6dns_domain_tostring(zbuf, 256, &decoded) ; + while (len) + { + size_t seppos = byte_in(axfrok, len, SEPS, sizeof(SEPS)) ; + if (!memcmp(zbuf, axfrok, seppos) && (seppos == zonelen || seppos + 1 == zonelen)) break ; + axfrok += seppos + 1 ; + len -= seppos + 1 ; + } + if (!len) return 5 ; + } + + { + cdb_find_state state = CDB_FIND_STATE_ZERO ; + int r = shibari_tdb_read_entry(tdb, &state, &soa, zone->s, zone->len, SHIBARI_T_SOA, 0, loc, wstamp, 0) ; + if (r == -1) return 2 ; + if (!r) return 9 ; + } + + shibari_packet_begin(pkt, qhdr->id, zone, SHIBARI_T_AXFR) ; + pkt->hdr.aa = 1 ; + if (!add(b, pkt, &soa, 0, qhdr->id, zone, deadline, stamp)) return -1 ; + + for (;;) + { + cdb_data data ; + int prefixlen ; + int r = cdb_traverse_next(tdb, &cur.key, &data, &pos) ; + if (r == -1) return 2 ; + if (!r) break ; + prefixlen = shibari_util_get_prefixlen(cur.key.s, cur.key.len, zone->s, zone->len) ; + if (prefixlen == -1) continue ; + r = shibari_tdb_entry_parse(&cur, data.s, data.len, SHIBARI_T_ANY, 2, loc, wstamp) ; + if (r == -1) return 2 ; + if (!r) continue ; + if (cur.type == SHIBARI_T_SOA) continue ; + if (!add(b, pkt, &cur, prefixlen, qhdr->id, zone, deadline, stamp)) return -1 ; + } + + if (!add(b, pkt, &soa, 0, qhdr->id, zone, deadline, stamp)) return -1 ; + shibari_packet_end(pkt) ; + return 0 ; +} -- cgit v1.3.1