OpenVPN 3 Core Library
Loading...
Searching...
No Matches
test_capture.cpp
Go to the documentation of this file.
1#include "test_common.hpp"
2#include "test_generators.hpp"
3#include <rapidcheck/state.h>
4
5#include <iostream>
6
9
10using namespace openvpn;
11
12TEST(misc, capture)
13{
14 DnsServer server;
15 server.addresses = {{{"8.8.8.8"}, 0}, {{"8.8.4.4"}, 53}};
17 dns_options.servers[0] = std::move(server);
18 dns_options.search_domains = {{"yonan.net"}, {"openvpn.net"}};
19
21
22 tbc->tun_builder_set_remote_address("52.7.171.249", false);
23 tbc->tun_builder_add_address("1.2.3.4", 24, "10.10.0.1", false, false);
24 tbc->tun_builder_add_address("fe80::c32:4ff:febf:97d9", 64, "9999::7777", true, false);
25 tbc->tun_builder_reroute_gw(true, false, 123);
26 tbc->tun_builder_add_route("192.168.0.0", 16, 33, false);
27 tbc->tun_builder_add_route("10.0.0.0", 8, -1, false);
28 tbc->tun_builder_add_route("2000::", 4, 55, true);
29 // tbc->tun_builder_add_route("X000::", 4, -1, true); // fixme
30 tbc->tun_builder_add_route("3000::", 4, -1, true);
31 tbc->tun_builder_add_route("fc00::", 7, 66, true);
32 tbc->tun_builder_exclude_route("10.10.0.0", 24, 77, false);
33 tbc->tun_builder_exclude_route("::1", 128, -1, true);
36 tbc->tun_builder_set_session_name("onewaytickettothemoon");
37 tbc->tun_builder_add_proxy_bypass("bypass.example.com");
38 tbc->tun_builder_set_proxy_auto_config_url("http://wpad.yonan.net/");
39 tbc->tun_builder_set_proxy_http("foo.bar.gov", 1234);
40 tbc->tun_builder_set_proxy_https("zoo.bar.gov", 4321);
43 tbc->tun_builder_set_allow_family(AF_INET6, true);
44
45 // OPENVPN_LOG("TEXT #1:\n" << tbc->to_string());
46
47 // const std::string fn1 = "cap1.txt";
48 Json::Value j1 = tbc->to_json();
49 const std::string j1_txt = j1.toStyledString();
50
51 // OPENVPN_LOG("writing to " << fn1);
52
54 // OPENVPN_LOG("JSON #1:\n" << j1_txt);
55
56 // const std::string fn2 = "cap2.txt";
58 tbc2->validate();
59 Json::Value j2 = tbc2->to_json();
60 const std::string j2_txt = j2.toStyledString();
61 // OPENVPN_LOG("writing to " << fn2);
62 // write_string(fn2, j2_txt);
63 // OPENVPN_LOG("JSON #2:\n" << j2_txt);
64
65 ASSERT_EQ(j1_txt, j2_txt) << "round trip failed";
66}
67
68// ===============================================================================================
69// RemoteAddress tests
70// ===============================================================================================
71
72TEST(RemoteAddress, EmptyIsNotDefined)
73{
75 ASSERT_FALSE(remote_address.defined());
76}
77
78RC_GTEST_PROP(RemoteAddress, NonEmptyIsDefined, ())
79{
80 const auto address = *rc::gen::nonEmpty<std::string>();
84}
85
86TEST(RemoteAddress, EmptyStringRepresentation)
87{
89 ASSERT_TRUE(remote_address.to_string().empty());
90}
91
92TEST(RemoteAddress, EmptyStringRepresentationIncludesIPv6Setting)
93{
95 remote_address.ipv6 = true;
96 ASSERT_EQ(remote_address.to_string(), " [IPv6]");
97}
98
99RC_GTEST_PROP(RemoteAddress, StringRepresentationReturnsAddress, (const std::string &address))
100{
104}
105
106RC_GTEST_PROP(RemoteAddress, StringRepresentationIncludesIPv6Setting, (const std::string &address))
107{
111 RC_ASSERT(remote_address.to_string() == address + " [IPv6]");
112}
113
114RC_GTEST_PROP(RemoteAddress, EmptyThrowsOnValidation, (const std::string &title))
115{
117 RC_ASSERT_THROWS_AS(remote_address.validate(title), openvpn::IP::ip_exception);
118}
119
120RC_GTEST_PROP(RemoteAddress, ValidatesIPv4, (const std::string &title))
121{
123 remote_address.address = *rc::IPv4Address().as("Valid IPv4 address");
125}
126
127RC_GTEST_PROP(RemoteAddress, ValidatesIPv6, (const std::string &title))
128{
130 remote_address.address = *rc::IPv6Address().as("Valid IPv6 address");
131 // Assumption: you have to specify manually and don't forget to set .ipv6 or else it throws
132 remote_address.ipv6 = true;
134}
135
136RC_GTEST_PROP(RemoteAddress, ThrowsValidatingMismatchedIPVersion, (const std::string &title, bool ipv6))
137{
139 // Intentionally generate IP Address with mismatched version: IPv4 if ipv6 is true, IPv6 otherwise
140 remote_address.address = ipv6 ? *rc::IPv4Address().as("Valid IPv4 address") : *rc::IPv6Address().as("Valid IPv6 address");
141 // Assumption: you have to specify manually
143 RC_ASSERT_THROWS_AS(remote_address.validate(title), openvpn::IP::ip_exception);
144}
145
146RC_GTEST_PROP(RemoteAddress, ThrowsValidatingInvalidIP, (const std::string &title, bool ipv6))
147{
149 remote_address.address = ipv6 ? *rc::IPv6Address(false).as("Invalid IPv6 address") : *rc::IPv4Address(false).as("Invalid IPv4 address");
150 // Assumption: you have to specify manually
152 RC_ASSERT_THROWS_AS(remote_address.validate(title), openvpn::IP::ip_exception);
153}
154
155RC_GTEST_PROP(RemoteAddress, EmptyJsonRoundTripHaveSameStringRepresentation, (const std::string &title))
156{
162}
163
164RC_GTEST_PROP(RemoteAddress, EmptyJsonRoundTripHaveSameDefinedStatus, (const std::string &title))
165{
171}
172
173RC_GTEST_PROP(RemoteAddress, EmptyJsonRoundTripThrowsOnValidation, (const std::string &title))
174{
176 RC_ASSERT_THROWS_AS(remote_address.validate(title), openvpn::IP::ip_exception);
180 RC_ASSERT_THROWS_AS(from_json.validate(title), openvpn::IP::ip_exception);
181}
182
183RC_GTEST_PROP(RemoteAddress, JsonRoundTripHaveSameStringRepresentation, (const std::string &address, const std::string &title, bool ipv6))
184{
192}
193
194RC_GTEST_PROP(RemoteAddress, JsonRoundTripHaveSameDefinedStatus, (const std::string &title))
195{
201}
202
203RC_GTEST_PROP(RemoteAddress, JsonRoundTripThrowsValidatingMismatchedIPVersion, (const std::string &title, bool ipv6))
204{
206 // Intentionally generate IP Address with mismatched version: IPv4 if ipv6 is true, IPv6 otherwise
207 remote_address.address = ipv6 ? *rc::IPv4Address().as("Valid IPv4 address") : *rc::IPv6Address().as("Valid IPv6 address");
209 RC_ASSERT_THROWS_AS(remote_address.validate(title), openvpn::IP::ip_exception);
213 RC_ASSERT_THROWS_AS(from_json.validate(title), openvpn::IP::ip_exception);
214}
215
216RC_GTEST_PROP(RemoteAddress, JsonRoundTripThrowsValidatingInvalidIP, (const std::string &title, bool ipv6))
217{
219 remote_address.address = ipv6 ? *rc::IPv6Address(false).as("Invalid IPv6 address") : *rc::IPv4Address(false).as("Invalid IPv4 address");
221 RC_ASSERT_THROWS_AS(remote_address.validate(title), openvpn::IP::ip_exception);
225 RC_ASSERT_THROWS_AS(from_json.validate(title), openvpn::IP::ip_exception);
226}
227
228RC_GTEST_PROP(RemoteAddress, JsonRoundTripValidatesCorrectIP, (const std::string &title, bool ipv6))
229{
231 remote_address.address = ipv6 ? *rc::IPv6Address().as("Valid IPv6 address") : *rc::IPv4Address().as("Valid IPv4 address");
237 from_json.validate(title);
238}
239
240RC_GTEST_PROP(RemoteAddress, FromInvalidJsonDoesNotChangeOriginalObject, (const std::string &address, const std::string &title, bool ipv6))
241{
245 const Json::Value invalid_json;
249}
250
251// ===============================================================================================
252// RerouteGW tests
253// ===============================================================================================
254
255TEST(RerouteGW, EmptyStringRepresentationReturnsUnsetOptions)
256{
258 ASSERT_EQ(reroute_gw.to_string(), "IPv4=0 IPv6=0 flags=[ ]");
259}
260
261RC_GTEST_PROP(RerouteGW, StringRepresentationReturnsSetOptions, (bool ipv4, bool ipv6, rc::RedirectGatewayFlagsValues flags))
262{
267 // TODO: refactor original code so there's no need to rewrite method
268 std::string ret;
269 ret += "[ ";
271 ret += "ENABLE ";
273 ret += "REROUTE_GW ";
275 ret += "LOCAL ";
277 ret += "AUTO_LOCAL ";
279 ret += "DEF1 ";
281 ret += "BYPASS_DHCP ";
283 ret += "BYPASS_DNS ";
285 ret += "BLOCK_LOCAL ";
287 ret += "IPv4 ";
289 ret += "IPv6 ";
290 ret += "]";
291 const std::string ipv4_and_ipv6_return_string = {"IPv4=" + std::to_string(ipv4) + " IPv6=" + std::to_string(ipv6) + " "};
293}
294
295RC_GTEST_PROP(RerouteGW, EmptyJsonRoundTripHaveSameStringRepresentation, (const std::string &title))
296{
302}
303
304RC_GTEST_PROP(RerouteGW, JsonRoundTripHaveSameStringRepresentation, (bool ipv4, bool ipv6, rc::RedirectGatewayFlagsValues flags, const std::string &title))
305{
314}
315
316RC_GTEST_PROP(RerouteGW, FromInvalidJsonThrows, (bool ipv4, bool ipv6, rc::RedirectGatewayFlagsValues flags, const std::string &title))
317{
319 from_json.ipv4 = ipv4;
321 from_json.flags = flags;
322 const Json::Value invalid_json;
324}
325
326// ===============================================================================================
327// RouteBased tests
328// ===============================================================================================
329
330RC_GTEST_PROP(RouteBased, EmptyStringRepresentationReturnsUnsetPrefixLength, (rc::RouteBased route_based))
331{
332 std::visit(
333 [](auto &&route_base_variant)
334 { RC_ASSERT(route_base_variant.to_string() == "/0"); },
335 route_based);
336}
337
338RC_GTEST_PROP(RouteBased, StringRepresentationReturnsSetOptions, (rc::RouteBased route_based, const std::string &address, unsigned char prefix_length, int metric, const std::string &gateway, bool ipv6, bool net30))
339{
340 std::visit(
341 [&address, prefix_length, metric, &gateway, ipv6, net30](auto &&route_base_variant)
342 {
343 route_base_variant.address = address;
344 route_base_variant.prefix_length = prefix_length;
345 route_base_variant.metric = metric;
346 route_base_variant.gateway = gateway;
347 route_base_variant.ipv6 = ipv6;
348 route_base_variant.net30 = net30;
349 std::string output;
350 output += address + "/" + std::to_string(prefix_length);
351 if (!gateway.empty())
352 output += " -> " + gateway;
353 if (metric >= 0)
354 output += " [METRIC=" + std::to_string(metric) + "]";
355 if (ipv6)
356 output += " [IPv6]";
357 if (net30)
358 output += " [net30]";
359 RC_ASSERT(route_base_variant.to_string() == output);
360 },
361 route_based);
362}
363
364RC_GTEST_PROP(RouteBased, EmptyThrowsOnValidation, (rc::RouteBased route_based, const std::string &title))
365{
366 std::visit(
367 [&title](auto &&route_base_variant)
368 {
369 using T = std::decay_t<decltype(route_base_variant)>;
370 if constexpr (std::is_same_v<T, TunBuilderCapture::RouteBase>)
371 {
372 RC_DISCARD("RouteBase does not have public validate method");
373 }
374 else
375 {
376 RC_ASSERT_THROWS_AS(route_base_variant.validate(title), openvpn::IP::ip_exception);
377 }
378 },
379 route_based);
380}
381
382RC_GTEST_PROP(RouteBased, Validates, (rc::RouteBased route_based, bool ipv6, bool net30, const std::string &title))
383{
384 // TODO: move to generator
385 std::visit(
386 [ipv6, net30, &title](auto &&route_base_variant)
387 {
388 using T = std::decay_t<decltype(route_base_variant)>;
389 if constexpr (std::is_same_v<T, TunBuilderCapture::RouteBase>)
390 {
391 RC_DISCARD("RouteBase does not have public validate method");
392 }
393 else
394 {
395 // Performs canonicalization so Route is valid
396 // TODO: separate path for RouteAddress that can be not canonical
397 if (ipv6)
398 {
399 route_base_variant.ipv6 = true;
400 auto ipv6_route = route_from_string(*rc::IPv6Address(), title, IP::Addr::V6);
401 ipv6_route.force_canonical();
402 route_base_variant.address = ipv6_route.to_string_optional_prefix_len();
403 route_base_variant.prefix_length = IPv6::Addr::SIZE;
404 }
405 else
406 {
407 route_base_variant.ipv6 = false;
408 route_base_variant.address = *rc::IPv4Address().as("Valid IPv4 address");
409 auto [prefix_min, prefix_max] = rc::calculateIPPrefixRange(route_base_variant.address);
410 if (net30 && prefix_min <= 30 && prefix_max >= 30)
411 {
412 route_base_variant.net30 = true;
413 route_base_variant.prefix_length = 30;
414 }
415 else
416 {
417 route_base_variant.net30 = false;
418 route_base_variant.prefix_length = *rc::gen::inRange(static_cast<char>(prefix_min), static_cast<char>(prefix_max + 1)).as("Valid prefix length");
419 }
420 }
421 if (auto maybe_metric = *rc::gen::maybe(rc::gen::arbitrary<int>().as("Metric value")).as("Maybe metric"))
422 {
423 route_base_variant.metric = *maybe_metric;
424 }
425 if (auto maybe_gateway = ipv6 ? *rc::gen::maybe(rc::IPv6Address().as("Valid IPv6 gateway")) : *rc::gen::maybe(rc::IPv4Address().as("Valid IPv4 gateway")))
426 {
427 route_base_variant.gateway = *maybe_gateway;
428 }
429 route_base_variant.validate(title);
430 }
431 },
432 route_based);
433}
434
435
436RC_GTEST_PROP(RouteBased, EmptyJsonRoundTripHaveSameStringRepresentation, (rc::RouteBased route_based, const std::string &title))
437{
438 std::visit(
439 [&title](auto &&route_base_variant)
440 {
441 const auto route_based_as_json = route_base_variant.to_json();
442 using T = std::decay_t<decltype(route_base_variant)>;
443 T from_json;
444 from_json.from_json(route_based_as_json, title);
445 RC_ASSERT(route_base_variant.to_string() == from_json.to_string());
446 },
447 route_based);
448}
449
450RC_GTEST_PROP(RouteBased, JsonRoundTripHaveSameStringRepresentation, (rc::RouteBased route_based, const std::string &address, unsigned char prefix_length, int metric, const std::string &gateway, bool ipv6, bool net30, const std::string &title))
451{
452 std::visit(
453 [&address, prefix_length, metric, &gateway, ipv6, net30, &title](auto &&route_base_variant)
454 {
455 route_base_variant.address = address;
456 route_base_variant.prefix_length = prefix_length;
457 route_base_variant.metric = metric;
458 route_base_variant.gateway = gateway;
459 route_base_variant.ipv6 = ipv6;
460 route_base_variant.net30 = net30;
461 const auto route_based_as_json = route_base_variant.to_json();
462 using T = std::decay_t<decltype(route_base_variant)>;
463 T from_json;
464 from_json.from_json(route_based_as_json, title);
465 RC_ASSERT(route_base_variant.to_string() == from_json.to_string());
466 },
467 route_based);
468}
469
470
471RC_GTEST_PROP(RouteBased, FromInvalidJsonThrows, (rc::RouteBased route_based, const std::string &title))
472{
473 std::visit(
474 [&title](auto &&route_base_variant)
475 {
476 const Json::Value invalid_json = {};
477 RC_ASSERT_THROWS_AS(route_base_variant.from_json(invalid_json, title), json::json_parse);
478 },
479 route_based);
480}
481
482// ===============================================================================================
483// ProxyBypass tests
484// ===============================================================================================
485
486TEST(ProxyBypass, EmptyIsNotDefined)
487{
489 ASSERT_FALSE(proxy_bypass.defined());
490}
491
492RC_GTEST_PROP(ProxyBypass, NonEmptyIsDefined, ())
493{
494 const auto bypass_host = *rc::gen::nonEmpty<std::string>();
498}
499
500TEST(ProxyBypass, EmptyStringRepresentation)
501{
503 ASSERT_TRUE(proxy_bypass.to_string().empty());
504}
505
506RC_GTEST_PROP(ProxyBypass, StringRepresentationReturnBypassHost, (const std::string &bypass_host))
507{
511}
512
513RC_GTEST_PROP(ProxyBypass, EmptyValidates, (const std::string &title))
514{
516 proxy_bypass.validate(title);
517}
518
519RC_GTEST_PROP(ProxyBypass, EmptyJsonRoundTripHaveSameStringRepresentation, (const std::string &title))
520{
526}
527
528RC_GTEST_PROP(ProxyBypass, EmptyJsonRoundTripHaveSameDefinedStatus, (const std::string &title))
529{
535}
536
537RC_GTEST_PROP(ProxyBypass, EmptyJsonRoundTripValidates, (const std::string &title))
538{
540 proxy_bypass.validate(title);
544 from_json.validate(title);
545}
546
547RC_GTEST_PROP(ProxyBypass, JsonRoundTripHaveSameStringRepresentation, (const std::string &bypass_host, const std::string &title))
548{
555}
556
557RC_GTEST_PROP(ProxyBypass, JsonRoundTripHaveSameDefinedStatus, (const std::string &bypass_host, const std::string &title))
558{
565}
566
567RC_GTEST_PROP(ProxyBypass, FromInvalidJsonThrows, (const std::string &title))
568{
570 const Json::Value invalid_json;
571 RC_ASSERT_THROWS_AS(from_json.from_json(invalid_json, title), json::json_parse);
572}
573
574// ===============================================================================================
575// ProxyAutoConfigURL tests
576// ===============================================================================================
577
578TEST(ProxyAutoConfigURL, EmptyIsNotDefined)
579{
581 ASSERT_FALSE(proxy_autoconfig_url.defined());
582}
583
584RC_GTEST_PROP(ProxyAutoConfigURL, NonEmptyIsDefined, ())
585{
586 const auto url = *rc::gen::nonEmpty<std::string>();
590}
591
592TEST(ProxyAutoConfigURL, EmptyStringRepresentation)
593{
595 ASSERT_TRUE(proxy_autoconfig_url.to_string().empty());
596}
597
598RC_GTEST_PROP(ProxyAutoConfigURL, StringRepresentationReturnsURL, (const std::string &url))
599{
603}
604
605RC_GTEST_PROP(ProxyAutoConfigURL, EmptyValidates, (const std::string &title))
606{
609}
610
611RC_GTEST_PROP(ProxyAutoConfigURL, EmptyJsonRoundTripHaveSameStringRepresentation, (const std::string &title))
612{
618}
619
620RC_GTEST_PROP(ProxyAutoConfigURL, EmptyJsonRoundTripHaveSameDefinedStatus, (const std::string &title))
621{
627}
628
629RC_GTEST_PROP(ProxyAutoConfigURL, EmptyJsonRoundTripValidates, (const std::string &title))
630{
636 from_json.validate(title);
637}
638
639RC_GTEST_PROP(ProxyAutoConfigURL, JsonRoundTripHaveSameStringRepresentation, (const std::string &url, const std::string &title))
640{
647}
648
649RC_GTEST_PROP(ProxyAutoConfigURL, JsonRoundTripHaveSameDefinedStatus, (const std::string &url, const std::string &title))
650{
657}
658
659RC_GTEST_PROP(ProxyAutoConfigURL, FromInvalidJsonDoesNotChangeOriginalObject, (const std::string &domain, const std::string &title))
660{
662 from_json.url = domain;
663 const Json::Value invalid_json;
665 RC_ASSERT(from_json.url == domain);
666}
667
668// ===============================================================================================
669// ProxyHostPort tests
670// ===============================================================================================
671
672TEST(ProxyHostPort, EmptyIsNotDefined)
673{
675 ASSERT_FALSE(proxy_host_port.defined());
676}
677
678RC_GTEST_PROP(ProxyHostPort, NonEmptyIsDefined, ())
679{
680 const auto host = *rc::gen::nonEmpty<std::string>();
684}
685
686TEST(ProxyHostPort, EmptyStringRepresentationReturnsDefaultPort)
687{
689 ASSERT_EQ(proxy_host_port.to_string(), std::string{" "} + std::to_string(proxy_host_port.port));
690}
691
692RC_GTEST_PROP(ProxyHostPort, StringRepresentationReturnsHostPort, (const std::string &host, const int port))
693{
697 RC_ASSERT(proxy_host_port.to_string() == host + std::string{" "} + std::to_string(port));
698}
699
700RC_GTEST_PROP(ProxyHostPort, EmptyValidates, (const std::string &title))
701{
704}
705
706RC_GTEST_PROP(ProxyHostPort, EmptyJsonRoundTripHaveSameStringRepresentation, (const std::string &title))
707{
713}
714
715RC_GTEST_PROP(ProxyHostPort, EmptyJsonRoundTripHaveSameDefinedStatus, (const std::string &title))
716{
722}
723
724RC_GTEST_PROP(ProxyHostPort, EmptyJsonRoundTripValidates, (const std::string &title))
725{
731 from_json.validate(title);
732}
733
734RC_GTEST_PROP(ProxyHostPort, JsonRoundTripHaveSameStringRepresentation, (const std::string &host, const int port, const std::string &title))
735{
743}
744
745RC_GTEST_PROP(ProxyHostPort, JsonRoundTripHaveSameDefinedStatus, (const std::string &host, const std::string &title))
746{
753}
754
755RC_GTEST_PROP(ProxyHostPort, FromInvalidJsonDoesNotChangeOriginalObject, (const std::string &host, const int port, const std::string &title))
756{
758 from_json.host = host;
759 from_json.port = port;
760 const Json::Value invalid_json;
762 RC_ASSERT(from_json.host == host);
763 RC_ASSERT(from_json.port == port);
764}
765
766// ===============================================================================================
767// WINSServer tests
768// ===============================================================================================
769
770TEST(WINSServer, EmptyStringRepresentation)
771{
772 const TunBuilderCapture::WINSServer wins_server;
773 ASSERT_TRUE(wins_server.to_string().empty());
774}
775
776RC_GTEST_PROP(WINSServer, StringRepresentationReturnsAddress, (const std::string &address))
777{
779 wins_server.address = address;
780 RC_ASSERT(wins_server.to_string() == address);
781}
782
783RC_GTEST_PROP(WINSServer, EmptyThrowsOnValidation, (const std::string &title))
784{
785 const TunBuilderCapture::WINSServer wins_server;
786 RC_ASSERT_THROWS_AS(wins_server.validate(title), openvpn::IP::ip_exception);
787}
788
789RC_GTEST_PROP(WINSServer, ValidatesAddress, (const std::string &title))
790{
792 wins_server.address = *rc::IPv4Address().as("Valid IPv4 address");
793 wins_server.validate(title);
794}
795
796RC_GTEST_PROP(WINSServer, ThrowsValidatingInvalidAddress, (const std::string &title))
797{
799 wins_server.address = *rc::IPv4Address(false).as("Invalid IPv4 address");
800 RC_ASSERT_THROWS_AS(wins_server.validate(title), openvpn::IP::ip_exception);
801}
802
803RC_GTEST_PROP(WINSServer, EmptyJsonRoundTripHaveSameStringRepresentation, (const std::string &title))
804{
805 const TunBuilderCapture::WINSServer wins_server;
806 const auto wins_server_as_json = wins_server.to_json();
809 RC_ASSERT(wins_server.to_string() == from_json.to_string());
810}
811
812RC_GTEST_PROP(WINSServer, EmptyJsonRoundTripThrowsOnValidation, (const std::string &title))
813{
814 const TunBuilderCapture::WINSServer wins_server;
815 RC_ASSERT_THROWS_AS(wins_server.validate(title), openvpn::IP::ip_exception);
816 const auto wins_server_as_json = wins_server.to_json();
819 RC_ASSERT_THROWS_AS(from_json.validate(title), openvpn::IP::ip_exception);
820}
821
822RC_GTEST_PROP(WINSServer, JsonRoundTripHaveSameStringRepresentation, (const std::string &address, const std::string &title))
823{
825 wins_server.address = address;
826 const auto wins_server_as_json = wins_server.to_json();
829 RC_ASSERT(wins_server.to_string() == from_json.to_string());
830}
831
832RC_GTEST_PROP(WINSServer, JsonRoundTripValidatesAddress, (const std::string &title))
833{
835 wins_server.address = *rc::IPv4Address().as("Valid IPv4 address");
836 wins_server.validate(title);
837 const auto wins_server_as_json = wins_server.to_json();
840 from_json.validate(title);
841}
842
843RC_GTEST_PROP(WINSServer, JsonRoundTripThrowsValidatingInvalidIP, (const std::string &title))
844{
846 wins_server.address = *rc::IPv4Address(false).as("Invalid IPv4 address");
847 RC_ASSERT_THROWS_AS(wins_server.validate(title), openvpn::IP::ip_exception);
848 const auto wins_server_as_json = wins_server.to_json();
851 RC_ASSERT_THROWS_AS(from_json.validate(title), openvpn::IP::ip_exception);
852}
853
854RC_GTEST_PROP(WINSServer, FromInvalidJsonThrows, (const std::string &title))
855{
857 const Json::Value invalid_json;
858 RC_ASSERT_THROWS_AS(from_json.from_json(invalid_json, title), json::json_parse);
859}
860
861// ===============================================================================================
862// TunBuilderCapture tests
863// ===============================================================================================
864
865RC_GTEST_PROP(TunBuilderCapture, SetsRemoteAddress, (const std::string &address, const bool ipv6))
866{
871}
872
873RC_GTEST_PROP(TunBuilderCapture, AddsAddress, (const std::string &address, const unsigned char prefix_length, const std::string &gateway, const bool ipv6, const bool net30))
874{
876 RC_ASSERT(tbc->tun_builder_add_address(address, prefix_length, gateway, ipv6, net30));
880 RC_ASSERT(vpn_address->prefix_length == prefix_length);
881 RC_ASSERT(vpn_address->gateway == gateway);
882 RC_ASSERT(vpn_address->net30 == net30);
883}
884
885RC_GTEST_PROP(TunBuilderCapture, SetsRerouteGW, (const bool ipv4, const bool ipv6, const unsigned int flags))
886{
892}
893
894RC_GTEST_PROP(TunBuilderCapture, SetsRouteMetricDefault, (const int metric))
895{
899}
900
901RC_GTEST_PROP(TunBuilderCapture, AddsRoute, (const std::string &address, const unsigned char prefix_length, const bool ipv6))
902{
904 const auto metric = *rc::gen::positive<int>().as("Valid route metric");
906 const auto &added_route = tbc->add_routes.back();
908 RC_ASSERT(added_route.prefix_length == prefix_length);
909 RC_ASSERT(added_route.metric == metric);
910 RC_ASSERT(added_route.ipv6 == ipv6);
911}
912
913RC_GTEST_PROP(TunBuilderCapture, ExcludesRoute, (const std::string &address, const unsigned char prefix_length, const int metric, const bool ipv6))
914{
917 const auto &excluded_route = tbc->exclude_routes.back();
919 RC_ASSERT(excluded_route.prefix_length == prefix_length);
922}
923
924RC_GTEST_PROP(TunBuilderCapture, SetsDNSOptions, (const std::string &address, const unsigned int port, const std::string &search_domain))
925{
926 DnsServer server = {};
927 server.addresses.push_back({address, port});
929 dns_options.servers[0] = std::move(server);
930 dns_options.search_domains = {{search_domain}};
933 RC_ASSERT(tbc->dns_options.search_domains.back().domain == search_domain);
934 RC_ASSERT(tbc->dns_options.servers.at(0).addresses.back().address == address);
935}
936
937RC_GTEST_PROP(TunBuilderCapture, SetsLayer, ())
938{
940 const auto layer = *rc::gen::element(3, 2, 0).as("Layer - 3, 2 or 0");
943}
944
945RC_GTEST_PROP(TunBuilderCapture, SetsMTU, (const int mtu))
946{
949 RC_ASSERT(tbc->mtu == mtu);
950}
951
952RC_GTEST_PROP(TunBuilderCapture, SetsSessionName, (const std::string &session_name))
953{
956 RC_ASSERT(tbc->session_name == session_name);
957}
958
959RC_GTEST_PROP(TunBuilderCapture, AddsProxyBypass, (const std::string &bypass_host))
960{
963 RC_ASSERT(tbc->proxy_bypass.back().bypass_host == bypass_host);
964}
965
966RC_GTEST_PROP(TunBuilderCapture, SetsProxyAutoConfigURL, (const std::string &url))
967{
971}
972
973RC_GTEST_PROP(TunBuilderCapture, SetsProxyHTTP, (const std::string &host, const int port))
974{
979}
980
981RC_GTEST_PROP(TunBuilderCapture, SetsProxyHTTPS, (const std::string &host, const int port))
982{
987}
988
989RC_GTEST_PROP(TunBuilderCapture, AddsWINSServer, (const std::string &address))
990{
993 RC_ASSERT(tbc->wins_servers.back().address == address);
994}
995
996RC_GTEST_PROP(TunBuilderCapture, SetsAllowFamily, (const bool allow))
997{
999 const auto allow_family = *rc::gen::element(AF_INET, AF_INET6).as("Allow family - AF_INET or AF_INET6");
1001 if (allow_family == AF_INET)
1002 {
1003 RC_ASSERT_FALSE(tbc->block_ipv4 == allow);
1004 }
1005 else
1006 {
1007 RC_ASSERT_FALSE(tbc->block_ipv6 == allow);
1008 }
1009}
1010
1011RC_GTEST_PROP(TunBuilderCapture, SetsAllowLocalDNS, (const bool allow))
1012{
1016}
1017
1018RC_GTEST_PROP(TunBuilderCapture, ResetsTunnelAddresses, (const std::string &address, const unsigned char prefix_length, const std::string &gateway, const bool ipv6, const bool net30))
1019{
1021 RC_ASSERT(tbc->tun_builder_add_address(address, prefix_length, gateway, ipv6, net30));
1022 RC_ASSERT(tbc->tun_builder_add_address(address, prefix_length, gateway, !ipv6, net30));
1030}
1031
1032RC_GTEST_PROP(TunBuilderCapture, ResetsDNSOptions, (const std::string &address, const unsigned int port, const std::string &search_domain))
1033{
1034 DnsServer server = {};
1035 server.addresses.push_back({address, port});
1037 dns_options.servers[0] = std::move(server);
1038 dns_options.search_domains = {{search_domain}};
1044}
1045
1046RC_GTEST_PROP(TunBuilderCapture, ReturnsVPNIPv4, (const std::string &address, const unsigned char prefix_length, const std::string &gateway, const bool net30))
1047{
1049 RC_ASSERT(tbc->vpn_ipv4() == nullptr);
1050 RC_ASSERT(tbc->tun_builder_add_address(address, prefix_length, gateway, false, net30));
1053 RC_ASSERT(vpn_address->prefix_length == prefix_length);
1054 RC_ASSERT(vpn_address->gateway == gateway);
1055 RC_ASSERT(vpn_address->net30 == net30);
1056}
1057
1058RC_GTEST_PROP(TunBuilderCapture, ReturnsVPNIPv6, (const std::string &address, const unsigned char prefix_length, const std::string &gateway, const bool net30))
1059{
1061 RC_ASSERT(tbc->vpn_ipv6() == nullptr);
1062 RC_ASSERT(tbc->tun_builder_add_address(address, prefix_length, gateway, true, net30));
1065 RC_ASSERT(vpn_address->prefix_length == prefix_length);
1066 RC_ASSERT(vpn_address->gateway == gateway);
1067 RC_ASSERT(vpn_address->net30 == net30);
1068}
1069
1070RC_GTEST_PROP(TunBuilderCapture, ReturnsVPNIP, (const std::string &address, const unsigned char prefix_length, const std::string &gateway, const bool ipv6, const bool net30))
1071{
1074 RC_ASSERT(tbc->tun_builder_add_address(address, prefix_length, gateway, ipv6, net30));
1075 const auto ip_version = ipv6 ? IP::Addr::V6 : IP::Addr::V4;
1078 RC_ASSERT(vpn_address->prefix_length == prefix_length);
1079 RC_ASSERT(vpn_address->gateway == gateway);
1080 RC_ASSERT(vpn_address->net30 == net30);
1081}
1082
1083RC_GTEST_PROP(TunBuilderCapture, StringRepresentation, (const std::string &address, const unsigned char prefix_length, const std::string &gateway, const bool ipv6, const bool net30))
1084{
1086 std::ostringstream os = {};
1087 os << "Session Name: " << tbc->session_name << '\n';
1088 os << "Layer: " << tbc->layer.str() << '\n';
1089 os << "Remote Address: " << tbc->remote_address.to_string() << '\n';
1090 os << "Tunnel Addresses:\n";
1091 os << "Reroute Gateway: " << tbc->reroute_gw.to_string() << '\n';
1092 os << "Block IPv4: " << (tbc->block_ipv4 ? "yes" : "no") << '\n';
1093 os << "Block IPv6: " << (tbc->block_ipv6 ? "yes" : "no") << '\n';
1094 os << "Block local DNS: " << (tbc->block_outside_dns ? "yes" : "no") << '\n';
1095 os << "Add Routes:\n";
1096 os << "Exclude Routes:\n";
1097 RC_ASSERT(tbc->to_string() == os.str());
1098}
1099
1100struct TunBuilderCaptureModel
1101{
1102 std::string session_name;
1103 int mtu{0};
1106 std::vector<TunBuilderCapture::RouteAddress> tunnel_addresses;
1110 bool block_ipv4{false};
1111 bool block_ipv6{false};
1114 std::vector<TunBuilderCapture::Route> add_routes;
1115 std::vector<TunBuilderCapture::Route> exclude_routes;
1117 std::vector<TunBuilderCapture::ProxyBypass> proxy_bypass;
1121 std::vector<TunBuilderCapture::WINSServer> wins_servers{};
1122 static constexpr auto mtu_ipv4_maximum{65'535};
1123};
1124
1125struct SetRemoteAddress final : rc::state::Command<TunBuilderCaptureModel, TunBuilderCapture>
1126{
1127 std::string address;
1128 bool ipv6{false};
1129
1131 : address{*rc::gen::arbitrary<std::string>()}, ipv6{*rc::gen::arbitrary<bool>()}
1132 {
1133 }
1134
1135 auto apply(TunBuilderCaptureModel &model) const -> void override
1136 {
1137 model.remote_address.address = address;
1138 model.remote_address.ipv6 = ipv6;
1139 }
1140
1141 auto run(const TunBuilderCaptureModel &model, TunBuilderCapture &sut) const -> void override
1142 {
1146 }
1147
1148 auto show(std::ostream &os) const -> void override
1149 {
1150 os << "Set RemoteAddress to " << address << " " << (ipv6 ? "IPv6" : "IPv4");
1151 }
1152};
1153
1154struct AddAddress final : rc::state::Command<TunBuilderCaptureModel, TunBuilderCapture>
1155{
1156 std::string address;
1157 unsigned char prefix_length{0};
1158 int metric{-1};
1159 std::string gateway;
1160 bool ipv6{false};
1161 bool net30{false};
1162
1163 explicit AddAddress()
1164 : address{*rc::gen::arbitrary<std::string>()}, prefix_length{*rc::gen::arbitrary<unsigned char>()}, gateway{*rc::gen::arbitrary<std::string>()}, ipv6{*rc::gen::arbitrary<bool>()}, net30{*rc::gen::arbitrary<bool>()}
1165 {
1166 }
1167
1168 auto apply(TunBuilderCaptureModel &model) const -> void override
1169 {
1171 address.address = this->address;
1172 address.prefix_length = static_cast<unsigned char>(prefix_length);
1173 address.gateway = gateway;
1174 address.ipv6 = ipv6;
1175 address.net30 = net30;
1176 if (ipv6)
1177 {
1178 model.tunnel_address_index_ipv6 = static_cast<int>(model.tunnel_addresses.size());
1179 }
1180 else
1181 {
1182 model.tunnel_address_index_ipv4 = static_cast<int>(model.tunnel_addresses.size());
1183 }
1184 model.tunnel_addresses.push_back(std::move(address));
1185 }
1186
1187 auto run(const TunBuilderCaptureModel &model, TunBuilderCapture &sut) const -> void override
1188 {
1190 RC_ASSERT(sut.tunnel_addresses.size() == model.tunnel_addresses.size() + 1);
1191 if (ipv6)
1192 {
1193 RC_ASSERT(sut.tunnel_address_index_ipv6 == static_cast<int>(model.tunnel_addresses.size()));
1194 const auto *current_address = sut.vpn_ipv6();
1195 RC_ASSERT(current_address->address == address);
1196 RC_ASSERT(current_address->prefix_length == prefix_length);
1197 RC_ASSERT(current_address->gateway == gateway);
1198 RC_ASSERT(current_address->ipv6 == ipv6);
1199 RC_ASSERT(current_address->net30 == net30);
1200 }
1201 else
1202 {
1203 RC_ASSERT(sut.tunnel_address_index_ipv4 == static_cast<int>(model.tunnel_addresses.size()));
1204 const auto *current_address = sut.vpn_ipv4();
1205 RC_ASSERT(current_address->address == address);
1206 RC_ASSERT(current_address->prefix_length == prefix_length);
1207 RC_ASSERT(current_address->gateway == gateway);
1208 RC_ASSERT(current_address->ipv6 == ipv6);
1209 RC_ASSERT(current_address->net30 == net30);
1210 }
1211 const auto *current_address = sut.vpn_ip(ipv6 ? IP::Addr::V6 : IP::Addr::V4);
1212 RC_ASSERT(current_address->address == address);
1213 RC_ASSERT(current_address->prefix_length == prefix_length);
1214 RC_ASSERT(current_address->gateway == gateway);
1215 RC_ASSERT(current_address->ipv6 == ipv6);
1216 RC_ASSERT(current_address->net30 == net30);
1217 }
1218
1219 auto show(std::ostream &os) const -> void override
1220 {
1221 os << "Add address: " << address << " prefix_length: " << prefix_length << " gateway: " << gateway << (ipv6 ? "IPv6" : "IPv4") << " net30: " << net30;
1222 }
1223};
1224
1225struct RerouteGW final : rc::state::Command<TunBuilderCaptureModel, TunBuilderCapture>
1226{
1227 bool ipv4{false};
1228 bool ipv6{false};
1229 unsigned int flags{0};
1230
1231 explicit RerouteGW()
1232 : ipv4{*rc::gen::arbitrary<bool>()}, ipv6{*rc::gen::arbitrary<bool>()}, flags{*rc::gen::arbitrary<unsigned int>()}
1233 {
1234 }
1235
1236 auto apply(TunBuilderCaptureModel &model) const -> void override
1237 {
1238 model.reroute_gw.ipv4 = ipv4;
1239 model.reroute_gw.ipv6 = ipv6;
1240 model.reroute_gw.flags = flags;
1241 }
1242
1243 auto run(const TunBuilderCaptureModel &model, TunBuilderCapture &sut) const -> void override
1244 {
1249 }
1250
1251 auto show(std::ostream &os) const -> void override
1252 {
1253 os << "Set RerouteGW ipv4: " << ipv4 << " ipv6: " << ipv6 << " flags: " << flags;
1254 }
1255};
1256
1257struct SetRouteMetricDefault final : rc::state::Command<TunBuilderCaptureModel, TunBuilderCapture>
1258{
1259 int metric{};
1260
1262 : metric{*rc::gen::arbitrary<int>()}
1263 {
1264 }
1265
1266 auto apply(TunBuilderCaptureModel &model) const -> void override
1267 {
1268 model.route_metric_default = metric;
1269 }
1270
1271 auto run(const TunBuilderCaptureModel &model, TunBuilderCapture &sut) const -> void override
1272 {
1275 }
1276
1277 auto show(std::ostream &os) const -> void override
1278 {
1279 os << "Set route metric default to " << metric;
1280 }
1281};
1282
1283struct AddRoute final : rc::state::Command<TunBuilderCaptureModel, TunBuilderCapture>
1284{
1285 std::string address;
1286 unsigned char prefix_length{0};
1287 int metric{-1};
1288 std::string gateway;
1289 bool ipv6{false};
1290 bool net30{false};
1291
1292 explicit AddRoute()
1293 : address{*rc::gen::arbitrary<std::string>()}, prefix_length{static_cast<unsigned char>(*rc::gen::arbitrary<int>())}, metric{*rc::gen::arbitrary<int>()}, ipv6{*rc::gen::arbitrary<bool>()}
1294 {
1295 }
1296
1297 auto apply(TunBuilderCaptureModel &model) const -> void override
1298 {
1300 route.address = address;
1301 route.prefix_length = static_cast<unsigned char>(prefix_length);
1302 route.metric = (metric < 0 ? model.route_metric_default : metric);
1303 route.ipv6 = ipv6;
1304 model.add_routes.push_back(std::move(route));
1305 }
1306
1307 auto run(const TunBuilderCaptureModel &model, TunBuilderCapture &sut) const -> void override
1308 {
1310 RC_ASSERT(sut.add_routes.size() == model.add_routes.size() + 1);
1311 const auto &added_route = sut.add_routes.back();
1312 RC_ASSERT(added_route.address == address);
1313 RC_ASSERT(added_route.prefix_length == prefix_length);
1314 RC_ASSERT(added_route.metric == (metric < 0 ? model.route_metric_default : metric));
1315 RC_ASSERT(added_route.ipv6 == ipv6);
1316 }
1317
1318 auto show(std::ostream &os) const -> void override
1319 {
1320 os << "Add Route: " << address << " prefix length: " << prefix_length << " metric: " << metric << " ipv6: " << ipv6;
1321 }
1322};
1323
1324struct ExcludeRoute final : rc::state::Command<TunBuilderCaptureModel, TunBuilderCapture>
1325{
1326 std::string address;
1327 unsigned char prefix_length{0};
1328 int metric{-1};
1329 std::string gateway;
1330 bool ipv6{false};
1331 bool net30{false};
1332
1333 explicit ExcludeRoute()
1334 : address{*rc::gen::arbitrary<std::string>()}, prefix_length{static_cast<unsigned char>(*rc::gen::arbitrary<int>())}, metric{*rc::gen::arbitrary<int>()}, ipv6{*rc::gen::arbitrary<bool>()}
1335 {
1336 }
1337
1338 auto apply(TunBuilderCaptureModel &model) const -> void override
1339 {
1341 route.address = address;
1342 route.prefix_length = static_cast<unsigned char>(prefix_length);
1343 route.metric = metric;
1344 route.ipv6 = ipv6;
1345 model.exclude_routes.push_back(std::move(route));
1346 }
1347
1348 auto run(const TunBuilderCaptureModel &model, TunBuilderCapture &sut) const -> void override
1349 {
1351 RC_ASSERT(sut.exclude_routes.size() == model.exclude_routes.size() + 1);
1352 const auto &excluded_route = sut.exclude_routes.back();
1353 RC_ASSERT(excluded_route.address == address);
1354 RC_ASSERT(excluded_route.prefix_length == prefix_length);
1355 RC_ASSERT(excluded_route.metric == metric);
1356 RC_ASSERT(excluded_route.ipv6 == ipv6);
1357 }
1358
1359 auto show(std::ostream &os) const -> void override
1360 {
1361 os << "Add Exclude Route: " << address << " prefix length: " << prefix_length << " metric: " << metric << " ipv6: " << ipv6;
1362 }
1363};
1364
1365struct SetLayer final : rc::state::Command<TunBuilderCaptureModel, TunBuilderCapture>
1366{
1367 int layer{};
1368
1369 explicit SetLayer() : layer{*rc::gen::elementOf<std::vector<int>>({0, 2, 3})}
1370 {
1371 }
1372
1373 auto apply(TunBuilderCaptureModel &model) const -> void override
1374 {
1375 model.layer = Layer::from_value(layer);
1376 }
1377
1378 auto run(const TunBuilderCaptureModel &model, TunBuilderCapture &sut) const -> void override
1379 {
1382 }
1383
1384 auto show(std::ostream &os) const -> void override
1385 {
1386 os << "Set Layer to: " << layer;
1387 }
1388};
1389
1390struct SetMTU final : rc::state::Command<TunBuilderCaptureModel, TunBuilderCapture>
1391{
1392 int mtu{};
1393
1394 explicit SetMTU() : mtu(*rc::gen::arbitrary<int>())
1395 {
1396 }
1397
1398 auto apply(TunBuilderCaptureModel &model) const -> void override
1399 {
1400 model.mtu = mtu;
1401 }
1402
1403 auto run(const TunBuilderCaptureModel &model, TunBuilderCapture &sut) const -> void override
1404 {
1406 RC_ASSERT(sut.mtu == mtu);
1407 }
1408
1409 auto show(std::ostream &os) const -> void override
1410 {
1411 os << "Set mtu to " << mtu;
1412 }
1413};
1414
1415struct SetSessionName final : rc::state::Command<TunBuilderCaptureModel, TunBuilderCapture>
1416{
1417 std::string session_name{};
1418
1419 explicit SetSessionName() : session_name(*rc::gen::arbitrary<std::string>())
1420 {
1421 }
1422
1423 auto apply(TunBuilderCaptureModel &model) const -> void override
1424 {
1425 model.session_name = session_name;
1426 }
1427
1428 auto run(const TunBuilderCaptureModel &model, TunBuilderCapture &sut) const -> void override
1429 {
1432 }
1433
1434 auto show(std::ostream &os) const -> void override
1435 {
1436 os << "Set session name to " << session_name;
1437 }
1438};
1439
1440struct AddProxyBypass final : rc::state::Command<TunBuilderCaptureModel, TunBuilderCapture>
1441{
1442 std::string bypass_host{};
1443
1444 explicit AddProxyBypass() : bypass_host(*rc::gen::arbitrary<std::string>())
1445 {
1446 }
1447
1448 auto apply(TunBuilderCaptureModel &model) const -> void override
1449 {
1452 model.proxy_bypass.push_back(std::move(proxy_bypass));
1453 }
1454
1455 auto run(const TunBuilderCaptureModel &model, TunBuilderCapture &sut) const -> void override
1456 {
1458 RC_ASSERT(sut.proxy_bypass.size() == model.proxy_bypass.size() + 1);
1459 const auto &added_bypass_host = sut.proxy_bypass.back();
1460 RC_ASSERT(added_bypass_host.bypass_host == bypass_host);
1461 }
1462
1463 auto show(std::ostream &os) const -> void override
1464 {
1465 os << "Add ProxyBypass: " << bypass_host;
1466 }
1467};
1468
1469struct SetProxyAutoConfigURL final : rc::state::Command<TunBuilderCaptureModel, TunBuilderCapture>
1470{
1472
1473 explicit SetProxyAutoConfigURL() : proxy_auto_config_url(*rc::gen::arbitrary<std::string>())
1474 {
1475 }
1476
1477 auto apply(TunBuilderCaptureModel &model) const -> void override
1478 {
1479 model.proxy_auto_config_url.url = proxy_auto_config_url;
1480 }
1481
1482 auto run(const TunBuilderCaptureModel &model, TunBuilderCapture &sut) const -> void override
1483 {
1486 }
1487
1488 auto show(std::ostream &os) const -> void override
1489 {
1490 os << "Set ProxyAutoConfigURL to " << proxy_auto_config_url;
1491 }
1492};
1493
1494struct SetProxyHTTP final : rc::state::Command<TunBuilderCaptureModel, TunBuilderCapture>
1495{
1496 std::string host;
1497 int port{0};
1498
1499 explicit SetProxyHTTP()
1500 : host{*rc::gen::arbitrary<std::string>()}, port{*rc::gen::arbitrary<int>()}
1501 {
1502 }
1503
1504 auto apply(TunBuilderCaptureModel &model) const -> void override
1505 {
1506 model.http_proxy.host = host;
1507 model.http_proxy.port = port;
1508 }
1509
1510 auto run(const TunBuilderCaptureModel &model, TunBuilderCapture &sut) const -> void override
1511 {
1515 }
1516
1517 auto show(std::ostream &os) const -> void override
1518 {
1519 os << "Set ProxyHTTP to host: " << host << " port: " << port;
1520 }
1521};
1522
1523struct SetProxyHTTPS final : rc::state::Command<TunBuilderCaptureModel, TunBuilderCapture>
1524{
1525 std::string host;
1526 int port{0};
1527
1528 explicit SetProxyHTTPS()
1529 : host{*rc::gen::arbitrary<std::string>()}, port{*rc::gen::arbitrary<int>()}
1530 {
1531 }
1532
1533 auto apply(TunBuilderCaptureModel &model) const -> void override
1534 {
1535 model.https_proxy.host = host;
1536 model.https_proxy.port = port;
1537 }
1538
1539 auto run(const TunBuilderCaptureModel &model, TunBuilderCapture &sut) const -> void override
1540 {
1544 }
1545
1546 auto show(std::ostream &os) const -> void override
1547 {
1548 os << "Set ProxyHTTPS to host: " << host << " port: " << port;
1549 }
1550};
1551
1552struct AddWINSServer final : rc::state::Command<TunBuilderCaptureModel, TunBuilderCapture>
1553{
1554 std::string address{};
1555
1556 explicit AddWINSServer() : address(*rc::gen::arbitrary<std::string>())
1557 {
1558 }
1559
1560 auto apply(TunBuilderCaptureModel &model) const -> void override
1561 {
1563 wins.address = address;
1564 model.wins_servers.push_back(std::move(wins));
1565 }
1566
1567 auto run(const TunBuilderCaptureModel &model, TunBuilderCapture &sut) const -> void override
1568 {
1570 RC_ASSERT(sut.wins_servers.size() == model.wins_servers.size() + 1);
1571 RC_ASSERT(sut.wins_servers.back().address == address);
1572 }
1573
1574 auto show(std::ostream &os) const -> void override
1575 {
1576 os << "Add WINSServer: " << address;
1577 }
1578};
1579
1580struct SetAllowFamily final : rc::state::Command<TunBuilderCaptureModel, TunBuilderCapture>
1581{
1582 int af{};
1583 bool allow{false};
1584
1586 : af(*rc::gen::elementOf<std::vector<int>>({AF_INET, AF_INET6})),
1587 allow{*rc::gen::arbitrary<bool>()}
1588 {
1589 }
1590
1591 auto apply(TunBuilderCaptureModel &model) const -> void override
1592 {
1593 if (af == AF_INET)
1594 {
1595 model.block_ipv4 = !allow;
1596 }
1597 else if (af == AF_INET6)
1598 {
1599 model.block_ipv6 = !allow;
1600 }
1601 }
1602
1603 auto run(const TunBuilderCaptureModel &model, TunBuilderCapture &sut) const -> void override
1604 {
1606 if (af == AF_INET)
1607 {
1609 }
1610 else if (af == AF_INET6)
1611 {
1613 }
1614 }
1615
1616 auto show(std::ostream &os) const -> void override
1617 {
1618 os << "Set allow local family to " << af << allow;
1619 }
1620};
1621
1622struct SetAllowLocalDNS final : rc::state::Command<TunBuilderCaptureModel, TunBuilderCapture>
1623{
1624 bool allow{false};
1625
1627 : allow{*rc::gen::arbitrary<bool>()}
1628 {
1629 }
1630
1631 auto apply(TunBuilderCaptureModel &model) const -> void override
1632 {
1633 model.block_outside_dns = !allow;
1634 }
1635
1636 auto run(const TunBuilderCaptureModel &model, TunBuilderCapture &sut) const -> void override
1637 {
1640 }
1641
1642 auto show(std::ostream &os) const -> void override
1643 {
1644 os << "Set allow local DNS to " << !allow;
1645 }
1646};
1647
1648struct ResetTunnelAddresses final : rc::state::Command<TunBuilderCaptureModel, TunBuilderCapture>
1649{
1650 auto apply(TunBuilderCaptureModel &model) const -> void override
1651 {
1652 model.tunnel_addresses.clear();
1653 model.tunnel_address_index_ipv4 = -1;
1654 model.tunnel_address_index_ipv6 = -1;
1655 }
1656
1657 auto run(const TunBuilderCaptureModel &model, TunBuilderCapture &sut) const -> void override
1658 {
1663 }
1664
1665 auto show(std::ostream &os) const -> void override
1666 {
1667 os << "Reset Tunnel Addresses";
1668 }
1669};
1670
1671struct ResetDNSOptions final : rc::state::Command<TunBuilderCaptureModel, TunBuilderCapture>
1672{
1673 auto apply(TunBuilderCaptureModel &model) const -> void override
1674 {
1675 model.dns_options = {};
1676 }
1677
1678 auto run(const TunBuilderCaptureModel &model, TunBuilderCapture &sut) const -> void override
1679 {
1681 const DnsOptions dns_options{};
1683 }
1684
1685 auto show(std::ostream &os) const -> void override
1686 {
1687 os << "Reset DNS Options";
1688 }
1689};
1690
1691struct VPN_IPv4 final : rc::state::Command<TunBuilderCaptureModel, TunBuilderCapture>
1692{
1693 auto run(const TunBuilderCaptureModel &model, TunBuilderCapture &sut) const -> void override
1694 {
1695 if (model.tunnel_address_index_ipv4 >= 0)
1696 {
1697 const auto &ipv4_address = sut.vpn_ipv4();
1698 RC_ASSERT(model.tunnel_addresses[model.tunnel_address_index_ipv4].address == ipv4_address->address);
1699 RC_ASSERT(model.tunnel_addresses[model.tunnel_address_index_ipv4].prefix_length == ipv4_address->prefix_length);
1700 RC_ASSERT(model.tunnel_addresses[model.tunnel_address_index_ipv4].metric == ipv4_address->metric);
1701 RC_ASSERT(model.tunnel_addresses[model.tunnel_address_index_ipv4].gateway == ipv4_address->gateway);
1702 RC_ASSERT(model.tunnel_addresses[model.tunnel_address_index_ipv4].ipv6 == ipv4_address->ipv6);
1703 RC_ASSERT(model.tunnel_addresses[model.tunnel_address_index_ipv4].net30 == ipv4_address->net30);
1704 }
1705 else
1706 {
1707 RC_ASSERT(sut.vpn_ipv4() == nullptr);
1708 }
1709 }
1710
1711 auto show(std::ostream &os) const -> void override
1712 {
1713 os << "VPN IPv4";
1714 }
1715};
1716
1717struct VPN_IPv6 final : rc::state::Command<TunBuilderCaptureModel, TunBuilderCapture>
1718{
1719 auto run(const TunBuilderCaptureModel &model, TunBuilderCapture &sut) const -> void override
1720 {
1721 if (model.tunnel_address_index_ipv6 >= 0)
1722 {
1723 const auto &ipv6_address = sut.vpn_ipv6();
1724 RC_ASSERT(model.tunnel_addresses[model.tunnel_address_index_ipv6].address == ipv6_address->address);
1725 RC_ASSERT(model.tunnel_addresses[model.tunnel_address_index_ipv6].prefix_length == ipv6_address->prefix_length);
1726 RC_ASSERT(model.tunnel_addresses[model.tunnel_address_index_ipv6].metric == ipv6_address->metric);
1727 RC_ASSERT(model.tunnel_addresses[model.tunnel_address_index_ipv6].gateway == ipv6_address->gateway);
1728 RC_ASSERT(model.tunnel_addresses[model.tunnel_address_index_ipv6].ipv6 == ipv6_address->ipv6);
1729 RC_ASSERT(model.tunnel_addresses[model.tunnel_address_index_ipv6].net30 == ipv6_address->net30);
1730 }
1731 else
1732 {
1733 RC_ASSERT(sut.vpn_ipv6() == nullptr);
1734 }
1735 }
1736
1737 auto show(std::ostream &os) const -> void override
1738 {
1739 os << "VPN IPv6";
1740 }
1741};
1742
1743struct VPN_IP final : rc::state::Command<TunBuilderCaptureModel, TunBuilderCapture>
1744{
1746
1747 explicit VPN_IP() : version{*rc::gen::elementOf<std::vector<IP::Addr::Version>>({IP::Addr::Version::V4, IP::Addr::Version::V6, IP::Addr::Version::UNSPEC})} {};
1748
1749 auto run(const TunBuilderCaptureModel &model, TunBuilderCapture &sut) const -> void override
1750 {
1751 const auto &ip_address = sut.vpn_ip(version);
1752 if (version == IP::Addr::Version::UNSPEC)
1753 {
1754 RC_ASSERT(ip_address == nullptr);
1755 }
1756 else if (version == IP::Addr::Version::V4 && model.tunnel_address_index_ipv4 >= 0)
1757 {
1758 RC_ASSERT(model.tunnel_addresses[model.tunnel_address_index_ipv4].address == ip_address->address);
1759 RC_ASSERT(model.tunnel_addresses[model.tunnel_address_index_ipv4].prefix_length == ip_address->prefix_length);
1760 RC_ASSERT(model.tunnel_addresses[model.tunnel_address_index_ipv4].metric == ip_address->metric);
1761 RC_ASSERT(model.tunnel_addresses[model.tunnel_address_index_ipv4].gateway == ip_address->gateway);
1762 RC_ASSERT(model.tunnel_addresses[model.tunnel_address_index_ipv4].ipv6 == ip_address->ipv6);
1763 RC_ASSERT(model.tunnel_addresses[model.tunnel_address_index_ipv4].net30 == ip_address->net30);
1764 }
1765 else if (version == IP::Addr::Version::V6 && model.tunnel_address_index_ipv6 >= 0)
1766 {
1767 RC_ASSERT(model.tunnel_addresses[model.tunnel_address_index_ipv6].address == ip_address->address);
1768 RC_ASSERT(model.tunnel_addresses[model.tunnel_address_index_ipv6].prefix_length == ip_address->prefix_length);
1769 RC_ASSERT(model.tunnel_addresses[model.tunnel_address_index_ipv6].metric == ip_address->metric);
1770 RC_ASSERT(model.tunnel_addresses[model.tunnel_address_index_ipv6].gateway == ip_address->gateway);
1771 RC_ASSERT(model.tunnel_addresses[model.tunnel_address_index_ipv6].ipv6 == ip_address->ipv6);
1772 RC_ASSERT(model.tunnel_addresses[model.tunnel_address_index_ipv6].net30 == ip_address->net30);
1773 }
1774 }
1775
1776 auto show(std::ostream &os) const -> void override
1777 {
1778 os << "VPN IP";
1779 }
1780};
1781
1782RC_GTEST_PROP(TunBuilderCapture, Stateful, ())
1783{
1784 const TunBuilderCaptureModel model{};
1786 check(model, sut, rc::state::gen::execOneOfWithArgs<SetRemoteAddress, AddAddress, RerouteGW, SetRouteMetricDefault, AddRoute, ExcludeRoute, SetLayer, SetMTU, SetSessionName, AddProxyBypass, SetProxyAutoConfigURL, SetProxyHTTP, SetProxyHTTPS, AddWINSServer, SetAllowFamily, SetAllowLocalDNS, ResetTunnelAddresses, ResetDNSOptions, VPN_IPv4, VPN_IPv6, VPN_IP>());
1787}
static Layer from_value(const int value)
Definition layer.hpp:103
int value() const
Definition layer.hpp:76
const char * str() const
Definition layer.hpp:61
Class for handling Proxy Auto-Configuration (PAC) URLs.
Definition capture.hpp:403
bool defined() const
Checks if the URL is defined.
Definition capture.hpp:421
std::string to_string() const
Returns the URL as a string.
Definition capture.hpp:411
void validate(const std::string &title) const
Validates the URL format.
Definition capture.hpp:434
Json::Value to_json() const
Converts the URL to a JSON object.
Definition capture.hpp:453
Class for managing proxy bypass host configurations.
Definition capture.hpp:332
void validate(const std::string &title) const
Validates the bypass host value.
Definition capture.hpp:363
std::string to_string() const
Converts the bypass host to a string representation.
Definition capture.hpp:340
bool defined() const
Checks if a bypass host is defined.
Definition capture.hpp:351
Json::Value to_json() const
Serializes the object to JSON.
Definition capture.hpp:375
Host and port configuration for proxy connections.
Definition capture.hpp:484
std::string to_string() const
Converts the host and port to a string representation.
Definition capture.hpp:494
void validate(const std::string &title) const
Validates the host and port.
Definition capture.hpp:518
bool defined() const
Checks if the proxy configuration is defined.
Definition capture.hpp:506
Json::Value to_json() const
Converts the object to a JSON representation.
Definition capture.hpp:533
Represents a remote IP address with IPv4/IPv6 designation.
Definition capture.hpp:55
void validate(const std::string &title) const
Validates the IP address format.
Definition capture.hpp:90
void from_json(const Json::Value &root, const std::string &title)
Deserializes the object from a JSON value.
Definition capture.hpp:116
Json::Value to_json() const
Serializes the object to a JSON value.
Definition capture.hpp:101
bool defined() const
Checks if the address is defined.
Definition capture.hpp:79
std::string to_string() const
Returns a string representation of the remote address.
Definition capture.hpp:66
Class for handling gateway rerouting configuration.
Definition capture.hpp:133
std::string to_string() const
Converts the object to a human-readable string representation.
Definition capture.hpp:145
Json::Value to_json() const
Serializes the object to a JSON value.
Definition capture.hpp:161
Route address class that may use non-canonical form.
Definition capture.hpp:295
Route class that must use canonical form.
Definition capture.hpp:313
Windows Internet Name Service (WINS) server configuration.
Definition capture.hpp:565
void validate(const std::string &title) const
Validates the WINS server address.
Definition capture.hpp:585
std::string to_string() const
Converts the WINS server to a string representation.
Definition capture.hpp:573
Json::Value to_json() const
Serializes the WINS server to a JSON object.
Definition capture.hpp:597
bool tun_builder_exclude_route(const std::string &address, int prefix_length, int metric, bool ipv6) override
Excludes a route from the tunnel.
Definition capture.hpp:720
RemoteAddress remote_address
Definition capture.hpp:1082
bool tun_builder_set_allow_family(int af, bool allow) override
Sets whether to allow a specific address family in the tunnel.
Definition capture.hpp:856
std::vector< RouteAddress > tunnel_addresses
Definition capture.hpp:1083
void validate() const
Validates the configuration of the tunnel.
Definition capture.hpp:946
bool tun_builder_add_proxy_bypass(const std::string &bypass_host) override
Adds a host to bypass proxy settings.
Definition capture.hpp:786
bool tun_builder_set_proxy_https(const std::string &host, int port) override
Sets the HTTPS proxy for the tunnel.
Definition capture.hpp:828
bool tun_builder_set_dns_options(const DnsOptions &dns) override
Set DNS options for use with tun builder.
Definition capture.hpp:737
bool tun_builder_add_route(const std::string &address, int prefix_length, int metric, bool ipv6) override
Adds a route to the tunnel.
Definition capture.hpp:699
bool tun_builder_set_allow_local_dns(bool allow) override
Sets whether to allow local DNS resolution.
Definition capture.hpp:871
bool tun_builder_set_route_metric_default(int metric) override
Sets the default route metric for VPN routes.
Definition capture.hpp:684
std::vector< Route > add_routes
Definition capture.hpp:1091
const RouteAddress * vpn_ip(const IP::Addr::Version v) const
Gets the tunnel address for the specified IP version.
Definition capture.hpp:927
ProxyAutoConfigURL proxy_auto_config_url
Definition capture.hpp:1096
bool tun_builder_set_session_name(const std::string &name) override
Sets a descriptive name for the VPN session.
Definition capture.hpp:773
void reset_dns_options()
Resets DNS options to default values.
Definition capture.hpp:892
bool tun_builder_set_remote_address(const std::string &address, bool ipv6) override
Sets the remote address for the TUN interface.
Definition capture.hpp:626
bool tun_builder_set_mtu(int mtu) override
Sets the Maximum Transmission Unit (MTU) for the tunnel.
Definition capture.hpp:761
static TunBuilderCapture::Ptr from_json(const Json::Value &root)
Creates a TunBuilderCapture instance from a JSON representation.
Definition capture.hpp:1049
Json::Value to_json() const
Serializes the tunnel configuration to a JSON object.
Definition capture.hpp:1011
bool tun_builder_add_address(const std::string &address, int prefix_length, const std::string &gateway, bool ipv6, bool net30) override
Adds a local address to the TUN interface.
Definition capture.hpp:644
const RouteAddress * vpn_ipv6() const
Gets the IPv6 tunnel address.
Definition capture.hpp:914
bool tun_builder_set_layer(int layer) override
Sets the tunnel's network layer.
Definition capture.hpp:749
const RouteAddress * vpn_ipv4() const
Gets the IPv4 tunnel address.
Definition capture.hpp:902
bool tun_builder_set_proxy_http(const std::string &host, int port) override
Sets the HTTP proxy for the tunnel.
Definition capture.hpp:814
std::string to_string() const
Converts the tunnel configuration to a human-readable string representation.
Definition capture.hpp:968
bool tun_builder_set_proxy_auto_config_url(const std::string &url) override
Sets the URL for a proxy auto-configuration (PAC) file.
Definition capture.hpp:801
bool tun_builder_add_wins_server(const std::string &address) override
Adds a WINS server to the tunnel configuration.
Definition capture.hpp:841
std::vector< Route > exclude_routes
Definition capture.hpp:1092
bool tun_builder_reroute_gw(bool ipv4, bool ipv6, unsigned int flags) override
Configures global gateway rerouting through the VPN tunnel.
Definition capture.hpp:669
std::vector< ProxyBypass > proxy_bypass
Definition capture.hpp:1095
std::vector< WINSServer > wins_servers
Definition capture.hpp:1100
void reset_tunnel_addresses()
Resets all tunnel addresses.
Definition capture.hpp:881
Route route_from_string(const std::string &rtstr, const TITLE &title, const IP::Addr::Version required_version=IP::Addr::UNSPEC)
Definition route.hpp:390
auto calculateIPPrefixRange(const std::string &ipAddress) -> std::tuple< int, int >
Calculates the valid IP prefix range for a given IP address.
std::variant< openvpn::TunBuilderCapture::Route, openvpn::TunBuilderCapture::RouteAddress, openvpn::TunBuilderCapture::RouteBase > RouteBased
Alias representing a route-based variant type.
auto IPv4Address(const bool valid=true) -> Gen< std::string >
Generates a random IPv4 address.
auto IPv6Address(const bool valid=true) -> Gen< std::string >
Generates a random IPv6 address.
auto show(std::ostream &os) const -> void override
std::string address
auto run(const TunBuilderCaptureModel &model, TunBuilderCapture &sut) const -> void override
auto apply(TunBuilderCaptureModel &model) const -> void override
std::string gateway
unsigned char prefix_length
std::string bypass_host
auto apply(TunBuilderCaptureModel &model) const -> void override
auto run(const TunBuilderCaptureModel &model, TunBuilderCapture &sut) const -> void override
auto show(std::ostream &os) const -> void override
auto show(std::ostream &os) const -> void override
auto run(const TunBuilderCaptureModel &model, TunBuilderCapture &sut) const -> void override
std::string gateway
auto apply(TunBuilderCaptureModel &model) const -> void override
std::string address
unsigned char prefix_length
std::string address
auto run(const TunBuilderCaptureModel &model, TunBuilderCapture &sut) const -> void override
auto apply(TunBuilderCaptureModel &model) const -> void override
auto show(std::ostream &os) const -> void override
auto show(std::ostream &os) const -> void override
auto apply(TunBuilderCaptureModel &model) const -> void override
auto run(const TunBuilderCaptureModel &model, TunBuilderCapture &sut) const -> void override
std::string gateway
std::string address
unsigned char prefix_length
auto show(std::ostream &os) const -> void override
auto apply(TunBuilderCaptureModel &model) const -> void override
unsigned int flags
auto run(const TunBuilderCaptureModel &model, TunBuilderCapture &sut) const -> void override
auto show(std::ostream &os) const -> void override
auto run(const TunBuilderCaptureModel &model, TunBuilderCapture &sut) const -> void override
auto apply(TunBuilderCaptureModel &model) const -> void override
auto show(std::ostream &os) const -> void override
auto apply(TunBuilderCaptureModel &model) const -> void override
auto run(const TunBuilderCaptureModel &model, TunBuilderCapture &sut) const -> void override
auto run(const TunBuilderCaptureModel &model, TunBuilderCapture &sut) const -> void override
auto apply(TunBuilderCaptureModel &model) const -> void override
auto show(std::ostream &os) const -> void override
auto show(std::ostream &os) const -> void override
auto run(const TunBuilderCaptureModel &model, TunBuilderCapture &sut) const -> void override
auto apply(TunBuilderCaptureModel &model) const -> void override
auto apply(TunBuilderCaptureModel &model) const -> void override
auto show(std::ostream &os) const -> void override
auto run(const TunBuilderCaptureModel &model, TunBuilderCapture &sut) const -> void override
auto run(const TunBuilderCaptureModel &model, TunBuilderCapture &sut) const -> void override
auto apply(TunBuilderCaptureModel &model) const -> void override
auto show(std::ostream &os) const -> void override
auto run(const TunBuilderCaptureModel &model, TunBuilderCapture &sut) const -> void override
auto show(std::ostream &os) const -> void override
std::string proxy_auto_config_url
auto apply(TunBuilderCaptureModel &model) const -> void override
auto apply(TunBuilderCaptureModel &model) const -> void override
auto run(const TunBuilderCaptureModel &model, TunBuilderCapture &sut) const -> void override
std::string host
auto show(std::ostream &os) const -> void override
auto apply(TunBuilderCaptureModel &model) const -> void override
auto show(std::ostream &os) const -> void override
auto run(const TunBuilderCaptureModel &model, TunBuilderCapture &sut) const -> void override
std::string host
auto run(const TunBuilderCaptureModel &model, TunBuilderCapture &sut) const -> void override
auto apply(TunBuilderCaptureModel &model) const -> void override
auto show(std::ostream &os) const -> void override
auto apply(TunBuilderCaptureModel &model) const -> void override
auto show(std::ostream &os) const -> void override
auto run(const TunBuilderCaptureModel &model, TunBuilderCapture &sut) const -> void override
auto apply(TunBuilderCaptureModel &model) const -> void override
std::string session_name
auto run(const TunBuilderCaptureModel &model, TunBuilderCapture &sut) const -> void override
auto show(std::ostream &os) const -> void override
IP::Addr::Version version
auto run(const TunBuilderCaptureModel &model, TunBuilderCapture &sut) const -> void override
auto show(std::ostream &os) const -> void override
auto run(const TunBuilderCaptureModel &model, TunBuilderCapture &sut) const -> void override
auto show(std::ostream &os) const -> void override
auto run(const TunBuilderCaptureModel &model, TunBuilderCapture &sut) const -> void override
auto show(std::ostream &os) const -> void override
All DNS options set with the –dns or –dhcp-option directive.
std::map< int, DnsServer > servers
std::vector< DnsDomain > search_domains
std::string to_string() const
DNS settings for a name server.
std::vector< DnsAddress > addresses
int tunnel_address_index_ipv4
RC_ASSERT_THROWS_AS(remote_address.validate(title), openvpn::IP::ip_exception)
const auto & excluded_route
const auto metric
TunBuilderCapture::RerouteGW reroute_gw
const auto allow_family
reroute_gw flags
proxy_host_port port
const TunBuilderCapture::Ptr tbc(new TunBuilderCapture)
proxy_autoconfig_url url
TunBuilderCapture::RemoteAddress remote_address
TunBuilderCapture::ProxyHostPort http_proxy
check(model, sut, rc::state::gen::execOneOfWithArgs< SetRemoteAddress, AddAddress, RerouteGW, SetRouteMetricDefault, AddRoute, ExcludeRoute, SetLayer, SetMTU, SetSessionName, AddProxyBypass, SetProxyAutoConfigURL, SetProxyHTTP, SetProxyHTTPS, AddWINSServer, SetAllowFamily, SetAllowLocalDNS, ResetTunnelAddresses, ResetDNSOptions, VPN_IPv4, VPN_IPv6, VPN_IP >())
const Json::Value invalid_json
std::vector< TunBuilderCapture::WINSServer > wins_servers
TunBuilderCapture::ProxyBypass proxy_bypass
TunBuilderCapture::ProxyAutoConfigURL proxy_auto_config_url
TEST(misc, capture)
const auto wins_server_as_json
const std::string ipv4_and_ipv6_return_string
const TunBuilderCapture::RouteAddress * vpn_address
remote_address ipv6
proxy_bypass bypass_host
TunBuilderCapture sut
TunBuilderCapture::ProxyHostPort https_proxy
const auto reroute_gw_as_json
TunBuilderCapture::ProxyHostPort proxy_host_port
bool block_outside_dns
TunBuilderCapture::RemoteAddress from_json
static constexpr auto mtu_ipv4_maximum
proxy_host_port host
const auto address_as_json
remote_address address
int route_metric_default
RC_ASSERT_FALSE(tbc->block_outside_dns==allow)
RC_ASSERT(remote_address.defined())
std::vector< TunBuilderCapture::Route > add_routes
os<< "Block IPv4: "<<(tbc->block_ipv4 ? "yes" :"no")<< '\n';os<< "Block IPv6: "<<(tbc->block_ipv6 ? "yes" :"no")<< '\n';os<< "Block local DNS: "<<(tbc->block_outside_dns ? "yes" :"no")<< '\n';os<< "Add Routes:\n";os<< "Exclude Routes:\n";RC_ASSERT(tbc->to_string()==os.str());}struct TunBuilderCaptureModel{ std::string session_name;int mtu{0};Layer layer{Layer::OSI_LAYER_3};TunBuilderCapture::RemoteAddress remote_address{};std::vector< TunBuilderCapture::RouteAddress > tunnel_addresses
bool block_ipv4
reroute_gw ipv4
const auto & added_route
bool block_ipv6
const auto ip_version
const auto proxy_autoconfig_url_as_json
TunBuilderCapture::ProxyAutoConfigURL proxy_autoconfig_url
const auto proxy_bypass_as_json
std::vector< TunBuilderCapture::Route > exclude_routes
DnsOptions dns_options
const auto proxy_host_port_as_json
std::string ret
int tunnel_address_index_ipv6
std::ostringstream os
const auto layer