Where Online Learning is simpler!
The C and C++ Include Header Files
cat -n /usr/include/nodejs/src/node_sockaddr.h
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 "node_worker.h" 11 #include "uv.h" 12 #include "v8.h" 13 14 #include <compare> 15 #include <list> 16 #include <memory> 17 #include <string> 18 #include <unordered_map> 19 20 namespace node { 21 22 class Environment; 23 24 class SocketAddress : public MemoryRetainer { 25 public: 26 struct Hash { 27 size_t operator()(const SocketAddress& addr) const; 28 }; 29 30 inline bool operator==(const SocketAddress& other) const; 31 inline bool operator!=(const SocketAddress& other) const; 32 33 inline std::partial_ordering operator<=>(const SocketAddress& other) const; 34 35 inline static bool is_numeric_host(const char* hostname); 36 inline static bool is_numeric_host(const char* hostname, int family); 37 38 // Returns true if converting {family, host, port} to *addr succeeded. 39 static bool ToSockAddr( 40 int32_t family, 41 const char* host, 42 uint32_t port, 43 sockaddr_storage* addr); 44 45 // Returns true if converting {family, host, port} to *addr succeeded. 46 static bool New( 47 int32_t family, 48 const char* host, 49 uint32_t port, 50 SocketAddress* addr); 51 52 static bool New( 53 const char* host, 54 uint32_t port, 55 SocketAddress* addr); 56 57 // Returns the port for an IPv4 or IPv6 address. 58 inline static int GetPort(const sockaddr* addr); 59 inline static int GetPort(const sockaddr_storage* addr); 60 61 // Returns the numeric host as a string for an IPv4 or IPv6 address. 62 inline static std::string GetAddress(const sockaddr* addr); 63 inline static std::string GetAddress(const sockaddr_storage* addr); 64 65 // Returns the struct length for an IPv4, IPv6 or UNIX domain. 66 inline static size_t GetLength(const sockaddr* addr); 67 inline static size_t GetLength(const sockaddr_storage* addr); 68 69 SocketAddress() = default; 70 71 inline explicit SocketAddress(const sockaddr* addr); 72 inline SocketAddress(const SocketAddress& addr); 73 inline SocketAddress& operator=(const sockaddr* other); 74 inline SocketAddress& operator=(const SocketAddress& other); 75 76 inline const sockaddr& operator*() const; 77 inline const sockaddr* operator->() const; 78 79 inline const sockaddr* data() const; 80 inline const uint8_t* raw() const; 81 inline sockaddr* storage(); 82 inline size_t length() const; 83 84 inline int family() const; 85 inline std::string address() const; 86 inline int port() const; 87 88 // Returns true if the given other SocketAddress is a match 89 // for this one. The addresses are a match if: 90 // 1. They are the same family and match identically 91 // 2. They are different family but match semantically ( 92 // for instance, an IPv4 address in IPv6 notation) 93 bool is_match(const SocketAddress& other) const; 94 95 // Compares this SocketAddress to the given other SocketAddress. 96 std::partial_ordering compare(const SocketAddress& other) const; 97 98 // Returns true if this SocketAddress is within the subnet 99 // identified by the given network address and CIDR prefix. 100 bool is_in_network(const SocketAddress& network, int prefix) const; 101 102 // If the SocketAddress is an IPv6 address, returns the 103 // current value of the IPv6 flow label, if set. Otherwise 104 // returns 0. 105 inline uint32_t flow_label() const; 106 107 // If the SocketAddress is an IPv6 address, sets the 108 // current value of the IPv6 flow label. If not an 109 // IPv6 address, set_flow_label is a non-op. It 110 // is important to note that the flow label, 111 // while represented as an uint32_t, the flow 112 // label is strictly limited to 20 bits, and 113 // this will assert if any value larger than 114 // 20-bits is specified. 115 inline void set_flow_label(uint32_t label = 0); 116 117 inline void Update(uint8_t* data, size_t len); 118 inline void Update(const sockaddr* data, size_t len); 119 120 static SocketAddress FromSockName(const uv_udp_t& handle); 121 static SocketAddress FromSockName(const uv_tcp_t& handle); 122 static SocketAddress FromPeerName(const uv_udp_t& handle); 123 static SocketAddress FromPeerName(const uv_tcp_t& handle); 124 125 inline v8::MaybeLocal<v8::Object> ToJS( 126 Environment* env, 127 v8::Local<v8::Object> obj = v8::Local<v8::Object>()) const; 128 129 inline std::string ToString() const; 130 131 SET_NO_MEMORY_INFO() 132 SET_MEMORY_INFO_NAME(SocketAddress) 133 SET_SELF_SIZE(SocketAddress) 134 135 template <typename T> 136 using Map = std::unordered_map<SocketAddress, T, Hash>; 137 138 private: 139 sockaddr_storage address_; 140 }; 141 142 class SocketAddressBase : public BaseObject { 143 public: 144 static bool HasInstance(Environment* env, v8::Local<v8::Value> value); 145 static v8::Local<v8::FunctionTemplate> GetConstructorTemplate( 146 Environment* env); 147 static void Initialize(Environment* env, v8::Local<v8::Object> target); 148 static BaseObjectPtr<SocketAddressBase> Create( 149 Environment* env, 150 std::shared_ptr<SocketAddress> address); 151 152 static void New(const v8::FunctionCallbackInfo<v8::Value>& args); 153 static void Detail(const v8::FunctionCallbackInfo<v8::Value>& args); 154 static void LegacyDetail(const v8::FunctionCallbackInfo<v8::Value>& args); 155 static void GetFlowLabel(const v8::FunctionCallbackInfo<v8::Value>& args); 156 157 SocketAddressBase( 158 Environment* env, 159 v8::Local<v8::Object> wrap, 160 std::shared_ptr<SocketAddress> address); 161 162 inline const std::shared_ptr<SocketAddress>& address() const { 163 return address_; 164 } 165 166 void MemoryInfo(MemoryTracker* tracker) const override; 167 SET_MEMORY_INFO_NAME(SocketAddressBase) 168 SET_SELF_SIZE(SocketAddressBase) 169 170 BaseObject::TransferMode GetTransferMode() const override { 171 return TransferMode::kCloneable; 172 } 173 std::unique_ptr<worker::TransferData> CloneForMessaging() const override; 174 175 class TransferData : public worker::TransferData { 176 public: 177 inline explicit TransferData(const SocketAddressBase* wrap) 178 : address_(wrap->address_) {} 179 180 inline explicit TransferData(std::shared_ptr<SocketAddress> address) 181 : address_(std::move(address)) {} 182 183 BaseObjectPtr<BaseObject> Deserialize( 184 Environment* env, 185 v8::Local<v8::Context> context, 186 std::unique_ptr<worker::TransferData> self) override; 187 188 void MemoryInfo(MemoryTracker* tracker) const override; 189 SET_MEMORY_INFO_NAME(SocketAddressBase::TransferData) 190 SET_SELF_SIZE(TransferData) 191 192 private: 193 std::shared_ptr<SocketAddress> address_; 194 }; 195 196 private: 197 std::shared_ptr<SocketAddress> address_; 198 }; 199 200 template <typename T> 201 class SocketAddressLRU : public MemoryRetainer { 202 public: 203 using Type = typename T::Type; 204 205 inline explicit SocketAddressLRU(size_t max_size); 206 207 // If the item already exists, returns a reference to 208 // the existing item, adjusting items position in the 209 // LRU. If the item does not exist, emplaces the item 210 // and returns the new item. 211 Type* Upsert(const SocketAddress& address); 212 213 // Returns a reference to the item if it exists, or 214 // nullptr. The position in the LRU is not modified. 215 Type* Peek(const SocketAddress& address) const; 216 217 size_t size() const { return map_.size(); } 218 size_t max_size() const { return max_size_; } 219 220 void MemoryInfo(MemoryTracker* tracker) const override; 221 SET_MEMORY_INFO_NAME(SocketAddressLRU) 222 SET_SELF_SIZE(SocketAddressLRU) 223 224 private: 225 using Pair = std::pair<SocketAddress, Type>; 226 using Iterator = typename std::list<Pair>::iterator; 227 228 void CheckExpired(); 229 230 std::list<Pair> list_; 231 SocketAddress::Map<Iterator> map_; 232 size_t max_size_; 233 }; 234 235 // A BlockList is used to evaluate whether a given 236 // SocketAddress should be accepted for inbound or 237 // outbound network activity. 238 class SocketAddressBlockList : public MemoryRetainer { 239 public: 240 explicit SocketAddressBlockList( 241 std::shared_ptr<SocketAddressBlockList> parent = {}); 242 ~SocketAddressBlockList() = default; 243 244 void AddSocketAddress(const std::shared_ptr<SocketAddress>& address); 245 246 void RemoveSocketAddress(const std::shared_ptr<SocketAddress>& address); 247 248 void AddSocketAddressRange( 249 const std::shared_ptr<SocketAddress>& start, 250 const std::shared_ptr<SocketAddress>& end); 251 252 void AddSocketAddressMask( 253 const std::shared_ptr<SocketAddress>& address, 254 int prefix); 255 256 bool Apply(const std::shared_ptr<SocketAddress>& address); 257 258 size_t size() const { return rules_.size(); } 259 260 v8::MaybeLocal<v8::Array> ListRules(Environment* env); 261 262 struct Rule : public MemoryRetainer { 263 virtual bool Apply(const std::shared_ptr<SocketAddress>& address) = 0; 264 inline v8::MaybeLocal<v8::Value> ToV8String(Environment* env); 265 virtual std::string ToString() = 0; 266 }; 267 268 struct SocketAddressRule final : Rule { 269 std::shared_ptr<SocketAddress> address; 270 271 explicit SocketAddressRule(const std::shared_ptr<SocketAddress>& address); 272 273 bool Apply(const std::shared_ptr<SocketAddress>& address) override; 274 std::string ToString() override; 275 276 void MemoryInfo(node::MemoryTracker* tracker) const override; 277 SET_MEMORY_INFO_NAME(SocketAddressRule) 278 SET_SELF_SIZE(SocketAddressRule) 279 }; 280 281 struct SocketAddressRangeRule final : Rule { 282 std::shared_ptr<SocketAddress> start; 283 std::shared_ptr<SocketAddress> end; 284 285 SocketAddressRangeRule( 286 const std::shared_ptr<SocketAddress>& start, 287 const std::shared_ptr<SocketAddress>& end); 288 289 bool Apply(const std::shared_ptr<SocketAddress>& address) override; 290 std::string ToString() override; 291 292 void MemoryInfo(node::MemoryTracker* tracker) const override; 293 SET_MEMORY_INFO_NAME(SocketAddressRangeRule) 294 SET_SELF_SIZE(SocketAddressRangeRule) 295 }; 296 297 struct SocketAddressMaskRule final : Rule { 298 std::shared_ptr<SocketAddress> network; 299 int prefix; 300 301 SocketAddressMaskRule( 302 const std::shared_ptr<SocketAddress>& address, 303 int prefix); 304 305 bool Apply(const std::shared_ptr<SocketAddress>& address) override; 306 std::string ToString() override; 307 308 void MemoryInfo(node::MemoryTracker* tracker) const override; 309 SET_MEMORY_INFO_NAME(SocketAddressMaskRule) 310 SET_SELF_SIZE(SocketAddressMaskRule) 311 }; 312 313 void MemoryInfo(node::MemoryTracker* tracker) const override; 314 SET_MEMORY_INFO_NAME(SocketAddressBlockList) 315 SET_SELF_SIZE(SocketAddressBlockList) 316 317 private: 318 bool ListRules(Environment* env, v8::LocalVector<v8::Value>* vec); 319 320 std::shared_ptr<SocketAddressBlockList> parent_; 321 std::list<std::unique_ptr<Rule>> rules_; 322 SocketAddress::Map<std::list<std::unique_ptr<Rule>>::iterator> address_rules_; 323 324 Mutex mutex_; 325 }; 326 327 class SocketAddressBlockListWrap : public BaseObject { 328 public: 329 static bool HasInstance(Environment* env, v8::Local<v8::Value> value); 330 static v8::Local<v8::FunctionTemplate> GetConstructorTemplate( 331 Environment* env); 332 static void Initialize(v8::Local<v8::Object> target, 333 v8::Local<v8::Value> unused, 334 v8::Local<v8::Context> context, 335 void* priv); 336 337 static BaseObjectPtr<SocketAddressBlockListWrap> New(Environment* env); 338 static BaseObjectPtr<SocketAddressBlockListWrap> New( 339 Environment* env, 340 std::shared_ptr<SocketAddressBlockList> blocklist); 341 342 static void New(const v8::FunctionCallbackInfo<v8::Value>& args); 343 static void AddAddress(const v8::FunctionCallbackInfo<v8::Value>& args); 344 static void AddRange(const v8::FunctionCallbackInfo<v8::Value>& args); 345 static void AddSubnet(const v8::FunctionCallbackInfo<v8::Value>& args); 346 static void Check(const v8::FunctionCallbackInfo<v8::Value>& args); 347 static void GetRules(const v8::FunctionCallbackInfo<v8::Value>& args); 348 349 SocketAddressBlockListWrap( 350 Environment* env, 351 v8::Local<v8::Object> wrap, 352 std::shared_ptr<SocketAddressBlockList> blocklist = 353 std::make_shared<SocketAddressBlockList>()); 354 355 void MemoryInfo(node::MemoryTracker* tracker) const override; 356 SET_MEMORY_INFO_NAME(SocketAddressBlockListWrap) 357 SET_SELF_SIZE(SocketAddressBlockListWrap) 358 359 BaseObject::TransferMode GetTransferMode() const override { 360 return TransferMode::kCloneable; 361 } 362 std::unique_ptr<worker::TransferData> CloneForMessaging() const override; 363 364 class TransferData : public worker::TransferData { 365 public: 366 inline explicit TransferData(const SocketAddressBlockListWrap* wrap) 367 : blocklist_(wrap->blocklist_) {} 368 369 inline explicit TransferData( 370 std::shared_ptr<SocketAddressBlockList> blocklist) 371 : blocklist_(std::move(blocklist)) {} 372 373 BaseObjectPtr<BaseObject> Deserialize( 374 Environment* env, 375 v8::Local<v8::Context> context, 376 std::unique_ptr<worker::TransferData> self) override; 377 378 void MemoryInfo(MemoryTracker* tracker) const override; 379 SET_MEMORY_INFO_NAME(SocketAddressBlockListWrap::TransferData) 380 SET_SELF_SIZE(TransferData) 381 382 private: 383 std::shared_ptr<SocketAddressBlockList> blocklist_; 384 }; 385 386 private: 387 std::shared_ptr<SocketAddressBlockList> blocklist_; 388 }; 389 390 } // namespace node 391 392 #endif // defined(NODE_WANT_INTERNALS) && NODE_WANT_INTERNALS 393 394 #endif // SRC_NODE_SOCKADDR_H_