aboutsummaryrefslogtreecommitdiffstats
path: root/src/server/shibari_packet_tdb_axfr.c
diff options
context:
space:
mode:
authorLaurent Bercot <ska-skaware@skarnet.org>2023-12-28 09:48:39 +0000
committerLaurent Bercot <ska@appnovation.com>2023-12-28 09:48:39 +0000
commitc1b02ce115e2d05b777d19e7f93e452b4c17773e (patch)
treef739b1f96fa5c12b653701b99ddf4793652702bd /src/server/shibari_packet_tdb_axfr.c
parenta35bd63ea7ea151e5253bc597aa3cd05913bb3d9 (diff)
downloadshibari-c1b02ce115e2d05b777d19e7f93e452b4c17773e.tar.gz
refactor: separate axfr into its own function
Signed-off-by: Laurent Bercot <ska@appnovation.com>
Diffstat (limited to 'src/server/shibari_packet_tdb_axfr.c')
-rw-r--r--src/server/shibari_packet_tdb_axfr.c86
1 files changed, 86 insertions, 0 deletions
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 <stdint.h>
+#include <string.h>
+
+#include <skalibs/bytestr.h>
+#include <skalibs/cdb.h>
+#include <skalibs/tai.h>
+#include <skalibs/unix-timed.h>
+
+#include <s6-dns/s6dns-domain.h>
+#include <s6-dns/s6dns-message.h>
+
+#include <shibari/constants.h>
+#include <shibari/tdb.h>
+#include <shibari/packet.h>
+#include <shibari/util.h>
+
+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 ;
+}