summaryrefslogtreecommitdiffstats
path: root/src/lib
diff options
context:
space:
mode:
authorPiotrek Zadroga <piotrek@isc.org>2024-02-14 22:57:13 +0100
committerPiotrek Zadroga <piotrek@isc.org>2024-02-23 17:14:05 +0100
commite9c507011486f21ee59b07c1ea40916d30753222 (patch)
tree39d6462b46a79e7a356967809cb5d1aae90b9de1 /src/lib
parent[#3141] unpack port SvcParam (diff)
downloadkea-e9c507011486f21ee59b07c1ea40916d30753222.tar.xz
kea-e9c507011486f21ee59b07c1ea40916d30753222.zip
[#3141] unpack dohpath SvcParam
Diffstat (limited to 'src/lib')
-rw-r--r--src/lib/dhcp/option4_dnr.h5
-rw-r--r--src/lib/dhcp/option6_dnr.cc37
2 files changed, 40 insertions, 2 deletions
diff --git a/src/lib/dhcp/option4_dnr.h b/src/lib/dhcp/option4_dnr.h
index 2d5b916535..fe570302d9 100644
--- a/src/lib/dhcp/option4_dnr.h
+++ b/src/lib/dhcp/option4_dnr.h
@@ -13,6 +13,7 @@
#include <dhcp/option.h>
#include <dhcp/option_data_types.h>
#include <dns/name.h>
+#include <util/encode/utf8.h>
#include <util/strutil.h>
#include <map>
@@ -459,6 +460,10 @@ protected:
/// @return length of DNR Instance data in octets.
uint16_t dnrInstanceLen() const;
+ /// @brief Indicates whether the "alpn" SvcParam contains support for HTTP.
+ /// Defaults to false.
+ bool alpn_http_;
+
private:
/// @brief Size in octets of DNR Instance Data Length field.
///
diff --git a/src/lib/dhcp/option6_dnr.cc b/src/lib/dhcp/option6_dnr.cc
index afdc348264..4659b36ca2 100644
--- a/src/lib/dhcp/option6_dnr.cc
+++ b/src/lib/dhcp/option6_dnr.cc
@@ -317,7 +317,12 @@ Option6Dnr::parseConfigData(const std::string& config_txt){
isc_throw(InvalidOptionDnrSvcParams,
getLogPrefix() << "Wrong Svc Params syntax - alpn-id "
<< alpn_id
- << " not found in ALPN-IDs registry");
+ << " not found in ALPN-IDs registry");
+ }
+
+ // Make notice if this is any of http alpn-ids.
+ if (alpn_id.starts_with('h')) {
+ alpn_http_ = true;
}
OpaqueDataTuple alpn_id_tuple(OpaqueDataTuple::LENGTH_1_BYTE);
@@ -350,11 +355,39 @@ Option6Dnr::parseConfigData(const std::string& config_txt){
svc_params_map_.insert(std::make_pair(num_svc_param_key, svc_param_val_tuple));
break;
case 7:
- // dohpath
+ // dohpath - RFC9461 Section 5
+ // single-valued SvcParamKey whose value (in both presentation format and wire
+ // format) MUST be a URI Template in relative form ([RFC6570], Section 1.1) encoded
+ // in UTF-8 [RFC3629]. If the "alpn" SvcParam indicates support for HTTP,
+ // "dohpath" MUST be present. The URI Template MUST contain a "dns" variable,
+ // and MUST be chosen such that the result after DoH URI Template expansion
+ // (Section 6 of [RFC8484]) is always a valid and functional ":path" value
+ // ([RFC9113], Section 8.3.1).
+
+ // Check that "dns" variable is there
+ if (svc_param_val.find("{?dns}") == std::string::npos) {
+ isc_throw(InvalidOptionDnrSvcParams,
+ getLogPrefix() << "Wrong Svc Params syntax - dohpath SvcParamValue URI"
+ << " Template MUST contain a 'dns' variable.");
+ }
+
+ // We hope to have URI containing < 0x80 ASCII chars, however to be sure
+ // and to be inline with RFC9461 Section 5, let's encode the dohpath with utf8.
+ auto const utf8_encoded = encode::encodeUtf8(svc_param_val);
+ svc_param_val_tuple.append(utf8_encoded.begin(), utf8_encoded.size());
+ svc_params_map_.insert(std::make_pair(num_svc_param_key, svc_param_val_tuple));
break;
}
}
+ // If the "alpn" SvcParam indicates support for HTTP, "dohpath" MUST be present.
+ if (alpn_http_ && svc_params_map_.find(7) == svc_params_map_.end()) {
+ isc_throw(InvalidOptionDnrSvcParams,
+ getLogPrefix() << "Wrong Svc Params syntax - dohpath SvcParam missing. "
+ << "When alpn SvcParam indicates "
+ << "support for HTTP, dohpath must be present.");
+ }
+
std::ostringstream stream;
for (auto const& p : SUPPORTED_SVC_PARAMS) {
auto it = svc_params_map_.find(p);