]> git.ipfire.org Git - thirdparty/systemd.git/blobdiff - src/resolve/resolved-dns-packet.c
Merge pull request #2147 from vcaputo/sd-event-measure-latencies
[thirdparty/systemd.git] / src / resolve / resolved-dns-packet.c
index 5f7970129610e3c4708fb227d4111ed0bf2f0d5b..a8a8632491908108183a1ce7df53ec1960c3b984 100644 (file)
@@ -466,12 +466,8 @@ int dns_packet_append_label(DnsPacket *p, const char *d, size_t l, bool canonica
                 /* Generate in canonical form, as defined by DNSSEC
                  * RFC 4034, Section 6.2, i.e. all lower-case. */
 
-                for (i = 0; i < l; i++) {
-                        if (d[i] >= 'A' && d[i] <= 'Z')
-                                w[i] = (uint8_t) (d[i] - 'A' + 'a');
-                        else
-                                w[i] = (uint8_t) d[i];
-                }
+                for (i = 0; i < l; i++)
+                        w[i] = (uint8_t) ascii_tolower(d[i]);
         } else
                 /* Otherwise, just copy the string unaltered. This is
                  * essential for DNS-SD, where the casing of labels
@@ -499,7 +495,7 @@ int dns_packet_append_name(
 
         saved_size = p->size;
 
-        while (*name) {
+        while (!dns_name_is_root(name)) {
                 const char *z = name;
                 char label[DNS_LABEL_MAX];
                 size_t n = 0;
@@ -723,7 +719,40 @@ int dns_packet_append_opt(DnsPacket *p, uint16_t max_udp_size, bool edns0_do, si
                 goto fail;
 
         /* RDLENGTH */
-        r = dns_packet_append_uint16(p, 0, NULL);
+
+        if (edns0_do) {
+                /* If DO is on, also append RFC6975 Algorithm data */
+
+                static const uint8_t rfc6975[] = {
+
+                        0, 5, /* OPTION_CODE: DAU */
+                        0, 6, /* LIST_LENGTH */
+                        DNSSEC_ALGORITHM_RSASHA1,
+                        DNSSEC_ALGORITHM_RSASHA1_NSEC3_SHA1,
+                        DNSSEC_ALGORITHM_RSASHA256,
+                        DNSSEC_ALGORITHM_RSASHA512,
+                        DNSSEC_ALGORITHM_ECDSAP256SHA256,
+                        DNSSEC_ALGORITHM_ECDSAP384SHA384,
+
+                        0, 6, /* OPTION_CODE: DHU */
+                        0, 3, /* LIST_LENGTH */
+                        DNSSEC_DIGEST_SHA1,
+                        DNSSEC_DIGEST_SHA256,
+                        DNSSEC_DIGEST_SHA384,
+
+                        0, 7, /* OPTION_CODE: N3U */
+                        0, 1, /* LIST_LENGTH */
+                        NSEC3_ALGORITHM_SHA1,
+                };
+
+                r = dns_packet_append_uint16(p, sizeof(rfc6975), NULL);
+                if (r < 0)
+                        goto fail;
+
+                r = dns_packet_append_blob(p, rfc6975, sizeof(rfc6975), NULL);
+        } else
+                r = dns_packet_append_uint16(p, 0, NULL);
+
         if (r < 0)
                 goto fail;
 
@@ -1580,6 +1609,11 @@ int dns_packet_read_rr(DnsPacket *p, DnsResourceRecord **ret, bool *ret_cache_fl
         if (r < 0)
                 goto fail;
 
+        /* RFC 2181, Section 8, suggests to
+         * treat a TTL with the MSB set as a zero TTL. */
+        if (rr->ttl & UINT32_C(0x80000000))
+                rr->ttl = 0;
+
         r = dns_packet_read_uint16(p, &rdlength, NULL);
         if (r < 0)
                 goto fail;
@@ -2051,11 +2085,12 @@ int dns_packet_extract(DnsPacket *p) {
                                         goto finish;
                                 }
 
-                                /* The OPT RR is only valid in the Additional section */
-                                if (i < DNS_PACKET_ANCOUNT(p) + DNS_PACKET_NSCOUNT(p)) {
-                                        r = -EBADMSG;
-                                        goto finish;
-                                }
+                                /* Note that we accept the OPT RR in
+                                 * any section, not just in the
+                                 * additional section, as some routers
+                                 * (Belkin!)  blindly copy the OPT RR
+                                 * from the query to the reply packet,
+                                 * and don't get the section right. */
 
                                 /* Two OPT RRs? */
                                 if (p->opt) {