File 0251-Update-inet_res-et.al.-for-RFC6891-EDNS-with-DNSSEC-.patch of Package erlang
From 4d2bf0d78380a3dbebbbffbb5283488afcc14a8e Mon Sep 17 00:00:00 2001
From: Raimo Niskanen <raimo@erlang.org>
Date: Thu, 2 Feb 2023 19:17:38 +0100
Subject: [PATCH] Update inet_res et.al. for RFC6891; EDNS with DNSSEC OK bit
---
lib/kernel/src/inet_db.erl | 17 ++++++++++++++---
lib/kernel/src/inet_dns.erl | 20 ++++++++++++--------
lib/kernel/src/inet_dns.hrl | 19 ++++++++++---------
lib/kernel/src/inet_dns_record_adts.pl | 4 ++--
lib/kernel/src/inet_res.erl | 14 +++++++++-----
5 files changed, 47 insertions(+), 27 deletions(-)
diff --git a/lib/kernel/src/inet_db.erl b/lib/kernel/src/inet_db.erl
index f792069a8b..dbcd181ef5 100644
--- a/lib/kernel/src/inet_db.erl
+++ b/lib/kernel/src/inet_db.erl
@@ -47,7 +47,7 @@
-export([set_cache_size/1, set_cache_refresh/1]).
-export([set_timeout/1, set_retry/1, set_servfail_retry_timeout/1,
set_inet6/1, set_usevc/1]).
--export([set_edns/1, set_udp_payload_size/1]).
+-export([set_edns/1, set_udp_payload_size/1, set_dnssec_ok/1]).
-export([set_resolv_conf/1, set_hosts_file/1, get_hosts_file/0]).
-export([tcp_module/0, set_tcp_module/1]).
-export([udp_module/0, set_udp_module/1]).
@@ -227,6 +227,8 @@ set_edns(Version) -> res_option(edns, Version).
set_udp_payload_size(Size) -> res_option(udp_payload_size, Size).
+set_dnssec_ok(DnssecOk) -> res_option(dnssec_ok, DnssecOk).
+
set_resolv_conf(Fname) when is_list(Fname) ->
res_option(resolv_conf, Fname).
@@ -312,7 +314,7 @@ valid_lookup() -> [dns, file, yp, nis, nisplus, native].
get_rc() ->
get_rc([hosts, domain, nameservers, search, alt_nameservers,
timeout, retry, servfail_retry_timeout, inet6, usevc,
- edns, udp_payload_size, resolv_conf, hosts_file,
+ edns, udp_payload_size, dnssec_ok, resolv_conf, hosts_file,
socks5_server, socks5_port, socks5_methods, socks5_noproxy,
udp, sctp, tcp, host, cache_size, cache_refresh, lookup], []).
@@ -361,6 +363,10 @@ get_rc([K | Ks], Ls) ->
res_udp_payload_size,
?DNS_UDP_PAYLOAD_SIZE,
Ks, Ls);
+ dnssec_ok -> get_rc(dnssec_ok,
+ res_res_dnssec_ok,
+ false,
+ Ks, Ls);
resolv_conf -> get_rc(resolv_conf,
res_resolv_conf,
undefined,
@@ -483,6 +489,7 @@ res_optname(inet6) -> res_inet6;
res_optname(usevc) -> res_usevc;
res_optname(edns) -> res_edns;
res_optname(udp_payload_size) -> res_udp_payload_size;
+res_optname(dnssec_ok) -> res_dnssec_ok;
res_optname(resolv_conf) -> res_resolv_conf;
res_optname(resolv_conf_name) -> res_resolv_conf;
res_optname(hosts_file) -> res_hosts_file;
@@ -517,6 +524,7 @@ res_check_option(inet6, Bool) when is_boolean(Bool) -> true;
res_check_option(usevc, Bool) when is_boolean(Bool) -> true;
res_check_option(edns, V) when V =:= false; V =:= 0 -> true;
res_check_option(udp_payload_size, S) when is_integer(S), S >= 512 -> true;
+res_check_option(dnssec_ok, D) when is_boolean(D) -> true;
res_check_option(resolv_conf, "") -> true;
res_check_option(resolv_conf, F) ->
res_check_option_absfile(F);
@@ -881,6 +889,7 @@ take_socket_type(MRef) ->
%% res_usevc Bool - use Virtual Circuit (TCP)
%% res_edns false|Integer - false or EDNS version
%% res_udp_payload_size Integer - size for EDNS, both query and reply
+%% res_dnssec_ok Bool - the DO bit in RFC6891 & RFC3225
%% res_resolv_conf Filename - file to watch for resolver config i.e
%% {res_ns, res_search}
%% res_hosts_file Filename - file to watch for hosts config
@@ -958,6 +967,7 @@ reset_db(Db) ->
{res_inet6, false},
{res_edns, false},
{res_udp_payload_size, ?DNS_UDP_PAYLOAD_SIZE},
+ {res_dnssec_ok, false},
{cache_size, ?CACHE_LIMIT},
{cache_refresh_interval,?CACHE_REFRESH},
{socks5_server, ""},
@@ -1641,6 +1651,7 @@ is_res_set(inet6) -> true;
is_res_set(usevc) -> true;
is_res_set(edns) -> true;
is_res_set(udp_payload_size) -> true;
+is_res_set(dnssec_ok) -> true;
is_res_set(resolv_conf) -> true;
is_res_set(hosts_file) -> true;
is_res_set(_) -> false.
diff --git a/lib/kernel/src/inet_dns.erl b/lib/kernel/src/inet_dns.erl
index c236dfd0d6..b1b939174f 100644
--- a/lib/kernel/src/inet_dns.erl
+++ b/lib/kernel/src/inet_dns.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1997-2021. All Rights Reserved.
+%% Copyright Ericsson AB 1997-2023. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -23,7 +23,7 @@
%%
%% RFC 1035: Domain Names - Implementation and Specification
%% RFC 2181: Clarifications to the DNS Specification
-%% RFC 2671: Extension Mechanisms for DNS (EDNS0)
+%% RFC 6891: Extension Mechanisms for DNS (EDNS0)
%% RFC 2782: A DNS RR for specifying the location of services (DNS SRV)
%% RFC 2915: The Naming Authority Pointer (NAPTR) DNS Resource Rec
%% RFC 6488: DNS Certification Authority Authorization (CAA) Resource Record
@@ -230,7 +230,8 @@ decode_rr_section(Bin, N, Buffer, RRs) ->
RR =
case Type of
?S_OPT ->
- <<ExtRcode,Version,Z:16>> = TTL,
+ <<ExtRcode,Version,DO:1,Z:15>> = TTL,
+ DnssecOk = (DO =/= 0),
#dns_rr_opt{
domain = Name,
type = Type,
@@ -238,7 +239,8 @@ decode_rr_section(Bin, N, Buffer, RRs) ->
ext_rcode = ExtRcode,
version = Version,
z = Z,
- data = D};
+ data = D,
+ do = DnssecOk};
_ ->
{Class,CacheFlush} = decode_class(C),
Data = decode_data(D, Class, Type, Buffer),
@@ -297,8 +299,8 @@ encode_query_section(Bin0, Comp0, [#dns_query{domain=DName}=Q | Qs]) ->
{Bin,Comp} = encode_name(Bin0, Comp0, byte_size(Bin0), DName),
encode_query_section(<<Bin/binary,T:16,C:16>>, Comp, Qs).
-%% RFC 1035: 4.1.3. Resource record format
-%% RFC 2671: 4.3, 4.4, 4.6 OPT RR format
+%% RFC 1035: 4.1.3. Resource record format
+%% RFC 6891: 6.1.2, 6.1.3, 6.2.3 Opt RR format
%%
encode_res_section(Bin, Comp, []) -> {Bin,Comp};
encode_res_section(
@@ -321,10 +323,12 @@ encode_res_section(
ext_rcode = ExtRCode,
version = Version,
z = Z,
- data = Data} | Rs]) ->
+ data = Data,
+ do = DnssecOk} | Rs]) ->
+ DO = case DnssecOk of true -> 1; false -> 0 end,
encode_res_section_rr(
Bin, Comp, Rs, DName, ?S_OPT, UdpPayloadSize, false,
- <<ExtRCode,Version,Z:16>>, Data).
+ <<ExtRCode,Version,DO:1,Z:15>>, Data).
encode_res_section_rr(
Bin0, Comp0, Rs, DName, Type, Class, CacheFlush, TTL, Data) ->
diff --git a/lib/kernel/src/inet_dns.hrl b/lib/kernel/src/inet_dns.hrl
index 5288c570b2..462b9b021b 100644
--- a/lib/kernel/src/inet_dns.hrl
+++ b/lib/kernel/src/inet_dns.hrl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1997-2021. All Rights Reserved.
+%% Copyright Ericsson AB 1997-2023. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -76,7 +76,7 @@
-define(T_SRV, 33). %% services
%% NAPTR (RFC 2915)
-define(T_NAPTR, 35). %% naming authority pointer
--define(T_OPT, 41). %% EDNS pseudo-rr RFC2671(7)
+-define(T_OPT, 41). %% EDNS pseudo-rr RFC6891(7)
%% SPF (RFC 4408)
-define(T_SPF, 99). %% server policy framework
%% non standard
@@ -118,7 +118,7 @@
-define(S_SRV, srv). %% services
%% NAPTR (RFC 2915)
-define(S_NAPTR, naptr). %% naming authority pointer
--define(S_OPT, opt). %% EDNS pseudo-rr RFC2671(7)
+-define(S_OPT, opt). %% EDNS pseudo-rr RFC6891(7)
%% SPF (RFC 4408)
-define(S_SPF, spf). %% server policy framework
%% non standard
@@ -201,15 +201,16 @@
-define(DNS_UDP_PAYLOAD_SIZE, 1280).
--record(dns_rr_opt, %% EDNS RR OPT (RFC2671), dns_rr{type=opt}
+-record(dns_rr_opt, %% EDNS RR OPT (RFC6891), dns_rr{type=opt}
{
domain = "", %% should be the root domain
type = opt,
- udp_payload_size = ?DNS_UDP_PAYLOAD_SIZE, %% RFC2671(4.5 CLASS)
- ext_rcode = 0, %% RFC2671(4.6 EXTENDED-RCODE)
- version = 0, %% RFC2671(4.6 VERSION)
- z = 0, %% RFC2671(4.6 Z)
- data = [] %% RFC2671(4.4)
+ udp_payload_size = ?DNS_UDP_PAYLOAD_SIZE, %% RFC6891(6.2.3 CLASS)
+ ext_rcode = 0, %% RFC6891(6.1.3 EXTENDED-RCODE)
+ version = 0, %% RFC6891(6.1.3 VERSION)
+ z = 0, %% RFC6891(6.1.3 Z)
+ data = [], %% RFC6891(6.1.2 RDATA)
+ do = false %% RFC6891(6.1.3 DO)
}).
-record(dns_query,
diff --git a/lib/kernel/src/inet_dns_record_adts.pl b/lib/kernel/src/inet_dns_record_adts.pl
index c89d837098..f3331222fc 100644
--- a/lib/kernel/src/inet_dns_record_adts.pl
+++ b/lib/kernel/src/inet_dns_record_adts.pl
@@ -2,7 +2,7 @@
#
# %CopyrightBegin%
#
-# Copyright Ericsson AB 2009-2016. All Rights Reserved.
+# Copyright Ericsson AB 2009-2023. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
@@ -32,7 +32,7 @@ my %Names = ('msg' => ['dns_rec', 'header', 'qdlist',
'dns_rr' => ['dns_rr', 'domain', 'type', 'class', 'ttl', 'data'],
'dns_rr_opt' => ['dns_rr_opt', 'domain', 'type',
'udp_payload_size', 'ext_rcode', 'version',
- 'z', 'data'],
+ 'z', 'data', 'do'],
'dns_query' => ['dns_query', 'domain', 'type', 'class'],
'header' => ['dns_header', 'id', 'qr', 'opcode', 'aa', 'tc',
'rd', 'ra', 'pr', 'rcode']);
diff --git a/lib/kernel/src/inet_res.erl b/lib/kernel/src/inet_res.erl
index 4e7809564c..f66fb00bca 100644
--- a/lib/kernel/src/inet_res.erl
+++ b/lib/kernel/src/inet_res.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1997-2022. All Rights Reserved.
+%% Copyright Ericsson AB 1997-2023. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -17,7 +17,7 @@
%%
%% %CopyrightEnd%
%%
-%% RFC 1035, 2671, 2782, 2915.
+%% RFC 1035, 2782, 2915, 6891.
%%
-module(inet_res).
@@ -61,6 +61,7 @@
| {retry, integer()}
| {timeout, integer()}
| {udp_payload_size, integer()}
+ | {dnssec_ok, boolean()}
| {usevc, boolean()}
| {nxdomain_reply, boolean()}.
@@ -263,7 +264,7 @@ do_nslookup(Name, Class, Type, Opts, Timeout) ->
%% options record
%%
-record(options, { % These must be sorted!
- alt_nameservers,edns,inet6,nameservers,
+ alt_nameservers,dnssec_ok,edns,inet6,nameservers,
nxdomain_reply, % this is a local option, not in inet_db
recurse,retry,servfail_retry_timeout,timeout,
udp_payload_size,usevc,
@@ -672,9 +673,12 @@ make_query(Dname, Class, Type, Options, Edns) ->
ARList = case Edns of
false -> [];
_ ->
- PSz = Options#options.udp_payload_size,
+ #options{
+ udp_payload_size = PSz,
+ dnssec_ok = DnssecOk } = Options,
[#dns_rr_opt{udp_payload_size=PSz,
- version=Edns}]
+ version=Edns,
+ do=DnssecOk}]
end,
Msg = #dns_rec{header=#dns_header{id=Id,
qr=false,
--
2.35.3