Skip to content

Commit 951ed19

Browse files
committed
Merge pull request #3173 from gavinandresen/fuzzmessages
-fuzzmessagestest=N : randomly corrupt 1-of-N sent messages
2 parents e13934c + 9038b18 commit 951ed19

File tree

4 files changed

+94
-3
lines changed

4 files changed

+94
-3
lines changed

src/net.cpp

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1894,3 +1894,38 @@ uint64 CNode::GetTotalBytesSent()
18941894
LOCK(cs_totalBytesSent);
18951895
return nTotalBytesSent;
18961896
}
1897+
1898+
void CNode::Fuzz(int nChance)
1899+
{
1900+
if (!fSuccessfullyConnected) return; // Don't fuzz initial handshake
1901+
if (GetRand(nChance) != 0) return; // Fuzz 1 of every nChance messages
1902+
1903+
switch (GetRand(3))
1904+
{
1905+
case 0:
1906+
// xor a random byte with a random value:
1907+
if (!ssSend.empty()) {
1908+
CDataStream::size_type pos = GetRand(ssSend.size());
1909+
ssSend[pos] ^= (unsigned char)(GetRand(256));
1910+
}
1911+
break;
1912+
case 1:
1913+
// delete a random byte:
1914+
if (!ssSend.empty()) {
1915+
CDataStream::size_type pos = GetRand(ssSend.size());
1916+
ssSend.erase(ssSend.begin()+pos);
1917+
}
1918+
break;
1919+
case 2:
1920+
// insert a random byte at a random position
1921+
{
1922+
CDataStream::size_type pos = GetRand(ssSend.size());
1923+
char ch = (char)GetRand(256);
1924+
ssSend.insert(ssSend.begin()+pos, ch);
1925+
}
1926+
break;
1927+
}
1928+
// Chance of more than one change half the time:
1929+
// (more changes exponentially less likely):
1930+
Fuzz(2);
1931+
}

src/net.h

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -218,6 +218,9 @@ class CNode
218218
static CCriticalSection cs_setBanned;
219219
int nMisbehavior;
220220

221+
// Basic fuzz-testing
222+
void Fuzz(int nChance); // modifies ssSend
223+
221224
public:
222225
uint256 hashContinue;
223226
CBlockIndex* pindexLastGetBlocksBegin;
@@ -434,12 +437,17 @@ class CNode
434437
// TODO: Document the precondition of this function. Is cs_vSend locked?
435438
void EndMessage() UNLOCK_FUNCTION(cs_vSend)
436439
{
437-
if (mapArgs.count("-dropmessagestest") && GetRand(atoi(mapArgs["-dropmessagestest"])) == 0)
440+
// The -*messagestest options are intentionally not documented in the help message,
441+
// since they are only used during development to debug the networking code and are
442+
// not intended for end-users.
443+
if (mapArgs.count("-dropmessagestest") && GetRand(GetArg("-dropmessagestest", 2)) == 0)
438444
{
439445
LogPrint("net", "dropmessages DROPPING SEND MESSAGE\n");
440446
AbortMessage();
441447
return;
442448
}
449+
if (mapArgs.count("-fuzzmessagestest"))
450+
Fuzz(GetArg("-fuzzmessagestest", 10));
443451

444452
if (ssSend.size() == 0)
445453
return;

src/serialize.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1091,8 +1091,8 @@ class CDataStream
10911091
}
10921092

10931093
void GetAndClear(CSerializeData &data) {
1094-
vch.swap(data);
1095-
CSerializeData().swap(vch);
1094+
data.insert(data.end(), begin(), end());
1095+
clear();
10961096
}
10971097
};
10981098

src/test/serialize_tests.cpp

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -102,4 +102,52 @@ BOOST_AUTO_TEST_CASE(noncanonical)
102102
BOOST_CHECK_EXCEPTION(ReadCompactSize(ss), std::ios_base::failure, isCanonicalException);
103103
}
104104

105+
BOOST_AUTO_TEST_CASE(insert_delete)
106+
{
107+
// Test inserting/deleting bytes.
108+
CDataStream ss(SER_DISK, 0);
109+
BOOST_CHECK_EQUAL(ss.size(), 0);
110+
111+
ss.write("\x00\x01\x02\xff", 4);
112+
BOOST_CHECK_EQUAL(ss.size(), 4);
113+
114+
char c = (char)11;
115+
116+
// Inserting at beginning/end/middle:
117+
ss.insert(ss.begin(), c);
118+
BOOST_CHECK_EQUAL(ss.size(), 5);
119+
BOOST_CHECK_EQUAL(ss[0], c);
120+
BOOST_CHECK_EQUAL(ss[1], 0);
121+
122+
ss.insert(ss.end(), c);
123+
BOOST_CHECK_EQUAL(ss.size(), 6);
124+
BOOST_CHECK_EQUAL(ss[4], (char)0xff);
125+
BOOST_CHECK_EQUAL(ss[5], c);
126+
127+
ss.insert(ss.begin()+2, c);
128+
BOOST_CHECK_EQUAL(ss.size(), 7);
129+
BOOST_CHECK_EQUAL(ss[2], c);
130+
131+
// Delete at beginning/end/middle
132+
ss.erase(ss.begin());
133+
BOOST_CHECK_EQUAL(ss.size(), 6);
134+
BOOST_CHECK_EQUAL(ss[0], 0);
135+
136+
ss.erase(ss.begin()+ss.size()-1);
137+
BOOST_CHECK_EQUAL(ss.size(), 5);
138+
BOOST_CHECK_EQUAL(ss[4], (char)0xff);
139+
140+
ss.erase(ss.begin()+1);
141+
BOOST_CHECK_EQUAL(ss.size(), 4);
142+
BOOST_CHECK_EQUAL(ss[0], 0);
143+
BOOST_CHECK_EQUAL(ss[1], 1);
144+
BOOST_CHECK_EQUAL(ss[2], 2);
145+
BOOST_CHECK_EQUAL(ss[3], (char)0xff);
146+
147+
// Make sure GetAndClear does the right thing:
148+
CSerializeData d;
149+
ss.GetAndClear(d);
150+
BOOST_CHECK_EQUAL(ss.size(), 0);
151+
}
152+
105153
BOOST_AUTO_TEST_SUITE_END()

0 commit comments

Comments
 (0)