GCC Code Coverage Report
Directory: ../ Exec Total Coverage
File: /home/iojs/build/workspace/node-test-commit-linux-coverage-daily/nodes/benchmark/out/../src/node_sockaddr-inl.h Lines: 111 115 96.5 %
Date: 2020-08-17 22:13:26 Branches: 35 42 83.3 %

Line Branch Exec Source
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
19
37
inline void hash_combine(size_t* seed) { }
20
21
template <typename T, typename... Args>
22
76
inline void hash_combine(size_t* seed, const T& value, Args... rest) {
23
76
    *seed ^= std::hash<T>{}(value) + 0x9e3779b9 + (*seed << 6) + (*seed >> 2);
24
76
    hash_combine(seed, rest...);
25
76
}
26
27
2
bool SocketAddress::is_numeric_host(const char* hostname) {
28

3
  return is_numeric_host(hostname, AF_INET) ||
29
3
         is_numeric_host(hostname, AF_INET6);
30
}
31
32
3
bool SocketAddress::is_numeric_host(const char* hostname, int family) {
33
  in6_addr dst;
34
3
  return inet_pton(family, hostname, &dst) == 1;
35
}
36
37
3
int SocketAddress::GetPort(const sockaddr* addr) {
38

3
  CHECK(addr->sa_family == AF_INET || addr->sa_family == AF_INET6);
39
6
  return ntohs(addr->sa_family == AF_INET ?
40
2
      reinterpret_cast<const sockaddr_in*>(addr)->sin_port :
41
4
      reinterpret_cast<const sockaddr_in6*>(addr)->sin6_port);
42
}
43
44
3
int SocketAddress::GetPort(const sockaddr_storage* addr) {
45
3
  return GetPort(reinterpret_cast<const sockaddr*>(addr));
46
}
47
48
11
std::string SocketAddress::GetAddress(const sockaddr* addr) {
49

11
  CHECK(addr->sa_family == AF_INET || addr->sa_family == AF_INET6);
50
  char host[INET6_ADDRSTRLEN];
51
11
  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
11
          &(reinterpret_cast<const sockaddr_in6*>(addr)->sin6_addr));
56
11
  uv_inet_ntop(addr->sa_family, src, host, INET6_ADDRSTRLEN);
57
11
  return std::string(host);
58
}
59
60
11
std::string SocketAddress::GetAddress(const sockaddr_storage* addr) {
61
11
  return GetAddress(reinterpret_cast<const sockaddr*>(addr));
62
}
63
64
171
size_t SocketAddress::GetLength(const sockaddr* addr) {
65
171
  return addr->sa_family == AF_INET ?
66
171
      sizeof(sockaddr_in) : sizeof(sockaddr_in6);
67
}
68
69
56
size_t SocketAddress::GetLength(const sockaddr_storage* addr) {
70
56
  return GetLength(reinterpret_cast<const sockaddr*>(addr));
71
}
72
73
115
SocketAddress::SocketAddress(const sockaddr* addr) {
74
115
  memcpy(&address_, addr, GetLength(addr));
75
115
}
76
77
33
SocketAddress::SocketAddress(const SocketAddress& addr) {
78
33
  memcpy(&address_, &addr.address_, addr.length());
79
33
}
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
99
56
size_t SocketAddress::length() const {
100
56
  return GetLength(&address_);
101
}
102
103
471
const sockaddr* SocketAddress::data() const {
104
471
  return reinterpret_cast<const sockaddr*>(&address_);
105
}
106
107
77
const uint8_t* SocketAddress::raw() const {
108
77
  return reinterpret_cast<const uint8_t*>(&address_);
109
}
110
111
sockaddr* SocketAddress::storage() {
112
  return reinterpret_cast<sockaddr*>(&address_);
113
}
114
115
560
int SocketAddress::family() const {
116
560
  return address_.ss_family;
117
}
118
119
11
std::string SocketAddress::address() const {
120
11
  return GetAddress(&address_);
121
}
122
123
3
int SocketAddress::port() const {
124
3
  return GetPort(&address_);
125
}
126
127
2
uint32_t SocketAddress::flow_label() const {
128
2
  if (family() != AF_INET6)
129
1
    return 0;
130
1
  const sockaddr_in6* in = reinterpret_cast<const sockaddr_in6*>(data());
131
1
  return in->sin6_flowinfo;
132
}
133
134
2
void SocketAddress::set_flow_label(uint32_t label) {
135
2
  if (family() != AF_INET6)
136
1
    return;
137
1
  CHECK_LE(label, kLabelMask);
138
1
  sockaddr_in6* in = reinterpret_cast<sockaddr_in6*>(&address_);
139
1
  in->sin6_flowinfo = label;
140
}
141
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
150
1
void SocketAddress::Update(uint8_t* data, size_t len) {
151
1
  CHECK_LE(len, sizeof(address_));
152
1
  memcpy(&address_, data, len);
153
1
}
154
155
v8::Local<v8::Object> SocketAddress::ToJS(
156
    Environment* env,
157
    v8::Local<v8::Object> info) const {
158
  return AddressToJS(env, data(), info);
159
}
160
161
20
bool SocketAddress::operator==(const SocketAddress& other) const {
162
20
  if (family() != other.family()) return false;
163
20
  return memcmp(raw(), other.raw(), length()) == 0;
164
}
165
166
1
bool SocketAddress::operator!=(const SocketAddress& other) const {
167
1
  return !(*this == other);
168
}
169
170
5
bool SocketAddress::operator<(const SocketAddress& other) const {
171
5
  return compare(other) == CompareResult::LESS_THAN;
172
}
173
174
8
bool SocketAddress::operator>(const SocketAddress& other) const {
175
8
  return compare(other) == CompareResult::GREATER_THAN;
176
}
177
178
40
bool SocketAddress::operator<=(const SocketAddress& other) const {
179
40
  CompareResult c = compare(other);
180

40
  return c == CompareResult::NOT_COMPARABLE ? false :
181
40
              c <= CompareResult::SAME;
182
}
183
184
58
bool SocketAddress::operator>=(const SocketAddress& other) const {
185
58
  return compare(other) >= CompareResult::SAME;
186
}
187
188
template <typename T>
189
1
SocketAddressLRU<T>::SocketAddressLRU(
190
    size_t max_size)
