Electroneum
dns_resolver.cpp
Go to the documentation of this file.
1 // Copyright (c) 2014-2019, The Monero Project
2 //
3 // All rights reserved.
4 //
5 // Redistribution and use in source and binary forms, with or without modification, are
6 // permitted provided that the following conditions are met:
7 //
8 // 1. Redistributions of source code must retain the above copyright notice, this list of
9 // conditions and the following disclaimer.
10 //
11 // 2. Redistributions in binary form must reproduce the above copyright notice, this list
12 // of conditions and the following disclaimer in the documentation and/or other
13 // materials provided with the distribution.
14 //
15 // 3. Neither the name of the copyright holder nor the names of its contributors may be
16 // used to endorse or promote products derived from this software without specific
17 // prior written permission.
18 //
19 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
20 // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
21 // MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
22 // THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
23 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
24 // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
25 // INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
26 // STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
27 // THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 
29 #include <iostream>
30 #include <vector>
31 
32 #include "gtest/gtest.h"
33 
34 #include "common/dns_utils.h"
35 
36 TEST(DNSResolver, IPv4Success)
37 {
39 
40  bool avail, valid;
41 
42  auto ips = resolver.get_ipv4("example.com", avail, valid);
43 
44  ASSERT_EQ(1, ips.size());
45 
46  //ASSERT_STREQ("93.184.216.119", ips[0].c_str());
47 
48  ips = tools::DNSResolver::instance().get_ipv4("example.com", avail, valid);
49 
50  ASSERT_EQ(1, ips.size());
51 
52  //ASSERT_STREQ("93.184.216.119", ips[0].c_str());
53 }
54 
55 TEST(DNSResolver, IPv4Failure)
56 {
57  // guaranteed by IANA/ICANN/RFC to be invalid
59 
60  bool avail, valid;
61 
62  auto ips = resolver.get_ipv4("example.invalid", avail, valid);
63 
64  ASSERT_EQ(0, ips.size());
65 
66  ips = tools::DNSResolver::instance().get_ipv4("example.invalid", avail, valid);
67 
68  ASSERT_EQ(0, ips.size());
69 }
70 
71 TEST(DNSResolver, DNSSECSuccess)
72 {
74 
75  bool avail, valid;
76 
77  auto ips = resolver.get_ipv4("example.com", avail, valid);
78 
79  ASSERT_EQ(1, ips.size());
80 
81  //ASSERT_STREQ("93.184.216.119", ips[0].c_str());
82 
83  ASSERT_TRUE(avail);
84  ASSERT_TRUE(valid);
85 }
86 
87 TEST(DNSResolver, DNSSECFailure)
88 {
90 
91  bool avail, valid;
92 
93  auto ips = resolver.get_ipv4("dnssec-failed.org", avail, valid);
94 
95  ASSERT_EQ(1, ips.size());
96 
97  //ASSERT_STREQ("93.184.216.119", ips[0].c_str());
98 
99  ASSERT_TRUE(avail);
100  ASSERT_FALSE(valid);
101 }
102 
103 // It would be great to include an IPv6 test and assume it'll pass, but not every ISP / resolver plays nicely with IPv6;)
104 /*TEST(DNSResolver, IPv6Success)
105 {
106  tools::DNSResolver resolver = tools::DNSResolver::create();
107 
108  bool avail, valid;
109 
110  auto ips = resolver.get_ipv6("example.com", avail, valid);
111 
112  ASSERT_EQ(1, ips.size());
113 
114  ASSERT_STREQ("2606:2800:220:6d:26bf:1447:1097:aa7", ips[0].c_str());
115 
116  ips = tools::DNSResolver::instance().get_ipv6("example.com", avail, valid);
117 
118  ASSERT_EQ(1, ips.size());
119 
120  ASSERT_STREQ("2606:2800:220:6d:26bf:1447:1097:aa7", ips[0].c_str());
121 }*/
122 
123 TEST(DNSResolver, IPv6Failure)
124 {
125  // guaranteed by IANA/ICANN/RFC to be invalid
127 
128  bool avail, valid;
129 
130  auto ips = resolver.get_ipv6("example.invalid", avail, valid);
131 
132  ASSERT_EQ(0, ips.size());
133 
134  ips = tools::DNSResolver::instance().get_ipv6("example.invalid", avail, valid);
135 
136  ASSERT_EQ(0, ips.size());
137 }
138 
139 TEST(DNSResolver, GetTXTRecord)
140 {
141  bool avail, valid;
142 
143  std::vector<std::string> records = tools::DNSResolver::instance().get_txt_record("donate.electroneumpulse.com", avail, valid);
144 
145  EXPECT_NE(0, records.size());
146 
147  for (auto& rec : records)
148  {
149  std::cout << "TXT record for donate.electroneumpulse.com: " << rec << std::endl;
150  }
151 
152  // replace first @ with .
153  std::string addr = tools::DNSResolver::instance().get_dns_format_from_oa_address("donate@electroneumpulse.com");
154  EXPECT_STREQ("donate.electroneumpulse.com", addr.c_str());
155 
156  // no change
157  addr = tools::DNSResolver::instance().get_dns_format_from_oa_address("donate.electroneumpulse.com");
158  EXPECT_STREQ("donate.electroneumpulse.com", addr.c_str());
159 }
160 
161 bool is_equal(const char *s, const std::vector<std::string> &v) { return v.size() == 1 && v[0] == s; }
162 
164 TEST(DNS_PUBLIC, default) { EXPECT_TRUE(tools::dns_utils::parse_dns_public("tcp").size() > 0); }
165 TEST(DNS_PUBLIC, invalid_scheme) { EXPECT_TRUE(tools::dns_utils::parse_dns_public("invalid").empty()); }
166 TEST(DNS_PUBLIC, invalid_ip_alpha) { EXPECT_TRUE(tools::dns_utils::parse_dns_public("tcp://invalid").empty()); }
167 TEST(DNS_PUBLIC, invalid_ip_num1) { EXPECT_TRUE(tools::dns_utils::parse_dns_public("tcp://3").empty()); }
168 TEST(DNS_PUBLIC, invalid_ip_num3) { EXPECT_TRUE(tools::dns_utils::parse_dns_public("tcp://3.4.5").empty()); }
169 TEST(DNS_PUBLIC, invalid_ip_num4_extra) { EXPECT_TRUE(tools::dns_utils::parse_dns_public("tcp://3.4.5.6x").empty()); }
170 TEST(DNS_PUBLIC, invalid_ip_num4_range) { EXPECT_TRUE(tools::dns_utils::parse_dns_public("tcp://3.4.542.6").empty()); }
171 TEST(DNS_PUBLIC, invalid_ip_dot) { EXPECT_TRUE(tools::dns_utils::parse_dns_public("tcp://3.4.5.6.").empty()); }
172 TEST(DNS_PUBLIC, invalid_ip_num5) { EXPECT_TRUE(tools::dns_utils::parse_dns_public("tcp://3.4.5.6.7").empty()); }
173 TEST(DNS_PUBLIC, invalid_ip_4_missing) { EXPECT_TRUE(tools::dns_utils::parse_dns_public("tcp://3.4..7").empty()); }
174 TEST(DNS_PUBLIC, valid_ip_lo) { EXPECT_TRUE(is_equal("127.0.0.1", tools::dns_utils::parse_dns_public("tcp://127.0.0.1"))); }
175 TEST(DNS_PUBLIC, valid_ip) { EXPECT_TRUE(is_equal("3.4.5.6", tools::dns_utils::parse_dns_public("tcp://3.4.5.6"))); }
bool is_equal(const char *s, const std::vector< std::string > &v)
#define EXPECT_TRUE(condition)
Definition: gtest.h:1859
#define EXPECT_STREQ(s1, s2)
Definition: gtest.h:1995
::std::string string
Definition: gtest-port.h:1097
std::vector< std::string > get_ipv4(const std::string &url, bool &dnssec_available, bool &dnssec_valid)
gets ipv4 addresses from DNS query of a URL
Definition: dns_utils.cpp:355
static DNSResolver create()
Gets a new instance of DNSResolver.
Definition: dns_utils.cpp:391
#define ASSERT_FALSE(condition)
Definition: gtest.h:1868
#define ASSERT_EQ(val1, val2)
Definition: gtest.h:1956
std::vector< std::string > get_ipv6(const std::string &url, bool &dnssec_available, bool &dnssec_valid)
gets ipv6 addresses from DNS query
Definition: dns_utils.cpp:360
std::string get_dns_format_from_oa_address(const std::string &oa_addr)
Gets a DNS address from OpenAlias format.
Definition: dns_utils.cpp:370
Provides high-level access to DNS resolution.
Definition: dns_utils.h:55
#define EXPECT_NE(val1, val2)
Definition: gtest.h:1926
TEST(DNSResolver, IPv4Success)
static DNSResolver & instance()
Gets the singleton instance of DNSResolver.
Definition: dns_utils.cpp:383
std::vector< std::string > parse_dns_public(const char *s)
Definition: dns_utils.cpp:601
#define ASSERT_TRUE(condition)
Definition: gtest.h:1865
std::vector< std::string > get_txt_record(const std::string &url, bool &dnssec_available, bool &dnssec_valid)
gets all TXT records from a DNS query for the supplied URL; if no TXT record present returns an empty...
Definition: dns_utils.cpp:365