chiark / gitweb /
sd-network: remove redundant array size parameter from functions that return arrays
[elogind.git] / src / resolve / resolved-dns-packet.c
index 2a666924b080099036970a3b96cd30058d0f92bd..5597ffd96909eb8fbd84a416e7a1a1576c539ce8 100644 (file)
@@ -20,7 +20,7 @@
  ***/
 
 #include "utf8.h"
-
+#include "util.h"
 #include "resolved-dns-domain.h"
 #include "resolved-dns-packet.h"
 
@@ -38,6 +38,13 @@ int dns_packet_new(DnsPacket **ret, size_t mtu) {
         if (a < DNS_PACKET_HEADER_SIZE)
                 a = DNS_PACKET_HEADER_SIZE;
 
+        /* round up to next page size */
+        a = PAGE_ALIGN(ALIGN(sizeof(DnsPacket)) + a) - ALIGN(sizeof(DnsPacket));
+
+        /* make sure we never allocate more than useful */
+        if (a > DNS_PACKET_SIZE_MAX)
+                a = DNS_PACKET_SIZE_MAX;
+
         p = malloc0(ALIGN(sizeof(DnsPacket)) + a);
         if (!p)
                 return -ENOMEM;
@@ -112,11 +119,13 @@ int dns_packet_validate(DnsPacket *p) {
         if (p->size < DNS_PACKET_HEADER_SIZE)
                 return -EBADMSG;
 
+        if (p->size > DNS_PACKET_SIZE_MAX)
+                return -EBADMSG;
+
         return 0;
 }
 
 int dns_packet_validate_reply(DnsPacket *p) {
-        DnsPacketHeader *h;
         int r;
 
         assert(p);
@@ -125,14 +134,10 @@ int dns_packet_validate_reply(DnsPacket *p) {
         if (r < 0)
                 return r;
 
-        h = DNS_PACKET_HEADER(p);
-
-        /* Check QR field */
-        if ((be16toh(h->flags) & 1) == 0)
+        if (DNS_PACKET_QR(p) == 0)
                 return -EBADMSG;
 
-        /* Check opcode field */
-        if (((be16toh(h->flags) >> 1) & 15) != 0)
+        if (DNS_PACKET_OPCODE(p) != 0)
                 return -EBADMSG;
 
         return 0;
@@ -141,8 +146,35 @@ int dns_packet_validate_reply(DnsPacket *p) {
 static int dns_packet_extend(DnsPacket *p, size_t add, void **ret, size_t *start) {
         assert(p);
 
-        if (p->size + add > p->allocated)
-                return -ENOMEM;
+        if (p->size + add > p->allocated) {
+                size_t a;
+
+                a = PAGE_ALIGN((p->size + add) * 2);
+                if (a > DNS_PACKET_SIZE_MAX)
+                        a = DNS_PACKET_SIZE_MAX;
+
+                if (p->size + add > a)
+                        return -EMSGSIZE;
+
+                if (p->data) {
+                        void *d;
+
+                        d = realloc(p->data, a);
+                        if (!d)
+                                return -ENOMEM;
+
+                        p->data = d;
+                } else {
+                        p->data = malloc(a);
+                        if (!p->data)
+                                return -ENOMEM;
+
+                        memcpy(p->data, (uint8_t*) p + ALIGN(sizeof(DnsPacket)), p->size);
+                        memzero((uint8_t*) p->data + p->size, a - p->size);
+                }
+
+                p->allocated = a;
+        }
 
         if (start)
                 *start = p->size;
@@ -363,7 +395,7 @@ int dns_packet_read(DnsPacket *p, size_t sz, const void **ret, size_t *start) {
         return 0;
 }
 
-static void dns_packet_rewind(DnsPacket *p, size_t idx) {
+void dns_packet_rewind(DnsPacket *p, size_t idx) {
         assert(p);
         assert(idx <= p->size);
         assert(idx >= DNS_PACKET_HEADER_SIZE);
@@ -594,7 +626,7 @@ fail:
 }
 
 int dns_packet_read_rr(DnsPacket *p, DnsResourceRecord **ret, size_t *start) {
-        _cleanup_(dns_resource_record_unrefp) DnsResourceRecord *rr = NULL;
+        _cleanup_(dns_resource_record_unrefp) DnsResourceRecord *rr;
         size_t saved_rindex, offset;
         uint16_t rdlength;
         const void *d;
@@ -603,11 +635,11 @@ int dns_packet_read_rr(DnsPacket *p, DnsResourceRecord **ret, size_t *start) {
         assert(p);
         assert(ret);
 
-        saved_rindex = p->rindex;
-
         rr = dns_resource_record_new();
         if (!rr)
-                goto fail;
+                return -ENOMEM;
+
+        saved_rindex = p->rindex;
 
         r = dns_packet_read_key(p, &rr->key, NULL);
         if (r < 0)
@@ -699,7 +731,7 @@ int dns_packet_skip_question(DnsPacket *p) {
         unsigned i, n;
         assert(p);
 
-        n = be16toh(DNS_PACKET_HEADER(p)->qdcount);
+        n = DNS_PACKET_QDCOUNT(p);
         for (i = 0; i < n; i++) {
                 _cleanup_(dns_resource_key_free) DnsResourceKey key = {};