]> git.proxmox.com Git - ceph.git/blob - ceph/src/seastar/tests/unit/dns_test.cc
update ceph source to reef 18.1.2
[ceph.git] / ceph / src / seastar / tests / unit / dns_test.cc
1 /*
2 * This file is open source software, licensed to you under the terms
3 * of the Apache License, Version 2.0 (the "License"). See the NOTICE file
4 * distributed with this work for additional information regarding copyright
5 * ownership. You may not use this file except in compliance with the License.
6 *
7 * You may obtain a copy of the License at
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing,
12 * software distributed under the License is distributed on an
13 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14 * KIND, either express or implied. See the License for the
15 * specific language governing permissions and limitations
16 * under the License.
17 */
18
19 /*
20 * Copyright (C) 2016 ScyllaDB.
21 */
22 #include <vector>
23 #include <algorithm>
24
25 #include <seastar/core/do_with.hh>
26 #include <seastar/testing/test_case.hh>
27 #include <seastar/core/sstring.hh>
28 #include <seastar/core/reactor.hh>
29 #include <seastar/core/do_with.hh>
30 #include <seastar/core/when_all.hh>
31 #include <seastar/net/dns.hh>
32 #include <seastar/net/inet_address.hh>
33
34 using namespace seastar;
35 using namespace seastar::net;
36
37 static const sstring seastar_name = "seastar.io";
38
39 static future<> test_resolve(dns_resolver::options opts) {
40 auto d = ::make_lw_shared<dns_resolver>(std::move(opts));
41 return d->get_host_by_name(seastar_name, inet_address::family::INET).then([d](hostent e) {
42 return d->get_host_by_addr(e.addr_list.front()).then([d, a = e.addr_list.front()](hostent e) {
43 return d->get_host_by_name(e.names.front(), inet_address::family::INET).then([a](hostent e) {
44 BOOST_REQUIRE(std::count(e.addr_list.begin(), e.addr_list.end(), a));
45 });
46 });
47 }).finally([d]{
48 return d->close();
49 });
50 }
51
52 static future<> test_bad_name(dns_resolver::options opts) {
53 auto d = ::make_lw_shared<dns_resolver>(std::move(opts));
54 return d->get_host_by_name("apa.ninja.gnu", inet_address::family::INET).then_wrapped([d](future<hostent> f) {
55 try {
56 f.get();
57 BOOST_FAIL("should not succeed");
58 } catch (...) {
59 // ok.
60 }
61 }).finally([d]{
62 return d->close();
63 });
64 }
65
66 SEASTAR_TEST_CASE(test_resolve_udp) {
67 return test_resolve(dns_resolver::options());
68 }
69
70 SEASTAR_TEST_CASE(test_bad_name_udp) {
71 return test_bad_name(dns_resolver::options());
72 }
73
74 SEASTAR_TEST_CASE(test_timeout_udp) {
75 dns_resolver::options opts;
76 opts.servers = std::vector<inet_address>({ inet_address("1.2.3.4") }); // not a server
77 opts.udp_port = 29953; // not a dns port
78 opts.timeout = std::chrono::milliseconds(500);
79
80 auto d = ::make_lw_shared<dns_resolver>(engine().net(), opts);
81 return d->get_host_by_name(seastar_name, inet_address::family::INET).then_wrapped([d](future<hostent> f) {
82 try {
83 f.get();
84 BOOST_FAIL("should not succeed");
85 } catch (...) {
86 // ok.
87 }
88 }).finally([d]{
89 return d->close();
90 });
91 }
92
93 // NOTE: cannot really test timeout in TCP mode, because seastar sockets do not support
94 // connect with timeout -> cannot complete connect future in dns::do_connect in reasonable
95 // time.
96
97 // But we can test for connection refused working as expected.
98 SEASTAR_TEST_CASE(test_connection_refused_tcp) {
99 dns_resolver::options opts;
100 opts.servers = std::vector<inet_address>({ inet_address("127.0.0.1") });
101 opts.use_tcp_query = true;
102 opts.tcp_port = 29953; // not a dns port
103
104 auto d = ::make_lw_shared<dns_resolver>(engine().net(), opts);
105 return d->get_host_by_name(seastar_name, inet_address::family::INET).then_wrapped([d](future<hostent> f) {
106 try {
107 f.get();
108 BOOST_FAIL("should not succeed");
109 } catch (...) {
110 // ok.
111 }
112 }).finally([d]{
113 return d->close();
114 });
115 }
116
117 SEASTAR_TEST_CASE(test_resolve_tcp) {
118 dns_resolver::options opts;
119 opts.use_tcp_query = true;
120 return test_resolve(opts);
121 }
122
123 SEASTAR_TEST_CASE(test_bad_name_tcp) {
124 dns_resolver::options opts;
125 opts.use_tcp_query = true;
126 return test_bad_name(opts);
127 }
128
129 static const sstring imaps_service = "imaps";
130 static const sstring gmail_domain = "gmail.com";
131
132 static future<> test_srv() {
133 auto d = ::make_lw_shared<dns_resolver>();
134 return d->get_srv_records(dns_resolver::srv_proto::tcp,
135 imaps_service,
136 gmail_domain).then([d](dns_resolver::srv_records records) {
137 BOOST_REQUIRE(!records.empty());
138 for (auto& record : records) {
139 // record.target should end with "gmail.com"
140 BOOST_REQUIRE_GT(record.target.size(), gmail_domain.size());
141 BOOST_REQUIRE_EQUAL(record.target.compare(record.target.size() - gmail_domain.size(),
142 gmail_domain.size(),
143 gmail_domain),
144 0);
145 }
146 }).finally([d]{
147 return d->close();
148 });
149 }
150
151 SEASTAR_TEST_CASE(test_srv_tcp) {
152 return test_srv();
153 }
154
155
156 SEASTAR_TEST_CASE(test_parallel_resolve_name) {
157 dns_resolver::options opts;
158 opts.use_tcp_query = true;
159
160 auto d = ::make_lw_shared<dns_resolver>(std::move(opts));
161 return when_all(
162 d->resolve_name("www.google.com"),
163 d->resolve_name("www.google.com"),
164 d->resolve_name("www.google.com"),
165 d->resolve_name("www.google.com"),
166 d->resolve_name("www.google.com"),
167 d->resolve_name("www.google.com")
168 ).finally([d](auto&&...) {}).discard_result();
169 }
170
171 SEASTAR_TEST_CASE(test_parallel_resolve_name_udp) {
172 dns_resolver::options opts;
173
174 auto d = ::make_lw_shared<dns_resolver>(std::move(opts));
175 return when_all(
176 d->resolve_name("www.google.com"),
177 d->resolve_name("www.google.com"),
178 d->resolve_name("www.google.com"),
179 d->resolve_name("www.google.com"),
180 d->resolve_name("www.google.com"),
181 d->resolve_name("www.google.com")
182 ).finally([d](auto&...) {}).discard_result();
183 }