]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
resolved: set the DNSSEC OK (DO) flag
authorTom Gundersen <teg@jklm.no>
Wed, 24 Jun 2015 13:08:40 +0000 (15:08 +0200)
committerTom Gundersen <teg@jklm.no>
Fri, 27 Nov 2015 00:35:34 +0000 (01:35 +0100)
This indicates that we can handle DNSSEC records (per RFC3225), even if
all we do is silently drop them. This feature requires EDNS0 support.

As we do not yet support larger UDP packets, this feature increases the
risk of getting truncated packets.

Similarly to how we fall back to plain UDP if EDNS0 fails, we will fall
back to plain EDNS0 if EDNS0+DO fails (with the same logic of remembering
success and retrying after a grace period after failure).

src/resolve/resolved-dns-packet.c
src/resolve/resolved-dns-packet.h
src/resolve/resolved-dns-scope.c
src/resolve/resolved-dns-server.c
src/resolve/resolved-dns-server.h

index cb713f1f8590c1493a54f19148c2183fd1b5cc9b..75ca23fd087c2e417e4aab50040c678192debb23 100644 (file)
@@ -28,6 +28,8 @@
 #include "utf8.h"
 #include "util.h"
 
+#define EDNS0_OPT_DO (1<<15)
+
 int dns_packet_new(DnsPacket **ret, DnsProtocol protocol, size_t mtu) {
         DnsPacket *p;
         size_t a;
@@ -610,7 +612,7 @@ fail:
 }
 
 /* Append the OPT pseudo-RR described in RFC6891 */
-int dns_packet_append_opt_rr(DnsPacket *p, uint16_t max_udp_size, size_t *start) {
+int dns_packet_append_opt_rr(DnsPacket *p, uint16_t max_udp_size, bool edns0_do, size_t *start) {
         size_t saved_size;
         int r;
 
@@ -640,8 +642,8 @@ int dns_packet_append_opt_rr(DnsPacket *p, uint16_t max_udp_size, size_t *start)
         if (r < 0)
                 goto fail;
 
-        /* flags */
-        r = dns_packet_append_uint16(p, 0, NULL);
+        /* flags: DNSSEC OK (DO), see RFC3225 */
+        r = dns_packet_append_uint16(p, edns0_do ? EDNS0_OPT_DO : 0, NULL);
         if (r < 0)
                 goto fail;
 
index 385a8af7968aecb59acb9871b34b43740d53ba4e..feded09db31d495c9afe26619f84d02a98f23da5 100644 (file)
@@ -160,7 +160,7 @@ int dns_packet_append_label(DnsPacket *p, const char *s, size_t l, size_t *start
 int dns_packet_append_name(DnsPacket *p, const char *name, bool allow_compression, size_t *start);
 int dns_packet_append_key(DnsPacket *p, const DnsResourceKey *key, size_t *start);
 int dns_packet_append_rr(DnsPacket *p, const DnsResourceRecord *rr, size_t *start);
-int dns_packet_append_opt_rr(DnsPacket *p, uint16_t max_udp_size, size_t *start);
+int dns_packet_append_opt_rr(DnsPacket *p, uint16_t max_udp_size, bool edns0_do, size_t *start);
 
 void dns_packet_truncate(DnsPacket *p, size_t sz);
 
index 42478e41e205088a0ae096118a8c5489748c1aac..80070da2b921c51fcc2b89aa7eafefeac5aa5e09 100644 (file)
@@ -185,7 +185,11 @@ int dns_scope_emit(DnsScope *s, int fd, DnsServer *server, DnsPacket *p) {
                         return -EOPNOTSUPP;
 
                 if (server->possible_features >= DNS_SERVER_FEATURE_LEVEL_EDNS0) {
-                        r = dns_packet_append_opt_rr(p, DNS_PACKET_UNICAST_SIZE_MAX, &saved_size);
+                        bool edns_do;
+
+                        edns_do = server->possible_features >= DNS_SERVER_FEATURE_LEVEL_DO;
+
+                        r = dns_packet_append_opt_rr(p, DNS_PACKET_UNICAST_SIZE_MAX, edns_do, &saved_size);
                         if (r < 0)
                                 return r;
 
index f8c921e4c8566a3e79da3fee71543047b37a60ba..916f5dadb8def0b120514dc5fbd3cc9fc0aa9740 100644 (file)
@@ -479,5 +479,6 @@ static const char* const dns_server_feature_level_table[_DNS_SERVER_FEATURE_LEVE
         [DNS_SERVER_FEATURE_LEVEL_TCP] = "TCP",
         [DNS_SERVER_FEATURE_LEVEL_UDP] = "UDP",
         [DNS_SERVER_FEATURE_LEVEL_EDNS0] = "UDP+EDNS0",
+        [DNS_SERVER_FEATURE_LEVEL_DO] = "UDP+EDNS0+DO",
 };
 DEFINE_STRING_TABLE_LOOKUP(dns_server_feature_level, DnsServerFeatureLevel);
index e9b425430fc399b61f7ca274726b7864d0393877..9dd4961d5fc449de397271b10bfc14d7a72eeeb8 100644 (file)
@@ -35,6 +35,7 @@ typedef enum DnsServerFeatureLevel {
         DNS_SERVER_FEATURE_LEVEL_TCP,
         DNS_SERVER_FEATURE_LEVEL_UDP,
         DNS_SERVER_FEATURE_LEVEL_EDNS0,
+        DNS_SERVER_FEATURE_LEVEL_DO,
         _DNS_SERVER_FEATURE_LEVEL_MAX,
         _DNS_SERVER_FEATURE_LEVEL_INVALID = -1
 } DnsServerFeatureLevel;