1 /*
2  * This file is part of PowerDNS or dnsdist.
3  * Copyright -- PowerDNS.COM B.V. and its contributors
4  *
5  * This program is free software; you can redistribute it and/or modify
6  * it under the terms of version 2 of the GNU General Public License as
7  * published by the Free Software Foundation.
8  *
9  * In addition, for the avoidance of any doubt, permission is granted to
10  * link this program with OpenSSL and to (re)distribute the binaries
11  * produced as the result of such linking.
12  *
13  * This program is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16  * GNU General Public License for more details.
17  *
18  * You should have received a copy of the GNU General Public License
19  * along with this program; if not, write to the Free Software
20  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
21  */
22 #pragma once
23 #include <string>
24 #include <map>
25 #include <set>
26 #include "iputils.hh"
27 
28 class SvcParam {
29   public:
30     enum SvcParamKey: uint16_t {
31       // TODO link to IANA registry
32       /* When adding new values, you *must* update SvcParam::SvcParam(const std::string &key, const std::string &value)
33        * in svc-record.cc with the new numbers
34        */
35       mandatory = 0,
36       alpn = 1,
37       no_default_alpn = 2,
38       port = 3,
39       ipv4hint = 4,
40       ech = 5,
41       ipv6hint = 6
42     };
43 
44   //! empty Param, unusable
45   SvcParam();
46 
47   //! To create a value-less SvcParam (like no-default-alpn)
48   SvcParam(const SvcParamKey &key);
49 
50   //! To create a "generic" SvcParam (for keyNNNNN and ech)
51   SvcParam(const SvcParamKey &key, const std::string &value);
52 
53   //! To create a multi-value SvcParam (like mandatory)
54   SvcParam(const SvcParamKey &key, std::set<std::string> &&value);
55 
56   //! To create a multi-value SvcParam (like alpn)
57   SvcParam(const SvcParamKey &key, std::vector<std::string> &&value);
58 
59   //! To create a multi-value SvcParam with key values (like mandatory)
60   SvcParam(const SvcParamKey &key, std::set<SvcParamKey> &&value);
61 
62   //! To create and ipv{4,6}hists SvcParam
63   SvcParam(const SvcParamKey &key, std::vector<ComboAddress> &&value);
64 
65   //! To create a port SvcParam
66   SvcParam(const SvcParamKey &key, const uint16_t value);
67 
68   //! Returns the SvcParamKey based on the input
69   static SvcParamKey keyFromString(const std::string &k);
70 
71   //! Returns the string value of the SvcParamKey
72   static std::string keyToString(const SvcParamKey &k);
73 
74   bool operator< (const SvcParam &other) const;
75 
getKey() const76   SvcParamKey getKey() const {
77     return d_key;
78   }
79 
80   uint16_t getPort() const;
81   const std::vector<ComboAddress>& getIPHints() const;
82   const std::vector<std::string>& getALPN() const;
83   const std::set<SvcParamKey>& getMandatory() const;
84   const std::string& getECH() const;
85   const std::string& getValue() const;
86 
getAutoHint() const87   bool getAutoHint() const { return d_autohint; };
setAutoHint(const bool value)88   void setAutoHint(const bool value) { d_autohint = value; };
89 
90   private:
91     SvcParamKey d_key;
92     std::string d_value; // For keyNNNNN vals
93 
94     std::vector<std::string> d_alpn; // For ALPN
95     std::set<SvcParamKey> d_mandatory; // For mandatory
96     std::vector<ComboAddress> d_ipHints; // For ipv{6,4}hints
97     std::string d_ech; // For Encrypted Client Hello
98     uint16_t d_port{0}; // For port
99 
100     // Set to true if we encountered an "auto" field in hints
101     // Can only be true when we read SVCParams from text
102     bool d_autohint{false};
103 
104     static const std::map<std::string, SvcParamKey> SvcParams;
105 };
106