1 |
|
|
#ifndef SRC_NODE_SOCKADDR_H_ |
2 |
|
|
#define SRC_NODE_SOCKADDR_H_ |
3 |
|
|
|
4 |
|
|
#if defined(NODE_WANT_INTERNALS) && NODE_WANT_INTERNALS |
5 |
|
|
|
6 |
|
|
#include "env.h" |
7 |
|
|
#include "memory_tracker.h" |
8 |
|
|
#include "base_object.h" |
9 |
|
|
#include "node.h" |
10 |
|
|
#include "uv.h" |
11 |
|
|
#include "v8.h" |
12 |
|
|
|
13 |
|
|
#include <memory> |
14 |
|
|
#include <string> |
15 |
|
|
#include <list> |
16 |
|
|
#include <unordered_map> |
17 |
|
|
|
18 |
|
|
namespace node { |
19 |
|
|
|
20 |
|
|
class Environment; |
21 |
|
|
|
22 |
|
149 |
class SocketAddress : public MemoryRetainer { |
23 |
|
|
public: |
24 |
|
|
enum class CompareResult { |
25 |
|
|
NOT_COMPARABLE = -2, |
26 |
|
|
LESS_THAN, |
27 |
|
|
SAME, |
28 |
|
|
GREATER_THAN |
29 |
|
|
}; |
30 |
|
|
|
31 |
|
9 |
struct Hash { |
32 |
|
|
size_t operator()(const SocketAddress& addr) const; |
33 |
|
|
}; |
34 |
|
|
|
35 |
|
|
inline bool operator==(const SocketAddress& other) const; |
36 |
|
|
inline bool operator!=(const SocketAddress& other) const; |
37 |
|
|
|
38 |
|
|
inline bool operator<(const SocketAddress& other) const; |
39 |
|
|
inline bool operator>(const SocketAddress& other) const; |
40 |
|
|
inline bool operator<=(const SocketAddress& other) const; |
41 |
|
|
inline bool operator>=(const SocketAddress& other) const; |
42 |
|
|
|
43 |
|
|
inline static bool is_numeric_host(const char* hostname); |
44 |
|
|
inline static bool is_numeric_host(const char* hostname, int family); |
45 |
|
|
|
46 |
|
|
// Returns true if converting {family, host, port} to *addr succeeded. |
47 |
|
|
static bool ToSockAddr( |
48 |
|
|
int32_t family, |
49 |
|
|
const char* host, |
50 |
|
|
uint32_t port, |
51 |
|
|
sockaddr_storage* addr); |
52 |
|
|
|
53 |
|
|
// Returns true if converting {family, host, port} to *addr succeeded. |
54 |
|
|
static bool New( |
55 |
|
|
int32_t family, |
56 |
|
|
const char* host, |
57 |
|
|
uint32_t port, |
58 |
|
|
SocketAddress* addr); |
59 |
|
|
|
60 |
|
|
static bool New( |
61 |
|
|
const char* host, |
62 |
|
|
uint32_t port, |
63 |
|
|
SocketAddress* addr); |
64 |
|
|
|
65 |
|
|
// Returns the port for an IPv4 or IPv6 address. |
66 |
|
|
inline static int GetPort(const sockaddr* addr); |
67 |
|
|
inline static int GetPort(const sockaddr_storage* addr); |
68 |
|
|
|
69 |
|
|
// Returns the numeric host as a string for an IPv4 or IPv6 address. |
70 |
|
|
inline static std::string GetAddress(const sockaddr* addr); |
71 |
|
|
inline static std::string GetAddress(const sockaddr_storage* addr); |
72 |
|
|
|
73 |
|
|
// Returns the struct length for an IPv4, IPv6 or UNIX domain. |
74 |
|
|
inline static size_t GetLength(const sockaddr* addr); |
75 |
|
|
inline static size_t GetLength(const sockaddr_storage* addr); |
76 |
|
|
|
77 |
|
|
SocketAddress() = default; |
78 |
|
|
|
79 |
|
|
inline explicit SocketAddress(const sockaddr* addr); |
80 |
|
|
inline SocketAddress(const SocketAddress& addr); |
81 |
|
|
inline SocketAddress& operator=(const sockaddr* other); |
82 |
|
|
inline SocketAddress& operator=(const SocketAddress& other); |
83 |
|
|
|
84 |
|
|
inline const sockaddr& operator*() const; |
85 |
|
|
inline const sockaddr* operator->() const; |
86 |
|
|
|
87 |
|
|
inline const sockaddr* data() const; |
88 |
|
|
inline const uint8_t* raw() const; |
89 |
|
|
inline sockaddr* storage(); |
90 |
|
|
inline size_t length() const; |
91 |
|
|
|
92 |
|
|
inline int family() const; |
93 |
|
|
inline std::string address() const; |
94 |
|
|
inline int port() const; |
95 |
|
|
|
96 |
|
|
// Returns true if the given other SocketAddress is a match |
97 |
|
|
// for this one. The addresses are a match if: |
98 |
|
|
// 1. They are the same family and match identically |
99 |
|
|
// 2. They are different family but match semantically ( |
100 |
|
|
// for instance, an IPv4 addres in IPv6 notation) |
101 |
|
|
bool is_match(const SocketAddress& other) const; |
102 |
|
|
|
103 |
|
|
// Compares this SocketAddress to the given other SocketAddress. |
104 |
|
|
CompareResult compare(const SocketAddress& other) const; |
105 |
|
|
|
106 |
|
|
// Returns true if this SocketAddress is within the subnet |
107 |
|
|
// identified by the given network address and CIDR prefix. |
108 |
|
|
bool is_in_network(const SocketAddress& network, int prefix) const; |
109 |
|
|
|
110 |
|
|
// If the SocketAddress is an IPv6 address, returns the |
111 |
|
|
// current value of the IPv6 flow label, if set. Otherwise |
112 |
|
|
// returns 0. |
113 |
|
|
inline uint32_t flow_label() const; |
114 |
|
|
|
115 |
|
|
// If the SocketAddress is an IPv6 address, sets the |
116 |
|
|
// current value of the IPv6 flow label. If not an |
117 |
|
|
// IPv6 address, set_flow_label is a non-op. It |
118 |
|
|
// is important to note that the flow label, |
119 |
|
|
// while represented as an uint32_t, the flow |
120 |
|
|
// label is strictly limited to 20 bits, and |
121 |
|
|
// this will assert if any value larger than |
122 |
|
|
// 20-bits is specified. |
123 |
|
|
inline void set_flow_label(uint32_t label = 0); |
124 |
|
|
|
125 |
|
|
inline void Update(uint8_t* data, size_t len); |
126 |
|
|
inline void Update(const sockaddr* data, size_t len); |
127 |
|
|
|
128 |
|
|
static SocketAddress FromSockName(const uv_udp_t& handle); |
129 |
|
|
static SocketAddress FromSockName(const uv_tcp_t& handle); |
130 |
|
|
static SocketAddress FromPeerName(const uv_udp_t& handle); |
131 |
|
|
static SocketAddress FromPeerName(const uv_tcp_t& handle); |
132 |
|
|
|
133 |
|
|
inline v8::Local<v8::Object> ToJS( |
134 |
|
|
Environment* env, |
135 |
|
|
v8::Local<v8::Object> obj = v8::Local<v8::Object>()) const; |
136 |
|
|
|
137 |
|
|
inline std::string ToString() const; |
138 |
|
|
|
139 |
|
|
SET_NO_MEMORY_INFO() |
140 |
|
|
SET_MEMORY_INFO_NAME(SocketAddress) |
141 |
|
|
SET_SELF_SIZE(SocketAddress) |
142 |
|
|
|
143 |
|
|
template <typename T> |
144 |
|
|
using Map = std::unordered_map<SocketAddress, T, Hash>; |
145 |
|
|
|
146 |
|
|
private: |
147 |
|
|
sockaddr_storage address_; |
148 |
|
|
}; |
149 |
|
|
|
150 |
|
|
template <typename T> |
151 |
|
1 |
class SocketAddressLRU : public MemoryRetainer { |
152 |
|
|
public: |
153 |
|
|
using Type = typename T::Type; |
154 |
|
|
|
155 |
|
|
inline explicit SocketAddressLRU(size_t max_size); |
156 |
|
|
|
157 |
|
|
// If the item already exists, returns a reference to |
158 |
|
|
// the existing item, adjusting items position in the |
159 |
|
|
// LRU. If the item does not exist, emplaces the item |
160 |
|
|
// and returns the new item. |
161 |
|
|
Type* Upsert(const SocketAddress& address); |
162 |
|
|
|
163 |
|
|
// Returns a reference to the item if it exists, or |
164 |
|
|
// nullptr. The position in the LRU is not modified. |
165 |
|
|
Type* Peek(const SocketAddress& address) const; |
166 |
|
|
|
167 |
|
3 |
size_t size() const { return map_.size(); } |
168 |
|
|
size_t max_size() const { return max_size_; } |
169 |
|
|
|
170 |
|
|
void MemoryInfo(MemoryTracker* tracker) const override; |
171 |
|
|
SET_MEMORY_INFO_NAME(SocketAddressLRU) |
172 |
|
|
SET_SELF_SIZE(SocketAddressLRU) |
173 |
|
|
|
174 |
|
|
private: |
175 |
|
|
using Pair = std::pair<SocketAddress, Type>; |
176 |
|
|
using Iterator = typename std::list<Pair>::iterator; |
177 |
|
|
|
178 |
|
|
void CheckExpired(); |
179 |
|
|
|
180 |
|
|
std::list<Pair> list_; |
181 |
|
|
SocketAddress::Map<Iterator> map_; |
182 |
|
|
size_t max_size_; |
183 |
|
|
}; |
184 |
|
|
|
185 |
|
|
// A BlockList is used to evaluate whether a given |
186 |
|
|
// SocketAddress should be accepted for inbound or |
187 |
|
|
// outbound network activity. |
188 |
|
|
class SocketAddressBlockList : public MemoryRetainer { |
189 |
|
|
public: |
190 |
|
|
explicit SocketAddressBlockList( |
191 |
|
|
std::shared_ptr<SocketAddressBlockList> parent = {}); |
192 |
|
7 |
~SocketAddressBlockList() = default; |
193 |
|
|
|
194 |
|
|
void AddSocketAddress( |
195 |
|
|
const SocketAddress& address); |
196 |
|
|
|
197 |
|
|
void RemoveSocketAddress( |
198 |
|
|
const SocketAddress& address); |
199 |
|
|
|
200 |
|
|
void AddSocketAddressRange( |
201 |
|
|
const SocketAddress& start, |
202 |
|
|
const SocketAddress& end); |
203 |
|
|
|
204 |
|
|
void AddSocketAddressMask( |
205 |
|
|
const SocketAddress& address, |
206 |
|
|
int prefix); |
207 |
|
|
|
208 |
|
|
bool Apply(const SocketAddress& address); |
209 |
|
|
|
210 |
|
|
size_t size() const { return rules_.size(); } |
211 |
|
|
|
212 |
|
|
v8::MaybeLocal<v8::Array> ListRules(Environment* env); |
213 |
|
|
|
214 |
|
28 |
struct Rule : public MemoryRetainer { |
215 |
|
|
virtual bool Apply(const SocketAddress& address) = 0; |
216 |
|
|
inline v8::MaybeLocal<v8::Value> ToV8String(Environment* env); |
217 |
|
|
virtual std::string ToString() = 0; |
218 |
|
|
}; |
219 |
|
|
|
220 |
|
12 |
struct SocketAddressRule final : Rule { |
221 |
|
|
SocketAddress address; |
222 |
|
|
|
223 |
|
|
explicit SocketAddressRule(const SocketAddress& address); |
224 |
|
|
|
225 |
|
|
bool Apply(const SocketAddress& address) override; |
226 |
|
|
std::string ToString() override; |
227 |
|
|
|
228 |
|
|
void MemoryInfo(node::MemoryTracker* tracker) const override; |
229 |
|
|
SET_MEMORY_INFO_NAME(SocketAddressRule) |
230 |
|
|
SET_SELF_SIZE(SocketAddressRule) |
231 |
|
|
}; |
232 |
|
|
|
233 |
|
6 |
struct SocketAddressRangeRule final : Rule { |
234 |
|
|
SocketAddress start; |
235 |
|
|
SocketAddress end; |
236 |
|
|
|
237 |
|
|
SocketAddressRangeRule( |
238 |
|
|
const SocketAddress& start, |
239 |
|
|
const SocketAddress& end); |
240 |
|
|
|
241 |
|
|
bool Apply(const SocketAddress& address) override; |
242 |
|
|
std::string ToString() override; |
243 |
|
|
|
244 |
|
|
void MemoryInfo(node::MemoryTracker* tracker) const override; |
245 |
|
|
SET_MEMORY_INFO_NAME(SocketAddressRangeRule) |
246 |
|
|
SET_SELF_SIZE(SocketAddressRangeRule) |
247 |
|
|
}; |
248 |
|
|
|
249 |
|
10 |
struct SocketAddressMaskRule final : Rule { |
250 |
|
|
SocketAddress network; |
251 |
|
|
int prefix; |
252 |
|
|
|
253 |
|
|
SocketAddressMaskRule( |
254 |
|
|
const SocketAddress& address, |
255 |
|
|
int prefix); |
256 |
|
|
|
257 |
|
|
bool Apply(const SocketAddress& address) override; |
258 |
|
|
std::string ToString() override; |
259 |
|
|
|
260 |
|
|
void MemoryInfo(node::MemoryTracker* tracker) const override; |
261 |
|
|
SET_MEMORY_INFO_NAME(SocketAddressMaskRule) |
262 |
|
|
SET_SELF_SIZE(SocketAddressMaskRule) |
263 |
|
|
}; |
264 |
|
|
|
265 |
|
|
void MemoryInfo(node::MemoryTracker* tracker) const override; |
266 |
|
|
SET_MEMORY_INFO_NAME(SocketAddressBlockList) |
267 |
|
|
SET_SELF_SIZE(SocketAddressBlockList) |
268 |
|
|
|
269 |
|
|
private: |
270 |
|
|
std::shared_ptr<SocketAddressBlockList> parent_; |
271 |
|
|
std::list<std::unique_ptr<Rule>> rules_; |
272 |
|
|
SocketAddress::Map<std::list<std::unique_ptr<Rule>>::iterator> address_rules_; |
273 |
|
|
}; |
274 |
|
|
|
275 |
|
12 |
class SocketAddressBlockListWrap : |
276 |
|
|
public BaseObject, |
277 |
|
|
public SocketAddressBlockList { |
278 |
|
|
public: |
279 |
|
|
static void Initialize(v8::Local<v8::Object> target, |
280 |
|
|
v8::Local<v8::Value> unused, |
281 |
|
|
v8::Local<v8::Context> context, |
282 |
|
|
void* priv); |
283 |
|
|
|
284 |
|
|
static BaseObjectPtr<SocketAddressBlockListWrap> New(Environment* env); |
285 |
|
|
static void New(const v8::FunctionCallbackInfo<v8::Value>& args); |
286 |
|
|
static void AddAddress(const v8::FunctionCallbackInfo<v8::Value>& args); |
287 |
|
|
static void AddRange(const v8::FunctionCallbackInfo<v8::Value>& args); |
288 |
|
|
static void AddSubnet(const v8::FunctionCallbackInfo<v8::Value>& args); |
289 |
|
|
static void Check(const v8::FunctionCallbackInfo<v8::Value>& args); |
290 |
|
|
static void GetRules(const v8::FunctionCallbackInfo<v8::Value>& args); |
291 |
|
|
|
292 |
|
|
SocketAddressBlockListWrap( |
293 |
|
|
Environment* env, |
294 |
|
|
v8::Local<v8::Object> wrap); |
295 |
|
|
|
296 |
|
|
void MemoryInfo(node::MemoryTracker* tracker) const override { |
297 |
|
|
SocketAddressBlockList::MemoryInfo(tracker); |
298 |
|
|
} |
299 |
|
|
SET_MEMORY_INFO_NAME(SocketAddressBlockListWrap) |
300 |
|
|
SET_SELF_SIZE(SocketAddressBlockListWrap) |
301 |
|
|
}; |
302 |
|
|
|
303 |
|
|
} // namespace node |
304 |
|
|
|
305 |
|
|
#endif // NOE_WANT_INTERNALS |
306 |
|
|
|
307 |
|
|
#endif // SRC_NODE_SOCKADDR_H_ |