1#include "node_sockaddr-inl.h"
2#include "gtest/gtest.h"
3
4using node::SocketAddress;
5using node::SocketAddressBlockList;
6using node::SocketAddressLRU;
7
8TEST(SocketAddress, SocketAddress) {
9  CHECK(SocketAddress::is_numeric_host("123.123.123.123"));
10  CHECK(!SocketAddress::is_numeric_host("localhost"));
11
12  sockaddr_storage storage;
13  sockaddr_storage storage2;
14  SocketAddress::ToSockAddr(AF_INET, "123.123.123.123", 443, &storage);
15  SocketAddress::ToSockAddr(AF_INET, "1.1.1.1", 80, &storage2);
16
17  SocketAddress addr(reinterpret_cast<const sockaddr*>(&storage));
18  SocketAddress addr2(reinterpret_cast<const sockaddr*>(&storage2));
19
20  CHECK_EQ(addr.length(), sizeof(sockaddr_in));
21  CHECK_EQ(addr.family(), AF_INET);
22  CHECK_EQ(addr.address(), "123.123.123.123");
23  CHECK_EQ(addr.port(), 443);
24
25  addr.set_flow_label(12345);
26  CHECK_EQ(addr.flow_label(), 0);
27
28  CHECK_NE(addr, addr2);
29  CHECK_EQ(addr, addr);
30
31  CHECK_EQ(SocketAddress::Hash()(addr), SocketAddress::Hash()(addr));
32  CHECK_NE(SocketAddress::Hash()(addr), SocketAddress::Hash()(addr2));
33
34  addr.Update(reinterpret_cast<uint8_t*>(&storage2), sizeof(sockaddr_in));
35  CHECK_EQ(addr.length(), sizeof(sockaddr_in));
36  CHECK_EQ(addr.family(), AF_INET);
37  CHECK_EQ(addr.address(), "1.1.1.1");
38  CHECK_EQ(addr.port(), 80);
39
40  SocketAddress::Map<size_t> map;
41  map[addr]++;
42  map[addr]++;
43  CHECK_EQ(map[addr], 2);
44}
45
46TEST(SocketAddress, SocketAddressIPv6) {
47  sockaddr_storage storage;
48  SocketAddress::ToSockAddr(AF_INET6, "::1", 443, &storage);
49
50  SocketAddress addr(reinterpret_cast<const sockaddr*>(&storage));
51
52  CHECK_EQ(addr.length(), sizeof(sockaddr_in6));
53  CHECK_EQ(addr.family(), AF_INET6);
54  CHECK_EQ(addr.address(), "::1");
55  CHECK_EQ(addr.port(), 443);
56
57  addr.set_flow_label(12345);
58  CHECK_EQ(addr.flow_label(), 12345);
59}
60
61TEST(SocketAddressLRU, SocketAddressLRU) {
62  struct Foo {
63    int c;
64    bool expired;
65  };
66
67  struct FooLRUTraits {
68    using Type = Foo;
69
70    static bool CheckExpired(const SocketAddress& address, const Type& type) {
71      return type.expired;
72    }
73
74    static void Touch(const SocketAddress& address, Type* type) {
75      type->expired = false;
76    }
77  };
78
79  SocketAddressLRU<FooLRUTraits> lru(2);
80
81  sockaddr_storage storage[4];
82
83  SocketAddress::ToSockAddr(AF_INET, "123.123.123.123", 443, &storage[0]);
84  SocketAddress::ToSockAddr(AF_INET, "123.123.123.124", 443, &storage[1]);
85  SocketAddress::ToSockAddr(AF_INET, "123.123.123.125", 443, &storage[2]);
86  SocketAddress::ToSockAddr(AF_INET, "123.123.123.123", 443, &storage[3]);
87
88
89  SocketAddress addr1(reinterpret_cast<const sockaddr*>(&storage[0]));
90  SocketAddress addr2(reinterpret_cast<const sockaddr*>(&storage[1]));
91  SocketAddress addr3(reinterpret_cast<const sockaddr*>(&storage[2]));
92  SocketAddress addr4(reinterpret_cast<const sockaddr*>(&storage[3]));
93
94  Foo* foo = lru.Upsert(addr1);
95  CHECK_NOT_NULL(foo);
96  CHECK_EQ(foo->c, 0);
97  CHECK_EQ(foo->expired, false);
98
99  foo->c = 1;
100  foo->expired = true;
101
102  foo = lru.Upsert(addr1);
103  CHECK_NOT_NULL(lru.Peek(addr1));
104  CHECK_EQ(lru.Peek(addr1), lru.Peek(addr4));
105  CHECK_EQ(lru.Peek(addr1)->c, 1);
106  CHECK_EQ(lru.Peek(addr1)->expired, false);
107  CHECK_EQ(lru.size(), 1);
108
109  foo = lru.Upsert(addr2);
110  foo->c = 2;
111  foo->expired = true;
112  CHECK_NOT_NULL(lru.Peek(addr2));
113  CHECK_EQ(lru.Peek(addr2)->c, 2);
114  CHECK_EQ(lru.size(), 2);
115
116  foo->expired = true;
117
118  foo = lru.Upsert(addr3);
119  foo->c = 3;
120  foo->expired = false;
121  CHECK_NOT_NULL(lru.Peek(addr3));
122  CHECK_EQ(lru.Peek(addr3)->c, 3);
123  CHECK_EQ(lru.size(), 1);
124
125  // addr1 was removed because we exceeded size.
126  // addr2 was removed because it was expired.
127  CHECK_NULL(lru.Peek(addr1));
128  CHECK_NULL(lru.Peek(addr2));
129}
130
131TEST(SocketAddress, Comparison) {
132  sockaddr_storage storage[6];
133
134  SocketAddress::ToSockAddr(AF_INET, "10.0.0.1", 0, &storage[0]);
135  SocketAddress::ToSockAddr(AF_INET, "10.0.0.2", 0, &storage[1]);
136  SocketAddress::ToSockAddr(AF_INET6, "::1", 0, &storage[2]);
137  SocketAddress::ToSockAddr(AF_INET6, "::2", 0, &storage[3]);
138  SocketAddress::ToSockAddr(AF_INET6, "::ffff:10.0.0.1", 0, &storage[4]);
139  SocketAddress::ToSockAddr(AF_INET6, "::ffff:10.0.0.2", 0, &storage[5]);
140
141  SocketAddress addr1(reinterpret_cast<const sockaddr*>(&storage[0]));
142  SocketAddress addr2(reinterpret_cast<const sockaddr*>(&storage[1]));
143  SocketAddress addr3(reinterpret_cast<const sockaddr*>(&storage[2]));
144  SocketAddress addr4(reinterpret_cast<const sockaddr*>(&storage[3]));
145  SocketAddress addr5(reinterpret_cast<const sockaddr*>(&storage[4]));
146  SocketAddress addr6(reinterpret_cast<const sockaddr*>(&storage[5]));
147
148  CHECK_EQ(addr1.compare(addr1), SocketAddress::CompareResult::SAME);
149  CHECK_EQ(addr1.compare(addr2), SocketAddress::CompareResult::LESS_THAN);
150  CHECK_EQ(addr2.compare(addr1), SocketAddress::CompareResult::GREATER_THAN);
151  CHECK(addr1 <= addr1);
152  CHECK(addr1 < addr2);
153  CHECK(addr1 <= addr2);
154  CHECK(addr2 >= addr2);
155  CHECK(addr2 > addr1);
156  CHECK(addr2 >= addr1);
157
158  CHECK_EQ(addr3.compare(addr3), SocketAddress::CompareResult::SAME);
159  CHECK_EQ(addr3.compare(addr4), SocketAddress::CompareResult::LESS_THAN);
160  CHECK_EQ(addr4.compare(addr3), SocketAddress::CompareResult::GREATER_THAN);
161  CHECK(addr3 <= addr3);
162  CHECK(addr3 < addr4);
163  CHECK(addr3 <= addr4);
164  CHECK(addr4 >= addr4);
165  CHECK(addr4 > addr3);
166  CHECK(addr4 >= addr3);
167
168  // Not comparable
169  CHECK_EQ(addr1.compare(addr3), SocketAddress::CompareResult::NOT_COMPARABLE);
170  CHECK_EQ(addr3.compare(addr1), SocketAddress::CompareResult::NOT_COMPARABLE);
171  CHECK(!(addr1 < addr3));
172  CHECK(!(addr1 > addr3));
173  CHECK(!(addr1 >= addr3));
174  CHECK(!(addr1 <= addr3));
175  CHECK(!(addr3 < addr1));
176  CHECK(!(addr3 > addr1));
177  CHECK(!(addr3 >= addr1));
178  CHECK(!(addr3 <= addr1));
179
180  // Comparable
181  CHECK_EQ(addr1.compare(addr5), SocketAddress::CompareResult::SAME);
182  CHECK_EQ(addr2.compare(addr6), SocketAddress::CompareResult::SAME);
183  CHECK_EQ(addr1.compare(addr6), SocketAddress::CompareResult::LESS_THAN);
184  CHECK_EQ(addr6.compare(addr1), SocketAddress::CompareResult::GREATER_THAN);
185  CHECK(addr1 <= addr5);
186  CHECK(addr1 <= addr6);
187  CHECK(addr1 < addr6);
188  CHECK(addr6 > addr1);
189  CHECK(addr6 >= addr1);
190  CHECK(addr2 >= addr6);
191  CHECK(addr2 >= addr5);
192}
193
194TEST(SocketAddressBlockList, Simple) {
195  SocketAddressBlockList bl;
196
197  sockaddr_storage storage[2];
198  SocketAddress::ToSockAddr(AF_INET, "10.0.0.1", 0, &storage[0]);
199  SocketAddress::ToSockAddr(AF_INET, "10.0.0.2", 0, &storage[1]);
200  std::shared_ptr<SocketAddress> addr1 =
201      std::make_shared<SocketAddress>(
202          reinterpret_cast<const sockaddr*>(&storage[0]));
203  std::shared_ptr<SocketAddress> addr2 =
204      std::make_shared<SocketAddress>(
205          reinterpret_cast<const sockaddr*>(&storage[1]));
206
207  bl.AddSocketAddress(addr1);
208  bl.AddSocketAddress(addr2);
209
210  CHECK(bl.Apply(addr1));
211  CHECK(bl.Apply(addr2));
212
213  bl.RemoveSocketAddress(addr1);
214
215  CHECK(!bl.Apply(addr1));
216  CHECK(bl.Apply(addr2));
217}
218