about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/include/shibari/packet.h3
-rw-r--r--src/server/deps-lib/shibari-server1
-rw-r--r--src/server/shibari-server-tcp.c97
-rw-r--r--src/server/shibari_packet_tdb_axfr.c86
4 files changed, 104 insertions, 83 deletions
diff --git a/src/include/shibari/packet.h b/src/include/shibari/packet.h
index 1f4fa93..0d53c2a 100644
--- a/src/include/shibari/packet.h
+++ b/src/include/shibari/packet.h
@@ -5,6 +5,7 @@
 
 #include <stdint.h>
 
+#include <skalibs/buffer.h>
 #include <skalibs/cdb.h>
 #include <skalibs/tai.h>
 
@@ -35,5 +36,7 @@ extern unsigned int shibari_packet_add_glue (shibari_packet *, cdb const *, char
 extern unsigned int shibari_packet_assert_authority (shibari_packet *, cdb const *, char const *, uint16_t, uint16_t, char const *, tain const *) ;
 
 extern unsigned int shibari_packet_tdb_answer_query (shibari_packet *, cdb const *, s6dns_message_header_t const *, s6dns_domain_t const *, uint16_t, char const *, tain const *) ;
+extern int shibari_packet_tdb_axfr (buffer *, char const *, char const *, cdb const *, s6dns_message_header_t const *, s6dns_domain_t const *, shibari_packet *, tain const *, tain const *, tain *) ;
+#define shibari_packet_tdb_axfr_g(b, axfrok, loc, tdb, qhdr, zone, pkt, deadline, wstamp) shibari_packet_tdb_axfr(b, axfrok, loc, tdb, qhdr, zone, pkt, deadline, (wstamp), &STAMP)
 
 #endif
diff --git a/src/server/deps-lib/shibari-server b/src/server/deps-lib/shibari-server
index 7c5b981..b1604a6 100644
--- a/src/server/deps-lib/shibari-server
+++ b/src/server/deps-lib/shibari-server
@@ -9,5 +9,6 @@ shibari_tdb_read_entry.o
 shibari_packet_add_glue.o
 shibari_packet_assert_authority.o
 shibari_packet_tdb_answer_query.o
+shibari_packet_tdb_axfr.o
 -ls6dns
 -lskarnet
diff --git a/src/server/shibari-server-tcp.c b/src/server/shibari-server-tcp.c
index 94d0ccd..cd35a9e 100644
--- a/src/server/shibari-server-tcp.c
+++ b/src/server/shibari-server-tcp.c
@@ -10,7 +10,6 @@
 #include <skalibs/uint16.h>
 #include <skalibs/uint32.h>
 #include <skalibs/types.h>
-#include <skalibs/bytestr.h>
 #include <skalibs/strerr.h>
 #include <skalibs/buffer.h>
 #include <skalibs/sgetopt.h>
@@ -63,76 +62,6 @@ static inline void get_socket_info (ip46 *localip, uint16_t *localport, ip46 *re
   }
 }
 
-static void add (shibari_packet *pkt, shibari_tdb_entry const *entry, int prefixlen, uint16_t id, s6dns_domain_t const *zone, tain const *deadline)
-{
-  if (!shibari_packet_add_rr(pkt, entry, prefixlen, 0, 2))
-  {
-    shibari_packet_end(pkt) ;
-    if (!buffer_timed_put_g(buffer_1, pkt->buf - 2, pkt->pos + 2, deadline))
-      strerr_diefu1sys(111, "write to stdout") ;
-    shibari_packet_begin(pkt, id, zone, SHIBARI_T_AXFR) ;
-    if (!shibari_packet_add_rr(pkt, entry, prefixlen, 0, 2))
-      strerr_dief1x(101, "can't happen: record too long to fit in single packet") ;
-  }
-}
-
-#define SEPS "/,; \t\n"
-
-static inline int axfr (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)
-{
-  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 ;
-  add(pkt, &soa, 0, qhdr->id, zone, deadline) ;
-
-  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 ;
-    add(pkt, &cur, prefixlen, qhdr->id, zone, deadline) ;
-  }
-
-  add(pkt, &soa, 0, qhdr->id, zone, deadline) ;
-  shibari_packet_end(pkt) ;
-  return 0 ;
-}
-
 int main (int argc, char const *const *argv)
 {
   cdb tdb = CDB_ZERO ;
@@ -210,20 +139,22 @@ int main (int argc, char const *const *argv)
 
     if (!s6dns_message_parse_init(&hdr, &counts, buf, len, &rcode))
       strerr_diefu1sys(111, "parse message") ;
-    if (hdr.opcode) { rcode = 4 ; goto answer ; }
-    if (!s6dns_message_parse_question(&counts, &name, &qtype, buf, len, &rcode) || !s6dns_domain_encode(&name))
-    {
+    if (hdr.opcode) rcode = 4 ;
+    else if (!s6dns_message_parse_question(&counts, &name, &qtype, buf, len, &rcode) || !s6dns_domain_encode(&name))
       rcode = errno == ENOTSUP ? 4 : 1 ;
-      goto answer ;
+    else
+    {
+      shibari_log_query(verbosity, &name, qtype) ;
+      tain_add_g(&deadline, &wtto) ;
+      tain_wallclock_read(&wstamp) ;
+      if (qtype == SHIBARI_T_AXFR)
+      {
+        int r = shibari_packet_tdb_axfr_g(buffer_1, axfrok, loc, &tdb, &hdr, &name, &pkt, &deadline, &wstamp) ;
+        if (r < 0) strerr_diefu1sys(111, "write to stdout") ;
+        else rcode = r ;
+      }
+      else rcode = shibari_packet_tdb_answer_query(&pkt, &tdb, &hdr, &name, qtype, loc, &wstamp) ;
     }
-    shibari_log_query(verbosity, &name, qtype) ;
-    tain_add_g(&deadline, &wtto) ;
-    tain_wallclock_read(&wstamp) ;
-    rcode = qtype == SHIBARI_T_AXFR ?
-      axfr(axfrok, loc, &tdb, &hdr, &name, &pkt, &deadline, &wstamp) :
-      shibari_packet_tdb_answer_query(&pkt, &tdb, &hdr, &name, qtype, loc, &wstamp) ;
-
- answer:
     if (rcode && rcode != 3)
     {
       shibari_packet_begin(&pkt, hdr.id, &name, qtype) ;
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 ;
+}