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

openSUSE Build Service is sponsored by