aboutsummaryrefslogtreecommitdiff
path: root/src/test/fuzz/p2p_handshake.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/test/fuzz/p2p_handshake.cpp')
-rw-r--r--src/test/fuzz/p2p_handshake.cpp107
1 files changed, 107 insertions, 0 deletions
diff --git a/src/test/fuzz/p2p_handshake.cpp b/src/test/fuzz/p2p_handshake.cpp
new file mode 100644
index 0000000000..6c1ed11d45
--- /dev/null
+++ b/src/test/fuzz/p2p_handshake.cpp
@@ -0,0 +1,107 @@
+// Copyright (c) 2020-present The Bitcoin Core developers
+// Distributed under the MIT software license, see the accompanying
+// file COPYING or http://www.opensource.org/licenses/mit-license.php.
+
+#include <addrman.h>
+#include <consensus/consensus.h>
+#include <net.h>
+#include <net_processing.h>
+#include <node/warnings.h>
+#include <protocol.h>
+#include <script/script.h>
+#include <sync.h>
+#include <test/fuzz/FuzzedDataProvider.h>
+#include <test/fuzz/fuzz.h>
+#include <test/fuzz/util.h>
+#include <test/fuzz/util/net.h>
+#include <test/util/mining.h>
+#include <test/util/net.h>
+#include <test/util/setup_common.h>
+#include <test/util/validation.h>
+#include <util/time.h>
+#include <validationinterface.h>
+
+#include <ios>
+#include <string>
+#include <utility>
+#include <vector>
+
+namespace {
+const TestingSetup* g_setup;
+
+void initialize()
+{
+ static const auto testing_setup = MakeNoLogFileContext<const TestingSetup>(
+ /*chain_type=*/ChainType::REGTEST);
+ g_setup = testing_setup.get();
+}
+} // namespace
+
+FUZZ_TARGET(p2p_handshake, .init = ::initialize)
+{
+ FuzzedDataProvider fuzzed_data_provider(buffer.data(), buffer.size());
+
+ ConnmanTestMsg& connman = static_cast<ConnmanTestMsg&>(*g_setup->m_node.connman);
+ auto& chainman = static_cast<TestChainstateManager&>(*g_setup->m_node.chainman);
+ SetMockTime(1610000000); // any time to successfully reset ibd
+ chainman.ResetIbd();
+
+ node::Warnings warnings{};
+ NetGroupManager netgroupman{{}};
+ AddrMan addrman{netgroupman, /*deterministic=*/true, 0};
+ auto peerman = PeerManager::make(connman, addrman,
+ /*banman=*/nullptr, chainman,
+ *g_setup->m_node.mempool, warnings,
+ PeerManager::Options{
+ .reconcile_txs = true,
+ .deterministic_rng = true,
+ });
+ connman.SetMsgProc(peerman.get());
+
+ LOCK(NetEventsInterface::g_msgproc_mutex);
+
+ std::vector<CNode*> peers;
+ const auto num_peers_to_add = fuzzed_data_provider.ConsumeIntegralInRange(1, 3);
+ for (int i = 0; i < num_peers_to_add; ++i) {
+ peers.push_back(ConsumeNodeAsUniquePtr(fuzzed_data_provider, i).release());
+ connman.AddTestNode(*peers.back());
+ peerman->InitializeNode(
+ *peers.back(),
+ static_cast<ServiceFlags>(fuzzed_data_provider.ConsumeIntegral<uint64_t>()));
+ }
+
+ LIMITED_WHILE(fuzzed_data_provider.ConsumeBool(), 100)
+ {
+ CNode& connection = *PickValue(fuzzed_data_provider, peers);
+ if (connection.fDisconnect || connection.fSuccessfullyConnected) {
+ // Skip if the connection was disconnected or if the version
+ // handshake was already completed.
+ continue;
+ }
+
+ SetMockTime(GetTime() +
+ fuzzed_data_provider.ConsumeIntegralInRange<int64_t>(
+ -std::chrono::seconds{10min}.count(), // Allow mocktime to go backwards slightly
+ std::chrono::seconds{TIMEOUT_INTERVAL}.count()));
+
+ CSerializedNetMsg net_msg;
+ net_msg.m_type = PickValue(fuzzed_data_provider, ALL_NET_MESSAGE_TYPES);
+ net_msg.data = ConsumeRandomLengthByteVector(fuzzed_data_provider, MAX_PROTOCOL_MESSAGE_LENGTH);
+
+ connman.FlushSendBuffer(connection);
+ (void)connman.ReceiveMsgFrom(connection, std::move(net_msg));
+
+ bool more_work{true};
+ while (more_work) {
+ connection.fPauseSend = false;
+
+ try {
+ more_work = connman.ProcessMessagesOnce(connection);
+ } catch (const std::ios_base::failure&) {
+ }
+ peerman->SendMessages(&connection);
+ }
+ }
+
+ g_setup->m_node.connman->StopNodes();
+}