1 //
2 // v6_only.cpp
3 // ~~~~~~~~~~~
4 //
5 // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com)
6 //
7 // Distributed under the Boost Software License, Version 1.0. (See accompanying
8 // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
9 //
10 
11 // Disable autolinking for unit tests.
12 #if !defined(BOOST_ALL_NO_LIB)
13 #define BOOST_ALL_NO_LIB 1
14 #endif // !defined(BOOST_ALL_NO_LIB)
15 
16 // Test that header file is self-contained.
17 #include <boost/asio/ip/v6_only.hpp>
18 
19 #include <boost/asio/io_context.hpp>
20 #include <boost/asio/ip/tcp.hpp>
21 #include <boost/asio/ip/udp.hpp>
22 #include "../unit_test.hpp"
23 
24 //------------------------------------------------------------------------------
25 
26 // ip_v6_only_compile test
27 // ~~~~~~~~~~~~~~~~~~~~~~~
28 // The following test checks that the ip::v6_only socket option compiles and
29 // link correctly. Runtime failures are ignored.
30 
31 namespace ip_v6_only_compile {
32 
test()33 void test()
34 {
35   using namespace boost::asio;
36   namespace ip = boost::asio::ip;
37 
38   try
39   {
40     io_context ioc;
41     ip::udp::socket sock(ioc);
42 
43     // v6_only class.
44 
45     ip::v6_only v6_only1(true);
46     sock.set_option(v6_only1);
47     ip::v6_only v6_only2;
48     sock.get_option(v6_only2);
49     v6_only1 = true;
50     (void)static_cast<bool>(v6_only1);
51     (void)static_cast<bool>(!v6_only1);
52     (void)static_cast<bool>(v6_only1.value());
53   }
54   catch (std::exception&)
55   {
56   }
57 }
58 
59 } // namespace ip_v6_only_compile
60 
61 //------------------------------------------------------------------------------
62 
63 // ip_v6_only_runtime test
64 // ~~~~~~~~~~~~~~~~~~~~~~~
65 // The following test checks the runtime operation of the ip::v6_only socket
66 // option.
67 
68 namespace ip_v6_only_runtime {
69 
test()70 void test()
71 {
72   using namespace boost::asio;
73   namespace ip = boost::asio::ip;
74 
75   io_context ioc;
76   boost::system::error_code ec;
77 
78   ip::tcp::endpoint ep_v6(ip::address_v6::loopback(), 0);
79   ip::tcp::acceptor acceptor_v6(ioc);
80   acceptor_v6.open(ep_v6.protocol(), ec);
81   acceptor_v6.bind(ep_v6, ec);
82   bool have_v6 = !ec;
83   acceptor_v6.close(ec);
84   acceptor_v6.open(ep_v6.protocol(), ec);
85 
86   if (have_v6)
87   {
88     ip::v6_only v6_only1;
89     acceptor_v6.get_option(v6_only1, ec);
90     BOOST_ASIO_CHECK(!ec);
91     bool have_dual_stack = !v6_only1.value();
92 
93     if (have_dual_stack)
94     {
95       ip::v6_only v6_only2(false);
96       BOOST_ASIO_CHECK(!v6_only2.value());
97       BOOST_ASIO_CHECK(!static_cast<bool>(v6_only2));
98       BOOST_ASIO_CHECK(!v6_only2);
99       acceptor_v6.set_option(v6_only2, ec);
100       BOOST_ASIO_CHECK(!ec);
101 
102       ip::v6_only v6_only3;
103       acceptor_v6.get_option(v6_only3, ec);
104       BOOST_ASIO_CHECK(!ec);
105       BOOST_ASIO_CHECK(!v6_only3.value());
106       BOOST_ASIO_CHECK(!static_cast<bool>(v6_only3));
107       BOOST_ASIO_CHECK(!v6_only3);
108 
109       ip::v6_only v6_only4(true);
110       BOOST_ASIO_CHECK(v6_only4.value());
111       BOOST_ASIO_CHECK(static_cast<bool>(v6_only4));
112       BOOST_ASIO_CHECK(!!v6_only4);
113       acceptor_v6.set_option(v6_only4, ec);
114       BOOST_ASIO_CHECK(!ec);
115 
116       ip::v6_only v6_only5;
117       acceptor_v6.get_option(v6_only5, ec);
118       BOOST_ASIO_CHECK(!ec);
119       BOOST_ASIO_CHECK(v6_only5.value());
120       BOOST_ASIO_CHECK(static_cast<bool>(v6_only5));
121       BOOST_ASIO_CHECK(!!v6_only5);
122     }
123   }
124 }
125 
126 } // namespace ip_v6_only_runtime
127 
128 //------------------------------------------------------------------------------
129 
130 BOOST_ASIO_TEST_SUITE
131 (
132   "ip/v6_only",
133   BOOST_ASIO_TEST_CASE(ip_v6_only_compile::test)
134   BOOST_ASIO_TEST_CASE(ip_v6_only_runtime::test)
135 )
136