diff options
Diffstat (limited to 'src/test/fuzz/util/net.cpp')
-rw-r--r-- | src/test/fuzz/util/net.cpp | 78 |
1 files changed, 54 insertions, 24 deletions
diff --git a/src/test/fuzz/util/net.cpp b/src/test/fuzz/util/net.cpp index eb0f14ede0..99151bb84d 100644 --- a/src/test/fuzz/util/net.cpp +++ b/src/test/fuzz/util/net.cpp @@ -25,33 +25,63 @@ class CNode; -CNetAddr ConsumeNetAddr(FuzzedDataProvider& fuzzed_data_provider) noexcept +CNetAddr ConsumeNetAddr(FuzzedDataProvider& fuzzed_data_provider, FastRandomContext* rand) noexcept { - const Network network = fuzzed_data_provider.PickValueInArray({Network::NET_IPV4, Network::NET_IPV6, Network::NET_INTERNAL, Network::NET_ONION}); - CNetAddr net_addr; - if (network == Network::NET_IPV4) { - in_addr v4_addr = {}; - v4_addr.s_addr = fuzzed_data_provider.ConsumeIntegral<uint32_t>(); - net_addr = CNetAddr{v4_addr}; - } else if (network == Network::NET_IPV6) { - if (fuzzed_data_provider.remaining_bytes() >= 16) { - in6_addr v6_addr = {}; - auto addr_bytes = fuzzed_data_provider.ConsumeBytes<uint8_t>(16); - if (addr_bytes[0] == CJDNS_PREFIX) { // Avoid generating IPv6 addresses that look like CJDNS. - addr_bytes[0] = 0x55; // Just an arbitrary number, anything != CJDNS_PREFIX would do. - } - memcpy(v6_addr.s6_addr, addr_bytes.data(), 16); - net_addr = CNetAddr{v6_addr, fuzzed_data_provider.ConsumeIntegral<uint32_t>()}; + struct NetAux { + Network net; + CNetAddr::BIP155Network bip155; + size_t len; + }; + + static constexpr std::array<NetAux, 6> nets{ + NetAux{.net = Network::NET_IPV4, .bip155 = CNetAddr::BIP155Network::IPV4, .len = ADDR_IPV4_SIZE}, + NetAux{.net = Network::NET_IPV6, .bip155 = CNetAddr::BIP155Network::IPV6, .len = ADDR_IPV6_SIZE}, + NetAux{.net = Network::NET_ONION, .bip155 = CNetAddr::BIP155Network::TORV3, .len = ADDR_TORV3_SIZE}, + NetAux{.net = Network::NET_I2P, .bip155 = CNetAddr::BIP155Network::I2P, .len = ADDR_I2P_SIZE}, + NetAux{.net = Network::NET_CJDNS, .bip155 = CNetAddr::BIP155Network::CJDNS, .len = ADDR_CJDNS_SIZE}, + NetAux{.net = Network::NET_INTERNAL, .bip155 = CNetAddr::BIP155Network{0}, .len = 0}, + }; + + const size_t nets_index{rand == nullptr + ? fuzzed_data_provider.ConsumeIntegralInRange<size_t>(0, nets.size() - 1) + : static_cast<size_t>(rand->randrange(nets.size()))}; + + const auto& aux = nets[nets_index]; + + CNetAddr addr; + + if (aux.net == Network::NET_INTERNAL) { + if (rand == nullptr) { + addr.SetInternal(fuzzed_data_provider.ConsumeBytesAsString(32)); + } else { + const auto v = rand->randbytes(32); + addr.SetInternal(std::string{v.begin(), v.end()}); } - } else if (network == Network::NET_INTERNAL) { - net_addr.SetInternal(fuzzed_data_provider.ConsumeBytesAsString(32)); - } else if (network == Network::NET_ONION) { - auto pub_key{fuzzed_data_provider.ConsumeBytes<uint8_t>(ADDR_TORV3_SIZE)}; - pub_key.resize(ADDR_TORV3_SIZE); - const bool ok{net_addr.SetSpecial(OnionToString(pub_key))}; - assert(ok); + return addr; + } + + DataStream s; + + s << static_cast<uint8_t>(aux.bip155); + + std::vector<uint8_t> addr_bytes; + if (rand == nullptr) { + addr_bytes = fuzzed_data_provider.ConsumeBytes<uint8_t>(aux.len); + addr_bytes.resize(aux.len); + } else { + addr_bytes = rand->randbytes(aux.len); } - return net_addr; + if (aux.net == NET_IPV6 && addr_bytes[0] == CJDNS_PREFIX) { // Avoid generating IPv6 addresses that look like CJDNS. + addr_bytes[0] = 0x55; // Just an arbitrary number, anything != CJDNS_PREFIX would do. + } + if (aux.net == NET_CJDNS) { // Avoid generating CJDNS addresses that don't start with CJDNS_PREFIX because those are !IsValid(). + addr_bytes[0] = CJDNS_PREFIX; + } + s << addr_bytes; + + s >> CAddress::V2_NETWORK(addr); + + return addr; } CAddress ConsumeAddress(FuzzedDataProvider& fuzzed_data_provider) noexcept |