| OLD | NEW |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "net/base/address_list.h" | 5 #include "net/base/address_list.h" |
| 6 | 6 |
| 7 #include "base/memory/scoped_ptr.h" | |
| 8 #include "base/string_util.h" | 7 #include "base/string_util.h" |
| 9 #include "net/base/host_resolver_proc.h" | 8 #include "base/sys_byteorder.h" |
| 10 #include "net/base/net_util.h" | 9 #include "net/base/net_util.h" |
| 11 #include "net/base/sys_addrinfo.h" | 10 #include "net/base/sys_addrinfo.h" |
| 12 #if defined(OS_WIN) | |
| 13 #include "net/base/winsock_init.h" | |
| 14 #endif | |
| 15 #include "testing/gtest/include/gtest/gtest.h" | 11 #include "testing/gtest/include/gtest/gtest.h" |
| 16 | 12 |
| 17 namespace net { | 13 namespace net { |
| 18 namespace { | 14 namespace { |
| 19 | 15 |
| 20 void MutableSetPort(uint16 port, AddressList* addrlist) { | |
| 21 struct addrinfo* mutable_head = | |
| 22 const_cast<struct addrinfo*>(addrlist->head()); | |
| 23 SetPortForAllAddrinfos(mutable_head, port); | |
| 24 } | |
| 25 | |
| 26 // Use getaddrinfo() to allocate an addrinfo structure. | |
| 27 int CreateAddressList(const std::string& hostname, int port, | |
| 28 AddressList* addrlist) { | |
| 29 #if defined(OS_WIN) | |
| 30 EnsureWinsockInit(); | |
| 31 #endif | |
| 32 int rv = SystemHostResolverProc(hostname, | |
| 33 ADDRESS_FAMILY_UNSPECIFIED, | |
| 34 0, | |
| 35 addrlist, NULL); | |
| 36 if (rv == 0) | |
| 37 MutableSetPort(port, addrlist); | |
| 38 return rv; | |
| 39 } | |
| 40 | |
| 41 void CreateLongAddressList(AddressList* addrlist, int port) { | |
| 42 EXPECT_EQ(0, CreateAddressList("192.168.1.1", port, addrlist)); | |
| 43 AddressList second_list; | |
| 44 EXPECT_EQ(0, CreateAddressList("192.168.1.2", port, &second_list)); | |
| 45 addrlist->Append(second_list.head()); | |
| 46 } | |
| 47 | |
| 48 TEST(AddressListTest, GetPort) { | |
| 49 AddressList addrlist; | |
| 50 EXPECT_EQ(0, CreateAddressList("192.168.1.1", 81, &addrlist)); | |
| 51 EXPECT_EQ(81, addrlist.GetPort()); | |
| 52 | |
| 53 MutableSetPort(83, &addrlist); | |
| 54 EXPECT_EQ(83, addrlist.GetPort()); | |
| 55 } | |
| 56 | |
| 57 TEST(AddressListTest, SetPortMakesCopy) { | |
| 58 AddressList addrlist1; | |
| 59 EXPECT_EQ(0, CreateAddressList("192.168.1.1", 85, &addrlist1)); | |
| 60 EXPECT_EQ(85, addrlist1.GetPort()); | |
| 61 | |
| 62 AddressList addrlist2 = addrlist1; | |
| 63 EXPECT_EQ(85, addrlist2.GetPort()); | |
| 64 | |
| 65 // addrlist1 should not be affected by the assignment to | |
| 66 // addrlist2. | |
| 67 addrlist1.SetPort(80); | |
| 68 EXPECT_EQ(80, addrlist1.GetPort()); | |
| 69 EXPECT_EQ(85, addrlist2.GetPort()); | |
| 70 } | |
| 71 | |
| 72 TEST(AddressListTest, Assignment) { | |
| 73 AddressList addrlist1; | |
| 74 EXPECT_EQ(0, CreateAddressList("192.168.1.1", 85, &addrlist1)); | |
| 75 EXPECT_EQ(85, addrlist1.GetPort()); | |
| 76 | |
| 77 // Should reference the same data as addrlist1 -- so when we change addrlist1 | |
| 78 // both are changed. | |
| 79 AddressList addrlist2 = addrlist1; | |
| 80 EXPECT_EQ(85, addrlist2.GetPort()); | |
| 81 | |
| 82 MutableSetPort(80, &addrlist1); | |
| 83 EXPECT_EQ(80, addrlist1.GetPort()); | |
| 84 EXPECT_EQ(80, addrlist2.GetPort()); | |
| 85 } | |
| 86 | |
| 87 TEST(AddressListTest, CopyRecursive) { | |
| 88 AddressList addrlist1; | |
| 89 CreateLongAddressList(&addrlist1, 85); | |
| 90 EXPECT_EQ(85, addrlist1.GetPort()); | |
| 91 | |
| 92 AddressList addrlist2 = | |
| 93 AddressList::CreateByCopying(addrlist1.head()); | |
| 94 | |
| 95 ASSERT_TRUE(addrlist2.head()->ai_next != NULL); | |
| 96 | |
| 97 // addrlist1 is the same as addrlist2 at this point. | |
| 98 EXPECT_EQ(85, addrlist1.GetPort()); | |
| 99 EXPECT_EQ(85, addrlist2.GetPort()); | |
| 100 | |
| 101 // Changes to addrlist1 are not reflected in addrlist2. | |
| 102 MutableSetPort(70, &addrlist1); | |
| 103 MutableSetPort(90, &addrlist2); | |
| 104 | |
| 105 EXPECT_EQ(70, addrlist1.GetPort()); | |
| 106 EXPECT_EQ(90, addrlist2.GetPort()); | |
| 107 } | |
| 108 | |
| 109 TEST(AddressListTest, CopyNonRecursive) { | |
| 110 AddressList addrlist1; | |
| 111 CreateLongAddressList(&addrlist1, 85); | |
| 112 EXPECT_EQ(85, addrlist1.GetPort()); | |
| 113 | |
| 114 AddressList addrlist2 = | |
| 115 AddressList::CreateByCopyingFirstAddress(addrlist1.head()); | |
| 116 | |
| 117 ASSERT_TRUE(addrlist2.head()->ai_next == NULL); | |
| 118 | |
| 119 // addrlist1 is the same as addrlist2 at this point. | |
| 120 EXPECT_EQ(85, addrlist1.GetPort()); | |
| 121 EXPECT_EQ(85, addrlist2.GetPort()); | |
| 122 | |
| 123 // Changes to addrlist1 are not reflected in addrlist2. | |
| 124 MutableSetPort(70, &addrlist1); | |
| 125 MutableSetPort(90, &addrlist2); | |
| 126 | |
| 127 EXPECT_EQ(70, addrlist1.GetPort()); | |
| 128 EXPECT_EQ(90, addrlist2.GetPort()); | |
| 129 } | |
| 130 | |
| 131 TEST(AddressListTest, Append) { | |
| 132 AddressList addrlist1; | |
| 133 EXPECT_EQ(0, CreateAddressList("192.168.1.1", 11, &addrlist1)); | |
| 134 EXPECT_EQ(11, addrlist1.GetPort()); | |
| 135 AddressList addrlist2; | |
| 136 EXPECT_EQ(0, CreateAddressList("192.168.1.2", 12, &addrlist2)); | |
| 137 EXPECT_EQ(12, addrlist2.GetPort()); | |
| 138 | |
| 139 ASSERT_TRUE(addrlist1.head()->ai_next == NULL); | |
| 140 addrlist1.Append(addrlist2.head()); | |
| 141 ASSERT_TRUE(addrlist1.head()->ai_next != NULL); | |
| 142 | |
| 143 AddressList addrlist3 = | |
| 144 AddressList::CreateByCopyingFirstAddress(addrlist1.head()->ai_next); | |
| 145 EXPECT_EQ(12, addrlist3.GetPort()); | |
| 146 } | |
| 147 | |
| 148 static const char* kCanonicalHostname = "canonical.bar.com"; | 16 static const char* kCanonicalHostname = "canonical.bar.com"; |
| 149 | 17 |
| 150 TEST(AddressListTest, Canonical) { | 18 TEST(AddressListTest, Canonical) { |
| 151 // Create an addrinfo with a canonical name. | 19 // Create an addrinfo with a canonical name. |
| 152 sockaddr_in address; | 20 struct sockaddr_in address; |
| 153 // The contents of address do not matter for this test, | 21 // The contents of address do not matter for this test, |
| 154 // so just zero-ing them out for consistency. | 22 // so just zero-ing them out for consistency. |
| 155 memset(&address, 0x0, sizeof(address)); | 23 memset(&address, 0x0, sizeof(address)); |
| 24 // But we need to set the family. |
| 25 address.sin_family = AF_INET; |
| 156 struct addrinfo ai; | 26 struct addrinfo ai; |
| 157 memset(&ai, 0x0, sizeof(ai)); | 27 memset(&ai, 0x0, sizeof(ai)); |
| 158 ai.ai_family = AF_INET; | 28 ai.ai_family = AF_INET; |
| 159 ai.ai_socktype = SOCK_STREAM; | 29 ai.ai_socktype = SOCK_STREAM; |
| 160 ai.ai_addrlen = sizeof(address); | 30 ai.ai_addrlen = sizeof(address); |
| 161 ai.ai_addr = reinterpret_cast<sockaddr*>(&address); | 31 ai.ai_addr = reinterpret_cast<sockaddr*>(&address); |
| 162 ai.ai_canonname = const_cast<char *>(kCanonicalHostname); | 32 ai.ai_canonname = const_cast<char *>(kCanonicalHostname); |
| 163 | 33 |
| 164 // Copy the addrinfo struct into an AddressList object and | 34 // Copy the addrinfo struct into an AddressList object and |
| 165 // make sure it seems correct. | 35 // make sure it seems correct. |
| 166 AddressList addrlist1 = AddressList::CreateByCopying(&ai); | 36 AddressList addrlist1 = AddressList::CreateFromAddrinfo(&ai); |
| 167 const struct addrinfo* addrinfo1 = addrlist1.head(); | 37 EXPECT_EQ("canonical.bar.com", addrlist1.canonical_name()); |
| 168 EXPECT_TRUE(addrinfo1 != NULL); | |
| 169 EXPECT_TRUE(addrinfo1->ai_next == NULL); | |
| 170 std::string canon_name1; | |
| 171 EXPECT_TRUE(addrlist1.GetCanonicalName(&canon_name1)); | |
| 172 EXPECT_EQ("canonical.bar.com", canon_name1); | |
| 173 | 38 |
| 174 // Copy the AddressList to another one. | 39 // Copy the AddressList to another one. |
| 175 AddressList addrlist2 = AddressList::CreateByCopying(addrinfo1); | 40 AddressList addrlist2 = addrlist1; |
| 176 const struct addrinfo* addrinfo2 = addrlist2.head(); | 41 EXPECT_EQ("canonical.bar.com", addrlist2.canonical_name()); |
| 177 EXPECT_TRUE(addrinfo2 != NULL); | |
| 178 EXPECT_TRUE(addrinfo2->ai_next == NULL); | |
| 179 EXPECT_TRUE(addrinfo2->ai_canonname != NULL); | |
| 180 EXPECT_NE(addrinfo1, addrinfo2); | |
| 181 EXPECT_NE(addrinfo1->ai_canonname, addrinfo2->ai_canonname); | |
| 182 std::string canon_name2; | |
| 183 EXPECT_TRUE(addrlist2.GetCanonicalName(&canon_name2)); | |
| 184 EXPECT_EQ("canonical.bar.com", canon_name2); | |
| 185 | |
| 186 // Make sure that GetCanonicalName correctly returns false | |
| 187 // when ai_canonname is NULL. | |
| 188 ai.ai_canonname = NULL; | |
| 189 AddressList addrlist_no_canon = AddressList::CreateByCopying(&ai); | |
| 190 std::string canon_name3 = "blah"; | |
| 191 EXPECT_FALSE(addrlist_no_canon.GetCanonicalName(&canon_name3)); | |
| 192 EXPECT_EQ("blah", canon_name3); | |
| 193 } | 42 } |
| 194 | 43 |
| 195 TEST(AddressListTest, IPLiteralConstructor) { | 44 TEST(AddressListTest, CreateFromAddrinfo) { |
| 196 struct TestData { | 45 // Create an 4-element addrinfo. |
| 197 std::string ip_address; | 46 const unsigned kNumElements = 4; |
| 198 std::string canonical_ip_address; | 47 SockaddrStorage storage[kNumElements]; |
| 199 bool is_ipv6; | 48 struct addrinfo ai[kNumElements]; |
| 200 } tests[] = { | 49 for (unsigned i = 0; i < kNumElements; ++i) { |
| 201 { "127.0.00.1", "127.0.0.1", false }, | 50 struct sockaddr_in* addr = |
| 202 { "192.168.1.1", "192.168.1.1", false }, | 51 reinterpret_cast<struct sockaddr_in*>(storage[i].addr); |
| 203 { "::1", "::1", true }, | 52 storage[i].addr_len = sizeof(struct sockaddr_in); |
| 204 { "2001:db8:0::42", "2001:db8::42", true }, | 53 // Populating the address with { i, i, i, i }. |
| 205 }; | 54 memset(&addr->sin_addr, i, kIPv4AddressSize); |
| 206 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(tests); i++) { | 55 addr->sin_family = AF_INET; |
| 207 AddressList expected_list; | 56 // Set port to i << 2; |
| 208 int rv = CreateAddressList(tests[i].canonical_ip_address, 80, | 57 addr->sin_port = base::HostToNet16(static_cast<uint16>(i << 2)); |
| 209 &expected_list); | 58 memset(&ai[i], 0x0, sizeof(ai[i])); |
| 210 if (tests[i].is_ipv6 && rv != 0) { | 59 ai[i].ai_family = addr->sin_family; |
| 211 LOG(WARNING) << "Unable to resolve ip literal '" << tests[i].ip_address | 60 ai[i].ai_socktype = SOCK_STREAM; |
| 212 << "' test skipped."; | 61 ai[i].ai_addrlen = storage[i].addr_len; |
| 213 continue; | 62 ai[i].ai_addr = storage[i].addr; |
| 214 } | 63 if (i + 1 < kNumElements) |
| 215 ASSERT_EQ(0, rv); | 64 ai[i].ai_next = &ai[i + 1]; |
| 216 const struct addrinfo* good_ai = expected_list.head(); | 65 } |
| 217 | 66 |
| 218 IPAddressNumber ip_number; | 67 AddressList list = AddressList::CreateFromAddrinfo(&ai[0]); |
| 219 ASSERT_TRUE(ParseIPLiteralToNumber(tests[i].ip_address, &ip_number)); | |
| 220 AddressList test_list = AddressList::CreateFromIPAddressWithCname( | |
| 221 ip_number, 80, true); | |
| 222 const struct addrinfo* test_ai = test_list.head(); | |
| 223 | 68 |
| 224 EXPECT_EQ(good_ai->ai_family, test_ai->ai_family); | 69 ASSERT_EQ(kNumElements, list.size()); |
| 225 EXPECT_EQ(good_ai->ai_socktype, test_ai->ai_socktype); | 70 for (size_t i = 0; i < list.size(); ++i) { |
| 226 EXPECT_EQ(good_ai->ai_addrlen, test_ai->ai_addrlen); | 71 EXPECT_EQ(AF_INET, list[i].GetFamily()); |
| 227 size_t sockaddr_size = | 72 // Only check the first byte of the address. |
| 228 good_ai->ai_socktype == AF_INET ? sizeof(struct sockaddr_in) : | 73 EXPECT_EQ(i, list[i].address()[0]); |
| 229 good_ai->ai_socktype == AF_INET6 ? sizeof(struct sockaddr_in6) : 0; | 74 EXPECT_EQ(static_cast<int>(i << 2), list[i].port()); |
| 230 EXPECT_EQ(memcmp(good_ai->ai_addr, test_ai->ai_addr, sockaddr_size), 0); | |
| 231 EXPECT_EQ(good_ai->ai_next, test_ai->ai_next); | |
| 232 EXPECT_EQ(strcmp(tests[i].canonical_ip_address.c_str(), | |
| 233 test_ai->ai_canonname), 0); | |
| 234 } | 75 } |
| 235 } | |
| 236 | 76 |
| 237 TEST(AddressListTest, AddressFromAddrInfo) { | 77 // Check if operator= works. |
| 238 struct TestData { | 78 AddressList copy; |
| 239 std::string ip_address; | 79 copy = list; |
| 240 std::string canonical_ip_address; | 80 ASSERT_EQ(kNumElements, copy.size()); |
| 241 bool is_ipv6; | |
| 242 } tests[] = { | |
| 243 { "127.0.00.1", "127.0.0.1", false }, | |
| 244 { "192.168.1.1", "192.168.1.1", false }, | |
| 245 { "::1", "::1", true }, | |
| 246 { "2001:db8:0::42", "2001:db8::42", true }, | |
| 247 }; | |
| 248 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(tests); i++) { | |
| 249 AddressList expected_list; | |
| 250 int rv = CreateAddressList(tests[i].canonical_ip_address, 80, | |
| 251 &expected_list); | |
| 252 if (tests[i].is_ipv6 && rv != 0) { | |
| 253 LOG(WARNING) << "Unable to resolve ip literal '" << tests[i].ip_address | |
| 254 << "' test skipped."; | |
| 255 continue; | |
| 256 } | |
| 257 ASSERT_EQ(0, rv); | |
| 258 const struct addrinfo* good_ai = expected_list.head(); | |
| 259 | 81 |
| 260 AddressList test_list = | 82 // Check if copy is independent. |
| 261 AddressList::CreateFromSockaddr(good_ai->ai_addr, | 83 copy[1] = IPEndPoint(copy[2].address(), 0xBEEF); |
| 262 good_ai->ai_addrlen, | 84 // Original should be unchanged. |
| 263 SOCK_STREAM, | 85 EXPECT_EQ(1u, list[1].address()[0]); |
| 264 IPPROTO_TCP); | 86 EXPECT_EQ(1 << 2, list[1].port()); |
| 265 const struct addrinfo* test_ai = test_list.head(); | |
| 266 | |
| 267 EXPECT_EQ(good_ai->ai_family, test_ai->ai_family); | |
| 268 EXPECT_EQ(good_ai->ai_addrlen, test_ai->ai_addrlen); | |
| 269 size_t sockaddr_size = | |
| 270 good_ai->ai_family == AF_INET ? sizeof(struct sockaddr_in) : | |
| 271 good_ai->ai_family == AF_INET6 ? sizeof(struct sockaddr_in6) : 0; | |
| 272 EXPECT_EQ(memcmp(good_ai->ai_addr, test_ai->ai_addr, sockaddr_size), 0); | |
| 273 EXPECT_EQ(good_ai->ai_next, test_ai->ai_next); | |
| 274 } | |
| 275 } | 87 } |
| 276 | 88 |
| 277 TEST(AddressListTest, CreateFromIPAddressList) { | 89 TEST(AddressListTest, CreateFromIPAddressList) { |
| 278 struct TestData { | 90 struct TestData { |
| 279 std::string ip_address; | 91 std::string ip_address; |
| 280 const char* in_addr; | 92 const char* in_addr; |
| 281 int ai_family; | 93 int ai_family; |
| 282 size_t ai_addrlen; | 94 size_t ai_addrlen; |
| 283 size_t in_addr_offset; | 95 size_t in_addr_offset; |
| 284 size_t in_addr_size; | 96 size_t in_addr_size; |
| (...skipping 26 matching lines...) Expand all Loading... |
| 311 IPAddressList ip_list; | 123 IPAddressList ip_list; |
| 312 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(tests); ++i) { | 124 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(tests); ++i) { |
| 313 IPAddressNumber ip_number; | 125 IPAddressNumber ip_number; |
| 314 ASSERT_TRUE(ParseIPLiteralToNumber(tests[i].ip_address, &ip_number)); | 126 ASSERT_TRUE(ParseIPLiteralToNumber(tests[i].ip_address, &ip_number)); |
| 315 ip_list.push_back(ip_number); | 127 ip_list.push_back(ip_number); |
| 316 } | 128 } |
| 317 | 129 |
| 318 AddressList test_list = AddressList::CreateFromIPAddressList(ip_list, | 130 AddressList test_list = AddressList::CreateFromIPAddressList(ip_list, |
| 319 kCanonicalName); | 131 kCanonicalName); |
| 320 std::string canonical_name; | 132 std::string canonical_name; |
| 321 EXPECT_TRUE(test_list.GetCanonicalName(&canonical_name)); | 133 EXPECT_EQ(kCanonicalName, test_list.canonical_name()); |
| 322 EXPECT_EQ(kCanonicalName, canonical_name); | 134 EXPECT_EQ(ARRAYSIZE_UNSAFE(tests), test_list.size()); |
| 323 | |
| 324 // Make sure that CreateFromIPAddressList has created an addrinfo | |
| 325 // chain of exactly the same length as the |tests| with correct content. | |
| 326 const struct addrinfo* next_ai = test_list.head(); | |
| 327 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(tests); ++i) { | |
| 328 ASSERT_TRUE(next_ai != NULL); | |
| 329 EXPECT_EQ(tests[i].ai_family, next_ai->ai_family); | |
| 330 EXPECT_EQ(tests[i].ai_addrlen, static_cast<size_t>(next_ai->ai_addrlen)); | |
| 331 | |
| 332 char* ai_addr = reinterpret_cast<char*>(next_ai->ai_addr); | |
| 333 int rv = memcmp(tests[i].in_addr, | |
| 334 ai_addr + tests[i].in_addr_offset, | |
| 335 tests[i].in_addr_size); | |
| 336 EXPECT_EQ(0, rv); | |
| 337 next_ai = next_ai->ai_next; | |
| 338 } | |
| 339 EXPECT_EQ(NULL, next_ai); | |
| 340 } | 135 } |
| 341 | 136 |
| 342 } // namespace | 137 } // namespace |
| 343 } // namespace net | 138 } // namespace net |
| OLD | NEW |