@@ -35,11 +35,43 @@ bool parseDnsOverTCPLength(std::span<const std::byte> payload) noexcept
3535 return dnsDataLength;
3636}
3737
38+ constexpr static
39+ std::optional<std::size_t >
40+ parseSection (
41+ std::span<const std::byte> payload,
42+ std::span<const std::byte> fullDNSPayload,
43+ const uint16_t recordCount,
44+ std::function<bool (const DNSRecord& record)>& recordCallback) noexcept
45+ {
46+ const std::byte* lastRecordPayloadEnd = payload.data ();
47+ DNSSectionReader reader (payload, fullDNSPayload, recordCount);
48+
49+ std::ranges::for_each (reader,
50+ [&recordCallback, &lastRecordPayloadEnd, needToCallCallback = true ]
51+ (const DNSRecord& record) mutable {
52+ lastRecordPayloadEnd = record.data .getSpan ().end ();
53+ if (needToCallCallback) {
54+ needToCallCallback = !recordCallback (record);
55+ }
56+ });
57+
58+ /* if (!parsedSection->records.empty()) {
59+ m_firstAnswer = parsedSection->records[0];
60+ }*/
61+
62+ return lastRecordPayloadEnd - payload.data ();
63+ }
64+
3865constexpr
3966bool DnsParser::parse (
40- std::span<const std::byte> payload, const bool isDnsOverTCP) noexcept
67+ std::span<const std::byte> payload,
68+ const bool isDnsOverTCP,
69+ std::function<bool (const DNSQuestion& query)>& queryCallback,
70+ std::function<bool(const DNSRecord& answer)>& answerCallback,
71+ std::function<bool(const DNSRecord& authorityRecord)>& authorityCallback,
72+ std::function<bool(const DNSRecord& additionalRecord)>& additionalCallback
73+ ) noexcept
4174{
42- const std::byte* dnsBegin = payload.data ();
4375 if (isDnsOverTCP) {
4476 const std::optional<uint16_t > dnsDataLength
4577 = parseDnsOverTCPLength (payload);
@@ -48,47 +80,61 @@ bool DnsParser::parse(
4880 return false ;
4981 }
5082 payload = payload.subspan (sizeof (uint16_t ), *dnsDataLength);
51- dnsBegin = payload. data ();
83+
5284 }
5385
86+ fullDNSPayload = payload;
87+
5488 const std::optional<DNSHeader> header = parseHeader (payload);
5589 if (!header.has_value ()) {
5690 return false ;
5791 }
58- m_answersCount = ntohs (header->answerRecordCount );
59- m_id = header->id ;
60- m_responseCode = header->flags .responseCode ;
92+ answersCount = ntohs (header->answerRecordCount );
93+ id = header->id ;
94+ responseCode = header->flags .responseCode ;
6195
62- const std::span<const std::byte> originalDNSPayload = payload;
6396 constexpr std::size_t questionSectionOffset = sizeof (DNSHeader);
6497 const std::optional<std::size_t > questionSectionSize = parseQuestionSection (
65- originalDNSPayload,
66- originalDNSPayload.subspan (questionSectionOffset),
67- ntohs (header->questionRecordCount ));
98+ payload.subspan (questionSectionOffset),
99+ fullDNSPayload,
100+ ntohs (header->questionRecordCount ),
101+ queryCallback);
68102 if (!questionSectionSize.has_value ()) {
69103 return false ;
70104 }
71105
72106 const std::size_t answerSectionOffset
73107 = questionSectionOffset + *questionSectionSize;
74108 const std::optional<std::size_t > answerSectionSize
75- = parseAnswerSection (payload.subspan (answerSectionOffset), dnsBegin, *header);
109+ = parseSection (
110+ payload.subspan (answerSectionOffset),
111+ fullDNSPayload,
112+ ntohs (header->answerRecordCount ),
113+ answerCallback);
76114 if (!answerSectionSize.has_value ()) {
77115 return false ;
78116 }
79117
80118 const std::size_t authoritySectionOffset
81119 = questionSectionOffset + *parseQuestionSection;
82120 const std::optional<std::size_t > authoritySectionSize
83- = parseAuthorityResourceRecordsSection (payload.subspan (authoritySectionOffset), dnsBegin, *header);
121+ = parseSection (
122+ payload.subspan (authoritySectionOffset),
123+ fullDNSPayload,
124+ ntohs (header->authorityRecordCount ),
125+ authorityCallback);
84126 if (!authoritySectionSize.has_value ()) {
85127 return false ;
86128 }
87129
88130 const std::size_t additionalSectionOffset
89131 = authoritySectionOffset + *authoritySectionSize;
90132 const std::optional<std::size_t > additionalSectionSize
91- = parseAdditionalResourceRecordsSection (payload.subspan (additionalSectionOffset), dnsBegin, *header);
133+ = parseSection (
134+ payload.subspan (additionalSectionOffset),
135+ fullDNSPayload,
136+ ntohs (header->additionalRecordCount ),
137+ additionalCallback);
92138 if (!additionalSectionSize.has_value ()) {
93139 return false ;
94140 }
@@ -108,13 +154,17 @@ std::optional<DNSHeader> parseHeader(std::span<const std::byte> payload) noexcep
108154constexpr
109155std::optional<std::size_t > DnsParser::parseQuestionSection (
110156 std::span<const std::byte> payload,
111- const std::byte* dnsBegin,
112- const uint16_t questionCount) noexcept
157+ std::span<const std::byte> fullDNSPayload,
158+ const uint16_t questionCount,
159+ std::function<bool (const DNSQuestion& query)>& queryCallback) noexcept
113160{
114- for (size_t questionIndex = 0 ; questionIndex < questionCount;
115- questionIndex++) {
161+ const std::byte* queriesBegin = payload.data ();
162+ bool needToCallCallback = true ;
163+
164+ for (size_t questionIndex = 0 ; questionIndex < questionCount; questionIndex++) {
116165
117- const std::optional<DNSName> name = DNSName::createFrom (payload, dnsBegin);
166+ const std::optional<DNSName> name
167+ = DNSName::createFrom (payload, fullDNSPayload);
118168 if (!name.has_value ()) {
119169 return std::nullopt ;
120170 }
@@ -129,17 +179,23 @@ std::optional<std::size_t> DnsParser::parseQuestionSection(
129179
130180 payload = payload.subspan (name->length () + 2 * sizeof (uint16_t ));
131181
132- if (questionIndex == 0 ) {
133- m_parsedFirstQuestion = {ParsedQuestion {
134- .name = *name,
135- .type = queryType,
136- .recordClass = queryClass}};
137- }
138- }
182+ if (needToCallCallback) {
183+ needToCallCallback = !queryCallback (DNSQuery{
184+ .name = *name,
185+ .type = queryType,
186+ .class = queryClass
187+ });
188+ }
189+ /* if (questionIndex == 0) {
190+ m_parsedFirstQuestion = {ParsedQuestion {
191+ .name = *name,
192+ .type = queryType,
193+ .recordClass = queryClass}};
194+ }*/
139195
140- return static_cast <std::size_t >(questionBegin - m_dnsData .data ());
196+ return static_cast <std::size_t >(payload .data () - queriesBegin );
141197}
142-
198+ /*
143199constexpr
144200std::optional<std::size_t>
145201DnsParser::parseAnswerSection(
@@ -208,7 +264,7 @@ DnsParser::parseAdditionalResourceRecordsSection(
208264 }
209265
210266 return parsedSection->records.back().data.end() - payload.data().begin();
211- }
267+ }*/
212268
213- } // namespace ipxp2
269+ } // namespace ipxp
214270
0 commit comments