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 
24 #include "dnsdist.hh"
25 #include "dnsname.hh"
26 #include "protozero.hh"
27 
28 class DNSDistProtoBufMessage
29 {
30 public:
31   DNSDistProtoBufMessage(const DNSQuestion& dq);
32   DNSDistProtoBufMessage(const DNSResponse& dr, bool includeCNAME);
33 
34   void setServerIdentity(const std::string& serverId);
35   void setRequestor(const ComboAddress& requestor);
36   void setResponder(const ComboAddress& responder);
37   void setRequestorPort(uint16_t port);
38   void setResponderPort(uint16_t port);
39   void setResponseCode(uint8_t rcode);
40   void setType(pdns::ProtoZero::Message::MessageType type);
41   void setBytes(size_t bytes);
42   void setTime(time_t sec, uint32_t usec);
43   void setQueryTime(time_t sec, uint32_t usec);
44   void setQuestion(const DNSName& name, uint16_t qtype, uint16_t qclass);
45   void setEDNSSubnet(const Netmask& nm);
46 
47   void addTag(const std::string& strValue);
48   void addRR(DNSName&& qname, uint16_t uType, uint16_t uClass, uint32_t uTTL, const std::string& data);
49 
50   void serialize(std::string& data) const;
51 
52   std::string toDebugString() const;
53 
54 private:
55   struct PBRecord
56   {
57     DNSName d_name;
58     std::string d_data;
59     uint32_t d_ttl;
60     uint16_t d_type;
61     uint16_t d_class;
62   };
63   struct PBQuestion
64   {
PBQuestionDNSDistProtoBufMessage::PBQuestion65     PBQuestion(const DNSName& name, uint16_t type, uint16_t class_): d_name(name), d_type(type), d_class(class_)
66     {
67     }
68 
69     DNSName d_name;
70     uint16_t d_type;
71     uint16_t d_class;
72   };
73 
74   std::vector<PBRecord> d_additionalRRs;
75   std::vector<std::string> d_additionalTags;
76 
77   const DNSQuestion& d_dq;
78   const DNSResponse* d_dr{nullptr};
79   const std::string* d_ServerIdentityRef{nullptr};
80 
81   boost::optional<PBQuestion> d_question{boost::none};
82   boost::optional<std::string> d_serverIdentity{boost::none};
83   boost::optional<ComboAddress> d_requestor{boost::none};
84   boost::optional<ComboAddress> d_responder{boost::none};
85   boost::optional<Netmask> d_ednsSubnet{boost::none};
86   boost::optional<std::pair<time_t, uint32_t>> d_time{boost::none};
87   boost::optional<std::pair<time_t, uint32_t>> d_queryTime{boost::none};
88   boost::optional<size_t> d_bytes{boost::none};
89   boost::optional<uint8_t> d_rcode{boost::none};
90 
91   pdns::ProtoZero::Message::MessageType d_type{pdns::ProtoZero::Message::MessageType::DNSQueryType};
92   bool d_includeCNAME{false};
93 };
94