]> git.ipfire.org Git - thirdparty/pdns.git/blame - pdns/test-proxy_protocol_cc.cc
Meson: Separate test files from common files
[thirdparty/pdns.git] / pdns / test-proxy_protocol_cc.cc
CommitLineData
1c2d079d 1#ifndef BOOST_TEST_DYN_LINK
530e3e1a 2#define BOOST_TEST_DYN_LINK
1c2d079d
FM
3#endif
4
530e3e1a 5#define BOOST_TEST_NO_MAIN
1c2d079d 6
530e3e1a
PD
7#include <boost/test/unit_test.hpp>
8
9#include "iputils.hh"
10#include "proxy-protocol.hh"
11
12using namespace boost;
13using std::string;
14
15
16BOOST_AUTO_TEST_SUITE(test_proxy_protocol_cc)
17
18#define BINARY(s) (std::string(s, sizeof(s) - 1))
19
20#define PROXYMAGIC "\x0D\x0A\x0D\x0A\x00\x0D\x0A\x51\x55\x49\x54\x0A"
21#define PROXYMAGICLEN sizeof(PROXYMAGIC)-1
22
23static string proxymagic(PROXYMAGIC, PROXYMAGICLEN);
24
25BOOST_AUTO_TEST_CASE(test_roundtrip) {
bde73d5b 26 std::vector<ProxyProtocolValue> values;
530e3e1a
PD
27 string proxyheader;
28
29 bool ptcp = true;
30 ComboAddress src("65.66.67.68:18762"); // 18762 = 0x494a = "IJ"
31 ComboAddress dest("69.70.71.72:19276"); // 19276 = 0x4b4c = "KL"
bde73d5b 32 proxyheader = makeProxyHeader(ptcp, src, dest, values);
530e3e1a
PD
33
34 BOOST_CHECK_EQUAL(proxyheader, BINARY(
35 PROXYMAGIC
36 "\x21" // version | command
37 "\x11" // ipv4=0x10 | TCP=0x1
38 "\x00\x0c" // 4 bytes IPv4 * 2 + 2 port numbers = 8 + 2 * 2 =12 = 0xc
39 "ABCD" // 65.66.67.68
40 "EFGH" // 69.70.71.72
41 "IJ" // src port
42 "KL" // dst port
43 ));
44
8c73c703 45 bool proxy;
530e3e1a
PD
46 bool ptcp2;
47 ComboAddress src2, dest2;
48
8c73c703 49 BOOST_CHECK_EQUAL(parseProxyHeader(proxyheader, proxy, src2, dest2, ptcp2, values), 28);
530e3e1a 50
8c73c703 51 BOOST_CHECK_EQUAL(proxy, true);
530e3e1a 52 BOOST_CHECK_EQUAL(ptcp2, true);
9a6a9e15
RG
53 BOOST_CHECK(src2 == src);
54 BOOST_CHECK(dest2 == dest);
55}
56
57BOOST_AUTO_TEST_CASE(test_local_proxy_header) {
58 auto payload = makeLocalProxyHeader();
59
60 BOOST_CHECK_EQUAL(payload, BINARY(
61 PROXYMAGIC
62 "\x20" // version | command
63 "\x00" // protocol family and address are set to 0
64 "\x00\x00" // no content
65 ));
66
67 bool proxy;
68 bool tcp = false;
69 ComboAddress src, dest;
70 std::vector<ProxyProtocolValue> values;
71
72 BOOST_CHECK_EQUAL(parseProxyHeader(payload, proxy, src, dest, tcp, values), 16);
73
74 BOOST_CHECK_EQUAL(proxy, false);
75 BOOST_CHECK_EQUAL(tcp, false);
76 BOOST_CHECK_EQUAL(values.size(), 0U);
77}
78
79BOOST_AUTO_TEST_CASE(test_tlv_values_content_len_signedness) {
80 std::string largeValue;
81 /* this value will make the content length parsing fail in case of signedness mistake */
82 largeValue.resize(65128, 'A');
83 const std::vector<ProxyProtocolValue> values = { { "foo", 0 }, { largeValue, 255 }};
84
85 const bool tcp = false;
86 const ComboAddress src("[2001:db8::1]:0");
87 const ComboAddress dest("[::1]:65535");
88 const auto payload = makeProxyHeader(tcp, src, dest, values);
89
90 bool proxy;
91 bool tcp2;
92 ComboAddress src2;
93 ComboAddress dest2;
94 std::vector<ProxyProtocolValue> parsedValues;
95
96 BOOST_CHECK_EQUAL(parseProxyHeader(payload, proxy, src2, dest2, tcp2, parsedValues), 16 + 36 + 6 + 65131);
97 BOOST_CHECK_EQUAL(proxy, true);
98 BOOST_CHECK_EQUAL(tcp2, tcp);
99 BOOST_CHECK(src2 == src);
100 BOOST_CHECK(dest2 == dest);
101 BOOST_REQUIRE_EQUAL(parsedValues.size(), values.size());
102 for (size_t idx = 0; idx < values.size(); idx++) {
103 BOOST_CHECK_EQUAL(parsedValues.at(idx).type, values.at(idx).type);
104 BOOST_CHECK_EQUAL(parsedValues.at(idx).content, values.at(idx).content);
105 }
106}
107
b98373ad
RG
108BOOST_AUTO_TEST_CASE(test_payload_too_large) {
109 const bool tcp = false;
110 const ComboAddress src("[2001:db8::1]:0");
111 const ComboAddress dest("[::1]:65535");
112 std::string largeValue;
113 /* this value is larger than the maximum size for a TLV */
114 largeValue.resize(65536, 'A');
115 const std::vector<ProxyProtocolValue> values = {{ largeValue, 255 }};
116
117 BOOST_CHECK_THROW(makeProxyHeader(tcp, src, dest, values), std::runtime_error);
118}
119
9a6a9e15
RG
120BOOST_AUTO_TEST_CASE(test_tlv_values_length_signedness) {
121 std::string largeValue;
122 /* this value will make the TLV length parsing fail in case of signedness mistake */
123 largeValue.resize(65000, 'A');
124 const std::vector<ProxyProtocolValue> values = { { "foo", 0 }, { largeValue, 255 }};
125
126 const bool tcp = false;
127 const ComboAddress src("[2001:db8::1]:0");
128 const ComboAddress dest("[::1]:65535");
129 const auto payload = makeProxyHeader(tcp, src, dest, values);
130
131 bool proxy;
132 bool tcp2;
133 ComboAddress src2;
134 ComboAddress dest2;
135 std::vector<ProxyProtocolValue> parsedValues;
136
137 BOOST_CHECK_EQUAL(parseProxyHeader(payload, proxy, src2, dest2, tcp2, parsedValues), 16 + 36 + 6 + 65003);
138 BOOST_CHECK_EQUAL(proxy, true);
139 BOOST_CHECK_EQUAL(tcp2, tcp);
140 BOOST_CHECK(src2 == src);
141 BOOST_CHECK(dest2 == dest);
142 BOOST_REQUIRE_EQUAL(parsedValues.size(), values.size());
143 for (size_t idx = 0; idx < values.size(); idx++) {
144 BOOST_CHECK_EQUAL(parsedValues.at(idx).type, values.at(idx).type);
145 BOOST_CHECK_EQUAL(parsedValues.at(idx).content, values.at(idx).content);
146 }
147}
148
149BOOST_AUTO_TEST_CASE(test_parsing_invalid_headers) {
150 const std::vector<ProxyProtocolValue> noValues;
151
152 const bool tcp = false;
153 const ComboAddress src("[2001:db8::1]:0");
154 const ComboAddress dest("[::1]:65535");
155 const auto payload = makeProxyHeader(tcp, src, dest, noValues);
156
157 bool proxy;
158 bool tcp2;
159 ComboAddress src2;
160 ComboAddress dest2;
161 std::vector<ProxyProtocolValue> values;
162
163 {
164 /* just checking that everything works */
165 BOOST_CHECK_EQUAL(parseProxyHeader(payload, proxy, src2, dest2, tcp2, values), 52);
166 BOOST_CHECK_EQUAL(proxy, true);
167 BOOST_CHECK_EQUAL(tcp2, tcp);
168 BOOST_CHECK(src2 == src);
169 BOOST_CHECK(dest2 == dest);
170 BOOST_CHECK_EQUAL(values.size(), 0U);
171 }
172
173 {
174 /* too short (not even full header) */
175 std::string truncated = payload;
176 truncated.resize(15);
177 BOOST_CHECK_EQUAL(parseProxyHeader(truncated, proxy, src2, dest2, tcp2, values), -1);
178 }
179
180 {
181 /* too short (missing address part) */
182 std::string truncated = payload;
183 truncated.resize(/* full header */ 16 + /* two IPv6s + port */ 36 - /* truncation */ 1);
184 BOOST_CHECK_EQUAL(parseProxyHeader(truncated, proxy, src2, dest2, tcp2, values), -1);
185 }
186
187 {
188 /* too short (missing TLV) */
189 values = { { "foo", 0 }, { "bar", 255 }} ;
190 const auto payloadWithValues = makeProxyHeader(tcp, src, dest, values);
191
192 std::string truncated = payloadWithValues;
193 truncated.resize(/* full header */ 16 + /* two IPv6s + port */ 36 + /* TLV 1 */ 6 + /* TLV 2 */ 6 - /* truncation */ 2);
194 BOOST_CHECK_EQUAL(parseProxyHeader(truncated, proxy, src2, dest2, tcp2, values), -2);
195 }
196
197 {
198 /* invalid magic */
199 std::string invalid = payload;
200 invalid.at(4) = 42;
201 BOOST_CHECK_EQUAL(parseProxyHeader(invalid, proxy, src2, dest2, tcp2, values), 0);
202 }
203
204 {
205 /* invalid version */
206 std::string invalid = payload;
207 invalid.at(12) = 0x10 | 0x01;
208 BOOST_CHECK_EQUAL(parseProxyHeader(invalid, proxy, src2, dest2, tcp2, values), 0);
209 }
210
211 {
212 /* invalid command */
213 std::string invalid = payload;
214 invalid.at(12) = 0x20 | 0x02;
215 BOOST_CHECK_EQUAL(parseProxyHeader(invalid, proxy, src2, dest2, tcp2, values), 0);
216 }
217
218 {
219 /* invalid family */
220 std::string invalid = payload;
221 invalid.at(13) = (0x04 << 4) | 0x01 /* STREAM */;
222 BOOST_CHECK_EQUAL(parseProxyHeader(invalid, proxy, src2, dest2, tcp2, values), 0);
223 }
224
225 {
226 /* invalid address */
227 std::string invalid = payload;
228 invalid.at(13) = (0x02 /* AF_INET */ << 4) | 0x03;
229 BOOST_CHECK_EQUAL(parseProxyHeader(invalid, proxy, src2, dest2, tcp2, values), 0);
230 }
231
232 {
233 /* TLV advertised len gets out of bounds */
234 values = { { "foo", 0 }, { "bar", 255 }} ;
235 const auto payloadWithValues = makeProxyHeader(tcp, src, dest, values);
236 std::string invalid = payloadWithValues;
237 /* full header (16) + two IPv6s + port (36) + TLV (6) TLV 2 (6) */
238 invalid.at(59) += 1;
239 BOOST_CHECK_EQUAL(parseProxyHeader(invalid, proxy, src2, dest2, tcp2, values), 0);
240 }
530e3e1a
PD
241}
242
243BOOST_AUTO_TEST_SUITE_END()