Skip to content

Commit

Permalink
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
net: allow net.BlockList to use net.SocketAddress objects
Browse files Browse the repository at this point in the history
Signed-off-by: James M Snell <[email protected]>

PR-URL: #37917
Reviewed-By: Matteo Collina <[email protected]>
jasnell authored and BethGriggs committed Aug 12, 2021

Verified

This commit was signed with the committer’s verified signature.
snyk-bot Snyk bot
1 parent 3895945 commit d0a88bc
Showing 8 changed files with 238 additions and 162 deletions.
17 changes: 9 additions & 8 deletions doc/api/net.md
Original file line number Diff line number Diff line change
@@ -69,8 +69,8 @@ IP subnets.
added: REPLACEME
-->

* `address` {string} An IPv4 or IPv6 address.
* `type` {string} Either `'ipv4'` or `'ipv6'`. **Default**: `'ipv4'`.
* `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,9 +79,10 @@ Adds a rule to block the given IP address.
added: REPLACEME
-->

* `start` {string} The starting IPv4 or IPv6 address in the range.
* `end` {string} The ending IPv4 or IPv6 address in the range.
* `type` {string} Either `'ipv4'` or `'ipv6'`. **Default**: `'ipv4'`.
* `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
`end` (inclusive).
@@ -91,7 +92,7 @@ Adds a rule to block a range of IP addresses from `start` (inclusive) to
added: REPLACEME
-->

* `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,8 +105,8 @@ Adds a rule to block a range of IP addresses specified as a subnet mask.
added: REPLACEME
-->

* `address` {string} The IP address to check
* `type` {string} Either `'ipv4'` or `'ipv6'`. **Default**: `'ipv4'`.
* `address` {string|net.SocketAddress} The IP address to check
* `type` {string} Either `'ipv4'` or `'ipv6'`. **Default:** `'ipv4'`.
* Returns: {boolean}

Returns `true` if the given IP address matches any of the rules added to the
91 changes: 57 additions & 34 deletions lib/internal/blocklist.js
Original file line number Diff line number Diff line change
@@ -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() {
7 changes: 5 additions & 2 deletions lib/internal/socketaddress.js
Original file line number Diff line number Diff line change
@@ -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,
};
140 changes: 53 additions & 87 deletions src/node_sockaddr.cc
Original file line number Diff line number Diff line change
@@ -391,43 +391,44 @@ 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);
}
}

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);
rules_.emplace_front(std::move(rule));
}

void SocketAddressBlockList::AddSocketAddressMask(
const SocketAddress& network,
const std::shared_ptr<SocketAddress>& network,
int prefix) {
Mutex::ScopedLock lock(mutex_);
std::unique_ptr<Rule> rule =
std::make_unique<SocketAddressMaskRule>(network, prefix);
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))
@@ -437,59 +438,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;
}
@@ -590,20 +592,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<const sockaddr*>(&address)));
wrap->blocklist_->AddSocketAddress(addr->address());

args.GetReturnValue().Set(true);
}
@@ -614,30 +607,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<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);
}
@@ -648,29 +632,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);
}
@@ -681,21 +658,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(
@@ -868,7 +835,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());
42 changes: 22 additions & 20 deletions src/node_sockaddr.h
Original file line number Diff line number Diff line change
@@ -167,6 +167,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);
@@ -245,38 +249,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;
@@ -285,14 +287,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;
@@ -301,14 +303,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;
8 changes: 6 additions & 2 deletions test/cctest/test_sockaddr.cc
Original file line number Diff line number Diff line change
@@ -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);
94 changes: 85 additions & 9 deletions test/parallel/test-blocklist.js
Original file line number Diff line number Diff line change
@@ -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/);
}

{
1 change: 1 addition & 0 deletions tools/doc/type-parser.mjs
Original file line number Diff line number Diff line change
@@ -125,6 +125,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',

0 comments on commit d0a88bc

Please sign in to comment.