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.h Lines: 10 28 35.7 %
Date: 2020-09-03 22:13:26 Branches: 0 0 - %

Line Branch Exec Source
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_