Inside Bitcoin
Opening the selected file…
Inside Bitcoin
Opening the selected file…
The code behind the network, with room to understand it.
Release published 2026-10-28 · Snapshot fetched 2026-11-01. Latest stable release at fetch time; development branches and Git history are excluded. Only the selected code window and visible folders load here.
251};252if (m_fuzzed_data_provider.ConsumeBool()) {253SetFuzzedErrNo(m_fuzzed_data_provider, connect_errnos);254return -1;255}256return 0;257}259int FuzzedSock::Bind(const sockaddr*, socklen_t) const260{261// Have a permanent error at bind_errnos[0] because when the fuzzed data is exhausted262// SetFuzzedErrNo() will always set the global errno to bind_errnos[0]. We want to263// avoid this method returning -1 and setting errno to a temporary error (like EAGAIN)264// repeatedly because proper code should retry on temporary errors, leading to an265// infinite loop.266constexpr std::array bind_errnos{267EACCES,268EADDRINUSE,269EADDRNOTAVAIL,270EAGAIN,271};272if (m_fuzzed_data_provider.ConsumeBool()) {273SetFuzzedErrNo(m_fuzzed_data_provider, bind_errnos);274return -1;275}276return 0;277}279int FuzzedSock::Listen(int) const280{281// Have a permanent error at listen_errnos[0] because when the fuzzed data is exhausted282// SetFuzzedErrNo() will always set the global errno to listen_errnos[0]. We want to283// avoid this method returning -1 and setting errno to a temporary error (like EAGAIN)284// repeatedly because proper code should retry on temporary errors, leading to an285// infinite loop.286constexpr std::array listen_errnos{287EADDRINUSE,288EINVAL,289EOPNOTSUPP,290};291if (m_fuzzed_data_provider.ConsumeBool()) {292SetFuzzedErrNo(m_fuzzed_data_provider, listen_errnos);293return -1;294}295return 0;296}298std::unique_ptr<Sock> FuzzedSock::Accept(sockaddr* addr, socklen_t* addr_len) const299{300constexpr std::array accept_errnos{301ECONNABORTED,302EINTR,303ENOMEM,304};305if (m_fuzzed_data_provider.ConsumeBool()) {306SetFuzzedErrNo(m_fuzzed_data_provider, accept_errnos);307return std::unique_ptr<FuzzedSock>();308}309if (addr != nullptr) {310// Set a fuzzed address in the output argument addr.311memset(addr, 0x00, *addr_len);312if (m_fuzzed_data_provider.ConsumeBool()) {313// IPv4314const socklen_t write_len = static_cast<socklen_t>(sizeof(sockaddr_in));315if (*addr_len >= write_len) {316*addr_len = write_len;317auto addr4 = reinterpret_cast<sockaddr_in*>(addr);318addr4->sin_family = AF_INET;319const auto sin_addr_bytes{m_fuzzed_data_provider.ConsumeBytes<std::byte>(sizeof(addr4->sin_addr))};320std::ranges::copy(sin_addr_bytes, reinterpret_cast<std::byte*>(&addr4->sin_addr));321addr4->sin_port = m_fuzzed_data_provider.ConsumeIntegralInRange<uint16_t>(1, 65535);322}323} else {324// IPv6325const socklen_t write_len = static_cast<socklen_t>(sizeof(sockaddr_in6));326if (*addr_len >= write_len) {327*addr_len = write_len;328auto addr6 = reinterpret_cast<sockaddr_in6*>(addr);329addr6->sin6_family = AF_INET6;330const auto sin_addr_bytes{m_fuzzed_data_provider.ConsumeBytes<std::byte>(sizeof(addr6->sin6_addr))};331std::ranges::copy(sin_addr_bytes, reinterpret_cast<std::byte*>(&addr6->sin6_addr));332addr6->sin6_port = m_fuzzed_data_provider.ConsumeIntegralInRange<uint16_t>(1, 65535);333}334}335}336return std::make_unique<FuzzedSock>(m_fuzzed_data_provider, m_clock);337}339int FuzzedSock::GetSockOpt(int level, int opt_name, void* opt_val, socklen_t* opt_len) const340{341constexpr std::array getsockopt_errnos{342ENOMEM,343ENOBUFS,344};345if (m_fuzzed_data_provider.ConsumeBool()) {346SetFuzzedErrNo(m_fuzzed_data_provider, getsockopt_errnos);347return -1;348}349if (opt_val == nullptr) {350return 0;351}352std::memcpy(opt_val,353ConsumeFixedLengthByteVector(m_fuzzed_data_provider, *opt_len).data(),354*opt_len);355return 0;356}358int FuzzedSock::SetSockOpt(int, int, const void*, socklen_t) const359{360constexpr std::array setsockopt_errnos{361ENOMEM,362ENOBUFS,363};364if (m_fuzzed_data_provider.ConsumeBool()) {365SetFuzzedErrNo(m_fuzzed_data_provider, setsockopt_errnos);366return -1;367}368return 0;369}371int FuzzedSock::GetSockName(sockaddr* name, socklen_t* name_len) const372{373constexpr std::array getsockname_errnos{374ECONNRESET,375ENOBUFS,376};377if (m_fuzzed_data_provider.ConsumeBool()) {378SetFuzzedErrNo(m_fuzzed_data_provider, getsockname_errnos);379return -1;380}381assert(name_len);382const auto bytes{ConsumeRandomLengthByteVector(m_fuzzed_data_provider, *name_len)};383if (bytes.size() < (int)sizeof(sockaddr)) return -1;384std::memcpy(name, bytes.data(), bytes.size());385*name_len = bytes.size();386return 0;387}389bool FuzzedSock::SetNonBlocking() const390{391constexpr std::array setnonblocking_errnos{392EBADF,393EPERM,394};395if (m_fuzzed_data_provider.ConsumeBool()) {396SetFuzzedErrNo(m_fuzzed_data_provider, setnonblocking_errnos);397return false;398}399return true;400}402bool FuzzedSock::IsSelectable() const403{404return m_selectable;405}407bool FuzzedSock::Wait(std::chrono::milliseconds timeout, Event requested, Event* occurred) const408{409constexpr std::array wait_errnos{410EBADF,411EINTR,412EINVAL,413};414if (m_fuzzed_data_provider.ConsumeBool()) {415SetFuzzedErrNo(m_fuzzed_data_provider, wait_errnos);416return false;417}418if (occurred != nullptr) {419// We simulate the requested event as occurred when ConsumeBool()420// returns false. This avoids simulating endless waiting if the421// FuzzedDataProvider runs out of data.422*occurred = m_fuzzed_data_provider.ConsumeBool() ? 0 : requested;423}424m_clock += timeout;425return true;426}428bool FuzzedSock::WaitMany(std::chrono::milliseconds timeout, EventsPerSock& events_per_sock) const429{430for (auto& [sock, events] : events_per_sock) {431(void)sock;432// We simulate the requested event as occurred when ConsumeBool()433// returns false. This avoids simulating endless waiting if the434// FuzzedDataProvider runs out of data.435events.occurred = m_fuzzed_data_provider.ConsumeBool() ? 0 : events.requested;436}437m_clock += timeout;438return true;439}441bool FuzzedSock::IsConnected(std::string& errmsg) const442{443if (m_fuzzed_data_provider.ConsumeBool()) {444return true;445}446errmsg = "disconnected at random by the fuzzer";447return false;448}450void FillNode(FuzzedDataProvider& fuzzed_data_provider, ConnmanTestMsg& connman, CNode& node) noexcept451{452auto successfully_connected = fuzzed_data_provider.ConsumeBool();453auto remote_services = ConsumeWeakEnum(fuzzed_data_provider, ALL_SERVICE_FLAGS);454auto local_services = ConsumeWeakEnum(fuzzed_data_provider, ALL_SERVICE_FLAGS);455auto version = fuzzed_data_provider.ConsumeIntegralInRange<int32_t>(MIN_PEER_PROTO_VERSION, std::numeric_limits<int32_t>::max());456auto relay_txs = fuzzed_data_provider.ConsumeBool();457connman.Handshake(node, successfully_connected, remote_services, local_services, version, relay_txs);458}
Independent explanations by MyBitcoinExplorer. Not affiliated with or endorsed by Bitcoin Core. Guides are educational and do not replace the source or its tests.
Bitcoin Core source © its contributors, distributed under the MIT license. Original notices and bundled third-party licenses are retained in the source tree.