aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGavin Andresen <gavinandresen@gmail.com>2013-10-28 16:28:00 +1000
committerGavin Andresen <gavinandresen@gmail.com>2013-10-29 11:20:14 +1000
commit9038b18f4655a5b8ad119d768decd1c693ebd7dd (patch)
tree6c1f93a7b83201ef029347bfdbf388a9216860b8
parentd5d1425657d0dd2dc76f4938c8141a387a81a5a8 (diff)
-fuzzmessagestest=N : randomly corrupt 1-of-N sent messages
I needed this to test the new "reject" p2p message, but it should be generally useful for fuzz-testing network message handling code.
-rw-r--r--src/net.cpp35
-rw-r--r--src/net.h10
2 files changed, 44 insertions, 1 deletions
diff --git a/src/net.cpp b/src/net.cpp
index d223b3999e..de8543da59 100644
--- a/src/net.cpp
+++ b/src/net.cpp
@@ -1894,3 +1894,38 @@ uint64 CNode::GetTotalBytesSent()
LOCK(cs_totalBytesSent);
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);
+}
diff --git a/src/net.h b/src/net.h
index a1dc19df34..b32178ad41 100644
--- a/src/net.h
+++ b/src/net.h
@@ -218,6 +218,9 @@ protected:
static CCriticalSection cs_setBanned;
int nMisbehavior;
+ // Basic fuzz-testing
+ void Fuzz(int nChance); // modifies ssSend
+
public:
uint256 hashContinue;
CBlockIndex* pindexLastGetBlocksBegin;
@@ -434,12 +437,17 @@ public:
// TODO: Document the precondition of this function. Is cs_vSend locked?
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");
AbortMessage();
return;
}
+ if (mapArgs.count("-fuzzmessagestest"))
+ Fuzz(GetArg("-fuzzmessagestest", 10));
if (ssSend.size() == 0)
return;