191
1
    : max_size_(max_size) {}
192
193
template <typename T>
194
11
typename T::Type* SocketAddressLRU<T>::Peek(
195
    const SocketAddress& address) const {
196
11
  auto it = map_.find(address);
197
11
  return it == std::end(map_) ? nullptr : &it->second->second;
198
}
199
200
template <typename T>
201
4
void SocketAddressLRU<T>::CheckExpired() {
202
4
  auto it = list_.rbegin();
203
6
  while (it != list_.rend()) {
204
5
    if (T::CheckExpired(it->first, it->second)) {
205
1
      map_.erase(it->first);
206
1
      list_.pop_back();
207
1
      it = list_.rbegin();
208
1
      continue;
209
    } else {
210
4
      break;
211
    }
212
  }
213
4
}
214
215
template <typename T>
216
void SocketAddressLRU<T>::MemoryInfo(MemoryTracker* tracker) const {
217
  tracker->TrackFieldWithSize("list", size() * sizeof(Pair));
218
}
219
220
// If an item already exists for the given address, bump up it's
221
// position in the LRU list and return it. If the item does not
222
// exist, create it. If an item is created, check the size of the
223
// cache and adjust if necessary. Whether the item exists or not,
224
// purge expired items.
225
template <typename T>
226
4
typename T::Type* SocketAddressLRU<T>::Upsert(
227
    const SocketAddress& address) {
228
229
12
  auto on_exit = OnScopeLeave([&]() { CheckExpired(); });
230
231
4
  auto it = map_.find(address);
232
4
  if (it != std::end(map_)) {
233
1
    list_.splice(list_.begin(), list_, it->second);
234
1
    T::Touch(it->first, &it->second->second);
235
1
    return &it->second->second;
236
  }
237
238
3
  list_.push_front(Pair(address, { }));
239
3
  map_[address] = list_.begin();
240
3
  T::Touch(list_.begin()->first, &list_.begin()->second);
241
242
  // Drop the last item in the list if we are
243
  // over the size limit...
244
3
  if (map_.size() > max_size_) {
245
1
    auto last = list_.end();
246
1
    map_.erase((--last)->first);
247
1
    list_.pop_back();
248
  }
249
250
3
  return &map_[address]->second;
251
}
252
253
6
v8::MaybeLocal<v8::Value> SocketAddressBlockList::Rule::ToV8String(
254
    Environment* env) {
255
12
  std::string str = ToString();
256
12
  return ToV8Value(env->context(), str);
257
}
258
}  // namespace node
259
260
#endif  // NODE_WANT_INTERNALS
261
#endif  // SRC_NODE_SOCKADDR_INL_H_