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.
7 * You may obtain a copy of the License at
9 * http://www.apache.org/licenses/LICENSE-2.0
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
20 * Copyright (C) 2016 ScyllaDB.
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>
34 using namespace seastar
;
35 using namespace seastar::net
;
37 static const sstring seastar_name
= "seastar.io";
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
));
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
) {
57 BOOST_FAIL("should not succeed");
66 SEASTAR_TEST_CASE(test_resolve_udp
) {
67 return test_resolve(dns_resolver::options());
70 SEASTAR_TEST_CASE(test_bad_name_udp
) {
71 return test_bad_name(dns_resolver::options());
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);
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
) {
84 BOOST_FAIL("should not succeed");
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
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
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
) {
108 BOOST_FAIL("should not succeed");
117 SEASTAR_TEST_CASE(test_resolve_tcp
) {
118 dns_resolver::options opts
;
119 opts
.use_tcp_query
= true;
120 return test_resolve(opts
);
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
);
129 static const sstring imaps_service
= "imaps";
130 static const sstring gmail_domain
= "gmail.com";
132 static future
<> test_srv() {
133 auto d
= ::make_lw_shared
<dns_resolver
>();
134 return d
->get_srv_records(dns_resolver::srv_proto::tcp
,
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(),
151 SEASTAR_TEST_CASE(test_srv_tcp
) {
156 SEASTAR_TEST_CASE(test_parallel_resolve_name
) {
157 dns_resolver::options opts
;
158 opts
.use_tcp_query
= true;
160 auto d
= ::make_lw_shared
<dns_resolver
>(std::move(opts
));
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();
171 SEASTAR_TEST_CASE(test_parallel_resolve_name_udp
) {
172 dns_resolver::options opts
;
174 auto d
= ::make_lw_shared
<dns_resolver
>(std::move(opts
));
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();