aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/banman.cpp2
-rw-r--r--src/netaddress.cpp11
-rw-r--r--src/netaddress.h20
3 files changed, 31 insertions, 2 deletions
diff --git a/src/banman.cpp b/src/banman.cpp
index 8752185a60..995fef3d07 100644
--- a/src/banman.cpp
+++ b/src/banman.cpp
@@ -184,7 +184,7 @@ void BanMan::SweepBanned()
while (it != m_banned.end()) {
CSubNet sub_net = (*it).first;
CBanEntry ban_entry = (*it).second;
- if (now > ban_entry.nBanUntil) {
+ if (!sub_net.IsValid() || now > ban_entry.nBanUntil) {
m_banned.erase(it++);
m_is_dirty = true;
notify_ui = true;
diff --git a/src/netaddress.cpp b/src/netaddress.cpp
index 6695ec3700..c0193fa2e9 100644
--- a/src/netaddress.cpp
+++ b/src/netaddress.cpp
@@ -1109,6 +1109,17 @@ bool CSubNet::IsValid() const
return valid;
}
+bool CSubNet::SanityCheck() const
+{
+ if (!(network.IsIPv4() || network.IsIPv6())) return false;
+
+ for (size_t x = 0; x < network.m_addr.size(); ++x) {
+ if (network.m_addr[x] & ~netmask[x]) return false;
+ }
+
+ return true;
+}
+
bool operator==(const CSubNet& a, const CSubNet& b)
{
return a.valid == b.valid && a.network == b.network && !memcmp(a.netmask, b.netmask, 16);
diff --git a/src/netaddress.h b/src/netaddress.h
index 9c8148e33e..f35b01d202 100644
--- a/src/netaddress.h
+++ b/src/netaddress.h
@@ -459,6 +459,8 @@ class CSubNet
/// Is this value valid? (only used to signal parse errors)
bool valid;
+ bool SanityCheck() const;
+
public:
CSubNet();
CSubNet(const CNetAddr& addr, uint8_t mask);
@@ -476,7 +478,23 @@ class CSubNet
friend bool operator!=(const CSubNet& a, const CSubNet& b) { return !(a == b); }
friend bool operator<(const CSubNet& a, const CSubNet& b);
- SERIALIZE_METHODS(CSubNet, obj) { READWRITE(obj.network, obj.netmask, obj.valid); }
+ SERIALIZE_METHODS(CSubNet, obj)
+ {
+ READWRITE(obj.network);
+ if (obj.network.IsIPv4()) {
+ // Before commit 102867c587f5f7954232fb8ed8e85cda78bb4d32, CSubNet used the last 4 bytes of netmask
+ // to store the relevant bytes for an IPv4 mask. For compatiblity reasons, keep doing so in
+ // serialized form.
+ unsigned char dummy[12] = {0};
+ READWRITE(dummy);
+ READWRITE(MakeSpan(obj.netmask).first(4));
+ } else {
+ READWRITE(obj.netmask);
+ }
+ READWRITE(obj.valid);
+ // Mark invalid if the result doesn't pass sanity checking.
+ SER_READ(obj, if (obj.valid) obj.valid = obj.SanityCheck());
+ }
};
/** A combination of a network address (CNetAddr) and a (TCP) port */