1+ /* *
2+ * @file
3+ * @brief Provides DNS name structure and parsing functionality.
4+ * @author Damir Zainullin <zaidamilda@gmail.com>
5+ */
6+
17#include " dnsName.hpp"
28
3- #include < numeric>
4- #include < span>
5- #include < string>
6- #include < optional>
79#include < algorithm>
810#include < cstddef>
911#include < cstdint>
12+ #include < numeric>
13+ #include < optional>
14+ #include < span>
15+ #include < string>
16+
1017#include < arpa/inet.h>
1118#include < boost/container/static_vector.hpp>
1219#include < boost/static_string.hpp>
13-
1420#include < utils/stringViewUtils.hpp>
1521#include < utils/toHostByteOrder.hpp>
1622
17- namespace ipxp
18- {
23+ namespace ipxp {
1924
2025constexpr static bool isPointer (const std::byte byte) noexcept
2126{
@@ -31,79 +36,78 @@ constexpr static uint16_t getPointerOffset(const std::byte* pointer) noexcept
3136
3237constexpr static std::size_t calculateElementsLength (auto && container) noexcept
3338{
34- return std::accumulate (
35- container.begin (), container. end (), std:: size_t { 0 } ,
36- [](std:: size_t sum, auto && element) {
37- return sum + element. size ();
38- });
39+ return std::accumulate (
40+ container.begin (),
41+ container. end (),
42+ std:: size_t { 0 },
43+ [](std:: size_t sum, auto && element) { return sum + element. size (); });
3944}
4045
4146std::optional<DNSName> DNSName::createFrom (
42- std::span<const std::byte> payload,
43- std::span<const std::byte> fullDNSpayload) noexcept
47+ std::span<const std::byte> payload,
48+ std::span<const std::byte> fullDNSpayload) noexcept
4449{
45- auto dnsName = std::make_optional<DNSName>();
46- while (!payload.empty ()) {
47- if (isPointer (*payload.data ())) {
48- if (payload.size () < sizeof (uint16_t )) {
49- return std::nullopt ;
50- }
51- const uint16_t pointerOffset = getPointerOffset (payload.data ());
52- if (pointerOffset >= fullDNSpayload.size ()) {
53- return std::nullopt ;
54- }
55-
56- const std::size_t lengthBytesCount =
57- dnsName->m_labels .empty () ? 0 : dnsName->m_labels .size ();
58- dnsName->m_length = calculateElementsLength (
59- dnsName->m_labels ) + lengthBytesCount + sizeof (pointerOffset);
60-
61- payload = fullDNSpayload.subspan (pointerOffset);
62- continue ;
63- }
64-
65- const auto labelLength = static_cast <uint8_t >(*payload.data ());
66- if (labelLength + sizeof (uint8_t ) > payload.size ()) {
67- return std::nullopt ;
68- }
69- if (labelLength == 0 ) {
70- return dnsName;
71- }
72-
73- if (dnsName->m_labels .size () == dnsName->m_labels .capacity ()) {
74- return std::nullopt ;
75- }
76-
77- dnsName->m_labels .push_back (toStringView (
78- payload.subspan (sizeof (uint8_t ), labelLength)));
79-
80- payload = payload.subspan (labelLength + sizeof (uint8_t ));
81- }
82-
83- return std::nullopt ;
50+ auto dnsName = std::make_optional<DNSName>();
51+ while (!payload.empty ()) {
52+ if (isPointer (*payload.data ())) {
53+ if (payload.size () < sizeof (uint16_t )) {
54+ return std::nullopt ;
55+ }
56+ const uint16_t pointerOffset = getPointerOffset (payload.data ());
57+ if (pointerOffset >= fullDNSpayload.size ()) {
58+ return std::nullopt ;
59+ }
60+
61+ const std::size_t lengthBytesCount
62+ = dnsName->m_labels .empty () ? 0 : dnsName->m_labels .size ();
63+ dnsName->m_length = calculateElementsLength (dnsName->m_labels ) + lengthBytesCount
64+ + sizeof (pointerOffset);
65+
66+ payload = fullDNSpayload.subspan (pointerOffset);
67+ continue ;
68+ }
69+
70+ const auto labelLength = static_cast <uint8_t >(*payload.data ());
71+ if (labelLength + sizeof (uint8_t ) > payload.size ()) {
72+ return std::nullopt ;
73+ }
74+ if (labelLength == 0 ) {
75+ return dnsName;
76+ }
77+
78+ if (dnsName->m_labels .size () == dnsName->m_labels .capacity ()) {
79+ return std::nullopt ;
80+ }
81+
82+ dnsName->m_labels .push_back (toStringView (payload.subspan (sizeof (uint8_t ), labelLength)));
83+
84+ payload = payload.subspan (labelLength + sizeof (uint8_t ));
85+ }
86+
87+ return std::nullopt ;
8488}
8589
8690bool DNSName::operator ==(const DNSName& other) const noexcept
8791{
88- return std::equal (
89- m_labels.begin (), m_labels.end (),
90- other.m_labels .begin (), other.m_labels .end ());
92+ return std::equal (
93+ m_labels.begin (),
94+ m_labels.end (),
95+ other.m_labels .begin (),
96+ other.m_labels .end ());
9197}
9298
9399std::string DNSName::toString (const char delimiter) const noexcept
94100{
95- std::string res;
96- std::ranges::for_each (m_labels, [&res, delimiter](std::string_view label) {
97- res += label;
98- res += delimiter;
99- });
100-
101- if (!res.empty ()) {
102- res.pop_back ();
103- }
104- return res;
101+ std::string res;
102+ std::ranges::for_each (m_labels, [&res, delimiter](std::string_view label) {
103+ res += label;
104+ res += delimiter;
105+ });
106+
107+ if (!res.empty ()) {
108+ res.pop_back ();
109+ }
110+ return res;
105111}
106112
107-
108-
109113} // namespace ipxp
0 commit comments