]> git.ipfire.org Git - thirdparty/systemd.git/blobdiff - src/resolve/resolved-dns-packet.c
resolved: rr - add OPT pseudo-rr support
[thirdparty/systemd.git] / src / resolve / resolved-dns-packet.c
index 40b662246f89a444de2a86a96b409ff7bb27bb96..49c36e38f380c64a47251413d60533ae699ceefc 100644 (file)
@@ -609,6 +609,57 @@ fail:
         return r;
 }
 
+/* Append the OPT pseudo-RR described in RFC6891 */
+int dns_packet_append_opt_rr(DnsPacket *p, uint16_t max_udp_size, size_t *start) {
+        size_t saved_size;
+        int r;
+
+        assert(p);
+        /* we must never advertise supported packet size smaller than the legacy max */
+        assert(max_udp_size >= DNS_PACKET_UNICAST_SIZE_MAX);
+
+        saved_size = p->size;
+
+        /* empty name */
+        r = dns_packet_append_uint8(p, 0, NULL);
+        if (r < 0)
+                return r;
+
+        /* type */
+        r = dns_packet_append_uint16(p, DNS_TYPE_OPT, NULL);
+        if (r < 0)
+                goto fail;
+
+        /* maximum udp packet that can be received */
+        r = dns_packet_append_uint16(p, max_udp_size, NULL);
+        if (r < 0)
+                goto fail;
+
+        /* extended RCODE and VERSION */
+        r = dns_packet_append_uint16(p, 0, NULL);
+        if (r < 0)
+                goto fail;
+
+        /* flags */
+        r = dns_packet_append_uint16(p, 0, NULL);
+        if (r < 0)
+                goto fail;
+
+        /* RDLENGTH */
+        r = dns_packet_append_uint16(p, 0, NULL);
+        if (r < 0)
+                goto fail;
+
+        if (start)
+                *start = saved_size;
+
+        return 0;
+
+fail:
+        dns_packet_truncate(p, saved_size);
+        return r;
+}
+
 int dns_packet_append_rr(DnsPacket *p, const DnsResourceRecord *rr, size_t *start) {
         size_t saved_size, rdlength_offset, end, rdlength;
         int r;
@@ -1450,6 +1501,10 @@ int dns_packet_read_rr(DnsPacket *p, DnsResourceRecord **ret, size_t *start) {
                 r = dns_packet_read_name(p, &rr->ptr.name, true, NULL);
                 break;
 
+        case DNS_TYPE_OPT: /* we only care about the header */
+                r = 0;
+                break;
+
         case DNS_TYPE_HINFO:
                 r = dns_packet_read_string(p, &rr->hinfo.cpu, NULL);
                 if (r < 0)