mirror of
https://github.com/dashpay/dash.git
synced 2024-12-26 04:22:55 +01:00
Merge #20140: Restore compatibility with old CSubNet serialization
886be97af5d4aba338b23a7b20b8560be8156231 Ignore incorrectly-serialized banlist.dat entries (Pieter Wuille) 883cea7dea3cedc9b45b6191f7d4e7be2d9a11ca Restore compatibility with old CSubNet serialization (Pieter Wuille) Pull request description: #19628 changed CSubNet for IPv4 netmasks, using the first 4 bytes of `netmask` rather than the last 4 to store the actual mask. Unfortunately, CSubNet objects are serialized on disk in banlist.dat, breaking compatibility with existing banlists (and bringing them into an inconsistent state where entries reported in `listbanned` cannot be removed). Fix this by reverting to the old format (just for serialization). Also add a sanity check to the deserializer so that nonsensical banlist.dat entries are ignored (which would otherwise be possible if someone added IPv4 entries after #19628 but without this PR). Reported by Greg Maxwell. ACKs for top commit: laanwj: Code review ACK 886be97af5d4aba338b23a7b20b8560be8156231 vasild: ACK 886be97af Tree-SHA512: d3fb91e8ecd933406e527187974f22770374ee2e12a233e7870363f52ecda471fb0b7bae72420e8ff6b6b1594e3037a5115984c023dbadf38f86aeaffcd681e7
This commit is contained in:
parent
857814d1eb
commit
45b30c3b3a
@ -192,7 +192,7 @@ void BanMan::SweepBanned()
|
|||||||
while (it != m_banned.end()) {
|
while (it != m_banned.end()) {
|
||||||
CSubNet sub_net = (*it).first;
|
CSubNet sub_net = (*it).first;
|
||||||
CBanEntry ban_entry = (*it).second;
|
CBanEntry ban_entry = (*it).second;
|
||||||
if (now > ban_entry.nBanUntil) {
|
if (!sub_net.IsValid() || now > ban_entry.nBanUntil) {
|
||||||
m_banned.erase(it++);
|
m_banned.erase(it++);
|
||||||
m_is_dirty = true;
|
m_is_dirty = true;
|
||||||
notify_ui = true;
|
notify_ui = true;
|
||||||
|
@ -1076,6 +1076,17 @@ bool CSubNet::IsValid() const
|
|||||||
return valid;
|
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)
|
bool operator==(const CSubNet& a, const CSubNet& b)
|
||||||
{
|
{
|
||||||
return a.valid == b.valid && a.network == b.network && !memcmp(a.netmask, b.netmask, 16);
|
return a.valid == b.valid && a.network == b.network && !memcmp(a.netmask, b.netmask, 16);
|
||||||
|
@ -461,6 +461,8 @@ class CSubNet
|
|||||||
/// Is this value valid? (only used to signal parse errors)
|
/// Is this value valid? (only used to signal parse errors)
|
||||||
bool valid;
|
bool valid;
|
||||||
|
|
||||||
|
bool SanityCheck() const;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
CSubNet();
|
CSubNet();
|
||||||
CSubNet(const CNetAddr& addr, uint8_t mask);
|
CSubNet(const CNetAddr& addr, uint8_t mask);
|
||||||
@ -478,7 +480,23 @@ class CSubNet
|
|||||||
friend bool operator!=(const CSubNet& a, const CSubNet& b) { return !(a == b); }
|
friend bool operator!=(const CSubNet& a, const CSubNet& b) { return !(a == b); }
|
||||||
friend bool operator<(const CSubNet& a, const CSubNet& 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 */
|
/** A combination of a network address (CNetAddr) and a (TCP) port */
|
||||||
|
Loading…
Reference in New Issue
Block a user