11cb0ef41Sopenharmony_ci#include "node_sockaddr-inl.h" // NOLINT(build/include) 21cb0ef41Sopenharmony_ci#include "env-inl.h" 31cb0ef41Sopenharmony_ci#include "base64-inl.h" 41cb0ef41Sopenharmony_ci#include "base_object-inl.h" 51cb0ef41Sopenharmony_ci#include "memory_tracker-inl.h" 61cb0ef41Sopenharmony_ci#include "node_errors.h" 71cb0ef41Sopenharmony_ci#include "uv.h" 81cb0ef41Sopenharmony_ci 91cb0ef41Sopenharmony_ci#include <memory> 101cb0ef41Sopenharmony_ci#include <string> 111cb0ef41Sopenharmony_ci#include <vector> 121cb0ef41Sopenharmony_ci 131cb0ef41Sopenharmony_cinamespace node { 141cb0ef41Sopenharmony_ci 151cb0ef41Sopenharmony_ciusing v8::Array; 161cb0ef41Sopenharmony_ciusing v8::Context; 171cb0ef41Sopenharmony_ciusing v8::FunctionCallbackInfo; 181cb0ef41Sopenharmony_ciusing v8::FunctionTemplate; 191cb0ef41Sopenharmony_ciusing v8::Int32; 201cb0ef41Sopenharmony_ciusing v8::Isolate; 211cb0ef41Sopenharmony_ciusing v8::Local; 221cb0ef41Sopenharmony_ciusing v8::MaybeLocal; 231cb0ef41Sopenharmony_ciusing v8::Object; 241cb0ef41Sopenharmony_ciusing v8::Uint32; 251cb0ef41Sopenharmony_ciusing v8::Value; 261cb0ef41Sopenharmony_ci 271cb0ef41Sopenharmony_cinamespace { 281cb0ef41Sopenharmony_citemplate <typename T, typename F> 291cb0ef41Sopenharmony_ciSocketAddress FromUVHandle(F fn, const T& handle) { 301cb0ef41Sopenharmony_ci SocketAddress addr; 311cb0ef41Sopenharmony_ci int len = sizeof(sockaddr_storage); 321cb0ef41Sopenharmony_ci if (fn(&handle, addr.storage(), &len) == 0) 331cb0ef41Sopenharmony_ci CHECK_EQ(static_cast<size_t>(len), addr.length()); 341cb0ef41Sopenharmony_ci else 351cb0ef41Sopenharmony_ci addr.storage()->sa_family = 0; 361cb0ef41Sopenharmony_ci return addr; 371cb0ef41Sopenharmony_ci} 381cb0ef41Sopenharmony_ci} // namespace 391cb0ef41Sopenharmony_ci 401cb0ef41Sopenharmony_cibool SocketAddress::ToSockAddr( 411cb0ef41Sopenharmony_ci int32_t family, 421cb0ef41Sopenharmony_ci const char* host, 431cb0ef41Sopenharmony_ci uint32_t port, 441cb0ef41Sopenharmony_ci sockaddr_storage* addr) { 451cb0ef41Sopenharmony_ci switch (family) { 461cb0ef41Sopenharmony_ci case AF_INET: 471cb0ef41Sopenharmony_ci return uv_ip4_addr( 481cb0ef41Sopenharmony_ci host, 491cb0ef41Sopenharmony_ci port, 501cb0ef41Sopenharmony_ci reinterpret_cast<sockaddr_in*>(addr)) == 0; 511cb0ef41Sopenharmony_ci case AF_INET6: 521cb0ef41Sopenharmony_ci return uv_ip6_addr( 531cb0ef41Sopenharmony_ci host, 541cb0ef41Sopenharmony_ci port, 551cb0ef41Sopenharmony_ci reinterpret_cast<sockaddr_in6*>(addr)) == 0; 561cb0ef41Sopenharmony_ci default: 571cb0ef41Sopenharmony_ci UNREACHABLE(); 581cb0ef41Sopenharmony_ci } 591cb0ef41Sopenharmony_ci} 601cb0ef41Sopenharmony_ci 611cb0ef41Sopenharmony_cibool SocketAddress::New( 621cb0ef41Sopenharmony_ci const char* host, 631cb0ef41Sopenharmony_ci uint32_t port, 641cb0ef41Sopenharmony_ci SocketAddress* addr) { 651cb0ef41Sopenharmony_ci return New(AF_INET, host, port, addr) || New(AF_INET6, host, port, addr); 661cb0ef41Sopenharmony_ci} 671cb0ef41Sopenharmony_ci 681cb0ef41Sopenharmony_cibool SocketAddress::New( 691cb0ef41Sopenharmony_ci int32_t family, 701cb0ef41Sopenharmony_ci const char* host, 711cb0ef41Sopenharmony_ci uint32_t port, 721cb0ef41Sopenharmony_ci SocketAddress* addr) { 731cb0ef41Sopenharmony_ci return ToSockAddr(family, host, port, 741cb0ef41Sopenharmony_ci reinterpret_cast<sockaddr_storage*>(addr->storage())); 751cb0ef41Sopenharmony_ci} 761cb0ef41Sopenharmony_ci 771cb0ef41Sopenharmony_cisize_t SocketAddress::Hash::operator()(const SocketAddress& addr) const { 781cb0ef41Sopenharmony_ci size_t hash = 0; 791cb0ef41Sopenharmony_ci switch (addr.family()) { 801cb0ef41Sopenharmony_ci case AF_INET: { 811cb0ef41Sopenharmony_ci const sockaddr_in* ipv4 = 821cb0ef41Sopenharmony_ci reinterpret_cast<const sockaddr_in*>(addr.raw()); 831cb0ef41Sopenharmony_ci hash_combine(&hash, ipv4->sin_port, ipv4->sin_addr.s_addr); 841cb0ef41Sopenharmony_ci break; 851cb0ef41Sopenharmony_ci } 861cb0ef41Sopenharmony_ci case AF_INET6: { 871cb0ef41Sopenharmony_ci const sockaddr_in6* ipv6 = 881cb0ef41Sopenharmony_ci reinterpret_cast<const sockaddr_in6*>(addr.raw()); 891cb0ef41Sopenharmony_ci const uint64_t* a = 901cb0ef41Sopenharmony_ci reinterpret_cast<const uint64_t*>(&ipv6->sin6_addr); 911cb0ef41Sopenharmony_ci hash_combine(&hash, ipv6->sin6_port, a[0], a[1]); 921cb0ef41Sopenharmony_ci break; 931cb0ef41Sopenharmony_ci } 941cb0ef41Sopenharmony_ci default: 951cb0ef41Sopenharmony_ci UNREACHABLE(); 961cb0ef41Sopenharmony_ci } 971cb0ef41Sopenharmony_ci return hash; 981cb0ef41Sopenharmony_ci} 991cb0ef41Sopenharmony_ci 1001cb0ef41Sopenharmony_ciSocketAddress SocketAddress::FromSockName(const uv_tcp_t& handle) { 1011cb0ef41Sopenharmony_ci return FromUVHandle(uv_tcp_getsockname, handle); 1021cb0ef41Sopenharmony_ci} 1031cb0ef41Sopenharmony_ci 1041cb0ef41Sopenharmony_ciSocketAddress SocketAddress::FromSockName(const uv_udp_t& handle) { 1051cb0ef41Sopenharmony_ci return FromUVHandle(uv_udp_getsockname, handle); 1061cb0ef41Sopenharmony_ci} 1071cb0ef41Sopenharmony_ci 1081cb0ef41Sopenharmony_ciSocketAddress SocketAddress::FromPeerName(const uv_tcp_t& handle) { 1091cb0ef41Sopenharmony_ci return FromUVHandle(uv_tcp_getpeername, handle); 1101cb0ef41Sopenharmony_ci} 1111cb0ef41Sopenharmony_ci 1121cb0ef41Sopenharmony_ciSocketAddress SocketAddress::FromPeerName(const uv_udp_t& handle) { 1131cb0ef41Sopenharmony_ci return FromUVHandle(uv_udp_getpeername, handle); 1141cb0ef41Sopenharmony_ci} 1151cb0ef41Sopenharmony_ci 1161cb0ef41Sopenharmony_cinamespace { 1171cb0ef41Sopenharmony_ciconstexpr uint8_t mask[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xff, 0xff }; 1181cb0ef41Sopenharmony_ci 1191cb0ef41Sopenharmony_cibool is_match_ipv4( 1201cb0ef41Sopenharmony_ci const SocketAddress& one, 1211cb0ef41Sopenharmony_ci const SocketAddress& two) { 1221cb0ef41Sopenharmony_ci const sockaddr_in* one_in = 1231cb0ef41Sopenharmony_ci reinterpret_cast<const sockaddr_in*>(one.data()); 1241cb0ef41Sopenharmony_ci const sockaddr_in* two_in = 1251cb0ef41Sopenharmony_ci reinterpret_cast<const sockaddr_in*>(two.data()); 1261cb0ef41Sopenharmony_ci return memcmp(&one_in->sin_addr, &two_in->sin_addr, sizeof(uint32_t)) == 0; 1271cb0ef41Sopenharmony_ci} 1281cb0ef41Sopenharmony_ci 1291cb0ef41Sopenharmony_cibool is_match_ipv6( 1301cb0ef41Sopenharmony_ci const SocketAddress& one, 1311cb0ef41Sopenharmony_ci const SocketAddress& two) { 1321cb0ef41Sopenharmony_ci const sockaddr_in6* one_in = 1331cb0ef41Sopenharmony_ci reinterpret_cast<const sockaddr_in6*>(one.data()); 1341cb0ef41Sopenharmony_ci const sockaddr_in6* two_in = 1351cb0ef41Sopenharmony_ci reinterpret_cast<const sockaddr_in6*>(two.data()); 1361cb0ef41Sopenharmony_ci return memcmp(&one_in->sin6_addr, &two_in->sin6_addr, 16) == 0; 1371cb0ef41Sopenharmony_ci} 1381cb0ef41Sopenharmony_ci 1391cb0ef41Sopenharmony_cibool is_match_ipv4_ipv6( 1401cb0ef41Sopenharmony_ci const SocketAddress& ipv4, 1411cb0ef41Sopenharmony_ci const SocketAddress& ipv6) { 1421cb0ef41Sopenharmony_ci const sockaddr_in* check_ipv4 = 1431cb0ef41Sopenharmony_ci reinterpret_cast<const sockaddr_in*>(ipv4.data()); 1441cb0ef41Sopenharmony_ci const sockaddr_in6* check_ipv6 = 1451cb0ef41Sopenharmony_ci reinterpret_cast<const sockaddr_in6*>(ipv6.data()); 1461cb0ef41Sopenharmony_ci 1471cb0ef41Sopenharmony_ci const uint8_t* ptr = 1481cb0ef41Sopenharmony_ci reinterpret_cast<const uint8_t*>(&check_ipv6->sin6_addr); 1491cb0ef41Sopenharmony_ci 1501cb0ef41Sopenharmony_ci return memcmp(ptr, mask, sizeof(mask)) == 0 && 1511cb0ef41Sopenharmony_ci memcmp(ptr + sizeof(mask), 1521cb0ef41Sopenharmony_ci &check_ipv4->sin_addr, 1531cb0ef41Sopenharmony_ci sizeof(uint32_t)) == 0; 1541cb0ef41Sopenharmony_ci} 1551cb0ef41Sopenharmony_ci 1561cb0ef41Sopenharmony_ciSocketAddress::CompareResult compare_ipv4( 1571cb0ef41Sopenharmony_ci const SocketAddress& one, 1581cb0ef41Sopenharmony_ci const SocketAddress& two) { 1591cb0ef41Sopenharmony_ci const sockaddr_in* one_in = 1601cb0ef41Sopenharmony_ci reinterpret_cast<const sockaddr_in*>(one.data()); 1611cb0ef41Sopenharmony_ci const sockaddr_in* two_in = 1621cb0ef41Sopenharmony_ci reinterpret_cast<const sockaddr_in*>(two.data()); 1631cb0ef41Sopenharmony_ci const uint32_t s_addr_one = ntohl(one_in->sin_addr.s_addr); 1641cb0ef41Sopenharmony_ci const uint32_t s_addr_two = ntohl(two_in->sin_addr.s_addr); 1651cb0ef41Sopenharmony_ci 1661cb0ef41Sopenharmony_ci if (s_addr_one < s_addr_two) 1671cb0ef41Sopenharmony_ci return SocketAddress::CompareResult::LESS_THAN; 1681cb0ef41Sopenharmony_ci else if (s_addr_one == s_addr_two) 1691cb0ef41Sopenharmony_ci return SocketAddress::CompareResult::SAME; 1701cb0ef41Sopenharmony_ci else 1711cb0ef41Sopenharmony_ci return SocketAddress::CompareResult::GREATER_THAN; 1721cb0ef41Sopenharmony_ci} 1731cb0ef41Sopenharmony_ci 1741cb0ef41Sopenharmony_ciSocketAddress::CompareResult compare_ipv6( 1751cb0ef41Sopenharmony_ci const SocketAddress& one, 1761cb0ef41Sopenharmony_ci const SocketAddress& two) { 1771cb0ef41Sopenharmony_ci const sockaddr_in6* one_in = 1781cb0ef41Sopenharmony_ci reinterpret_cast<const sockaddr_in6*>(one.data()); 1791cb0ef41Sopenharmony_ci const sockaddr_in6* two_in = 1801cb0ef41Sopenharmony_ci reinterpret_cast<const sockaddr_in6*>(two.data()); 1811cb0ef41Sopenharmony_ci int ret = memcmp(&one_in->sin6_addr, &two_in->sin6_addr, 16); 1821cb0ef41Sopenharmony_ci if (ret < 0) 1831cb0ef41Sopenharmony_ci return SocketAddress::CompareResult::LESS_THAN; 1841cb0ef41Sopenharmony_ci else if (ret > 0) 1851cb0ef41Sopenharmony_ci return SocketAddress::CompareResult::GREATER_THAN; 1861cb0ef41Sopenharmony_ci return SocketAddress::CompareResult::SAME; 1871cb0ef41Sopenharmony_ci} 1881cb0ef41Sopenharmony_ci 1891cb0ef41Sopenharmony_ciSocketAddress::CompareResult compare_ipv4_ipv6( 1901cb0ef41Sopenharmony_ci const SocketAddress& ipv4, 1911cb0ef41Sopenharmony_ci const SocketAddress& ipv6) { 1921cb0ef41Sopenharmony_ci const sockaddr_in* ipv4_in = 1931cb0ef41Sopenharmony_ci reinterpret_cast<const sockaddr_in*>(ipv4.data()); 1941cb0ef41Sopenharmony_ci const sockaddr_in6 * ipv6_in = 1951cb0ef41Sopenharmony_ci reinterpret_cast<const sockaddr_in6*>(ipv6.data()); 1961cb0ef41Sopenharmony_ci 1971cb0ef41Sopenharmony_ci const uint8_t* ptr = 1981cb0ef41Sopenharmony_ci reinterpret_cast<const uint8_t*>(&ipv6_in->sin6_addr); 1991cb0ef41Sopenharmony_ci 2001cb0ef41Sopenharmony_ci if (memcmp(ptr, mask, sizeof(mask)) != 0) 2011cb0ef41Sopenharmony_ci return SocketAddress::CompareResult::NOT_COMPARABLE; 2021cb0ef41Sopenharmony_ci 2031cb0ef41Sopenharmony_ci int ret = memcmp( 2041cb0ef41Sopenharmony_ci &ipv4_in->sin_addr, 2051cb0ef41Sopenharmony_ci ptr + sizeof(mask), 2061cb0ef41Sopenharmony_ci sizeof(uint32_t)); 2071cb0ef41Sopenharmony_ci 2081cb0ef41Sopenharmony_ci if (ret < 0) 2091cb0ef41Sopenharmony_ci return SocketAddress::CompareResult::LESS_THAN; 2101cb0ef41Sopenharmony_ci else if (ret > 0) 2111cb0ef41Sopenharmony_ci return SocketAddress::CompareResult::GREATER_THAN; 2121cb0ef41Sopenharmony_ci return SocketAddress::CompareResult::SAME; 2131cb0ef41Sopenharmony_ci} 2141cb0ef41Sopenharmony_ci 2151cb0ef41Sopenharmony_cibool in_network_ipv4( 2161cb0ef41Sopenharmony_ci const SocketAddress& ip, 2171cb0ef41Sopenharmony_ci const SocketAddress& net, 2181cb0ef41Sopenharmony_ci int prefix) { 2191cb0ef41Sopenharmony_ci uint32_t mask = ((1ull << prefix) - 1) << (32 - prefix); 2201cb0ef41Sopenharmony_ci 2211cb0ef41Sopenharmony_ci const sockaddr_in* ip_in = 2221cb0ef41Sopenharmony_ci reinterpret_cast<const sockaddr_in*>(ip.data()); 2231cb0ef41Sopenharmony_ci const sockaddr_in* net_in = 2241cb0ef41Sopenharmony_ci reinterpret_cast<const sockaddr_in*>(net.data()); 2251cb0ef41Sopenharmony_ci 2261cb0ef41Sopenharmony_ci return (htonl(ip_in->sin_addr.s_addr) & mask) == 2271cb0ef41Sopenharmony_ci (htonl(net_in->sin_addr.s_addr) & mask); 2281cb0ef41Sopenharmony_ci} 2291cb0ef41Sopenharmony_ci 2301cb0ef41Sopenharmony_cibool in_network_ipv6( 2311cb0ef41Sopenharmony_ci const SocketAddress& ip, 2321cb0ef41Sopenharmony_ci const SocketAddress& net, 2331cb0ef41Sopenharmony_ci int prefix) { 2341cb0ef41Sopenharmony_ci // Special case, if prefix == 128, then just do a 2351cb0ef41Sopenharmony_ci // straight comparison. 2361cb0ef41Sopenharmony_ci if (prefix == 128) 2371cb0ef41Sopenharmony_ci return compare_ipv6(ip, net) == SocketAddress::CompareResult::SAME; 2381cb0ef41Sopenharmony_ci 2391cb0ef41Sopenharmony_ci uint8_t r = prefix % 8; 2401cb0ef41Sopenharmony_ci int len = (prefix - r) / 8; 2411cb0ef41Sopenharmony_ci uint8_t mask = ((1 << r) - 1) << (8 - r); 2421cb0ef41Sopenharmony_ci 2431cb0ef41Sopenharmony_ci const sockaddr_in6* ip_in = 2441cb0ef41Sopenharmony_ci reinterpret_cast<const sockaddr_in6*>(ip.data()); 2451cb0ef41Sopenharmony_ci const sockaddr_in6* net_in = 2461cb0ef41Sopenharmony_ci reinterpret_cast<const sockaddr_in6*>(net.data()); 2471cb0ef41Sopenharmony_ci 2481cb0ef41Sopenharmony_ci if (memcmp(&ip_in->sin6_addr, &net_in->sin6_addr, len) != 0) 2491cb0ef41Sopenharmony_ci return false; 2501cb0ef41Sopenharmony_ci 2511cb0ef41Sopenharmony_ci const uint8_t* p1 = reinterpret_cast<const uint8_t*>( 2521cb0ef41Sopenharmony_ci ip_in->sin6_addr.s6_addr); 2531cb0ef41Sopenharmony_ci const uint8_t* p2 = reinterpret_cast<const uint8_t*>( 2541cb0ef41Sopenharmony_ci net_in->sin6_addr.s6_addr); 2551cb0ef41Sopenharmony_ci 2561cb0ef41Sopenharmony_ci return (p1[len] & mask) == (p2[len] & mask); 2571cb0ef41Sopenharmony_ci} 2581cb0ef41Sopenharmony_ci 2591cb0ef41Sopenharmony_cibool in_network_ipv4_ipv6( 2601cb0ef41Sopenharmony_ci const SocketAddress& ip, 2611cb0ef41Sopenharmony_ci const SocketAddress& net, 2621cb0ef41Sopenharmony_ci int prefix) { 2631cb0ef41Sopenharmony_ci 2641cb0ef41Sopenharmony_ci if (prefix == 128) 2651cb0ef41Sopenharmony_ci return compare_ipv4_ipv6(ip, net) == SocketAddress::CompareResult::SAME; 2661cb0ef41Sopenharmony_ci 2671cb0ef41Sopenharmony_ci uint8_t r = prefix % 8; 2681cb0ef41Sopenharmony_ci int len = (prefix - r) / 8; 2691cb0ef41Sopenharmony_ci uint8_t mask = ((1 << r) - 1) << (8 - r); 2701cb0ef41Sopenharmony_ci 2711cb0ef41Sopenharmony_ci const sockaddr_in* ip_in = 2721cb0ef41Sopenharmony_ci reinterpret_cast<const sockaddr_in*>(ip.data()); 2731cb0ef41Sopenharmony_ci const sockaddr_in6* net_in = 2741cb0ef41Sopenharmony_ci reinterpret_cast<const sockaddr_in6*>(net.data()); 2751cb0ef41Sopenharmony_ci 2761cb0ef41Sopenharmony_ci uint8_t ip_mask[16] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xff, 0xff, 0, 0, 0, 0}; 2771cb0ef41Sopenharmony_ci uint8_t* ptr = ip_mask; 2781cb0ef41Sopenharmony_ci memcpy(ptr + 12, &ip_in->sin_addr, 4); 2791cb0ef41Sopenharmony_ci 2801cb0ef41Sopenharmony_ci if (memcmp(ptr, &net_in->sin6_addr, len) != 0) 2811cb0ef41Sopenharmony_ci return false; 2821cb0ef41Sopenharmony_ci 2831cb0ef41Sopenharmony_ci ptr += len; 2841cb0ef41Sopenharmony_ci const uint8_t* p2 = reinterpret_cast<const uint8_t*>( 2851cb0ef41Sopenharmony_ci net_in->sin6_addr.s6_addr); 2861cb0ef41Sopenharmony_ci 2871cb0ef41Sopenharmony_ci return (ptr[0] & mask) == (p2[len] & mask); 2881cb0ef41Sopenharmony_ci} 2891cb0ef41Sopenharmony_ci 2901cb0ef41Sopenharmony_cibool in_network_ipv6_ipv4( 2911cb0ef41Sopenharmony_ci const SocketAddress& ip, 2921cb0ef41Sopenharmony_ci const SocketAddress& net, 2931cb0ef41Sopenharmony_ci int prefix) { 2941cb0ef41Sopenharmony_ci if (prefix == 32) 2951cb0ef41Sopenharmony_ci return compare_ipv4_ipv6(net, ip) == SocketAddress::CompareResult::SAME; 2961cb0ef41Sopenharmony_ci 2971cb0ef41Sopenharmony_ci uint32_t m = ((1ull << prefix) - 1) << (32 - prefix); 2981cb0ef41Sopenharmony_ci 2991cb0ef41Sopenharmony_ci const sockaddr_in6* ip_in = 3001cb0ef41Sopenharmony_ci reinterpret_cast<const sockaddr_in6*>(ip.data()); 3011cb0ef41Sopenharmony_ci const sockaddr_in* net_in = 3021cb0ef41Sopenharmony_ci reinterpret_cast<const sockaddr_in*>(net.data()); 3031cb0ef41Sopenharmony_ci 3041cb0ef41Sopenharmony_ci const uint8_t* ptr = 3051cb0ef41Sopenharmony_ci reinterpret_cast<const uint8_t*>(&ip_in->sin6_addr); 3061cb0ef41Sopenharmony_ci 3071cb0ef41Sopenharmony_ci if (memcmp(ptr, mask, sizeof(mask)) != 0) 3081cb0ef41Sopenharmony_ci return false; 3091cb0ef41Sopenharmony_ci 3101cb0ef41Sopenharmony_ci ptr += sizeof(mask); 3111cb0ef41Sopenharmony_ci uint32_t check = ReadUint32BE(ptr); 3121cb0ef41Sopenharmony_ci 3131cb0ef41Sopenharmony_ci return (check & m) == (htonl(net_in->sin_addr.s_addr) & m); 3141cb0ef41Sopenharmony_ci} 3151cb0ef41Sopenharmony_ci} // namespace 3161cb0ef41Sopenharmony_ci 3171cb0ef41Sopenharmony_ci// TODO(@jasnell): The implementations of is_match, compare, and 3181cb0ef41Sopenharmony_ci// is_in_network have not been performance optimized and could 3191cb0ef41Sopenharmony_ci// likely benefit from work on more performant approaches. 3201cb0ef41Sopenharmony_ci 3211cb0ef41Sopenharmony_cibool SocketAddress::is_match(const SocketAddress& other) const { 3221cb0ef41Sopenharmony_ci switch (family()) { 3231cb0ef41Sopenharmony_ci case AF_INET: 3241cb0ef41Sopenharmony_ci switch (other.family()) { 3251cb0ef41Sopenharmony_ci case AF_INET: return is_match_ipv4(*this, other); 3261cb0ef41Sopenharmony_ci case AF_INET6: return is_match_ipv4_ipv6(*this, other); 3271cb0ef41Sopenharmony_ci } 3281cb0ef41Sopenharmony_ci break; 3291cb0ef41Sopenharmony_ci case AF_INET6: 3301cb0ef41Sopenharmony_ci switch (other.family()) { 3311cb0ef41Sopenharmony_ci case AF_INET: return is_match_ipv4_ipv6(other, *this); 3321cb0ef41Sopenharmony_ci case AF_INET6: return is_match_ipv6(*this, other); 3331cb0ef41Sopenharmony_ci } 3341cb0ef41Sopenharmony_ci break; 3351cb0ef41Sopenharmony_ci } 3361cb0ef41Sopenharmony_ci return false; 3371cb0ef41Sopenharmony_ci} 3381cb0ef41Sopenharmony_ci 3391cb0ef41Sopenharmony_ciSocketAddress::CompareResult SocketAddress::compare( 3401cb0ef41Sopenharmony_ci const SocketAddress& other) const { 3411cb0ef41Sopenharmony_ci switch (family()) { 3421cb0ef41Sopenharmony_ci case AF_INET: 3431cb0ef41Sopenharmony_ci switch (other.family()) { 3441cb0ef41Sopenharmony_ci case AF_INET: return compare_ipv4(*this, other); 3451cb0ef41Sopenharmony_ci case AF_INET6: return compare_ipv4_ipv6(*this, other); 3461cb0ef41Sopenharmony_ci } 3471cb0ef41Sopenharmony_ci break; 3481cb0ef41Sopenharmony_ci case AF_INET6: 3491cb0ef41Sopenharmony_ci switch (other.family()) { 3501cb0ef41Sopenharmony_ci case AF_INET: { 3511cb0ef41Sopenharmony_ci CompareResult c = compare_ipv4_ipv6(other, *this); 3521cb0ef41Sopenharmony_ci switch (c) { 3531cb0ef41Sopenharmony_ci case SocketAddress::CompareResult::NOT_COMPARABLE: 3541cb0ef41Sopenharmony_ci // Fall through 3551cb0ef41Sopenharmony_ci case SocketAddress::CompareResult::SAME: 3561cb0ef41Sopenharmony_ci return c; 3571cb0ef41Sopenharmony_ci case SocketAddress::CompareResult::GREATER_THAN: 3581cb0ef41Sopenharmony_ci return SocketAddress::CompareResult::LESS_THAN; 3591cb0ef41Sopenharmony_ci case SocketAddress::CompareResult::LESS_THAN: 3601cb0ef41Sopenharmony_ci return SocketAddress::CompareResult::GREATER_THAN; 3611cb0ef41Sopenharmony_ci } 3621cb0ef41Sopenharmony_ci break; 3631cb0ef41Sopenharmony_ci } 3641cb0ef41Sopenharmony_ci case AF_INET6: return compare_ipv6(*this, other); 3651cb0ef41Sopenharmony_ci } 3661cb0ef41Sopenharmony_ci break; 3671cb0ef41Sopenharmony_ci } 3681cb0ef41Sopenharmony_ci return SocketAddress::CompareResult::NOT_COMPARABLE; 3691cb0ef41Sopenharmony_ci} 3701cb0ef41Sopenharmony_ci 3711cb0ef41Sopenharmony_cibool SocketAddress::is_in_network( 3721cb0ef41Sopenharmony_ci const SocketAddress& other, 3731cb0ef41Sopenharmony_ci int prefix) const { 3741cb0ef41Sopenharmony_ci 3751cb0ef41Sopenharmony_ci switch (family()) { 3761cb0ef41Sopenharmony_ci case AF_INET: 3771cb0ef41Sopenharmony_ci switch (other.family()) { 3781cb0ef41Sopenharmony_ci case AF_INET: return in_network_ipv4(*this, other, prefix); 3791cb0ef41Sopenharmony_ci case AF_INET6: return in_network_ipv4_ipv6(*this, other, prefix); 3801cb0ef41Sopenharmony_ci } 3811cb0ef41Sopenharmony_ci break; 3821cb0ef41Sopenharmony_ci case AF_INET6: 3831cb0ef41Sopenharmony_ci switch (other.family()) { 3841cb0ef41Sopenharmony_ci case AF_INET: return in_network_ipv6_ipv4(*this, other, prefix); 3851cb0ef41Sopenharmony_ci case AF_INET6: return in_network_ipv6(*this, other, prefix); 3861cb0ef41Sopenharmony_ci } 3871cb0ef41Sopenharmony_ci break; 3881cb0ef41Sopenharmony_ci } 3891cb0ef41Sopenharmony_ci 3901cb0ef41Sopenharmony_ci return false; 3911cb0ef41Sopenharmony_ci} 3921cb0ef41Sopenharmony_ci 3931cb0ef41Sopenharmony_ciSocketAddressBlockList::SocketAddressBlockList( 3941cb0ef41Sopenharmony_ci std::shared_ptr<SocketAddressBlockList> parent) 3951cb0ef41Sopenharmony_ci : parent_(parent) {} 3961cb0ef41Sopenharmony_ci 3971cb0ef41Sopenharmony_civoid SocketAddressBlockList::AddSocketAddress( 3981cb0ef41Sopenharmony_ci const std::shared_ptr<SocketAddress>& address) { 3991cb0ef41Sopenharmony_ci Mutex::ScopedLock lock(mutex_); 4001cb0ef41Sopenharmony_ci std::unique_ptr<Rule> rule = 4011cb0ef41Sopenharmony_ci std::make_unique<SocketAddressRule>(address); 4021cb0ef41Sopenharmony_ci rules_.emplace_front(std::move(rule)); 4031cb0ef41Sopenharmony_ci address_rules_[*address.get()] = rules_.begin(); 4041cb0ef41Sopenharmony_ci} 4051cb0ef41Sopenharmony_ci 4061cb0ef41Sopenharmony_civoid SocketAddressBlockList::RemoveSocketAddress( 4071cb0ef41Sopenharmony_ci const std::shared_ptr<SocketAddress>& address) { 4081cb0ef41Sopenharmony_ci Mutex::ScopedLock lock(mutex_); 4091cb0ef41Sopenharmony_ci auto it = address_rules_.find(*address.get()); 4101cb0ef41Sopenharmony_ci if (it != std::end(address_rules_)) { 4111cb0ef41Sopenharmony_ci rules_.erase(it->second); 4121cb0ef41Sopenharmony_ci address_rules_.erase(it); 4131cb0ef41Sopenharmony_ci } 4141cb0ef41Sopenharmony_ci} 4151cb0ef41Sopenharmony_ci 4161cb0ef41Sopenharmony_civoid SocketAddressBlockList::AddSocketAddressRange( 4171cb0ef41Sopenharmony_ci const std::shared_ptr<SocketAddress>& start, 4181cb0ef41Sopenharmony_ci const std::shared_ptr<SocketAddress>& end) { 4191cb0ef41Sopenharmony_ci Mutex::ScopedLock lock(mutex_); 4201cb0ef41Sopenharmony_ci std::unique_ptr<Rule> rule = 4211cb0ef41Sopenharmony_ci std::make_unique<SocketAddressRangeRule>(start, end); 4221cb0ef41Sopenharmony_ci rules_.emplace_front(std::move(rule)); 4231cb0ef41Sopenharmony_ci} 4241cb0ef41Sopenharmony_ci 4251cb0ef41Sopenharmony_civoid SocketAddressBlockList::AddSocketAddressMask( 4261cb0ef41Sopenharmony_ci const std::shared_ptr<SocketAddress>& network, 4271cb0ef41Sopenharmony_ci int prefix) { 4281cb0ef41Sopenharmony_ci Mutex::ScopedLock lock(mutex_); 4291cb0ef41Sopenharmony_ci std::unique_ptr<Rule> rule = 4301cb0ef41Sopenharmony_ci std::make_unique<SocketAddressMaskRule>(network, prefix); 4311cb0ef41Sopenharmony_ci rules_.emplace_front(std::move(rule)); 4321cb0ef41Sopenharmony_ci} 4331cb0ef41Sopenharmony_ci 4341cb0ef41Sopenharmony_cibool SocketAddressBlockList::Apply( 4351cb0ef41Sopenharmony_ci const std::shared_ptr<SocketAddress>& address) { 4361cb0ef41Sopenharmony_ci Mutex::ScopedLock lock(mutex_); 4371cb0ef41Sopenharmony_ci for (const auto& rule : rules_) { 4381cb0ef41Sopenharmony_ci if (rule->Apply(address)) 4391cb0ef41Sopenharmony_ci return true; 4401cb0ef41Sopenharmony_ci } 4411cb0ef41Sopenharmony_ci return parent_ ? parent_->Apply(address) : false; 4421cb0ef41Sopenharmony_ci} 4431cb0ef41Sopenharmony_ci 4441cb0ef41Sopenharmony_ciSocketAddressBlockList::SocketAddressRule::SocketAddressRule( 4451cb0ef41Sopenharmony_ci const std::shared_ptr<SocketAddress>& address_) 4461cb0ef41Sopenharmony_ci : address(address_) {} 4471cb0ef41Sopenharmony_ci 4481cb0ef41Sopenharmony_ciSocketAddressBlockList::SocketAddressRangeRule::SocketAddressRangeRule( 4491cb0ef41Sopenharmony_ci const std::shared_ptr<SocketAddress>& start_, 4501cb0ef41Sopenharmony_ci const std::shared_ptr<SocketAddress>& end_) 4511cb0ef41Sopenharmony_ci : start(start_), 4521cb0ef41Sopenharmony_ci end(end_) {} 4531cb0ef41Sopenharmony_ci 4541cb0ef41Sopenharmony_ciSocketAddressBlockList::SocketAddressMaskRule::SocketAddressMaskRule( 4551cb0ef41Sopenharmony_ci const std::shared_ptr<SocketAddress>& network_, 4561cb0ef41Sopenharmony_ci int prefix_) 4571cb0ef41Sopenharmony_ci : network(network_), 4581cb0ef41Sopenharmony_ci prefix(prefix_) {} 4591cb0ef41Sopenharmony_ci 4601cb0ef41Sopenharmony_cibool SocketAddressBlockList::SocketAddressRule::Apply( 4611cb0ef41Sopenharmony_ci const std::shared_ptr<SocketAddress>& address) { 4621cb0ef41Sopenharmony_ci return this->address->is_match(*address.get()); 4631cb0ef41Sopenharmony_ci} 4641cb0ef41Sopenharmony_ci 4651cb0ef41Sopenharmony_cistd::string SocketAddressBlockList::SocketAddressRule::ToString() { 4661cb0ef41Sopenharmony_ci std::string ret = "Address: "; 4671cb0ef41Sopenharmony_ci ret += address->family() == AF_INET ? "IPv4" : "IPv6"; 4681cb0ef41Sopenharmony_ci ret += " "; 4691cb0ef41Sopenharmony_ci ret += address->address(); 4701cb0ef41Sopenharmony_ci return ret; 4711cb0ef41Sopenharmony_ci} 4721cb0ef41Sopenharmony_ci 4731cb0ef41Sopenharmony_cibool SocketAddressBlockList::SocketAddressRangeRule::Apply( 4741cb0ef41Sopenharmony_ci const std::shared_ptr<SocketAddress>& address) { 4751cb0ef41Sopenharmony_ci return *address.get() >= *start.get() && 4761cb0ef41Sopenharmony_ci *address.get() <= *end.get(); 4771cb0ef41Sopenharmony_ci} 4781cb0ef41Sopenharmony_ci 4791cb0ef41Sopenharmony_cistd::string SocketAddressBlockList::SocketAddressRangeRule::ToString() { 4801cb0ef41Sopenharmony_ci std::string ret = "Range: "; 4811cb0ef41Sopenharmony_ci ret += start->family() == AF_INET ? "IPv4" : "IPv6"; 4821cb0ef41Sopenharmony_ci ret += " "; 4831cb0ef41Sopenharmony_ci ret += start->address(); 4841cb0ef41Sopenharmony_ci ret += "-"; 4851cb0ef41Sopenharmony_ci ret += end->address(); 4861cb0ef41Sopenharmony_ci return ret; 4871cb0ef41Sopenharmony_ci} 4881cb0ef41Sopenharmony_ci 4891cb0ef41Sopenharmony_cibool SocketAddressBlockList::SocketAddressMaskRule::Apply( 4901cb0ef41Sopenharmony_ci const std::shared_ptr<SocketAddress>& address) { 4911cb0ef41Sopenharmony_ci return address->is_in_network(*network.get(), prefix); 4921cb0ef41Sopenharmony_ci} 4931cb0ef41Sopenharmony_ci 4941cb0ef41Sopenharmony_cistd::string SocketAddressBlockList::SocketAddressMaskRule::ToString() { 4951cb0ef41Sopenharmony_ci std::string ret = "Subnet: "; 4961cb0ef41Sopenharmony_ci ret += network->family() == AF_INET ? "IPv4" : "IPv6"; 4971cb0ef41Sopenharmony_ci ret += " "; 4981cb0ef41Sopenharmony_ci ret += network->address(); 4991cb0ef41Sopenharmony_ci ret += "/" + std::to_string(prefix); 5001cb0ef41Sopenharmony_ci return ret; 5011cb0ef41Sopenharmony_ci} 5021cb0ef41Sopenharmony_ci 5031cb0ef41Sopenharmony_ciMaybeLocal<Array> SocketAddressBlockList::ListRules(Environment* env) { 5041cb0ef41Sopenharmony_ci Mutex::ScopedLock lock(mutex_); 5051cb0ef41Sopenharmony_ci std::vector<Local<Value>> rules; 5061cb0ef41Sopenharmony_ci if (!ListRules(env, &rules)) 5071cb0ef41Sopenharmony_ci return MaybeLocal<Array>(); 5081cb0ef41Sopenharmony_ci return Array::New(env->isolate(), rules.data(), rules.size()); 5091cb0ef41Sopenharmony_ci} 5101cb0ef41Sopenharmony_ci 5111cb0ef41Sopenharmony_cibool SocketAddressBlockList::ListRules( 5121cb0ef41Sopenharmony_ci Environment* env, 5131cb0ef41Sopenharmony_ci std::vector<v8::Local<v8::Value>>* rules) { 5141cb0ef41Sopenharmony_ci if (parent_ && !parent_->ListRules(env, rules)) 5151cb0ef41Sopenharmony_ci return false; 5161cb0ef41Sopenharmony_ci for (const auto& rule : rules_) { 5171cb0ef41Sopenharmony_ci Local<Value> str; 5181cb0ef41Sopenharmony_ci if (!rule->ToV8String(env).ToLocal(&str)) 5191cb0ef41Sopenharmony_ci return false; 5201cb0ef41Sopenharmony_ci rules->push_back(str); 5211cb0ef41Sopenharmony_ci } 5221cb0ef41Sopenharmony_ci return true; 5231cb0ef41Sopenharmony_ci} 5241cb0ef41Sopenharmony_ci 5251cb0ef41Sopenharmony_civoid SocketAddressBlockList::MemoryInfo(node::MemoryTracker* tracker) const { 5261cb0ef41Sopenharmony_ci tracker->TrackField("rules", rules_); 5271cb0ef41Sopenharmony_ci} 5281cb0ef41Sopenharmony_ci 5291cb0ef41Sopenharmony_civoid SocketAddressBlockList::SocketAddressRule::MemoryInfo( 5301cb0ef41Sopenharmony_ci node::MemoryTracker* tracker) const { 5311cb0ef41Sopenharmony_ci tracker->TrackField("address", address); 5321cb0ef41Sopenharmony_ci} 5331cb0ef41Sopenharmony_ci 5341cb0ef41Sopenharmony_civoid SocketAddressBlockList::SocketAddressRangeRule::MemoryInfo( 5351cb0ef41Sopenharmony_ci node::MemoryTracker* tracker) const { 5361cb0ef41Sopenharmony_ci tracker->TrackField("start", start); 5371cb0ef41Sopenharmony_ci tracker->TrackField("end", end); 5381cb0ef41Sopenharmony_ci} 5391cb0ef41Sopenharmony_ci 5401cb0ef41Sopenharmony_civoid SocketAddressBlockList::SocketAddressMaskRule::MemoryInfo( 5411cb0ef41Sopenharmony_ci node::MemoryTracker* tracker) const { 5421cb0ef41Sopenharmony_ci tracker->TrackField("network", network); 5431cb0ef41Sopenharmony_ci} 5441cb0ef41Sopenharmony_ci 5451cb0ef41Sopenharmony_ciSocketAddressBlockListWrap::SocketAddressBlockListWrap( 5461cb0ef41Sopenharmony_ci Environment* env, 5471cb0ef41Sopenharmony_ci Local<Object> wrap, 5481cb0ef41Sopenharmony_ci std::shared_ptr<SocketAddressBlockList> blocklist) 5491cb0ef41Sopenharmony_ci : BaseObject(env, wrap), 5501cb0ef41Sopenharmony_ci blocklist_(std::move(blocklist)) { 5511cb0ef41Sopenharmony_ci MakeWeak(); 5521cb0ef41Sopenharmony_ci} 5531cb0ef41Sopenharmony_ci 5541cb0ef41Sopenharmony_ciBaseObjectPtr<SocketAddressBlockListWrap> SocketAddressBlockListWrap::New( 5551cb0ef41Sopenharmony_ci Environment* env) { 5561cb0ef41Sopenharmony_ci Local<Object> obj; 5571cb0ef41Sopenharmony_ci if (!env->blocklist_constructor_template() 5581cb0ef41Sopenharmony_ci ->InstanceTemplate() 5591cb0ef41Sopenharmony_ci ->NewInstance(env->context()).ToLocal(&obj)) { 5601cb0ef41Sopenharmony_ci return BaseObjectPtr<SocketAddressBlockListWrap>(); 5611cb0ef41Sopenharmony_ci } 5621cb0ef41Sopenharmony_ci BaseObjectPtr<SocketAddressBlockListWrap> wrap = 5631cb0ef41Sopenharmony_ci MakeBaseObject<SocketAddressBlockListWrap>(env, obj); 5641cb0ef41Sopenharmony_ci CHECK(wrap); 5651cb0ef41Sopenharmony_ci return wrap; 5661cb0ef41Sopenharmony_ci} 5671cb0ef41Sopenharmony_ci 5681cb0ef41Sopenharmony_ciBaseObjectPtr<SocketAddressBlockListWrap> SocketAddressBlockListWrap::New( 5691cb0ef41Sopenharmony_ci Environment* env, 5701cb0ef41Sopenharmony_ci std::shared_ptr<SocketAddressBlockList> blocklist) { 5711cb0ef41Sopenharmony_ci Local<Object> obj; 5721cb0ef41Sopenharmony_ci if (!env->blocklist_constructor_template() 5731cb0ef41Sopenharmony_ci ->InstanceTemplate() 5741cb0ef41Sopenharmony_ci ->NewInstance(env->context()).ToLocal(&obj)) { 5751cb0ef41Sopenharmony_ci return BaseObjectPtr<SocketAddressBlockListWrap>(); 5761cb0ef41Sopenharmony_ci } 5771cb0ef41Sopenharmony_ci BaseObjectPtr<SocketAddressBlockListWrap> wrap = 5781cb0ef41Sopenharmony_ci MakeBaseObject<SocketAddressBlockListWrap>( 5791cb0ef41Sopenharmony_ci env, 5801cb0ef41Sopenharmony_ci obj, 5811cb0ef41Sopenharmony_ci std::move(blocklist)); 5821cb0ef41Sopenharmony_ci CHECK(wrap); 5831cb0ef41Sopenharmony_ci return wrap; 5841cb0ef41Sopenharmony_ci} 5851cb0ef41Sopenharmony_ci 5861cb0ef41Sopenharmony_civoid SocketAddressBlockListWrap::New( 5871cb0ef41Sopenharmony_ci const FunctionCallbackInfo<Value>& args) { 5881cb0ef41Sopenharmony_ci CHECK(args.IsConstructCall()); 5891cb0ef41Sopenharmony_ci Environment* env = Environment::GetCurrent(args); 5901cb0ef41Sopenharmony_ci new SocketAddressBlockListWrap(env, args.This()); 5911cb0ef41Sopenharmony_ci} 5921cb0ef41Sopenharmony_ci 5931cb0ef41Sopenharmony_civoid SocketAddressBlockListWrap::AddAddress( 5941cb0ef41Sopenharmony_ci const FunctionCallbackInfo<Value>& args) { 5951cb0ef41Sopenharmony_ci Environment* env = Environment::GetCurrent(args); 5961cb0ef41Sopenharmony_ci SocketAddressBlockListWrap* wrap; 5971cb0ef41Sopenharmony_ci ASSIGN_OR_RETURN_UNWRAP(&wrap, args.Holder()); 5981cb0ef41Sopenharmony_ci 5991cb0ef41Sopenharmony_ci CHECK(SocketAddressBase::HasInstance(env, args[0])); 6001cb0ef41Sopenharmony_ci SocketAddressBase* addr; 6011cb0ef41Sopenharmony_ci ASSIGN_OR_RETURN_UNWRAP(&addr, args[0]); 6021cb0ef41Sopenharmony_ci 6031cb0ef41Sopenharmony_ci wrap->blocklist_->AddSocketAddress(addr->address()); 6041cb0ef41Sopenharmony_ci 6051cb0ef41Sopenharmony_ci args.GetReturnValue().Set(true); 6061cb0ef41Sopenharmony_ci} 6071cb0ef41Sopenharmony_ci 6081cb0ef41Sopenharmony_civoid SocketAddressBlockListWrap::AddRange( 6091cb0ef41Sopenharmony_ci const FunctionCallbackInfo<Value>& args) { 6101cb0ef41Sopenharmony_ci Environment* env = Environment::GetCurrent(args); 6111cb0ef41Sopenharmony_ci SocketAddressBlockListWrap* wrap; 6121cb0ef41Sopenharmony_ci ASSIGN_OR_RETURN_UNWRAP(&wrap, args.Holder()); 6131cb0ef41Sopenharmony_ci 6141cb0ef41Sopenharmony_ci CHECK(SocketAddressBase::HasInstance(env, args[0])); 6151cb0ef41Sopenharmony_ci CHECK(SocketAddressBase::HasInstance(env, args[1])); 6161cb0ef41Sopenharmony_ci 6171cb0ef41Sopenharmony_ci SocketAddressBase* start_addr; 6181cb0ef41Sopenharmony_ci SocketAddressBase* end_addr; 6191cb0ef41Sopenharmony_ci ASSIGN_OR_RETURN_UNWRAP(&start_addr, args[0]); 6201cb0ef41Sopenharmony_ci ASSIGN_OR_RETURN_UNWRAP(&end_addr, args[1]); 6211cb0ef41Sopenharmony_ci 6221cb0ef41Sopenharmony_ci // Starting address must come before the end address 6231cb0ef41Sopenharmony_ci if (*start_addr->address().get() > *end_addr->address().get()) 6241cb0ef41Sopenharmony_ci return args.GetReturnValue().Set(false); 6251cb0ef41Sopenharmony_ci 6261cb0ef41Sopenharmony_ci wrap->blocklist_->AddSocketAddressRange( 6271cb0ef41Sopenharmony_ci start_addr->address(), 6281cb0ef41Sopenharmony_ci end_addr->address()); 6291cb0ef41Sopenharmony_ci 6301cb0ef41Sopenharmony_ci args.GetReturnValue().Set(true); 6311cb0ef41Sopenharmony_ci} 6321cb0ef41Sopenharmony_ci 6331cb0ef41Sopenharmony_civoid SocketAddressBlockListWrap::AddSubnet( 6341cb0ef41Sopenharmony_ci const FunctionCallbackInfo<Value>& args) { 6351cb0ef41Sopenharmony_ci Environment* env = Environment::GetCurrent(args); 6361cb0ef41Sopenharmony_ci SocketAddressBlockListWrap* wrap; 6371cb0ef41Sopenharmony_ci ASSIGN_OR_RETURN_UNWRAP(&wrap, args.Holder()); 6381cb0ef41Sopenharmony_ci 6391cb0ef41Sopenharmony_ci CHECK(SocketAddressBase::HasInstance(env, args[0])); 6401cb0ef41Sopenharmony_ci CHECK(args[1]->IsInt32()); 6411cb0ef41Sopenharmony_ci 6421cb0ef41Sopenharmony_ci SocketAddressBase* addr; 6431cb0ef41Sopenharmony_ci ASSIGN_OR_RETURN_UNWRAP(&addr, args[0]); 6441cb0ef41Sopenharmony_ci 6451cb0ef41Sopenharmony_ci int32_t prefix; 6461cb0ef41Sopenharmony_ci if (!args[1]->Int32Value(env->context()).To(&prefix)) { 6471cb0ef41Sopenharmony_ci return; 6481cb0ef41Sopenharmony_ci } 6491cb0ef41Sopenharmony_ci 6501cb0ef41Sopenharmony_ci CHECK_IMPLIES(addr->address()->family() == AF_INET, prefix <= 32); 6511cb0ef41Sopenharmony_ci CHECK_IMPLIES(addr->address()->family() == AF_INET6, prefix <= 128); 6521cb0ef41Sopenharmony_ci CHECK_GE(prefix, 0); 6531cb0ef41Sopenharmony_ci 6541cb0ef41Sopenharmony_ci wrap->blocklist_->AddSocketAddressMask(addr->address(), prefix); 6551cb0ef41Sopenharmony_ci 6561cb0ef41Sopenharmony_ci args.GetReturnValue().Set(true); 6571cb0ef41Sopenharmony_ci} 6581cb0ef41Sopenharmony_ci 6591cb0ef41Sopenharmony_civoid SocketAddressBlockListWrap::Check( 6601cb0ef41Sopenharmony_ci const FunctionCallbackInfo<Value>& args) { 6611cb0ef41Sopenharmony_ci Environment* env = Environment::GetCurrent(args); 6621cb0ef41Sopenharmony_ci SocketAddressBlockListWrap* wrap; 6631cb0ef41Sopenharmony_ci ASSIGN_OR_RETURN_UNWRAP(&wrap, args.Holder()); 6641cb0ef41Sopenharmony_ci 6651cb0ef41Sopenharmony_ci CHECK(SocketAddressBase::HasInstance(env, args[0])); 6661cb0ef41Sopenharmony_ci SocketAddressBase* addr; 6671cb0ef41Sopenharmony_ci ASSIGN_OR_RETURN_UNWRAP(&addr, args[0]); 6681cb0ef41Sopenharmony_ci 6691cb0ef41Sopenharmony_ci args.GetReturnValue().Set(wrap->blocklist_->Apply(addr->address())); 6701cb0ef41Sopenharmony_ci} 6711cb0ef41Sopenharmony_ci 6721cb0ef41Sopenharmony_civoid SocketAddressBlockListWrap::GetRules( 6731cb0ef41Sopenharmony_ci const FunctionCallbackInfo<Value>& args) { 6741cb0ef41Sopenharmony_ci Environment* env = Environment::GetCurrent(args); 6751cb0ef41Sopenharmony_ci SocketAddressBlockListWrap* wrap; 6761cb0ef41Sopenharmony_ci ASSIGN_OR_RETURN_UNWRAP(&wrap, args.Holder()); 6771cb0ef41Sopenharmony_ci Local<Array> rules; 6781cb0ef41Sopenharmony_ci if (wrap->blocklist_->ListRules(env).ToLocal(&rules)) 6791cb0ef41Sopenharmony_ci args.GetReturnValue().Set(rules); 6801cb0ef41Sopenharmony_ci} 6811cb0ef41Sopenharmony_ci 6821cb0ef41Sopenharmony_civoid SocketAddressBlockListWrap::MemoryInfo(MemoryTracker* tracker) const { 6831cb0ef41Sopenharmony_ci blocklist_->MemoryInfo(tracker); 6841cb0ef41Sopenharmony_ci} 6851cb0ef41Sopenharmony_ci 6861cb0ef41Sopenharmony_cistd::unique_ptr<worker::TransferData> 6871cb0ef41Sopenharmony_ciSocketAddressBlockListWrap::CloneForMessaging() const { 6881cb0ef41Sopenharmony_ci return std::make_unique<TransferData>(this); 6891cb0ef41Sopenharmony_ci} 6901cb0ef41Sopenharmony_ci 6911cb0ef41Sopenharmony_cibool SocketAddressBlockListWrap::HasInstance( 6921cb0ef41Sopenharmony_ci Environment* env, 6931cb0ef41Sopenharmony_ci Local<Value> value) { 6941cb0ef41Sopenharmony_ci return GetConstructorTemplate(env)->HasInstance(value); 6951cb0ef41Sopenharmony_ci} 6961cb0ef41Sopenharmony_ci 6971cb0ef41Sopenharmony_ciLocal<FunctionTemplate> SocketAddressBlockListWrap::GetConstructorTemplate( 6981cb0ef41Sopenharmony_ci Environment* env) { 6991cb0ef41Sopenharmony_ci Local<FunctionTemplate> tmpl = env->blocklist_constructor_template(); 7001cb0ef41Sopenharmony_ci if (tmpl.IsEmpty()) { 7011cb0ef41Sopenharmony_ci Isolate* isolate = env->isolate(); 7021cb0ef41Sopenharmony_ci tmpl = NewFunctionTemplate(isolate, SocketAddressBlockListWrap::New); 7031cb0ef41Sopenharmony_ci tmpl->SetClassName(FIXED_ONE_BYTE_STRING(env->isolate(), "BlockList")); 7041cb0ef41Sopenharmony_ci tmpl->Inherit(BaseObject::GetConstructorTemplate(env)); 7051cb0ef41Sopenharmony_ci tmpl->InstanceTemplate()->SetInternalFieldCount(kInternalFieldCount); 7061cb0ef41Sopenharmony_ci SetProtoMethod(isolate, tmpl, "addAddress", AddAddress); 7071cb0ef41Sopenharmony_ci SetProtoMethod(isolate, tmpl, "addRange", AddRange); 7081cb0ef41Sopenharmony_ci SetProtoMethod(isolate, tmpl, "addSubnet", AddSubnet); 7091cb0ef41Sopenharmony_ci SetProtoMethod(isolate, tmpl, "check", Check); 7101cb0ef41Sopenharmony_ci SetProtoMethod(isolate, tmpl, "getRules", GetRules); 7111cb0ef41Sopenharmony_ci env->set_blocklist_constructor_template(tmpl); 7121cb0ef41Sopenharmony_ci } 7131cb0ef41Sopenharmony_ci return tmpl; 7141cb0ef41Sopenharmony_ci} 7151cb0ef41Sopenharmony_ci 7161cb0ef41Sopenharmony_civoid SocketAddressBlockListWrap::Initialize( 7171cb0ef41Sopenharmony_ci Local<Object> target, 7181cb0ef41Sopenharmony_ci Local<Value> unused, 7191cb0ef41Sopenharmony_ci Local<Context> context, 7201cb0ef41Sopenharmony_ci void* priv) { 7211cb0ef41Sopenharmony_ci Environment* env = Environment::GetCurrent(context); 7221cb0ef41Sopenharmony_ci 7231cb0ef41Sopenharmony_ci SetConstructorFunction(context, 7241cb0ef41Sopenharmony_ci target, 7251cb0ef41Sopenharmony_ci "BlockList", 7261cb0ef41Sopenharmony_ci GetConstructorTemplate(env), 7271cb0ef41Sopenharmony_ci SetConstructorFunctionFlag::NONE); 7281cb0ef41Sopenharmony_ci 7291cb0ef41Sopenharmony_ci SocketAddressBase::Initialize(env, target); 7301cb0ef41Sopenharmony_ci 7311cb0ef41Sopenharmony_ci NODE_DEFINE_CONSTANT(target, AF_INET); 7321cb0ef41Sopenharmony_ci NODE_DEFINE_CONSTANT(target, AF_INET6); 7331cb0ef41Sopenharmony_ci} 7341cb0ef41Sopenharmony_ci 7351cb0ef41Sopenharmony_ciBaseObjectPtr<BaseObject> SocketAddressBlockListWrap::TransferData::Deserialize( 7361cb0ef41Sopenharmony_ci Environment* env, 7371cb0ef41Sopenharmony_ci Local<Context> context, 7381cb0ef41Sopenharmony_ci std::unique_ptr<worker::TransferData> self) { 7391cb0ef41Sopenharmony_ci return New(env, std::move(blocklist_)); 7401cb0ef41Sopenharmony_ci} 7411cb0ef41Sopenharmony_ci 7421cb0ef41Sopenharmony_civoid SocketAddressBlockListWrap::TransferData::MemoryInfo( 7431cb0ef41Sopenharmony_ci MemoryTracker* tracker) const { 7441cb0ef41Sopenharmony_ci blocklist_->MemoryInfo(tracker); 7451cb0ef41Sopenharmony_ci} 7461cb0ef41Sopenharmony_ci 7471cb0ef41Sopenharmony_cibool SocketAddressBase::HasInstance(Environment* env, Local<Value> value) { 7481cb0ef41Sopenharmony_ci return GetConstructorTemplate(env)->HasInstance(value); 7491cb0ef41Sopenharmony_ci} 7501cb0ef41Sopenharmony_ci 7511cb0ef41Sopenharmony_ciLocal<FunctionTemplate> SocketAddressBase::GetConstructorTemplate( 7521cb0ef41Sopenharmony_ci Environment* env) { 7531cb0ef41Sopenharmony_ci Local<FunctionTemplate> tmpl = env->socketaddress_constructor_template(); 7541cb0ef41Sopenharmony_ci if (tmpl.IsEmpty()) { 7551cb0ef41Sopenharmony_ci Isolate* isolate = env->isolate(); 7561cb0ef41Sopenharmony_ci tmpl = NewFunctionTemplate(isolate, New); 7571cb0ef41Sopenharmony_ci tmpl->SetClassName(FIXED_ONE_BYTE_STRING(env->isolate(), "SocketAddress")); 7581cb0ef41Sopenharmony_ci tmpl->InstanceTemplate()->SetInternalFieldCount( 7591cb0ef41Sopenharmony_ci SocketAddressBase::kInternalFieldCount); 7601cb0ef41Sopenharmony_ci tmpl->Inherit(BaseObject::GetConstructorTemplate(env)); 7611cb0ef41Sopenharmony_ci SetProtoMethod(isolate, tmpl, "detail", Detail); 7621cb0ef41Sopenharmony_ci SetProtoMethod(isolate, tmpl, "legacyDetail", LegacyDetail); 7631cb0ef41Sopenharmony_ci SetProtoMethodNoSideEffect(isolate, tmpl, "flowlabel", GetFlowLabel); 7641cb0ef41Sopenharmony_ci env->set_socketaddress_constructor_template(tmpl); 7651cb0ef41Sopenharmony_ci } 7661cb0ef41Sopenharmony_ci return tmpl; 7671cb0ef41Sopenharmony_ci} 7681cb0ef41Sopenharmony_ci 7691cb0ef41Sopenharmony_civoid SocketAddressBase::Initialize(Environment* env, Local<Object> target) { 7701cb0ef41Sopenharmony_ci SetConstructorFunction(env->context(), 7711cb0ef41Sopenharmony_ci target, 7721cb0ef41Sopenharmony_ci "SocketAddress", 7731cb0ef41Sopenharmony_ci GetConstructorTemplate(env), 7741cb0ef41Sopenharmony_ci SetConstructorFunctionFlag::NONE); 7751cb0ef41Sopenharmony_ci} 7761cb0ef41Sopenharmony_ci 7771cb0ef41Sopenharmony_ciBaseObjectPtr<SocketAddressBase> SocketAddressBase::Create( 7781cb0ef41Sopenharmony_ci Environment* env, 7791cb0ef41Sopenharmony_ci std::shared_ptr<SocketAddress> address) { 7801cb0ef41Sopenharmony_ci Local<Object> obj; 7811cb0ef41Sopenharmony_ci if (!GetConstructorTemplate(env) 7821cb0ef41Sopenharmony_ci ->InstanceTemplate() 7831cb0ef41Sopenharmony_ci ->NewInstance(env->context()).ToLocal(&obj)) { 7841cb0ef41Sopenharmony_ci return BaseObjectPtr<SocketAddressBase>(); 7851cb0ef41Sopenharmony_ci } 7861cb0ef41Sopenharmony_ci 7871cb0ef41Sopenharmony_ci return MakeBaseObject<SocketAddressBase>(env, obj, std::move(address)); 7881cb0ef41Sopenharmony_ci} 7891cb0ef41Sopenharmony_ci 7901cb0ef41Sopenharmony_civoid SocketAddressBase::New(const FunctionCallbackInfo<Value>& args) { 7911cb0ef41Sopenharmony_ci Environment* env = Environment::GetCurrent(args); 7921cb0ef41Sopenharmony_ci CHECK(args.IsConstructCall()); 7931cb0ef41Sopenharmony_ci CHECK(args[0]->IsString()); // address 7941cb0ef41Sopenharmony_ci CHECK(args[1]->IsInt32()); // port 7951cb0ef41Sopenharmony_ci CHECK(args[2]->IsInt32()); // family 7961cb0ef41Sopenharmony_ci CHECK(args[3]->IsUint32()); // flow label 7971cb0ef41Sopenharmony_ci 7981cb0ef41Sopenharmony_ci Utf8Value address(env->isolate(), args[0]); 7991cb0ef41Sopenharmony_ci int32_t port = args[1].As<Int32>()->Value(); 8001cb0ef41Sopenharmony_ci int32_t family = args[2].As<Int32>()->Value(); 8011cb0ef41Sopenharmony_ci uint32_t flow_label = args[3].As<Uint32>()->Value(); 8021cb0ef41Sopenharmony_ci 8031cb0ef41Sopenharmony_ci std::shared_ptr<SocketAddress> addr = std::make_shared<SocketAddress>(); 8041cb0ef41Sopenharmony_ci 8051cb0ef41Sopenharmony_ci if (!SocketAddress::New(family, *address, port, addr.get())) 8061cb0ef41Sopenharmony_ci return THROW_ERR_INVALID_ADDRESS(env); 8071cb0ef41Sopenharmony_ci 8081cb0ef41Sopenharmony_ci addr->set_flow_label(flow_label); 8091cb0ef41Sopenharmony_ci 8101cb0ef41Sopenharmony_ci new SocketAddressBase(env, args.This(), std::move(addr)); 8111cb0ef41Sopenharmony_ci} 8121cb0ef41Sopenharmony_ci 8131cb0ef41Sopenharmony_civoid SocketAddressBase::Detail(const FunctionCallbackInfo<Value>& args) { 8141cb0ef41Sopenharmony_ci Environment* env = Environment::GetCurrent(args); 8151cb0ef41Sopenharmony_ci CHECK(args[0]->IsObject()); 8161cb0ef41Sopenharmony_ci Local<Object> detail = args[0].As<Object>(); 8171cb0ef41Sopenharmony_ci 8181cb0ef41Sopenharmony_ci SocketAddressBase* base; 8191cb0ef41Sopenharmony_ci ASSIGN_OR_RETURN_UNWRAP(&base, args.Holder()); 8201cb0ef41Sopenharmony_ci 8211cb0ef41Sopenharmony_ci Local<Value> address; 8221cb0ef41Sopenharmony_ci if (!ToV8Value(env->context(), base->address_->address()).ToLocal(&address)) 8231cb0ef41Sopenharmony_ci return; 8241cb0ef41Sopenharmony_ci 8251cb0ef41Sopenharmony_ci if (detail->Set(env->context(), env->address_string(), address).IsJust() && 8261cb0ef41Sopenharmony_ci detail->Set( 8271cb0ef41Sopenharmony_ci env->context(), 8281cb0ef41Sopenharmony_ci env->port_string(), 8291cb0ef41Sopenharmony_ci Int32::New(env->isolate(), base->address_->port())).IsJust() && 8301cb0ef41Sopenharmony_ci detail->Set( 8311cb0ef41Sopenharmony_ci env->context(), 8321cb0ef41Sopenharmony_ci env->family_string(), 8331cb0ef41Sopenharmony_ci Int32::New(env->isolate(), base->address_->family())).IsJust() && 8341cb0ef41Sopenharmony_ci detail->Set( 8351cb0ef41Sopenharmony_ci env->context(), 8361cb0ef41Sopenharmony_ci env->flowlabel_string(), 8371cb0ef41Sopenharmony_ci Uint32::New(env->isolate(), base->address_->flow_label())) 8381cb0ef41Sopenharmony_ci .IsJust()) { 8391cb0ef41Sopenharmony_ci args.GetReturnValue().Set(detail); 8401cb0ef41Sopenharmony_ci } 8411cb0ef41Sopenharmony_ci} 8421cb0ef41Sopenharmony_ci 8431cb0ef41Sopenharmony_civoid SocketAddressBase::GetFlowLabel(const FunctionCallbackInfo<Value>& args) { 8441cb0ef41Sopenharmony_ci SocketAddressBase* base; 8451cb0ef41Sopenharmony_ci ASSIGN_OR_RETURN_UNWRAP(&base, args.Holder()); 8461cb0ef41Sopenharmony_ci args.GetReturnValue().Set(base->address_->flow_label()); 8471cb0ef41Sopenharmony_ci} 8481cb0ef41Sopenharmony_ci 8491cb0ef41Sopenharmony_civoid SocketAddressBase::LegacyDetail(const FunctionCallbackInfo<Value>& args) { 8501cb0ef41Sopenharmony_ci Environment* env = Environment::GetCurrent(args); 8511cb0ef41Sopenharmony_ci SocketAddressBase* base; 8521cb0ef41Sopenharmony_ci ASSIGN_OR_RETURN_UNWRAP(&base, args.Holder()); 8531cb0ef41Sopenharmony_ci Local<Object> address; 8541cb0ef41Sopenharmony_ci if (!base->address_->ToJS(env).ToLocal(&address)) return; 8551cb0ef41Sopenharmony_ci args.GetReturnValue().Set(address); 8561cb0ef41Sopenharmony_ci} 8571cb0ef41Sopenharmony_ci 8581cb0ef41Sopenharmony_ciSocketAddressBase::SocketAddressBase( 8591cb0ef41Sopenharmony_ci Environment* env, 8601cb0ef41Sopenharmony_ci Local<Object> wrap, 8611cb0ef41Sopenharmony_ci std::shared_ptr<SocketAddress> address) 8621cb0ef41Sopenharmony_ci : BaseObject(env, wrap), 8631cb0ef41Sopenharmony_ci address_(std::move(address)) { 8641cb0ef41Sopenharmony_ci MakeWeak(); 8651cb0ef41Sopenharmony_ci} 8661cb0ef41Sopenharmony_ci 8671cb0ef41Sopenharmony_civoid SocketAddressBase::MemoryInfo(MemoryTracker* tracker) const { 8681cb0ef41Sopenharmony_ci tracker->TrackField("address", address_); 8691cb0ef41Sopenharmony_ci} 8701cb0ef41Sopenharmony_ci 8711cb0ef41Sopenharmony_cistd::unique_ptr<worker::TransferData> 8721cb0ef41Sopenharmony_ciSocketAddressBase::CloneForMessaging() const { 8731cb0ef41Sopenharmony_ci return std::make_unique<TransferData>(this); 8741cb0ef41Sopenharmony_ci} 8751cb0ef41Sopenharmony_ci 8761cb0ef41Sopenharmony_civoid SocketAddressBase::TransferData::MemoryInfo(MemoryTracker* tracker) const { 8771cb0ef41Sopenharmony_ci tracker->TrackField("address", address_); 8781cb0ef41Sopenharmony_ci} 8791cb0ef41Sopenharmony_ci 8801cb0ef41Sopenharmony_ciBaseObjectPtr<BaseObject> SocketAddressBase::TransferData::Deserialize( 8811cb0ef41Sopenharmony_ci Environment* env, 8821cb0ef41Sopenharmony_ci v8::Local<v8::Context> context, 8831cb0ef41Sopenharmony_ci std::unique_ptr<worker::TransferData> self) { 8841cb0ef41Sopenharmony_ci return SocketAddressBase::Create(env, std::move(address_)); 8851cb0ef41Sopenharmony_ci} 8861cb0ef41Sopenharmony_ci 8871cb0ef41Sopenharmony_ci} // namespace node 8881cb0ef41Sopenharmony_ci 8891cb0ef41Sopenharmony_ciNODE_BINDING_CONTEXT_AWARE_INTERNAL( 8901cb0ef41Sopenharmony_ci block_list, node::SocketAddressBlockListWrap::Initialize) 891