• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 #ifndef SRC_NODE_SOCKADDR_INL_H_
2 #define SRC_NODE_SOCKADDR_INL_H_
3 
4 #if defined(NODE_WANT_INTERNALS) && NODE_WANT_INTERNALS
5 
6 #include "node.h"
7 #include "env-inl.h"
8 #include "node_internals.h"
9 #include "node_sockaddr.h"
10 #include "util-inl.h"
11 #include "memory_tracker-inl.h"
12 
13 #include <string>
14 
15 namespace node {
16 
17 static constexpr uint32_t kLabelMask = 0xFFFFF;
18 
hash_combine(size_t * seed)19 inline void hash_combine(size_t* seed) { }
20 
21 template <typename T, typename... Args>
hash_combine(size_t * seed,const T & value,Args...rest)22 inline void hash_combine(size_t* seed, const T& value, Args... rest) {
23     *seed ^= std::hash<T>{}(value) + 0x9e3779b9 + (*seed << 6) + (*seed >> 2);
24     hash_combine(seed, rest...);
25 }
26 
is_numeric_host(const char * hostname)27 bool SocketAddress::is_numeric_host(const char* hostname) {
28   return is_numeric_host(hostname, AF_INET) ||
29          is_numeric_host(hostname, AF_INET6);
30 }
31 
is_numeric_host(const char * hostname,int family)32 bool SocketAddress::is_numeric_host(const char* hostname, int family) {
33   in6_addr dst;
34   return inet_pton(family, hostname, &dst) == 1;
35 }
36 
GetPort(const sockaddr * addr)37 int SocketAddress::GetPort(const sockaddr* addr) {
38   CHECK(addr->sa_family == AF_INET || addr->sa_family == AF_INET6);
39   return ntohs(addr->sa_family == AF_INET ?
40       reinterpret_cast<const sockaddr_in*>(addr)->sin_port :
41       reinterpret_cast<const sockaddr_in6*>(addr)->sin6_port);
42 }
43 
GetPort(const sockaddr_storage * addr)44 int SocketAddress::GetPort(const sockaddr_storage* addr) {
45   return GetPort(reinterpret_cast<const sockaddr*>(addr));
46 }
47 
GetAddress(const sockaddr * addr)48 std::string SocketAddress::GetAddress(const sockaddr* addr) {
49   CHECK(addr->sa_family == AF_INET || addr->sa_family == AF_INET6);
50   char host[INET6_ADDRSTRLEN];
51   const void* src = addr->sa_family == AF_INET ?
52       static_cast<const void*>(
53           &(reinterpret_cast<const sockaddr_in*>(addr)->sin_addr)) :
54       static_cast<const void*>(
55           &(reinterpret_cast<const sockaddr_in6*>(addr)->sin6_addr));
56   uv_inet_ntop(addr->sa_family, src, host, INET6_ADDRSTRLEN);
57   return std::string(host);
58 }
59 
GetAddress(const sockaddr_storage * addr)60 std::string SocketAddress::GetAddress(const sockaddr_storage* addr) {
61   return GetAddress(reinterpret_cast<const sockaddr*>(addr));
62 }
63 
GetLength(const sockaddr * addr)64 size_t SocketAddress::GetLength(const sockaddr* addr) {
65   return addr->sa_family == AF_INET ?
66       sizeof(sockaddr_in) : sizeof(sockaddr_in6);
67 }
68 
GetLength(const sockaddr_storage * addr)69 size_t SocketAddress::GetLength(const sockaddr_storage* addr) {
70   return GetLength(reinterpret_cast<const sockaddr*>(addr));
71 }
72 
SocketAddress(const sockaddr * addr)73 SocketAddress::SocketAddress(const sockaddr* addr) {
74   memcpy(&address_, addr, GetLength(addr));
75 }
76 
SocketAddress(const SocketAddress & addr)77 SocketAddress::SocketAddress(const SocketAddress& addr) {
78   memcpy(&address_, &addr.address_, addr.length());
79 }
80 
81 SocketAddress& SocketAddress::operator=(const sockaddr* addr) {
82   memcpy(&address_, addr, GetLength(addr));
83   return *this;
84 }
85 
86 SocketAddress& SocketAddress::operator=(const SocketAddress& addr) {
87   memcpy(&address_, &addr.address_, addr.length());
88   return *this;
89 }
90 
91 const sockaddr& SocketAddress::operator*() const {
92   return *data();
93 }
94 
95 const sockaddr* SocketAddress::operator->() const {
96   return data();
97 }
98 
length()99 size_t SocketAddress::length() const {
100   return GetLength(&address_);
101 }
102 
data()103 const sockaddr* SocketAddress::data() const {
104   return reinterpret_cast<const sockaddr*>(&address_);
105 }
106 
raw()107 const uint8_t* SocketAddress::raw() const {
108   return reinterpret_cast<const uint8_t*>(&address_);
109 }
110 
storage()111 sockaddr* SocketAddress::storage() {
112   return reinterpret_cast<sockaddr*>(&address_);
113 }
114 
family()115 int SocketAddress::family() const {
116   return address_.ss_family;
117 }
118 
address()119 std::string SocketAddress::address() const {
120   return GetAddress(&address_);
121 }
122 
port()123 int SocketAddress::port() const {
124   return GetPort(&address_);
125 }
126 
flow_label()127 uint32_t SocketAddress::flow_label() const {
128   if (family() != AF_INET6)
129     return 0;
130   const sockaddr_in6* in = reinterpret_cast<const sockaddr_in6*>(data());
131   return in->sin6_flowinfo;
132 }
133 
set_flow_label(uint32_t label)134 void SocketAddress::set_flow_label(uint32_t label) {
135   if (family() != AF_INET6)
136     return;
137   CHECK_LE(label, kLabelMask);
138   sockaddr_in6* in = reinterpret_cast<sockaddr_in6*>(&address_);
139   in->sin6_flowinfo = label;
140 }
141 
ToString()142 std::string SocketAddress::ToString() const {
143   if (family() != AF_INET && family() != AF_INET6) return "";
144   return (family() == AF_INET6 ?
145               std::string("[") + address() + "]:" :
146               address() + ":") +
147       std::to_string(port());
148 }
149 
Update(uint8_t * data,size_t len)150 void SocketAddress::Update(uint8_t* data, size_t len) {
151   CHECK_LE(len, sizeof(address_));
152   memcpy(&address_, data, len);
153 }
154 
Update(const sockaddr * data,size_t len)155 void SocketAddress::Update(const sockaddr* data, size_t len) {
156   CHECK_LE(len, sizeof(address_));
157   memcpy(&address_, data, len);
158 }
159 
ToJS(Environment * env,v8::Local<v8::Object> info)160 v8::MaybeLocal<v8::Object> SocketAddress::ToJS(
161     Environment* env,
162     v8::Local<v8::Object> info) const {
163   return AddressToJS(env, data(), info);
164 }
165 
166 bool SocketAddress::operator==(const SocketAddress& other) const {
167   if (family() != other.family()) return false;
168   return memcmp(raw(), other.raw(), length()) == 0;
169 }
170 
171 bool SocketAddress::operator!=(const SocketAddress& other) const {
172   return !(*this == other);
173 }
174 
175 bool SocketAddress::operator<(const SocketAddress& other) const {
176   return compare(other) == CompareResult::LESS_THAN;
177 }
178 
179 bool SocketAddress::operator>(const SocketAddress& other) const {
180   return compare(other) == CompareResult::GREATER_THAN;
181 }
182 
183 bool SocketAddress::operator<=(const SocketAddress& other) const {
184   CompareResult c = compare(other);
185   return c == CompareResult::NOT_COMPARABLE ? false :
186               c <= CompareResult::SAME;
187 }
188 
189 bool SocketAddress::operator>=(const SocketAddress& other) const {
190   return compare(other) >= CompareResult::SAME;
191 }
192 
193 template <typename T>
SocketAddressLRU(size_t max_size)194 SocketAddressLRU<T>::SocketAddressLRU(
195     size_t max_size)
196     : max_size_(max_size) {}
197 
198 template <typename T>
Peek(const SocketAddress & address)199 typename T::Type* SocketAddressLRU<T>::Peek(
200     const SocketAddress& address) const {
201   auto it = map_.find(address);
202   return it == std::end(map_) ? nullptr : &it->second->second;
203 }
204 
205 template <typename T>
CheckExpired()206 void SocketAddressLRU<T>::CheckExpired() {
207   auto it = list_.rbegin();
208   while (it != list_.rend()) {
209     if (T::CheckExpired(it->first, it->second)) {
210       map_.erase(it->first);
211       list_.pop_back();
212       it = list_.rbegin();
213       continue;
214     } else {
215       break;
216     }
217   }
218 }
219 
220 template <typename T>
MemoryInfo(MemoryTracker * tracker)221 void SocketAddressLRU<T>::MemoryInfo(MemoryTracker* tracker) const {
222   tracker->TrackFieldWithSize("list", size() * sizeof(Pair));
223 }
224 
225 // If an item already exists for the given address, bump up it's
226 // position in the LRU list and return it. If the item does not
227 // exist, create it. If an item is created, check the size of the
228 // cache and adjust if necessary. Whether the item exists or not,
229 // purge expired items.
230 template <typename T>
Upsert(const SocketAddress & address)231 typename T::Type* SocketAddressLRU<T>::Upsert(
232     const SocketAddress& address) {
233 
234   auto on_exit = OnScopeLeave([&]() { CheckExpired(); });
235 
236   auto it = map_.find(address);
237   if (it != std::end(map_)) {
238     list_.splice(list_.begin(), list_, it->second);
239     T::Touch(it->first, &it->second->second);
240     return &it->second->second;
241   }
242 
243   list_.push_front(Pair(address, { }));
244   map_[address] = list_.begin();
245   T::Touch(list_.begin()->first, &list_.begin()->second);
246 
247   // Drop the last item in the list if we are
248   // over the size limit...
249   if (map_.size() > max_size_) {
250     auto last = list_.end();
251     map_.erase((--last)->first);
252     list_.pop_back();
253   }
254 
255   return &map_[address]->second;
256 }
257 
ToV8String(Environment * env)258 v8::MaybeLocal<v8::Value> SocketAddressBlockList::Rule::ToV8String(
259     Environment* env) {
260   std::string str = ToString();
261   return ToV8Value(env->context(), str);
262 }
263 }  // namespace node
264 
265 #endif  // defined(NODE_WANT_INTERNALS) && NODE_WANT_INTERNALS
266 #endif  // SRC_NODE_SOCKADDR_INL_H_
267