Skip to content

Commit 59db544

Browse files
Zainullin DamirZainullin Damir
authored andcommitted
TLS - add server name reader
1 parent 44bd07c commit 59db544

File tree

1 file changed

+70
-0
lines changed

1 file changed

+70
-0
lines changed
Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
/**
2+
* @file
3+
* @brief Prefixed length string reader.
4+
* @author Damir Zainullin <[email protected]>
5+
* @date 2025
6+
*
7+
* @copyright Copyright (c) 2025 CESNET, z.s.p.o.
8+
*/
9+
10+
#pragma once
11+
12+
#include "../../readers/rangeReader/generator.hpp"
13+
#include "../../readers/rangeReader/rangeReader.hpp"
14+
15+
#include <cstddef>
16+
#include <cstdint>
17+
#include <optional>
18+
#include <ranges>
19+
#include <span>
20+
21+
#include <arpa/inet.h>
22+
23+
namespace ipxp {
24+
25+
/**
26+
* @struct PrefixedLengthStringReader
27+
* @brief Reader for strings prefixed with their length.
28+
*
29+
* This reader extracts strings from a byte span where each string is prefixed
30+
* by its length of type `LengthType`. It generates a range of strings until
31+
* it encounters an end or fails to parse a string.
32+
*
33+
* @tparam LengthType The type used for the length prefix (e.g., uint8_t, uint16_t).
34+
*/
35+
36+
struct [[gnu::packed]] ServerNameExtension {
37+
uint8_t type;
38+
uint16_t length;
39+
};
40+
41+
struct ServerNameReader : public RangeReader {
42+
auto getRange(std::span<const std::byte> extension) noexcept
43+
{
44+
return Generator([this, extension]() mutable -> std::optional<std::string_view> {
45+
if (extension.empty()) {
46+
setSuccess();
47+
return std::nullopt;
48+
}
49+
50+
if (extension.size() < sizeof(ServerNameExtension)) {
51+
return std::nullopt;
52+
}
53+
54+
const ServerNameExtension* serverNameExtension
55+
= reinterpret_cast<const ServerNameExtension*>(extension.data());
56+
const uint16_t length = ntohs(serverNameExtension->length);
57+
if (extension.size() < length + sizeof(ServerNameExtension)) {
58+
return std::nullopt;
59+
}
60+
61+
const auto label
62+
= reinterpret_cast<const char*>(extension.data() + sizeof(ServerNameExtension));
63+
extension = extension.subspan(length + sizeof(ServerNameExtension));
64+
65+
return std::string_view(label, length);
66+
});
67+
}
68+
};
69+
70+
} // namespace ipxp

0 commit comments

Comments
 (0)