#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;
}
/* 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;
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;
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);
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;
[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);
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;