]> git.ipfire.org Git - thirdparty/systemd.git/blobdiff - src/resolve/resolved-dns-packet.c
util-lib: move string table stuff into its own string-table.[ch]
[thirdparty/systemd.git] / src / resolve / resolved-dns-packet.c
index 649e8b74e15224ab2df3ef25c81ed112161d9123..f7f936d3435581d5ee094c8fef19193540421c8f 100644 (file)
   along with systemd; If not, see <http://www.gnu.org/licenses/>.
  ***/
 
-#include "utf8.h"
-#include "util.h"
-#include "strv.h"
-#include "unaligned.h"
 #include "dns-domain.h"
 #include "resolved-dns-packet.h"
+#include "string-table.h"
+#include "strv.h"
+#include "unaligned.h"
+#include "utf8.h"
+#include "util.h"
 
 int dns_packet_new(DnsPacket **ret, DnsProtocol protocol, size_t mtu) {
         DnsPacket *p;
@@ -388,14 +389,21 @@ int dns_packet_append_label(DnsPacket *p, const char *d, size_t l, size_t *start
         return 0;
 }
 
-int dns_packet_append_name(DnsPacket *p, const char *name,
-                           bool allow_compression, size_t *start) {
+int dns_packet_append_name(
+                DnsPacket *p,
+                const char *name,
+                bool allow_compression,
+                size_t *start) {
+
         size_t saved_size;
         int r;
 
         assert(p);
         assert(name);
 
+        if (p->refuse_compression)
+                allow_compression = false;
+
         saved_size = p->size;
 
         while (*name) {
@@ -508,23 +516,21 @@ static int dns_packet_append_type_window(DnsPacket *p, uint8_t window, uint8_t l
 
         assert(p);
         assert(types);
+        assert(length > 0);
 
         saved_size = p->size;
 
-        if (length != 0) {
-
-                r = dns_packet_append_uint8(p, window, NULL);
-                if (r < 0)
-                        goto fail;
+        r = dns_packet_append_uint8(p, window, NULL);
+        if (r < 0)
+                goto fail;
 
-                r = dns_packet_append_uint8(p, length, NULL);
-                if (r < 0)
-                        goto fail;
+        r = dns_packet_append_uint8(p, length, NULL);
+        if (r < 0)
+                goto fail;
 
-                r = dns_packet_append_blob(p, types, length, NULL);
-                if (r < 0)
-                        goto fail;
-        }
+        r = dns_packet_append_blob(p, types, length, NULL);
+        if (r < 0)
+                goto fail;
 
         if (start)
                 *start = saved_size;
@@ -538,7 +544,7 @@ fail:
 static int dns_packet_append_types(DnsPacket *p, Bitmap *types, size_t *start) {
         Iterator i;
         uint8_t window = 0;
-        uint8_t len = 0;
+        uint8_t entry = 0;
         uint8_t bitmaps[32] = {};
         unsigned n;
         size_t saved_size;
@@ -550,30 +556,24 @@ static int dns_packet_append_types(DnsPacket *p, Bitmap *types, size_t *start) {
         saved_size = p->size;
 
         BITMAP_FOREACH(n, types, i) {
-                uint8_t entry;
-
                 assert(n <= 0xffff);
 
-                if ((n << 8) != window) {
-                        r = dns_packet_append_type_window(p, window, len, bitmaps, NULL);
+                if ((n >> 8) != window && bitmaps[entry / 8] != 0) {
+                        r = dns_packet_append_type_window(p, window, entry / 8 + 1, bitmaps, NULL);
                         if (r < 0)
                                 goto fail;
 
-                        if (len > 0) {
-                                len = 0;
-                                zero(bitmaps);
-                        }
+                        zero(bitmaps);
                 }
 
-                window = n << 8;
-                len ++;
+                window = n >> 8;
 
                 entry = n & 255;
 
                 bitmaps[entry / 8] |= 1 << (7 - (entry % 8));
         }
 
-        r = dns_packet_append_type_window(p, window, len, bitmaps, NULL);
+        r = dns_packet_append_type_window(p, window, entry / 8 + 1, bitmaps, NULL);
         if (r < 0)
                 goto fail;
 
@@ -1061,8 +1061,12 @@ fail:
         return r;
 }
 
-int dns_packet_read_name(DnsPacket *p, char **_ret,
-                         bool allow_compression, size_t *start) {
+int dns_packet_read_name(
+                DnsPacket *p,
+                char **_ret,
+                bool allow_compression,
+                size_t *start) {
+
         size_t saved_rindex, after_rindex = 0, jump_barrier;
         _cleanup_free_ char *ret = NULL;
         size_t n = 0, allocated = 0;
@@ -1072,6 +1076,9 @@ int dns_packet_read_name(DnsPacket *p, char **_ret,
         assert(p);
         assert(_ret);
 
+        if (p->refuse_compression)
+                allow_compression = false;
+
         saved_rindex = p->rindex;
         jump_barrier = p->rindex;
 
@@ -1164,6 +1171,7 @@ static int dns_packet_read_type_window(DnsPacket *p, Bitmap **types, size_t *sta
         uint8_t window;
         uint8_t length;
         const uint8_t *bitmap;
+        uint8_t bit = 0;
         unsigned i;
         bool found = false;
         size_t saved_rindex;
@@ -1195,10 +1203,10 @@ static int dns_packet_read_type_window(DnsPacket *p, Bitmap **types, size_t *sta
 
         for (i = 0; i < length; i++) {
                 uint8_t bitmask = 1 << 7;
-                uint8_t bit = 0;
 
                 if (!bitmap[i]) {
                         found = false;
+                        bit += 8;
                         continue;
                 }
 
@@ -1673,8 +1681,12 @@ int dns_packet_read_rr(DnsPacket *p, DnsResourceRecord **ret, size_t *start) {
                 if (r < 0)
                         goto fail;
 
-                /* NSEC RRs with empty bitmpas makes no sense, but the RFC does not explicitly forbid them
-                   so we allow it */
+                /* The types bitmap must contain at least the NSEC record itself, so an empty bitmap means
+                   something went wrong */
+                if (bitmap_isclear(rr->nsec.types)) {
+                        r = -EBADMSG;
+                        goto fail;
+                }
 
                 break;
 
@@ -1715,7 +1727,7 @@ int dns_packet_read_rr(DnsPacket *p, DnsResourceRecord **ret, size_t *start) {
                 if (r < 0)
                         goto fail;
 
-                r = dns_packet_read_type_windows(p, &rr->nsec.types, offset + rdlength - p->rindex, NULL);
+                r = dns_packet_read_type_windows(p, &rr->nsec3.types, offset + rdlength - p->rindex, NULL);
                 if (r < 0)
                         goto fail;
 
@@ -1798,7 +1810,7 @@ int dns_packet_extract(DnsPacket *p) {
                         if (r < 0)
                                 goto finish;
 
-                        r = dns_answer_add(answer, rr);
+                        r = dns_answer_add(answer, rr, p->ifindex);
                         if (r < 0)
                                 goto finish;
                 }