net: allow net.BlockList to use net.SocketAddress objects

Signed-off-by: James M Snell <jasnell@gmail.com>

PR-URL: https://github.com/nodejs/node/pull/37917
Reviewed-By: Matteo Collina <matteo.collina@gmail.com>
This commit is contained in:
James M Snell
2021-03-25 13:27:03 -07:00
parent 0b90d35294
commit e79471deb7
8 changed files with 235 additions and 159 deletions

View File

@@ -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}

View File

@@ -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() {

View File

@@ -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,
};

View File

@@ -392,18 +392,18 @@ SocketAddressBlockList::SocketAddressBlockList(
: parent_(parent) {}
void SocketAddressBlockList::AddSocketAddress(
const SocketAddress& address) {
const std::shared_ptr<SocketAddress>& address) {
Mutex::ScopedLock lock(mutex_);
std::unique_ptr<Rule> rule =
std::make_unique<SocketAddressRule>(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<SocketAddress>& 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<SocketAddress>& start,
const std::shared_ptr<SocketAddress>& end) {
Mutex::ScopedLock lock(mutex_);
std::unique_ptr<Rule> rule =
std::make_unique<SocketAddressRangeRule>(start, end);
@@ -420,7 +420,7 @@ void SocketAddressBlockList::AddSocketAddressRange(
}
void SocketAddressBlockList::AddSocketAddressMask(
const SocketAddress& network,
const std::shared_ptr<SocketAddress>& network,
int prefix) {
Mutex::ScopedLock lock(mutex_);
std::unique_ptr<Rule> 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<SocketAddress>& 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<SocketAddress>& address_)
: address(address_) {}
SocketAddressBlockList::SocketAddressRangeRule::SocketAddressRangeRule(
const SocketAddress& start_,
const SocketAddress& end_)
const std::shared_ptr<SocketAddress>& start_,
const std::shared_ptr<SocketAddress>& end_)
: start(start_),
end(end_) {}
SocketAddressBlockList::SocketAddressMaskRule::SocketAddressMaskRule(
const SocketAddress& network_,
const std::shared_ptr<SocketAddress>& network_,
int prefix_)
: network(network_),
prefix(prefix_) {}
bool SocketAddressBlockList::SocketAddressRule::Apply(
const SocketAddress& address) {
return this->address.is_match(address);
const std::shared_ptr<SocketAddress>& 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<SocketAddress>& 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<SocketAddress>& 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());
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;
wrap->blocklist_->AddSocketAddress(
SocketAddress(reinterpret_cast<const sockaddr*>(&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());
CHECK(SocketAddressBase::HasInstance(env, args[0]));
CHECK(SocketAddressBase::HasInstance(env, args[1]));
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;
}
SocketAddress start_addr(reinterpret_cast<const sockaddr*>(&address[0]));
SocketAddress end_addr(reinterpret_cast<const sockaddr*>(&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<const sockaddr*>(&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<const sockaddr*>(&address))));
args.GetReturnValue().Set(wrap->blocklist_->Apply(addr->address()));
}
void SocketAddressBlockListWrap::GetRules(
@@ -869,7 +836,6 @@ void SocketAddressBase::Detail(const FunctionCallbackInfo<Value>& args) {
}
void SocketAddressBase::GetFlowLabel(const FunctionCallbackInfo<Value>& args) {
Environment* env = Environment::GetCurrent(args);
SocketAddressBase* base;
ASSIGN_OR_RETURN_UNWRAP(&base, args.Holder());
args.GetReturnValue().Set(base->address_->flow_label());

View File

@@ -168,6 +168,10 @@ class SocketAddressBase : public BaseObject {
v8::Local<v8::Object> wrap,
std::shared_ptr<SocketAddress> address);
inline const std::shared_ptr<SocketAddress>& 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<SocketAddressBlockList> parent = {});
~SocketAddressBlockList() = default;
void AddSocketAddress(
const SocketAddress& address);
void AddSocketAddress(const std::shared_ptr<SocketAddress>& address);
void RemoveSocketAddress(
const SocketAddress& address);
void RemoveSocketAddress(const std::shared_ptr<SocketAddress>& address);
void AddSocketAddressRange(
const SocketAddress& start,
const SocketAddress& end);
const std::shared_ptr<SocketAddress>& start,
const std::shared_ptr<SocketAddress>& end);
void AddSocketAddressMask(
const SocketAddress& address,
const std::shared_ptr<SocketAddress>& address,
int prefix);
bool Apply(const SocketAddress& address);
bool Apply(const std::shared_ptr<SocketAddress>& address);
size_t size() const { return rules_.size(); }
v8::MaybeLocal<v8::Array> ListRules(Environment* env);
struct Rule : public MemoryRetainer {
virtual bool Apply(const SocketAddress& address) = 0;
virtual bool Apply(const std::shared_ptr<SocketAddress>& address) = 0;
inline v8::MaybeLocal<v8::Value> ToV8String(Environment* env);
virtual std::string ToString() = 0;
};
struct SocketAddressRule final : Rule {
SocketAddress address;
std::shared_ptr<SocketAddress> address;
explicit SocketAddressRule(const SocketAddress& address);
explicit SocketAddressRule(const std::shared_ptr<SocketAddress>& address);
bool Apply(const SocketAddress& address) override;
bool Apply(const std::shared_ptr<SocketAddress>& 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<SocketAddress> start;
std::shared_ptr<SocketAddress> end;
SocketAddressRangeRule(
const SocketAddress& start,
const SocketAddress& end);
const std::shared_ptr<SocketAddress>& start,
const std::shared_ptr<SocketAddress>& end);
bool Apply(const SocketAddress& address) override;
bool Apply(const std::shared_ptr<SocketAddress>& 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<SocketAddress> network;
int prefix;
SocketAddressMaskRule(
const SocketAddress& address,
const std::shared_ptr<SocketAddress>& address,
int prefix);
bool Apply(const SocketAddress& address) override;
bool Apply(const std::shared_ptr<SocketAddress>& address) override;
std::string ToString() override;
void MemoryInfo(node::MemoryTracker* tracker) const override;

View File

@@ -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<const sockaddr*>(&storage[0]));
SocketAddress addr2(reinterpret_cast<const sockaddr*>(&storage[1]));
std::shared_ptr<SocketAddress> addr1 =
std::make_shared<SocketAddress>(
reinterpret_cast<const sockaddr*>(&storage[0]));
std::shared_ptr<SocketAddress> addr2 =
std::make_shared<SocketAddress>(
reinterpret_cast<const sockaddr*>(&storage[1]));
bl.AddSocketAddress(addr1);
bl.AddSocketAddress(addr2);

View File

@@ -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/);
}
{

View File

@@ -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',