From 0709cbb7fefd17687251a59d645b1dc84cdc7927 Mon Sep 17 00:00:00 2001 From: James M Snell Date: Thu, 25 Mar 2021 13:27:03 -0700 Subject: [PATCH] net: allow net.BlockList to use net.SocketAddress objects Signed-off-by: James M Snell PR-URL: https://github.com/nodejs/node/pull/37917 Reviewed-By: Matteo Collina --- doc/api/net.md | 11 +-- lib/internal/blocklist.js | 91 +++++++++++++-------- lib/internal/socketaddress.js | 7 +- src/node_sockaddr.cc | 140 ++++++++++++-------------------- src/node_sockaddr.h | 42 +++++----- test/cctest/test_sockaddr.cc | 8 +- test/parallel/test-blocklist.js | 94 +++++++++++++++++++-- tools/doc/type-parser.js | 1 + 8 files changed, 235 insertions(+), 159 deletions(-) diff --git a/doc/api/net.md b/doc/api/net.md index c7f3ba56165fb3..9a4b48317ea845 100644 --- a/doc/api/net.md +++ b/doc/api/net.md @@ -69,7 +69,7 @@ IP subnets. added: v15.0.0 --> -* `address` {string} An IPv4 or IPv6 address. +* `address` {string|net.SocketAddress} An IPv4 or IPv6 address. * `type` {string} Either `'ipv4'` or `'ipv6'`. **Default:** `'ipv4'`. Adds a rule to block the given IP address. @@ -79,8 +79,9 @@ Adds a rule to block the given IP address. added: v15.0.0 --> -* `start` {string} The starting IPv4 or IPv6 address in the range. -* `end` {string} The ending IPv4 or IPv6 address in the range. +* `start` {string|net.SocketAddress} The starting IPv4 or IPv6 address in the + range. +* `end` {string|net.SocketAddress} The ending IPv4 or IPv6 address in the range. * `type` {string} Either `'ipv4'` or `'ipv6'`. **Default:** `'ipv4'`. Adds a rule to block a range of IP addresses from `start` (inclusive) to @@ -91,7 +92,7 @@ Adds a rule to block a range of IP addresses from `start` (inclusive) to added: v15.0.0 --> -* `net` {string} The network IPv4 or IPv6 address. +* `net` {string|net.SocketAddress} The network IPv4 or IPv6 address. * `prefix` {number} The number of CIDR prefix bits. For IPv4, this must be a value between `0` and `32`. For IPv6, this must be between `0` and `128`. @@ -104,7 +105,7 @@ Adds a rule to block a range of IP addresses specified as a subnet mask. added: v15.0.0 --> -* `address` {string} The IP address to check +* `address` {string|net.SocketAddress} The IP address to check * `type` {string} Either `'ipv4'` or `'ipv6'`. **Default:** `'ipv4'`. * Returns: {boolean} diff --git a/lib/internal/blocklist.js b/lib/internal/blocklist.js index ecd1eec5bb92fc..a73f3f19de07ff 100644 --- a/lib/internal/blocklist.js +++ b/lib/internal/blocklist.js @@ -8,14 +8,17 @@ const { const { BlockList: BlockListHandle, - AF_INET, - AF_INET6, } = internalBinding('block_list'); const { customInspectSymbol: kInspect, } = require('internal/util'); +const { + SocketAddress, + kHandle: kSocketAddressHandle, +} = require('internal/socketaddress'); + const { JSTransferable, kClone, @@ -55,56 +58,76 @@ class BlockList extends JSTransferable { } addAddress(address, family = 'ipv4') { - validateString(address, 'address'); - validateString(family, 'family'); - family = family.toLowerCase(); - if (family !== 'ipv4' && family !== 'ipv6') - throw new ERR_INVALID_ARG_VALUE('family', family); - const type = family === 'ipv4' ? AF_INET : AF_INET6; - this[kHandle].addAddress(address, type); + if (!SocketAddress.isSocketAddress(address)) { + validateString(address, 'address'); + validateString(family, 'family'); + address = new SocketAddress({ + address, + family, + }); + } + this[kHandle].addAddress(address[kSocketAddressHandle]); } addRange(start, end, family = 'ipv4') { - validateString(start, 'start'); - validateString(end, 'end'); - validateString(family, 'family'); - family = family.toLowerCase(); - if (family !== 'ipv4' && family !== 'ipv6') - throw new ERR_INVALID_ARG_VALUE('family', family); - const type = family === 'ipv4' ? AF_INET : AF_INET6; - const ret = this[kHandle].addRange(start, end, type); + if (!SocketAddress.isSocketAddress(start)) { + validateString(start, 'start'); + validateString(family, 'family'); + start = new SocketAddress({ + address: start, + family, + }); + } + if (!SocketAddress.isSocketAddress(end)) { + validateString(end, 'end'); + validateString(family, 'family'); + end = new SocketAddress({ + address: end, + family, + }); + } + const ret = this[kHandle].addRange( + start[kSocketAddressHandle], + end[kSocketAddressHandle]); if (ret === false) throw new ERR_INVALID_ARG_VALUE('start', start, 'must come before end'); } addSubnet(network, prefix, family = 'ipv4') { - validateString(network, 'network'); - validateString(family, 'family'); - family = family.toLowerCase(); - let type; - switch (family) { + if (!SocketAddress.isSocketAddress(network)) { + validateString(network, 'network'); + validateString(family, 'family'); + network = new SocketAddress({ + address: network, + family, + }); + } + switch (network.family) { case 'ipv4': - type = AF_INET; validateInt32(prefix, 'prefix', 0, 32); break; case 'ipv6': - type = AF_INET6; validateInt32(prefix, 'prefix', 0, 128); break; - default: - throw new ERR_INVALID_ARG_VALUE('family', family); } - this[kHandle].addSubnet(network, type, prefix); + this[kHandle].addSubnet(network[kSocketAddressHandle], prefix); } check(address, family = 'ipv4') { - validateString(address, 'address'); - validateString(family, 'family'); - family = family.toLowerCase(); - if (family !== 'ipv4' && family !== 'ipv6') - throw new ERR_INVALID_ARG_VALUE('family', family); - const type = family === 'ipv4' ? AF_INET : AF_INET6; - return Boolean(this[kHandle].check(address, type)); + if (!SocketAddress.isSocketAddress(address)) { + validateString(address, 'address'); + validateString(family, 'family'); + try { + address = new SocketAddress({ + address, + family, + }); + } catch { + // Ignore the error. If it's not a valid address, return false. + return false; + } + } + return Boolean(this[kHandle].check(address[kSocketAddressHandle])); } get rules() { diff --git a/lib/internal/socketaddress.js b/lib/internal/socketaddress.js index d341abb297a69c..f3603e0521e96b 100644 --- a/lib/internal/socketaddress.js +++ b/lib/internal/socketaddress.js @@ -47,14 +47,16 @@ class SocketAddress extends JSTransferable { constructor(options = {}) { super(); validateObject(options, 'options'); + let { family = 'ipv4' } = options; const { - family = 'ipv4', address = (family === 'ipv4' ? '127.0.0.1' : '::'), port = 0, flowlabel = 0, } = options; let type; + if (typeof family?.toLowerCase === 'function') + family = family.toLowerCase(); switch (family) { case 'ipv4': type = AF_INET; @@ -63,7 +65,7 @@ class SocketAddress extends JSTransferable { type = AF_INET6; break; default: - throw new ERR_INVALID_ARG_VALUE('options.family', family); + throw new ERR_INVALID_ARG_VALUE('options.family', options.family); } validateString(address, 'options.address'); @@ -150,4 +152,5 @@ ObjectSetPrototypeOf(InternalSocketAddress.prototype, SocketAddress.prototype); module.exports = { SocketAddress, InternalSocketAddress, + kHandle, }; diff --git a/src/node_sockaddr.cc b/src/node_sockaddr.cc index e745589b1258ce..b15b6ab47194c1 100644 --- a/src/node_sockaddr.cc +++ b/src/node_sockaddr.cc @@ -392,18 +392,18 @@ SocketAddressBlockList::SocketAddressBlockList( : parent_(parent) {} void SocketAddressBlockList::AddSocketAddress( - const SocketAddress& address) { + const std::shared_ptr& address) { Mutex::ScopedLock lock(mutex_); std::unique_ptr rule = std::make_unique(address); rules_.emplace_front(std::move(rule)); - address_rules_[address] = rules_.begin(); + address_rules_[*address.get()] = rules_.begin(); } void SocketAddressBlockList::RemoveSocketAddress( - const SocketAddress& address) { + const std::shared_ptr& address) { Mutex::ScopedLock lock(mutex_); - auto it = address_rules_.find(address); + auto it = address_rules_.find(*address.get()); if (it != std::end(address_rules_)) { rules_.erase(it->second); address_rules_.erase(it); @@ -411,8 +411,8 @@ void SocketAddressBlockList::RemoveSocketAddress( } void SocketAddressBlockList::AddSocketAddressRange( - const SocketAddress& start, - const SocketAddress& end) { + const std::shared_ptr& start, + const std::shared_ptr& end) { Mutex::ScopedLock lock(mutex_); std::unique_ptr rule = std::make_unique(start, end); @@ -420,7 +420,7 @@ void SocketAddressBlockList::AddSocketAddressRange( } void SocketAddressBlockList::AddSocketAddressMask( - const SocketAddress& network, + const std::shared_ptr& network, int prefix) { Mutex::ScopedLock lock(mutex_); std::unique_ptr rule = @@ -428,7 +428,8 @@ void SocketAddressBlockList::AddSocketAddressMask( rules_.emplace_front(std::move(rule)); } -bool SocketAddressBlockList::Apply(const SocketAddress& address) { +bool SocketAddressBlockList::Apply( + const std::shared_ptr& address) { Mutex::ScopedLock lock(mutex_); for (const auto& rule : rules_) { if (rule->Apply(address)) @@ -438,59 +439,60 @@ bool SocketAddressBlockList::Apply(const SocketAddress& address) { } SocketAddressBlockList::SocketAddressRule::SocketAddressRule( - const SocketAddress& address_) + const std::shared_ptr& address_) : address(address_) {} SocketAddressBlockList::SocketAddressRangeRule::SocketAddressRangeRule( - const SocketAddress& start_, - const SocketAddress& end_) + const std::shared_ptr& start_, + const std::shared_ptr& end_) : start(start_), end(end_) {} SocketAddressBlockList::SocketAddressMaskRule::SocketAddressMaskRule( - const SocketAddress& network_, + const std::shared_ptr& network_, int prefix_) : network(network_), prefix(prefix_) {} bool SocketAddressBlockList::SocketAddressRule::Apply( - const SocketAddress& address) { - return this->address.is_match(address); + const std::shared_ptr& address) { + return this->address->is_match(*address.get()); } std::string SocketAddressBlockList::SocketAddressRule::ToString() { std::string ret = "Address: "; - ret += address.family() == AF_INET ? "IPv4" : "IPv6"; + ret += address->family() == AF_INET ? "IPv4" : "IPv6"; ret += " "; - ret += address.address(); + ret += address->address(); return ret; } bool SocketAddressBlockList::SocketAddressRangeRule::Apply( - const SocketAddress& address) { - return address >= start && address <= end; + const std::shared_ptr& address) { + return *address.get() >= *start.get() && + *address.get() <= *end.get(); } std::string SocketAddressBlockList::SocketAddressRangeRule::ToString() { std::string ret = "Range: "; - ret += start.family() == AF_INET ? "IPv4" : "IPv6"; + ret += start->family() == AF_INET ? "IPv4" : "IPv6"; ret += " "; - ret += start.address(); + ret += start->address(); ret += "-"; - ret += end.address(); + ret += end->address(); return ret; } bool SocketAddressBlockList::SocketAddressMaskRule::Apply( - const SocketAddress& address) { - return address.is_in_network(network, prefix); + const std::shared_ptr& address) { + return address->is_in_network(*network.get(), prefix); } std::string SocketAddressBlockList::SocketAddressMaskRule::ToString() { std::string ret = "Subnet: "; - ret += network.family() == AF_INET ? "IPv4" : "IPv6"; + ret += network->family() == AF_INET ? "IPv4" : "IPv6"; ret += " "; - ret += network.address(); + ret += network->address(); ret += "/" + std::to_string(prefix); return ret; } @@ -591,20 +593,11 @@ void SocketAddressBlockListWrap::AddAddress( SocketAddressBlockListWrap* wrap; ASSIGN_OR_RETURN_UNWRAP(&wrap, args.Holder()); - CHECK(args[0]->IsString()); - CHECK(args[1]->IsInt32()); - - sockaddr_storage address; - Utf8Value value(args.GetIsolate(), args[0]); - int32_t family; - if (!args[1]->Int32Value(env->context()).To(&family)) - return; - - if (!SocketAddress::ToSockAddr(family, *value, 0, &address)) - return; + CHECK(SocketAddressBase::HasInstance(env, args[0])); + SocketAddressBase* addr; + ASSIGN_OR_RETURN_UNWRAP(&addr, args[0]); - wrap->blocklist_->AddSocketAddress( - SocketAddress(reinterpret_cast(&address))); + wrap->blocklist_->AddSocketAddress(addr->address()); args.GetReturnValue().Set(true); } @@ -615,30 +608,21 @@ void SocketAddressBlockListWrap::AddRange( SocketAddressBlockListWrap* wrap; ASSIGN_OR_RETURN_UNWRAP(&wrap, args.Holder()); - CHECK(args[0]->IsString()); - CHECK(args[1]->IsString()); - CHECK(args[2]->IsInt32()); - - sockaddr_storage address[2]; - Utf8Value start(args.GetIsolate(), args[0]); - Utf8Value end(args.GetIsolate(), args[1]); - int32_t family; - if (!args[2]->Int32Value(env->context()).To(&family)) - return; - - if (!SocketAddress::ToSockAddr(family, *start, 0, &address[0]) || - !SocketAddress::ToSockAddr(family, *end, 0, &address[1])) { - return; - } + CHECK(SocketAddressBase::HasInstance(env, args[0])); + CHECK(SocketAddressBase::HasInstance(env, args[1])); - SocketAddress start_addr(reinterpret_cast(&address[0])); - SocketAddress end_addr(reinterpret_cast(&address[1])); + SocketAddressBase* start_addr; + SocketAddressBase* end_addr; + ASSIGN_OR_RETURN_UNWRAP(&start_addr, args[0]); + ASSIGN_OR_RETURN_UNWRAP(&end_addr, args[1]); // Starting address must come before the end address - if (start_addr > end_addr) + if (*start_addr->address().get() > *end_addr->address().get()) return args.GetReturnValue().Set(false); - wrap->blocklist_->AddSocketAddressRange(start_addr, end_addr); + wrap->blocklist_->AddSocketAddressRange( + start_addr->address(), + end_addr->address()); args.GetReturnValue().Set(true); } @@ -649,29 +633,22 @@ void SocketAddressBlockListWrap::AddSubnet( SocketAddressBlockListWrap* wrap; ASSIGN_OR_RETURN_UNWRAP(&wrap, args.Holder()); - CHECK(args[0]->IsString()); + CHECK(SocketAddressBase::HasInstance(env, args[0])); CHECK(args[1]->IsInt32()); - CHECK(args[2]->IsInt32()); - sockaddr_storage address; - Utf8Value network(args.GetIsolate(), args[0]); - int32_t family; + SocketAddressBase* addr; + ASSIGN_OR_RETURN_UNWRAP(&addr, args[0]); + int32_t prefix; - if (!args[1]->Int32Value(env->context()).To(&family) || - !args[2]->Int32Value(env->context()).To(&prefix)) { + if (!args[1]->Int32Value(env->context()).To(&prefix)) { return; } - if (!SocketAddress::ToSockAddr(family, *network, 0, &address)) - return; - - CHECK_IMPLIES(family == AF_INET, prefix <= 32); - CHECK_IMPLIES(family == AF_INET6, prefix <= 128); + CHECK_IMPLIES(addr->address()->family() == AF_INET, prefix <= 32); + CHECK_IMPLIES(addr->address()->family() == AF_INET6, prefix <= 128); CHECK_GE(prefix, 0); - wrap->blocklist_->AddSocketAddressMask( - SocketAddress(reinterpret_cast(&address)), - prefix); + wrap->blocklist_->AddSocketAddressMask(addr->address(), prefix); args.GetReturnValue().Set(true); } @@ -682,21 +659,11 @@ void SocketAddressBlockListWrap::Check( SocketAddressBlockListWrap* wrap; ASSIGN_OR_RETURN_UNWRAP(&wrap, args.Holder()); - CHECK(args[0]->IsString()); - CHECK(args[1]->IsInt32()); + CHECK(SocketAddressBase::HasInstance(env, args[0])); + SocketAddressBase* addr; + ASSIGN_OR_RETURN_UNWRAP(&addr, args[0]); - sockaddr_storage address; - Utf8Value value(args.GetIsolate(), args[0]); - int32_t family; - if (!args[1]->Int32Value(env->context()).To(&family)) - return; - - if (!SocketAddress::ToSockAddr(family, *value, 0, &address)) - return; - - args.GetReturnValue().Set( - wrap->blocklist_->Apply( - SocketAddress(reinterpret_cast(&address)))); + args.GetReturnValue().Set(wrap->blocklist_->Apply(addr->address())); } void SocketAddressBlockListWrap::GetRules( @@ -869,7 +836,6 @@ void SocketAddressBase::Detail(const FunctionCallbackInfo& args) { } void SocketAddressBase::GetFlowLabel(const FunctionCallbackInfo& args) { - Environment* env = Environment::GetCurrent(args); SocketAddressBase* base; ASSIGN_OR_RETURN_UNWRAP(&base, args.Holder()); args.GetReturnValue().Set(base->address_->flow_label()); diff --git a/src/node_sockaddr.h b/src/node_sockaddr.h index 62dcab6badd2c1..704fe0c5116f8f 100644 --- a/src/node_sockaddr.h +++ b/src/node_sockaddr.h @@ -168,6 +168,10 @@ class SocketAddressBase : public BaseObject { v8::Local wrap, std::shared_ptr address); + inline const std::shared_ptr& address() const { + return address_; + } + void MemoryInfo(MemoryTracker* tracker) const override; SET_MEMORY_INFO_NAME(SocketAddressBase); SET_SELF_SIZE(SocketAddressBase); @@ -246,38 +250,36 @@ class SocketAddressBlockList : public MemoryRetainer { std::shared_ptr parent = {}); ~SocketAddressBlockList() = default; - void AddSocketAddress( - const SocketAddress& address); + void AddSocketAddress(const std::shared_ptr& address); - void RemoveSocketAddress( - const SocketAddress& address); + void RemoveSocketAddress(const std::shared_ptr& address); void AddSocketAddressRange( - const SocketAddress& start, - const SocketAddress& end); + const std::shared_ptr& start, + const std::shared_ptr& end); void AddSocketAddressMask( - const SocketAddress& address, + const std::shared_ptr& address, int prefix); - bool Apply(const SocketAddress& address); + bool Apply(const std::shared_ptr& address); size_t size() const { return rules_.size(); } v8::MaybeLocal ListRules(Environment* env); struct Rule : public MemoryRetainer { - virtual bool Apply(const SocketAddress& address) = 0; + virtual bool Apply(const std::shared_ptr& address) = 0; inline v8::MaybeLocal ToV8String(Environment* env); virtual std::string ToString() = 0; }; struct SocketAddressRule final : Rule { - SocketAddress address; + std::shared_ptr address; - explicit SocketAddressRule(const SocketAddress& address); + explicit SocketAddressRule(const std::shared_ptr& address); - bool Apply(const SocketAddress& address) override; + bool Apply(const std::shared_ptr& address) override; std::string ToString() override; void MemoryInfo(node::MemoryTracker* tracker) const override; @@ -286,14 +288,14 @@ class SocketAddressBlockList : public MemoryRetainer { }; struct SocketAddressRangeRule final : Rule { - SocketAddress start; - SocketAddress end; + std::shared_ptr start; + std::shared_ptr end; SocketAddressRangeRule( - const SocketAddress& start, - const SocketAddress& end); + const std::shared_ptr& start, + const std::shared_ptr& end); - bool Apply(const SocketAddress& address) override; + bool Apply(const std::shared_ptr& address) override; std::string ToString() override; void MemoryInfo(node::MemoryTracker* tracker) const override; @@ -302,14 +304,14 @@ class SocketAddressBlockList : public MemoryRetainer { }; struct SocketAddressMaskRule final : Rule { - SocketAddress network; + std::shared_ptr network; int prefix; SocketAddressMaskRule( - const SocketAddress& address, + const std::shared_ptr& address, int prefix); - bool Apply(const SocketAddress& address) override; + bool Apply(const std::shared_ptr& address) override; std::string ToString() override; void MemoryInfo(node::MemoryTracker* tracker) const override; diff --git a/test/cctest/test_sockaddr.cc b/test/cctest/test_sockaddr.cc index 036dfae78a5ed2..bd80d59f821e5d 100644 --- a/test/cctest/test_sockaddr.cc +++ b/test/cctest/test_sockaddr.cc @@ -197,8 +197,12 @@ TEST(SocketAddressBlockList, Simple) { sockaddr_storage storage[2]; SocketAddress::ToSockAddr(AF_INET, "10.0.0.1", 0, &storage[0]); SocketAddress::ToSockAddr(AF_INET, "10.0.0.2", 0, &storage[1]); - SocketAddress addr1(reinterpret_cast(&storage[0])); - SocketAddress addr2(reinterpret_cast(&storage[1])); + std::shared_ptr addr1 = + std::make_shared( + reinterpret_cast(&storage[0])); + std::shared_ptr addr2 = + std::make_shared( + reinterpret_cast(&storage[1])); bl.AddSocketAddress(addr1); bl.AddSocketAddress(addr2); diff --git a/test/parallel/test-blocklist.js b/test/parallel/test-blocklist.js index 18b5e550bf322c..1f54c92621a257 100644 --- a/test/parallel/test-blocklist.js +++ b/test/parallel/test-blocklist.js @@ -2,7 +2,10 @@ require('../common'); -const { BlockList } = require('net'); +const { + BlockList, + SocketAddress, +} = require('net'); const assert = require('assert'); const util = require('util'); @@ -65,6 +68,36 @@ const util = require('util'); assert(!blockList.check('::1', 'ipv6')); } +{ + const blockList = new BlockList(); + const sa1 = new SocketAddress({ address: '1.1.1.1' }); + const sa2 = new SocketAddress({ + address: '8592:757c:efae:4e45:fb5d:d62a:0d00:8e17', + family: 'ipv6' + }); + const sa3 = new SocketAddress({ address: '1.1.1.2' }); + + blockList.addAddress(sa1); + blockList.addAddress(sa2); + blockList.addAddress('::ffff:1.1.1.2', 'ipv6'); + + assert(blockList.check('1.1.1.1')); + assert(blockList.check(sa1)); + assert(!blockList.check('1.1.1.1', 'ipv6')); + assert(!blockList.check('8592:757c:efae:4e45:fb5d:d62a:0d00:8e17')); + assert(blockList.check('8592:757c:efae:4e45:fb5d:d62a:0d00:8e17', 'ipv6')); + assert(blockList.check(sa2)); + + assert(blockList.check('::ffff:1.1.1.1', 'ipv6')); + assert(blockList.check('::ffff:1.1.1.1', 'IPV6')); + + assert(blockList.check('1.1.1.2')); + assert(blockList.check(sa3)); + + assert(!blockList.check('1.2.3.4')); + assert(!blockList.check('::1', 'ipv6')); +} + { const blockList = new BlockList(); blockList.addRange('1.1.1.1', '1.1.1.10'); @@ -83,6 +116,29 @@ const util = require('util'); assert(!blockList.check('::10', 'ipv6')); } +{ + const blockList = new BlockList(); + const sa1 = new SocketAddress({ address: '1.1.1.1' }); + const sa2 = new SocketAddress({ address: '1.1.1.10' }); + const sa3 = new SocketAddress({ address: '::1', family: 'ipv6' }); + const sa4 = new SocketAddress({ address: '::f', family: 'ipv6' }); + + blockList.addRange(sa1, sa2); + blockList.addRange(sa3, sa4); + + assert(!blockList.check('1.1.1.0')); + for (let n = 1; n <= 10; n++) + assert(blockList.check(`1.1.1.${n}`)); + assert(!blockList.check('1.1.1.11')); + + assert(!blockList.check('::0', 'ipv6')); + for (let n = 0x1; n <= 0xf; n++) { + assert(blockList.check(`::${n.toString(16)}`, 'ipv6'), + `::${n.toString(16)} check failed`); + } + assert(!blockList.check('::10', 'ipv6')); +} + { const blockList = new BlockList(); blockList.addSubnet('1.1.1.0', 16); @@ -98,6 +154,23 @@ const util = require('util'); assert(!blockList.check('8592:757c:efae:4f45::f', 'ipv6')); } +{ + const blockList = new BlockList(); + const sa1 = new SocketAddress({ address: '1.1.1.0' }); + const sa2 = new SocketAddress({ address: '1.1.1.1' }); + blockList.addSubnet(sa1, 16); + blockList.addSubnet('8592:757c:efae:4e45::', 64, 'ipv6'); + + assert(blockList.check('1.1.0.1')); + assert(blockList.check(sa2)); + assert(!blockList.check('1.2.0.1')); + assert(blockList.check('::ffff:1.1.0.1', 'ipv6')); + + assert(blockList.check('8592:757c:efae:4e45:f::', 'ipv6')); + assert(blockList.check('8592:757c:efae:4e45::f', 'ipv6')); + assert(!blockList.check('8592:757c:efae:4f45::f', 'ipv6')); +} + { const blockList = new BlockList(); blockList.addAddress('1.1.1.1'); @@ -110,7 +183,6 @@ const util = require('util'); 'Address: IPv4 1.1.1.1' ]; assert.deepStrictEqual(blockList.rules, rulesCheck); - console.log(blockList); assert(blockList.check('1.1.1.1')); assert(blockList.check('10.0.0.5')); @@ -145,23 +217,27 @@ const util = require('util'); { const blockList = new BlockList(); assert.throws(() => blockList.addSubnet(1), /ERR_INVALID_ARG_TYPE/); - assert.throws(() => blockList.addSubnet('', ''), /ERR_INVALID_ARG_TYPE/); - assert.throws(() => blockList.addSubnet('', NaN), /ERR_OUT_OF_RANGE/); + assert.throws(() => blockList.addSubnet('1.1.1.1', ''), + /ERR_INVALID_ARG_TYPE/); + assert.throws(() => blockList.addSubnet('1.1.1.1', NaN), /ERR_OUT_OF_RANGE/); assert.throws(() => blockList.addSubnet('', 1, 1), /ERR_INVALID_ARG_TYPE/); assert.throws(() => blockList.addSubnet('', 1, ''), /ERR_INVALID_ARG_VALUE/); - assert.throws(() => blockList.addSubnet('', -1, 'ipv4'), /ERR_OUT_OF_RANGE/); - assert.throws(() => blockList.addSubnet('', 33, 'ipv4'), /ERR_OUT_OF_RANGE/); + assert.throws(() => blockList.addSubnet('1.1.1.1', -1, 'ipv4'), + /ERR_OUT_OF_RANGE/); + assert.throws(() => blockList.addSubnet('1.1.1.1', 33, 'ipv4'), + /ERR_OUT_OF_RANGE/); - assert.throws(() => blockList.addSubnet('', -1, 'ipv6'), /ERR_OUT_OF_RANGE/); - assert.throws(() => blockList.addSubnet('', 129, 'ipv6'), /ERR_OUT_OF_RANGE/); + assert.throws(() => blockList.addSubnet('::', -1, 'ipv6'), + /ERR_OUT_OF_RANGE/); + assert.throws(() => blockList.addSubnet('::', 129, 'ipv6'), + /ERR_OUT_OF_RANGE/); } { const blockList = new BlockList(); assert.throws(() => blockList.check(1), /ERR_INVALID_ARG_TYPE/); assert.throws(() => blockList.check('', 1), /ERR_INVALID_ARG_TYPE/); - assert.throws(() => blockList.check('', ''), /ERR_INVALID_ARG_VALUE/); } { diff --git a/tools/doc/type-parser.js b/tools/doc/type-parser.js index c53628679594d4..a77a93a3008451 100644 --- a/tools/doc/type-parser.js +++ b/tools/doc/type-parser.js @@ -175,6 +175,7 @@ const customTypesMap = { 'net.BlockList': 'net.html#net_class_net_blocklist', 'net.Server': 'net.html#net_class_net_server', 'net.Socket': 'net.html#net_class_net_socket', + 'net.SocketAddress': 'net.html#net_class_net_socketaddress', 'NodeEventTarget': 'events.html#events_class_nodeeventtarget',