mirror of
https://github.com/zebrajr/node.git
synced 2026-01-15 12:15:26 +00:00
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:
@@ -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}
|
||||
|
||||
|
||||
@@ -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() {
|
||||
|
||||
@@ -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,
|
||||
};
|
||||
|
||||
@@ -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());
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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/);
|
||||
}
|
||||
|
||||
{
|
||||
|
||||
@@ -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',
|
||||
|
||||
Reference in New Issue
Block a user