• 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 "node_internals.h"
8 #include "node_sockaddr.h"
9 #include "util-inl.h"
10 
11 #include <string>
12 
13 namespace node {
14 
15 static constexpr uint32_t kLabelMask = 0xFFFFF;
16 
hash_combine(size_t * seed)17 inline void hash_combine(size_t* seed) { }
18 
19 template <typename T, typename... Args>
hash_combine(size_t * seed,const T & value,Args...rest)20 inline void hash_combine(size_t* seed, const T& value, Args... rest) {
21     *seed ^= std::hash<T>{}(value) + 0x9e3779b9 + (*seed << 6) + (*seed >> 2);
22     hash_combine(seed, rest...);
23 }
24 
is_numeric_host(const char * hostname)25 bool SocketAddress::is_numeric_host(const char* hostname) {
26   return is_numeric_host(hostname, AF_INET) ||
27          is_numeric_host(hostname, AF_INET6);
28 }
29 
is_numeric_host(const char * hostname,int family)30 bool SocketAddress::is_numeric_host(const char* hostname, int family) {
31   in6_addr dst;
32   return inet_pton(family, hostname, &dst) == 1;
33 }
34 
GetPort(const sockaddr * addr)35 int SocketAddress::GetPort(const sockaddr* addr) {
36   CHECK(addr->sa_family == AF_INET || addr->sa_family == AF_INET6);
37   return ntohs(addr->sa_family == AF_INET ?
38       reinterpret_cast<const sockaddr_in*>(addr)->sin_port :
39       reinterpret_cast<const sockaddr_in6*>(addr)->sin6_port);
40 }
41 
GetPort(const sockaddr_storage * addr)42 int SocketAddress::GetPort(const sockaddr_storage* addr) {
43   return GetPort(reinterpret_cast<const sockaddr*>(addr));
44 }
45 
GetAddress(const sockaddr * addr)46 std::string SocketAddress::GetAddress(const sockaddr* addr) {
47   CHECK(addr->sa_family == AF_INET || addr->sa_family == AF_INET6);
48   char host[INET6_ADDRSTRLEN];
49   const void* src = addr->sa_family == AF_INET ?
50       static_cast<const void*>(
51           &(reinterpret_cast<const sockaddr_in*>(addr)->sin_addr)) :
52       static_cast<const void*>(
53           &(reinterpret_cast<const sockaddr_in6*>(addr)->sin6_addr));
54   uv_inet_ntop(addr->sa_family, src, host, INET6_ADDRSTRLEN);
55   return std::string(host);
56 }
57 
GetAddress(const sockaddr_storage * addr)58 std::string SocketAddress::GetAddress(const sockaddr_storage* addr) {
59   return GetAddress(reinterpret_cast<const sockaddr*>(addr));
60 }
61 
GetLength(const sockaddr * addr)62 size_t SocketAddress::GetLength(const sockaddr* addr) {
63   return addr->sa_family == AF_INET ?
64       sizeof(sockaddr_in) : sizeof(sockaddr_in6);
65 }
66 
GetLength(const sockaddr_storage * addr)67 size_t SocketAddress::GetLength(const sockaddr_storage* addr) {
68   return GetLength(reinterpret_cast<const sockaddr*>(addr));
69 }
70 
SocketAddress(const sockaddr * addr)71 SocketAddress::SocketAddress(const sockaddr* addr) {
72   memcpy(&address_, addr, GetLength(addr));
73 }
74 
SocketAddress(const SocketAddress & addr)75 SocketAddress::SocketAddress(const SocketAddress& addr) {
76   memcpy(&address_, &addr.address_, addr.length());
77 }
78 
79 SocketAddress& SocketAddress::operator=(const sockaddr* addr) {
80   memcpy(&address_, addr, GetLength(addr));
81   return *this;
82 }
83 
84 SocketAddress& SocketAddress::operator=(const SocketAddress& addr) {
85   memcpy(&address_, &addr.address_, addr.length());
86   return *this;
87 }
88 
89 const sockaddr& SocketAddress::operator*() const {
90   return *this->data();
91 }
92 
93 const sockaddr* SocketAddress::operator->() const {
94   return this->data();
95 }
96 
length()97 size_t SocketAddress::length() const {
98   return GetLength(&address_);
99 }
100 
data()101 const sockaddr* SocketAddress::data() const {
102   return reinterpret_cast<const sockaddr*>(&address_);
103 }
104 
raw()105 const uint8_t* SocketAddress::raw() const {
106   return reinterpret_cast<const uint8_t*>(&address_);
107 }
108 
storage()109 sockaddr* SocketAddress::storage() {
110   return reinterpret_cast<sockaddr*>(&address_);
111 }
112 
family()113 int SocketAddress::family() const {
114   return address_.ss_family;
115 }
116 
address()117 std::string SocketAddress::address() const {
118   return GetAddress(&address_);
119 }
120 
port()121 int SocketAddress::port() const {
122   return GetPort(&address_);
123 }
124 
flow_label()125 uint32_t SocketAddress::flow_label() const {
126   if (family() != AF_INET6)
127     return 0;
128   const sockaddr_in6* in = reinterpret_cast<const sockaddr_in6*>(data());
129   return in->sin6_flowinfo;
130 }
131 
set_flow_label(uint32_t label)132 void SocketAddress::set_flow_label(uint32_t label) {
133   if (family() != AF_INET6)
134     return;
135   CHECK_LE(label, kLabelMask);
136   sockaddr_in6* in = reinterpret_cast<sockaddr_in6*>(&address_);
137   in->sin6_flowinfo = label;
138 }
139 
ToString()140 std::string SocketAddress::ToString() const {
141   if (family() != AF_INET && family() != AF_INET6) return "";
142   return (family() == AF_INET6 ?
143               std::string("[") + address() + "]:" :
144               address() + ":") +
145       std::to_string(port());
146 }
147 
Update(uint8_t * data,size_t len)148 void SocketAddress::Update(uint8_t* data, size_t len) {
149   CHECK_LE(len, sizeof(address_));
150   memcpy(&address_, data, len);
151 }
152 
ToJS(Environment * env,v8::Local<v8::Object> info)153 v8::Local<v8::Object> SocketAddress::ToJS(
154     Environment* env,
155     v8::Local<v8::Object> info) const {
156   return AddressToJS(env, data(), info);
157 }
158 
159 bool SocketAddress::operator==(const SocketAddress& other) const {
160   if (family() != other.family()) return false;
161   return memcmp(raw(), other.raw(), length()) == 0;
162 }
163 
164 bool SocketAddress::operator!=(const SocketAddress& other) const {
165   return !(*this == other);
166 }
167 }  // namespace node
168 
169 #endif  // NODE_WANT_INTERNALS
170 #endif  // SRC_NODE_SOCKADDR_INL_H_
171