2 * This file is part of PowerDNS or dnsdist.
3 * Copyright -- PowerDNS.COM B.V. and its contributors
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.
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.
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.
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.
24 #ifndef DISABLE_PROTOBUF
26 #include "dnsdist-protobuf.hh"
27 #include "protozero.hh"
29 DNSDistProtoBufMessage::DNSDistProtoBufMessage(const DNSQuestion
& dq
): d_dq(dq
), d_type(pdns::ProtoZero::Message::MessageType::DNSQueryType
)
33 DNSDistProtoBufMessage::DNSDistProtoBufMessage(const DNSResponse
& dr
, bool includeCNAME
): d_dq(dr
), d_dr(&dr
), d_type(pdns::ProtoZero::Message::MessageType::DNSResponseType
), d_includeCNAME(includeCNAME
)
37 void DNSDistProtoBufMessage::setServerIdentity(const std::string
& serverId
)
39 d_serverIdentity
= serverId
;
42 void DNSDistProtoBufMessage::setRequestor(const ComboAddress
& requestor
)
44 d_requestor
= requestor
;
47 void DNSDistProtoBufMessage::setResponder(const ComboAddress
& responder
)
49 d_responder
= responder
;
52 void DNSDistProtoBufMessage::setRequestorPort(uint16_t port
)
55 d_requestor
->setPort(port
);
59 void DNSDistProtoBufMessage::setResponderPort(uint16_t port
)
62 d_responder
->setPort(port
);
66 void DNSDistProtoBufMessage::setResponseCode(uint8_t rcode
)
71 void DNSDistProtoBufMessage::setType(pdns::ProtoZero::Message::MessageType type
)
76 void DNSDistProtoBufMessage::setBytes(size_t bytes
)
81 void DNSDistProtoBufMessage::setTime(time_t sec
, uint32_t usec
)
83 d_time
= std::pair(sec
, usec
);
86 void DNSDistProtoBufMessage::setQueryTime(time_t sec
, uint32_t usec
)
88 d_queryTime
= std::pair(sec
, usec
);
91 void DNSDistProtoBufMessage::setQuestion(const DNSName
& name
, uint16_t qtype
, uint16_t qclass
)
93 d_question
= DNSDistProtoBufMessage::PBQuestion(name
, qtype
, qclass
);
96 void DNSDistProtoBufMessage::setEDNSSubnet(const Netmask
& nm
)
101 void DNSDistProtoBufMessage::addTag(const std::string
& strValue
)
103 d_additionalTags
.push_back(strValue
);
106 void DNSDistProtoBufMessage::addRR(DNSName
&& qname
, uint16_t uType
, uint16_t uClass
, uint32_t uTTL
, const std::string
& strBlob
)
108 d_additionalRRs
.push_back({std::move(qname
), strBlob
, uTTL
, uType
, uClass
});
111 void DNSDistProtoBufMessage::serialize(std::string
& data
) const
113 if ((data
.capacity() - data
.size()) < 128) {
114 data
.reserve(data
.size() + 128);
116 pdns::ProtoZero::Message m
{data
};
121 m
.setTime(d_time
->first
, d_time
->second
);
126 m
.setTime(ts
.tv_sec
, ts
.tv_nsec
/ 1000);
129 const auto distProto
= d_dq
.getProtocol();
130 pdns::ProtoZero::Message::TransportProtocol protocol
= pdns::ProtoZero::Message::TransportProtocol::UDP
;
132 if (distProto
== dnsdist::Protocol::DoTCP
) {
133 protocol
= pdns::ProtoZero::Message::TransportProtocol::TCP
;
135 else if (distProto
== dnsdist::Protocol::DoT
) {
136 protocol
= pdns::ProtoZero::Message::TransportProtocol::DoT
;
138 else if (distProto
== dnsdist::Protocol::DoH
) {
139 protocol
= pdns::ProtoZero::Message::TransportProtocol::DoH
;
141 else if (distProto
== dnsdist::Protocol::DNSCryptUDP
) {
142 protocol
= pdns::ProtoZero::Message::TransportProtocol::DNSCryptUDP
;
144 else if (distProto
== dnsdist::Protocol::DNSCryptTCP
) {
145 protocol
= pdns::ProtoZero::Message::TransportProtocol::DNSCryptTCP
;
148 m
.setRequest(d_dq
.uniqueId
? *d_dq
.uniqueId
: getUniqueID(), d_requestor
? *d_requestor
: *d_dq
.remote
, d_responder
? *d_responder
: *d_dq
.local
, d_question
? d_question
->d_name
: *d_dq
.qname
, d_question
? d_question
->d_type
: d_dq
.qtype
, d_question
? d_question
->d_class
: d_dq
.qclass
, d_dq
.getHeader()->id
, protocol
, d_bytes
? *d_bytes
: d_dq
.getData().size());
150 if (d_serverIdentity
) {
151 m
.setServerIdentity(*d_serverIdentity
);
153 else if (d_ServerIdentityRef
!= nullptr) {
154 m
.setServerIdentity(*d_ServerIdentityRef
);
158 m
.setEDNSSubnet(*d_ednsSubnet
, 128);
163 // coverity[store_truncates_time_t]
164 m
.setQueryTime(d_queryTime
->first
, d_queryTime
->second
);
167 m
.setQueryTime(d_dq
.queryTime
->tv_sec
, d_dq
.queryTime
->tv_nsec
/ 1000);
170 if (d_dr
!= nullptr) {
171 m
.setResponseCode(d_rcode
? *d_rcode
: d_dr
->getHeader()->rcode
);
172 m
.addRRsFromPacket(reinterpret_cast<const char*>(d_dr
->getData().data()), d_dr
->getData().size(), d_includeCNAME
);
176 m
.setResponseCode(*d_rcode
);
180 for (const auto& rr
: d_additionalRRs
) {
181 m
.addRR(rr
.d_name
, rr
.d_type
, rr
.d_class
, rr
.d_ttl
, rr
.d_data
);
184 for (const auto& tag
: d_additionalTags
) {
191 #endif /* DISABLE_PROTOBUF */