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
3 // found in the LICENSE file.
5 #include "net/base/address_list.h"
7 #include "base/strings/string_util.h"
8 #include "base/sys_byteorder.h"
9 #include "net/base/net_util.h"
10 #include "net/base/sys_addrinfo.h"
11 #include "testing/gtest/include/gtest/gtest.h"
16 const char kCanonicalHostname
[] = "canonical.bar.com";
18 TEST(AddressListTest
, Canonical
) {
19 // Create an addrinfo with a canonical name.
20 struct sockaddr_in address
;
21 // The contents of address do not matter for this test,
22 // so just zero-ing them out for consistency.
23 memset(&address
, 0x0, sizeof(address
));
24 // But we need to set the family.
25 address
.sin_family
= AF_INET
;
27 memset(&ai
, 0x0, sizeof(ai
));
28 ai
.ai_family
= AF_INET
;
29 ai
.ai_socktype
= SOCK_STREAM
;
30 ai
.ai_addrlen
= sizeof(address
);
31 ai
.ai_addr
= reinterpret_cast<sockaddr
*>(&address
);
32 ai
.ai_canonname
= const_cast<char *>(kCanonicalHostname
);
34 // Copy the addrinfo struct into an AddressList object and
35 // make sure it seems correct.
36 AddressList addrlist1
= AddressList::CreateFromAddrinfo(&ai
);
37 EXPECT_EQ("canonical.bar.com", addrlist1
.canonical_name());
39 // Copy the AddressList to another one.
40 AddressList addrlist2
= addrlist1
;
41 EXPECT_EQ("canonical.bar.com", addrlist2
.canonical_name());
44 TEST(AddressListTest
, CreateFromAddrinfo
) {
45 // Create an 4-element addrinfo.
46 const unsigned kNumElements
= 4;
47 SockaddrStorage storage
[kNumElements
];
48 struct addrinfo ai
[kNumElements
];
49 for (unsigned i
= 0; i
< kNumElements
; ++i
) {
50 struct sockaddr_in
* addr
=
51 reinterpret_cast<struct sockaddr_in
*>(storage
[i
].addr
);
52 storage
[i
].addr_len
= sizeof(struct sockaddr_in
);
53 // Populating the address with { i, i, i, i }.
54 memset(&addr
->sin_addr
, i
, kIPv4AddressSize
);
55 addr
->sin_family
= AF_INET
;
56 // Set port to i << 2;
57 addr
->sin_port
= base::HostToNet16(static_cast<uint16_t>(i
<< 2));
58 memset(&ai
[i
], 0x0, sizeof(ai
[i
]));
59 ai
[i
].ai_family
= addr
->sin_family
;
60 ai
[i
].ai_socktype
= SOCK_STREAM
;
61 ai
[i
].ai_addrlen
= storage
[i
].addr_len
;
62 ai
[i
].ai_addr
= storage
[i
].addr
;
63 if (i
+ 1 < kNumElements
)
64 ai
[i
].ai_next
= &ai
[i
+ 1];
67 AddressList list
= AddressList::CreateFromAddrinfo(&ai
[0]);
69 ASSERT_EQ(kNumElements
, list
.size());
70 for (size_t i
= 0; i
< list
.size(); ++i
) {
71 EXPECT_EQ(ADDRESS_FAMILY_IPV4
, list
[i
].GetFamily());
72 // Only check the first byte of the address.
73 EXPECT_EQ(i
, list
[i
].address()[0]);
74 EXPECT_EQ(static_cast<int>(i
<< 2), list
[i
].port());
77 // Check if operator= works.
80 ASSERT_EQ(kNumElements
, copy
.size());
82 // Check if copy is independent.
83 copy
[1] = IPEndPoint(copy
[2].address(), 0xBEEF);
84 // Original should be unchanged.
85 EXPECT_EQ(1u, list
[1].address()[0]);
86 EXPECT_EQ(1 << 2, list
[1].port());
89 TEST(AddressListTest
, CreateFromIPAddressList
) {
91 std::string ip_address
;
95 size_t in_addr_offset
;
101 sizeof(struct sockaddr_in
),
102 offsetof(struct sockaddr_in
, sin_addr
),
103 sizeof(struct in_addr
),
106 "\x20\x01\x0d\xb8\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x42",
108 sizeof(struct sockaddr_in6
),
109 offsetof(struct sockaddr_in6
, sin6_addr
),
110 sizeof(struct in6_addr
),
115 sizeof(struct sockaddr_in
),
116 offsetof(struct sockaddr_in
, sin_addr
),
117 sizeof(struct in_addr
),
120 const std::string kCanonicalName
= "canonical.example.com";
122 // Construct a list of ip addresses.
123 IPAddressList ip_list
;
124 for (size_t i
= 0; i
< arraysize(tests
); ++i
) {
125 IPAddressNumber ip_number
;
126 ASSERT_TRUE(ParseIPLiteralToNumber(tests
[i
].ip_address
, &ip_number
));
127 ip_list
.push_back(ip_number
);
130 AddressList test_list
= AddressList::CreateFromIPAddressList(ip_list
,
132 std::string canonical_name
;
133 EXPECT_EQ(kCanonicalName
, test_list
.canonical_name());
134 EXPECT_EQ(arraysize(tests
), test_list
.size());