Merge pull request #3173 from gavinandresen/fuzzmessages
-fuzzmessagestest=N : randomly corrupt 1-of-N sent messages
This commit is contained in:
commit
951ed190fb
4 changed files with 94 additions and 3 deletions
35
src/net.cpp
35
src/net.cpp
|
@ -1894,3 +1894,38 @@ uint64 CNode::GetTotalBytesSent()
|
||||||
LOCK(cs_totalBytesSent);
|
LOCK(cs_totalBytesSent);
|
||||||
return nTotalBytesSent;
|
return nTotalBytesSent;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CNode::Fuzz(int nChance)
|
||||||
|
{
|
||||||
|
if (!fSuccessfullyConnected) return; // Don't fuzz initial handshake
|
||||||
|
if (GetRand(nChance) != 0) return; // Fuzz 1 of every nChance messages
|
||||||
|
|
||||||
|
switch (GetRand(3))
|
||||||
|
{
|
||||||
|
case 0:
|
||||||
|
// xor a random byte with a random value:
|
||||||
|
if (!ssSend.empty()) {
|
||||||
|
CDataStream::size_type pos = GetRand(ssSend.size());
|
||||||
|
ssSend[pos] ^= (unsigned char)(GetRand(256));
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
// delete a random byte:
|
||||||
|
if (!ssSend.empty()) {
|
||||||
|
CDataStream::size_type pos = GetRand(ssSend.size());
|
||||||
|
ssSend.erase(ssSend.begin()+pos);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
// insert a random byte at a random position
|
||||||
|
{
|
||||||
|
CDataStream::size_type pos = GetRand(ssSend.size());
|
||||||
|
char ch = (char)GetRand(256);
|
||||||
|
ssSend.insert(ssSend.begin()+pos, ch);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
// Chance of more than one change half the time:
|
||||||
|
// (more changes exponentially less likely):
|
||||||
|
Fuzz(2);
|
||||||
|
}
|
||||||
|
|
10
src/net.h
10
src/net.h
|
@ -218,6 +218,9 @@ protected:
|
||||||
static CCriticalSection cs_setBanned;
|
static CCriticalSection cs_setBanned;
|
||||||
int nMisbehavior;
|
int nMisbehavior;
|
||||||
|
|
||||||
|
// Basic fuzz-testing
|
||||||
|
void Fuzz(int nChance); // modifies ssSend
|
||||||
|
|
||||||
public:
|
public:
|
||||||
uint256 hashContinue;
|
uint256 hashContinue;
|
||||||
CBlockIndex* pindexLastGetBlocksBegin;
|
CBlockIndex* pindexLastGetBlocksBegin;
|
||||||
|
@ -434,12 +437,17 @@ public:
|
||||||
// TODO: Document the precondition of this function. Is cs_vSend locked?
|
// TODO: Document the precondition of this function. Is cs_vSend locked?
|
||||||
void EndMessage() UNLOCK_FUNCTION(cs_vSend)
|
void EndMessage() UNLOCK_FUNCTION(cs_vSend)
|
||||||
{
|
{
|
||||||
if (mapArgs.count("-dropmessagestest") && GetRand(atoi(mapArgs["-dropmessagestest"])) == 0)
|
// The -*messagestest options are intentionally not documented in the help message,
|
||||||
|
// since they are only used during development to debug the networking code and are
|
||||||
|
// not intended for end-users.
|
||||||
|
if (mapArgs.count("-dropmessagestest") && GetRand(GetArg("-dropmessagestest", 2)) == 0)
|
||||||
{
|
{
|
||||||
LogPrint("net", "dropmessages DROPPING SEND MESSAGE\n");
|
LogPrint("net", "dropmessages DROPPING SEND MESSAGE\n");
|
||||||
AbortMessage();
|
AbortMessage();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
if (mapArgs.count("-fuzzmessagestest"))
|
||||||
|
Fuzz(GetArg("-fuzzmessagestest", 10));
|
||||||
|
|
||||||
if (ssSend.size() == 0)
|
if (ssSend.size() == 0)
|
||||||
return;
|
return;
|
||||||
|
|
|
@ -1091,8 +1091,8 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
void GetAndClear(CSerializeData &data) {
|
void GetAndClear(CSerializeData &data) {
|
||||||
vch.swap(data);
|
data.insert(data.end(), begin(), end());
|
||||||
CSerializeData().swap(vch);
|
clear();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -102,4 +102,52 @@ BOOST_AUTO_TEST_CASE(noncanonical)
|
||||||
BOOST_CHECK_EXCEPTION(ReadCompactSize(ss), std::ios_base::failure, isCanonicalException);
|
BOOST_CHECK_EXCEPTION(ReadCompactSize(ss), std::ios_base::failure, isCanonicalException);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
BOOST_AUTO_TEST_CASE(insert_delete)
|
||||||
|
{
|
||||||
|
// Test inserting/deleting bytes.
|
||||||
|
CDataStream ss(SER_DISK, 0);
|
||||||
|
BOOST_CHECK_EQUAL(ss.size(), 0);
|
||||||
|
|
||||||
|
ss.write("\x00\x01\x02\xff", 4);
|
||||||
|
BOOST_CHECK_EQUAL(ss.size(), 4);
|
||||||
|
|
||||||
|
char c = (char)11;
|
||||||
|
|
||||||
|
// Inserting at beginning/end/middle:
|
||||||
|
ss.insert(ss.begin(), c);
|
||||||
|
BOOST_CHECK_EQUAL(ss.size(), 5);
|
||||||
|
BOOST_CHECK_EQUAL(ss[0], c);
|
||||||
|
BOOST_CHECK_EQUAL(ss[1], 0);
|
||||||
|
|
||||||
|
ss.insert(ss.end(), c);
|
||||||
|
BOOST_CHECK_EQUAL(ss.size(), 6);
|
||||||
|
BOOST_CHECK_EQUAL(ss[4], (char)0xff);
|
||||||
|
BOOST_CHECK_EQUAL(ss[5], c);
|
||||||
|
|
||||||
|
ss.insert(ss.begin()+2, c);
|
||||||
|
BOOST_CHECK_EQUAL(ss.size(), 7);
|
||||||
|
BOOST_CHECK_EQUAL(ss[2], c);
|
||||||
|
|
||||||
|
// Delete at beginning/end/middle
|
||||||
|
ss.erase(ss.begin());
|
||||||
|
BOOST_CHECK_EQUAL(ss.size(), 6);
|
||||||
|
BOOST_CHECK_EQUAL(ss[0], 0);
|
||||||
|
|
||||||
|
ss.erase(ss.begin()+ss.size()-1);
|
||||||
|
BOOST_CHECK_EQUAL(ss.size(), 5);
|
||||||
|
BOOST_CHECK_EQUAL(ss[4], (char)0xff);
|
||||||
|
|
||||||
|
ss.erase(ss.begin()+1);
|
||||||
|
BOOST_CHECK_EQUAL(ss.size(), 4);
|
||||||
|
BOOST_CHECK_EQUAL(ss[0], 0);
|
||||||
|
BOOST_CHECK_EQUAL(ss[1], 1);
|
||||||
|
BOOST_CHECK_EQUAL(ss[2], 2);
|
||||||
|
BOOST_CHECK_EQUAL(ss[3], (char)0xff);
|
||||||
|
|
||||||
|
// Make sure GetAndClear does the right thing:
|
||||||
|
CSerializeData d;
|
||||||
|
ss.GetAndClear(d);
|
||||||
|
BOOST_CHECK_EQUAL(ss.size(), 0);
|
||||||
|
}
|
||||||
|
|
||||||
BOOST_AUTO_TEST_SUITE_END()
|
BOOST_AUTO_TEST_SUITE_END()
|
||||||
|
|
Loading…
Reference in a new issue