// 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 #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include namespace { TestingSetup* g_setup; void initialize() { static const auto testing_setup = MakeNoLogFileContext( /*chain_type=*/ChainType::REGTEST); g_setup = testing_setup.get(); } } // namespace FUZZ_TARGET(p2p_handshake, .init = ::initialize) { SeedRandomStateForTest(SeedRand::ZEROS); FuzzedDataProvider fuzzed_data_provider(buffer.data(), buffer.size()); auto& node{g_setup->m_node}; auto& connman{static_cast(*node.connman)}; auto& chainman{static_cast(*node.chainman)}; FakeNodeClock clock{1610000000s}; // any time to successfully reset ibd FakeSteadyClock steady_clock; chainman.ResetIbd(); node.banman.reset(); node.addrman.reset(); node.peerman.reset(); node.addrman = std::make_unique( *node.netgroupman, /*deterministic=*/true, /*consistency_check_ratio=*/0); node.peerman = PeerManager::make(connman, *node.addrman, /*banman=*/nullptr, chainman, *node.mempool, *node.warnings, PeerManager::Options{ .reconcile_txs = true, .deterministic_rng = true, }); connman.SetMsgProc(node.peerman.get()); connman.SetAddrman(*node.addrman); LOCK(NetEventsInterface::g_msgproc_mutex); std::vector 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, steady_clock, i).release()); connman.AddTestNode(*peers.back()); node.peerman->InitializeNode( *peers.back(), static_cast(fuzzed_data_provider.ConsumeIntegral())); } 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; } clock += std::chrono::seconds{ fuzzed_data_provider.ConsumeIntegralInRange( -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&) { } node.peerman->SendMessages(connection); } } node.connman->StopNodes(); }