]>
git.ipfire.org Git - thirdparty/pdns.git/blob - pdns/recursordist/rec-protozero.cc
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.
23 #include "dnsrecords.hh"
24 #include "rec-protozero.hh"
27 void pdns::ProtoZero::RecMessage::addRR(const DNSRecord
& record
, const std::set
<uint16_t>& exportTypes
, [[maybe_unused
]] bool udr
)
29 if (record
.d_place
!= DNSResourceRecord::ANSWER
|| record
.d_class
!= QClass::IN
) {
33 if (exportTypes
.count(record
.d_type
) == 0) {
37 protozero::pbf_writer pbf_rr
{d_response
, static_cast<protozero::pbf_tag_type
>(pdns::ProtoZero::Message::ResponseField::rrs
)};
39 encodeDNSName(pbf_rr
, d_rspbuf
, static_cast<protozero::pbf_tag_type
>(pdns::ProtoZero::Message::RRField::name
), record
.d_name
);
40 pbf_rr
.add_uint32(static_cast<protozero::pbf_tag_type
>(pdns::ProtoZero::Message::RRField::type
), record
.d_type
);
41 pbf_rr
.add_uint32(static_cast<protozero::pbf_tag_type
>(pdns::ProtoZero::Message::RRField::class_
), record
.d_class
);
42 pbf_rr
.add_uint32(static_cast<protozero::pbf_tag_type
>(pdns::ProtoZero::Message::RRField::ttl
), record
.d_ttl
);
44 auto add
= [&](const std::string
& str
) {
45 if (size() + str
.length() < std::numeric_limits
<uint16_t>::max() / 2) {
46 pbf_rr
.add_string(static_cast<protozero::pbf_tag_type
>(pdns::ProtoZero::Message::RRField::rdata
), str
);
50 switch (record
.d_type
) {
52 const auto& content
= getRR
<ARecordContent
>(record
);
56 ComboAddress data
= content
->getCA();
57 pbf_rr
.add_bytes(static_cast<protozero::pbf_tag_type
>(pdns::ProtoZero::Message::RRField::rdata
), reinterpret_cast<const char*>(&data
.sin4
.sin_addr
.s_addr
), sizeof(data
.sin4
.sin_addr
.s_addr
));
61 const auto& content
= getRR
<AAAARecordContent
>(record
);
65 ComboAddress data
= content
->getCA();
66 pbf_rr
.add_bytes(static_cast<protozero::pbf_tag_type
>(pdns::ProtoZero::Message::RRField::rdata
), reinterpret_cast<const char*>(&data
.sin6
.sin6_addr
.s6_addr
), sizeof(data
.sin6
.sin6_addr
.s6_addr
));
70 const auto& content
= getRR
<CNAMERecordContent
>(record
);
74 add(content
->getTarget().toString());
78 const auto& content
= getRR
<TXTRecordContent
>(record
);
86 const auto& content
= getRR
<NSRecordContent
>(record
);
90 add(content
->getNS().toString());
94 const auto& content
= getRR
<PTRRecordContent
>(record
);
98 add(content
->getContent().toString());
102 const auto& content
= getRR
<MXRecordContent
>(record
);
106 add(content
->d_mxname
.toString());
110 const auto& content
= getRR
<SPFRecordContent
>(record
);
114 add(content
->getText());
118 const auto& content
= getRR
<SRVRecordContent
>(record
);
122 add(content
->d_target
.toString());
129 pbf_rr
.add_bool(static_cast<protozero::pbf_tag_type
>(pdns::ProtoZero::Message::RRField::udr
), udr
);
132 // Save the offset of the byte containing the just added bool. We can do this since
133 // we know a bit about how protobuf's encoding works.
134 offsets
.push_back(d_rspbuf
.length() - 1);
139 void pdns::ProtoZero::RecMessage::clearUDR(std::string
& str
)
141 for (auto i
: offsets
) {
147 void pdns::ProtoZero::RecMessage::addEvents(const RecEventTrace
& trace
)
149 for (const auto& t
: trace
.getEvents()) {
150 protozero::pbf_writer pbf_trace
{d_message
, static_cast<protozero::pbf_tag_type
>(Field::trace
)};
151 pbf_trace
.add_int64(static_cast<protozero::pbf_tag_type
>(Event::ts
), t
.d_ts
);
152 pbf_trace
.add_uint32(static_cast<protozero::pbf_tag_type
>(Event::event
), t
.d_event
);
153 pbf_trace
.add_bool(static_cast<protozero::pbf_tag_type
>(Event::start
), t
.d_start
);
155 const auto& v
= t
.d_value
;
156 if (std::holds_alternative
<std::nullopt_t
>(v
)) {
158 else if (std::holds_alternative
<bool>(v
)) {
159 pbf_trace
.add_bool(static_cast<protozero::pbf_tag_type
>(Event::boolVal
), std::get
<bool>(v
));
161 else if (std::holds_alternative
<int64_t>(v
)) {
162 pbf_trace
.add_int64(static_cast<protozero::pbf_tag_type
>(Event::intVal
), std::get
<int64_t>(v
));
164 else if (std::holds_alternative
<std::string
>(v
)) {
165 pbf_trace
.add_string(static_cast<protozero::pbf_tag_type
>(Event::stringVal
), std::get
<std::string
>(v
));
167 else if (std::holds_alternative
<PacketBuffer
>(v
)) {
168 const PacketBuffer
& p
= std::get
<PacketBuffer
>(v
);
169 pbf_trace
.add_bytes(static_cast<protozero::pbf_tag_type
>(Event::bytesVal
), reinterpret_cast<const char*>(p
.data()), p
.size());
171 if (!t
.d_custom
.empty()) {
172 pbf_trace
.add_string(static_cast<protozero::pbf_tag_type
>(Event::custom
), t
.d_custom
);