{"tls-supported-groups", SvcParam::SvcParamKey::tls_supported_groups},
};
-SvcParam::SvcParamKey SvcParam::keyFromString(const std::string& k) {
+SvcParam::SvcParamKey SvcParam::keyFromString(const std::string& k)
+{
bool ignored;
return SvcParam::keyFromString(k, ignored);
}
-SvcParam::SvcParamKey SvcParam::keyFromString(const std::string& k, bool &generic) {
+SvcParam::SvcParamKey SvcParam::keyFromString(const std::string& k, bool& generic)
+{
auto it = SvcParams.find(k);
if (it != SvcParams.end()) {
generic = false;
throw std::invalid_argument("SvcParam '" + k + "' is not recognized or in keyNNNN format");
}
-std::string SvcParam::keyToString(const SvcParam::SvcParamKey& k) {
+std::string SvcParam::keyToString(const SvcParam::SvcParamKey& k)
+{
auto ret = std::find_if(SvcParams.begin(), SvcParams.end(), [&](const std::pair<std::string, SvcParam::SvcParamKey>& e) { return e.second == k; });
if (ret != SvcParams.end()) {
return ret->first;
return "key" + std::to_string(k);
}
-SvcParam::SvcParam(const SvcParamKey &key) {
+SvcParam::SvcParam(const SvcParamKey& key)
+{
d_key = key;
if (d_key != SvcParamKey::no_default_alpn && d_key != SvcParamKey::ohttp) {
throw std::invalid_argument("can not create non-empty SvcParam for key '" + keyToString(key) + "'");
}
}
-SvcParam::SvcParam(const SvcParamKey &key, const std::string &value) {
+SvcParam::SvcParam(const SvcParamKey& key, const std::string& value)
+{
d_key = key;
if (d_key != SvcParamKey::ech && d_key != SvcParamKey::dohpath && d_key < 10) {
throw std::invalid_argument("can not create SvcParam for " + keyToString(key) + " with a string value");
d_value = value;
}
-SvcParam::SvcParam(const SvcParamKey &key, std::vector<std::string> &&value) {
+SvcParam::SvcParam(const SvcParamKey& key, std::vector<std::string>&& value)
+{
d_key = key;
if (d_key != SvcParamKey::alpn) {
throw std::invalid_argument("can not create SvcParam for " + keyToString(key) + " with a string-set value");
}
}
-SvcParam::SvcParam(const SvcParamKey &key, std::set<std::string> &&value) {
+SvcParam::SvcParam(const SvcParamKey& key, std::set<std::string>&& value)
+{
d_key = key;
if (d_key != SvcParamKey::mandatory) {
throw std::invalid_argument("can not create SvcParam for " + keyToString(key) + " with a string-set value");
}
if (d_key == SvcParamKey::mandatory) {
- for (auto const &v: value) {
+ for (auto const& v : value) {
d_mandatory.insert(keyFromString(v));
}
}
}
-SvcParam::SvcParam(const SvcParamKey &key, std::set<SvcParam::SvcParamKey> &&value) {
+SvcParam::SvcParam(const SvcParamKey& key, std::set<SvcParam::SvcParamKey>&& value)
+{
d_key = key;
if (d_key != SvcParamKey::mandatory) {
throw std::invalid_argument("can not create SvcParam for " + keyToString(key) + " with a SvcParamKey-set value");
d_mandatory = std::move(value);
}
-SvcParam::SvcParam(const SvcParamKey &key, std::vector<ComboAddress> &&value) {
+SvcParam::SvcParam(const SvcParamKey& key, std::vector<ComboAddress>&& value)
+{
d_key = key;
if (d_key != SvcParamKey::ipv6hint && d_key != SvcParamKey::ipv4hint) {
throw std::invalid_argument("can not create SvcParam for " + keyToString(key) + " with an IP address value");
}
- for (auto const &addr : value) {
+ for (auto const& addr : value) {
if (d_key == SvcParam::ipv6hint && !addr.isIPv6()) {
throw std::invalid_argument("non-IPv6 address ('" + addr.toString() + "') passed for " + keyToString(key));
}
d_ipHints = std::move(value);
}
-SvcParam::SvcParam(const SvcParamKey &key, std::vector<uint16_t> &&value) : d_key(key) {
+SvcParam::SvcParam(const SvcParamKey& key, std::vector<uint16_t>&& value) :
+ d_key(key)
+{
if (d_key != SvcParamKey::tls_supported_groups) {
throw std::invalid_argument("can not create SvcParam for " + keyToString(key) + " with a uint16 value-vector");
}
d_tls_supported_groups = std::move(value);
}
-SvcParam::SvcParam(const SvcParamKey &key, const uint16_t value) {
+SvcParam::SvcParam(const SvcParamKey& key, const uint16_t value)
+{
d_key = key;
if (d_key != SvcParamKey::port) {
throw std::invalid_argument("can not create SvcParam for " + keyToString(key) + " with a port value");
}
//! This ensures an std::set<SvcParam> will be sorted by key (section 2.2 mandates this for wire format)
-bool SvcParam::operator<(const SvcParam& other) const {
+bool SvcParam::operator<(const SvcParam& other) const
+{
return this->d_key < other.getKey();
}
-bool SvcParam::operator==(const SvcParam& other) const {
+bool SvcParam::operator==(const SvcParam& other) const
+{
if (this->getKey() != other.getKey()) {
return false;
}
switch (this->d_key) {
- case SvcParamKey::mandatory:
- return this->getMandatory() == other.getMandatory();
- case SvcParamKey::alpn:
- return this->getALPN() == other.getALPN();
- case SvcParamKey::no_default_alpn: /* fallthrough */
- case SvcParamKey::ohttp:
- return true;
- case SvcParamKey::port:
- return this->getPort() == other.getPort();
- case SvcParamKey::ipv4hint: /* fallthrough */
- case SvcParamKey::ipv6hint:
- return (this->getIPHints() == other.getIPHints() && this->getAutoHint() == other.getAutoHint());
- case SvcParamKey::ech:
- return this->getECH() == other.getECH();
- case SvcParamKey::dohpath:
- return this->getValue() == other.getValue();
- case SvcParamKey::tls_supported_groups:
- return this->getTLSSupportedGroups() == other.getTLSSupportedGroups();
- default:
- return this->getValue() == other.getValue();
- }
-}
-
-bool SvcParam::operator!=(const SvcParam& other) const {
+ case SvcParamKey::mandatory:
+ return this->getMandatory() == other.getMandatory();
+ case SvcParamKey::alpn:
+ return this->getALPN() == other.getALPN();
+ case SvcParamKey::no_default_alpn: /* fallthrough */
+ case SvcParamKey::ohttp:
+ return true;
+ case SvcParamKey::port:
+ return this->getPort() == other.getPort();
+ case SvcParamKey::ipv4hint: /* fallthrough */
+ case SvcParamKey::ipv6hint:
+ return (this->getIPHints() == other.getIPHints() && this->getAutoHint() == other.getAutoHint());
+ case SvcParamKey::ech:
+ return this->getECH() == other.getECH();
+ case SvcParamKey::dohpath:
+ return this->getValue() == other.getValue();
+ case SvcParamKey::tls_supported_groups:
+ return this->getTLSSupportedGroups() == other.getTLSSupportedGroups();
+ default:
+ return this->getValue() == other.getValue();
+ }
+}
+
+bool SvcParam::operator!=(const SvcParam& other) const
+{
return !(*this == other);
}
-const std::vector<ComboAddress>& SvcParam::getIPHints() const {
+const std::vector<ComboAddress>& SvcParam::getIPHints() const
+{
if (d_key != SvcParamKey::ipv6hint && d_key != SvcParamKey::ipv4hint) {
throw std::invalid_argument("getIPHints called for non-IP address key '" + keyToString(d_key) + "'");
}
return d_ipHints;
}
-uint16_t SvcParam::getPort() const {
+uint16_t SvcParam::getPort() const
+{
if (d_key != SvcParam::port) {
throw std::invalid_argument("getPort called for non-port key '" + keyToString(d_key) + "'");
}
return d_port;
}
-const std::vector<std::string>& SvcParam::getALPN() const {
+const std::vector<std::string>& SvcParam::getALPN() const
+{
if (d_key != SvcParam::alpn) {
throw std::invalid_argument("getALPN called for non-alpn key '" + keyToString(d_key) + "'");
}
return d_alpn;
}
-const std::set<SvcParam::SvcParamKey>& SvcParam::getMandatory() const {
+const std::set<SvcParam::SvcParamKey>& SvcParam::getMandatory() const
+{
if (d_key != SvcParam::mandatory) {
throw std::invalid_argument("getMandatory called for non-mandatory key '" + keyToString(d_key) + "'");
}
return d_mandatory;
}
-const std::string& SvcParam::getECH() const {
+const std::string& SvcParam::getECH() const
+{
if (d_key != SvcParam::ech) {
throw std::invalid_argument("getECH called for non-ech key '" + keyToString(d_key) + "'");
}
return d_ech;
}
-const std::string& SvcParam::getValue() const {
+const std::string& SvcParam::getValue() const
+{
if (d_key != SvcParamKey::dohpath && d_key < 10) {
throw std::invalid_argument("getValue called for non-single value key '" + keyToString(d_key) + "'");
}
return d_value;
}
-const std::vector<uint16_t>& SvcParam::getTLSSupportedGroups() const {
+const std::vector<uint16_t>& SvcParam::getTLSSupportedGroups() const
+{
if (d_key != SvcParam::tls_supported_groups) {
throw std::invalid_argument("getTLSSupportedGroups called for non-tls-supported-groups key '" + keyToString(d_key) + "'");
}
#include <set>
#include "iputils.hh"
-class SvcParam {
- public:
- enum SvcParamKey: uint16_t {
- // https://www.iana.org/assignments/dns-svcb/dns-svcb.xhtml#dns-svcparamkeys
- /* When adding new values, you *must* update SvcParam::SvcParam(const std::string &key, const std::string &value)
- * in svc-record.cc with the new numbers
- */
- mandatory = 0,
- alpn = 1,
- no_default_alpn = 2,
- port = 3,
- ipv4hint = 4,
- ech = 5,
- ipv6hint = 6,
- dohpath = 7,
- ohttp = 8,
- tls_supported_groups = 9, /* https://datatracker.ietf.org/doc/draft-ietf-tls-key-share-prediction/ */
- };
+class SvcParam
+{
+public:
+ enum SvcParamKey : uint16_t
+ {
+ // https://www.iana.org/assignments/dns-svcb/dns-svcb.xhtml#dns-svcparamkeys
+ /* When adding new values, you *must* update SvcParam::SvcParam(const std::string &key, const std::string &value)
+ * in svc-record.cc with the new numbers
+ */
+ mandatory = 0,
+ alpn = 1,
+ no_default_alpn = 2,
+ port = 3,
+ ipv4hint = 4,
+ ech = 5,
+ ipv6hint = 6,
+ dohpath = 7,
+ ohttp = 8,
+ tls_supported_groups = 9, /* https://datatracker.ietf.org/doc/draft-ietf-tls-key-share-prediction/ */
+ };
//! empty Param, unusable
SvcParam() = delete;
//! To create a value-less SvcParam (like no-default-alpn)
- SvcParam(const SvcParamKey &key);
+ SvcParam(const SvcParamKey& key);
//! To create a "generic" SvcParam (for keyNNNNN and ech)
- SvcParam(const SvcParamKey &key, const std::string &value);
+ SvcParam(const SvcParamKey& key, const std::string& value);
//! To create a multi-value SvcParam (like mandatory)
- SvcParam(const SvcParamKey &key, std::set<std::string> &&value);
+ SvcParam(const SvcParamKey& key, std::set<std::string>&& value);
//! To create a multi-value SvcParam (like alpn)
- SvcParam(const SvcParamKey &key, std::vector<std::string> &&value);
+ SvcParam(const SvcParamKey& key, std::vector<std::string>&& value);
//! To create a multi-value SvcParam with key values (like mandatory)
- SvcParam(const SvcParamKey &key, std::set<SvcParamKey> &&value);
+ SvcParam(const SvcParamKey& key, std::set<SvcParamKey>&& value);
//! To create an ipv{4,6}hints SvcParam
- SvcParam(const SvcParamKey &key, std::vector<ComboAddress> &&value);
+ SvcParam(const SvcParamKey& key, std::vector<ComboAddress>&& value);
//! To create a tls-supported-groups SvcParam
- SvcParam(const SvcParamKey &key, std::vector<uint16_t> &&value);
+ SvcParam(const SvcParamKey& key, std::vector<uint16_t>&& value);
//! To create a port SvcParam
- SvcParam(const SvcParamKey &key, const uint16_t value);
+ SvcParam(const SvcParamKey& key, const uint16_t value);
//! Returns the SvcParamKey based on the input
- static SvcParamKey keyFromString(const std::string &k);
+ static SvcParamKey keyFromString(const std::string& k);
//! Returns the SvcParamKey based on the input, generic is true when the format was 'keyNNNN'
- static SvcParamKey keyFromString(const std::string &k, bool &generic);
+ static SvcParamKey keyFromString(const std::string& k, bool& generic);
//! Returns the string value of the SvcParamKey
- static std::string keyToString(const SvcParamKey &k);
+ static std::string keyToString(const SvcParamKey& k);
- bool operator< (const SvcParam &other) const;
+ bool operator<(const SvcParam& other) const;
- bool operator==(const SvcParam &other) const;
+ bool operator==(const SvcParam& other) const;
- bool operator!=(const SvcParam &other) const;
+ bool operator!=(const SvcParam& other) const;
bool operator==(const SvcParamKey& key) const
{
return key == d_key;
}
- SvcParamKey getKey() const {
+ SvcParamKey getKey() const
+ {
return d_key;
}
bool getAutoHint() const { return d_autohint; };
void setAutoHint(const bool value) { d_autohint = value; };
- private:
- SvcParamKey d_key;
- std::string d_value; // For keyNNNNN vals
+private:
+ SvcParamKey d_key;
+ std::string d_value; // For keyNNNNN vals
- std::vector<std::string> d_alpn; // For ALPN
- std::set<SvcParamKey> d_mandatory; // For mandatory
- std::vector<ComboAddress> d_ipHints; // For ipv{6,4}hints
- std::string d_ech; // For Encrypted Client Hello
- std::vector<uint16_t> d_tls_supported_groups; // For tls-supported-groups
- uint16_t d_port{0}; // For port
+ std::vector<std::string> d_alpn; // For ALPN
+ std::set<SvcParamKey> d_mandatory; // For mandatory
+ std::vector<ComboAddress> d_ipHints; // For ipv{6,4}hints
+ std::string d_ech; // For Encrypted Client Hello
+ std::vector<uint16_t> d_tls_supported_groups; // For tls-supported-groups
+ uint16_t d_port{0}; // For port
- // Set to true if we encountered an "auto" field in hints
- // Can only be true when we read SVCParams from text
- bool d_autohint{false};
+ // Set to true if we encountered an "auto" field in hints
+ // Can only be true when we read SVCParams from text
+ bool d_autohint{false};
- static const std::map<std::string, SvcParamKey> SvcParams;
+ static const std::map<std::string, SvcParamKey> SvcParams;
};