Skip to content

Commit 1d82140

Browse files
author
Claude Code
committed
Merge bitcoin#26561: fuzz: Move-only net utils
fa3b2cf fuzz: Move-only net utils (MarcoFalke) Pull request description: This should speed up fuzz builds when `src/test/fuzz/util.h` is modified. Also, it makes sense on its own. ACKs for top commit: dergoegge: ACK fa3b2cf Tree-SHA512: 03d6abeb728ac8eb3f28167e8ac43d8d6e7e1b1738ec14f58a36e17502081fdde2d56f2d47a9e11b991754667e83b2eb22d154e394c0c1c4ffa0945db86b7e21
1 parent e3d61f2 commit 1d82140

File tree

11 files changed

+460
-431
lines changed

11 files changed

+460
-431
lines changed

src/test/fuzz/net.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
#include <test/fuzz/FuzzedDataProvider.h>
1414
#include <test/fuzz/fuzz.h>
1515
#include <test/fuzz/util.h>
16+
#include <test/fuzz/util/net.h>
1617
#include <test/util/net.h>
1718
#include <test/util/setup_common.h>
1819
#include <util/asmap.h>

src/test/fuzz/net_permissions.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
#include <test/fuzz/FuzzedDataProvider.h>
77
#include <test/fuzz/fuzz.h>
88
#include <test/fuzz/util.h>
9+
#include <test/fuzz/util/net.h>
910
#include <util/translation.h>
1011

1112
#include <cassert>

src/test/fuzz/node_eviction.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
#include <test/fuzz/FuzzedDataProvider.h>
88
#include <test/fuzz/fuzz.h>
99
#include <test/fuzz/util.h>
10+
#include <test/fuzz/util/net.h>
1011

1112
#include <algorithm>
1213
#include <cassert>

src/test/fuzz/pow.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
#include <test/fuzz/FuzzedDataProvider.h>
1010
#include <test/fuzz/fuzz.h>
1111
#include <test/fuzz/util.h>
12+
#include <util/check.h>
1213
#include <util/overflow.h>
1314

1415
#include <cstdint>

src/test/fuzz/process_message.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
#include <test/fuzz/FuzzedDataProvider.h>
1313
#include <test/fuzz/fuzz.h>
1414
#include <test/fuzz/util.h>
15+
#include <test/fuzz/util/net.h>
1516
#include <test/util/mining.h>
1617
#include <test/util/net.h>
1718
#include <test/util/setup_common.h>

src/test/fuzz/process_messages.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
#include <test/fuzz/FuzzedDataProvider.h>
1010
#include <test/fuzz/fuzz.h>
1111
#include <test/fuzz/util.h>
12+
#include <test/fuzz/util/net.h>
1213
#include <test/util/mining.h>
1314
#include <test/util/net.h>
1415
#include <test/util/setup_common.h>

src/test/fuzz/socks5.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
#include <test/fuzz/FuzzedDataProvider.h>
88
#include <test/fuzz/fuzz.h>
99
#include <test/fuzz/util.h>
10+
#include <test/fuzz/util/net.h>
1011
#include <test/util/setup_common.h>
1112

1213
#include <cstdint>

src/test/fuzz/util.cpp

Lines changed: 2 additions & 310 deletions
Original file line numberDiff line numberDiff line change
@@ -2,320 +2,17 @@
22
// Distributed under the MIT software license, see the accompanying
33
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
44

5-
#include <net_processing.h>
6-
#include <netaddress.h>
7-
#include <netmessagemaker.h>
5+
#include <consensus/amount.h>
86
#include <pubkey.h>
97
#include <test/fuzz/util.h>
108
#include <test/util/script.h>
9+
#include <util/check.h>
1110
#include <util/overflow.h>
1211
#include <util/time.h>
1312
#include <version.h>
1413

1514
#include <memory>
1615

17-
FuzzedSock::FuzzedSock(FuzzedDataProvider& fuzzed_data_provider)
18-
: m_fuzzed_data_provider{fuzzed_data_provider}, m_selectable{fuzzed_data_provider.ConsumeBool()}
19-
{
20-
m_socket = fuzzed_data_provider.ConsumeIntegralInRange<SOCKET>(INVALID_SOCKET - 1, INVALID_SOCKET);
21-
}
22-
23-
FuzzedSock::~FuzzedSock()
24-
{
25-
// Sock::~Sock() will be called after FuzzedSock::~FuzzedSock() and it will call
26-
// close(m_socket) if m_socket is not INVALID_SOCKET.
27-
// Avoid closing an arbitrary file descriptor (m_socket is just a random very high number which
28-
// theoretically may concide with a real opened file descriptor).
29-
m_socket = INVALID_SOCKET;
30-
}
31-
32-
FuzzedSock& FuzzedSock::operator=(Sock&& other)
33-
{
34-
assert(false && "Move of Sock into FuzzedSock not allowed.");
35-
return *this;
36-
}
37-
38-
ssize_t FuzzedSock::Send(const void* data, size_t len, int flags) const
39-
{
40-
constexpr std::array send_errnos{
41-
EACCES,
42-
EAGAIN,
43-
EALREADY,
44-
EBADF,
45-
ECONNRESET,
46-
EDESTADDRREQ,
47-
EFAULT,
48-
EINTR,
49-
EINVAL,
50-
EISCONN,
51-
EMSGSIZE,
52-
ENOBUFS,
53-
ENOMEM,
54-
ENOTCONN,
55-
ENOTSOCK,
56-
EOPNOTSUPP,
57-
EPIPE,
58-
EWOULDBLOCK,
59-
};
60-
if (m_fuzzed_data_provider.ConsumeBool()) {
61-
return len;
62-
}
63-
const ssize_t r = m_fuzzed_data_provider.ConsumeIntegralInRange<ssize_t>(-1, len);
64-
if (r == -1) {
65-
SetFuzzedErrNo(m_fuzzed_data_provider, send_errnos);
66-
}
67-
return r;
68-
}
69-
70-
ssize_t FuzzedSock::Recv(void* buf, size_t len, int flags) const
71-
{
72-
// Have a permanent error at recv_errnos[0] because when the fuzzed data is exhausted
73-
// SetFuzzedErrNo() will always return the first element and we want to avoid Recv()
74-
// returning -1 and setting errno to EAGAIN repeatedly.
75-
constexpr std::array recv_errnos{
76-
ECONNREFUSED,
77-
EAGAIN,
78-
EBADF,
79-
EFAULT,
80-
EINTR,
81-
EINVAL,
82-
ENOMEM,
83-
ENOTCONN,
84-
ENOTSOCK,
85-
EWOULDBLOCK,
86-
};
87-
assert(buf != nullptr || len == 0);
88-
if (len == 0 || m_fuzzed_data_provider.ConsumeBool()) {
89-
const ssize_t r = m_fuzzed_data_provider.ConsumeBool() ? 0 : -1;
90-
if (r == -1) {
91-
SetFuzzedErrNo(m_fuzzed_data_provider, recv_errnos);
92-
}
93-
return r;
94-
}
95-
std::vector<uint8_t> random_bytes;
96-
bool pad_to_len_bytes{m_fuzzed_data_provider.ConsumeBool()};
97-
if (m_peek_data.has_value()) {
98-
// `MSG_PEEK` was used in the preceding `Recv()` call, return `m_peek_data`.
99-
random_bytes.assign({m_peek_data.value()});
100-
if ((flags & MSG_PEEK) == 0) {
101-
m_peek_data.reset();
102-
}
103-
pad_to_len_bytes = false;
104-
} else if ((flags & MSG_PEEK) != 0) {
105-
// New call with `MSG_PEEK`.
106-
random_bytes = m_fuzzed_data_provider.ConsumeBytes<uint8_t>(1);
107-
if (!random_bytes.empty()) {
108-
m_peek_data = random_bytes[0];
109-
pad_to_len_bytes = false;
110-
}
111-
} else {
112-
random_bytes = m_fuzzed_data_provider.ConsumeBytes<uint8_t>(
113-
m_fuzzed_data_provider.ConsumeIntegralInRange<size_t>(0, len));
114-
}
115-
if (random_bytes.empty()) {
116-
const ssize_t r = m_fuzzed_data_provider.ConsumeBool() ? 0 : -1;
117-
if (r == -1) {
118-
SetFuzzedErrNo(m_fuzzed_data_provider, recv_errnos);
119-
}
120-
return r;
121-
}
122-
std::memcpy(buf, random_bytes.data(), random_bytes.size());
123-
if (pad_to_len_bytes) {
124-
if (len > random_bytes.size()) {
125-
std::memset((char*)buf + random_bytes.size(), 0, len - random_bytes.size());
126-
}
127-
return len;
128-
}
129-
if (m_fuzzed_data_provider.ConsumeBool() && std::getenv("FUZZED_SOCKET_FAKE_LATENCY") != nullptr) {
130-
std::this_thread::sleep_for(std::chrono::milliseconds{2});
131-
}
132-
return random_bytes.size();
133-
}
134-
135-
int FuzzedSock::Connect(const sockaddr*, socklen_t) const
136-
{
137-
// Have a permanent error at connect_errnos[0] because when the fuzzed data is exhausted
138-
// SetFuzzedErrNo() will always return the first element and we want to avoid Connect()
139-
// returning -1 and setting errno to EAGAIN repeatedly.
140-
constexpr std::array connect_errnos{
141-
ECONNREFUSED,
142-
EAGAIN,
143-
ECONNRESET,
144-
EHOSTUNREACH,
145-
EINPROGRESS,
146-
EINTR,
147-
ENETUNREACH,
148-
ETIMEDOUT,
149-
};
150-
if (m_fuzzed_data_provider.ConsumeBool()) {
151-
SetFuzzedErrNo(m_fuzzed_data_provider, connect_errnos);
152-
return -1;
153-
}
154-
return 0;
155-
}
156-
157-
int FuzzedSock::Bind(const sockaddr*, socklen_t) const
158-
{
159-
// Have a permanent error at bind_errnos[0] because when the fuzzed data is exhausted
160-
// SetFuzzedErrNo() will always set the global errno to bind_errnos[0]. We want to
161-
// avoid this method returning -1 and setting errno to a temporary error (like EAGAIN)
162-
// repeatedly because proper code should retry on temporary errors, leading to an
163-
// infinite loop.
164-
constexpr std::array bind_errnos{
165-
EACCES,
166-
EADDRINUSE,
167-
EADDRNOTAVAIL,
168-
EAGAIN,
169-
};
170-
if (m_fuzzed_data_provider.ConsumeBool()) {
171-
SetFuzzedErrNo(m_fuzzed_data_provider, bind_errnos);
172-
return -1;
173-
}
174-
return 0;
175-
}
176-
177-
int FuzzedSock::Listen(int) const
178-
{
179-
// Have a permanent error at listen_errnos[0] because when the fuzzed data is exhausted
180-
// SetFuzzedErrNo() will always set the global errno to listen_errnos[0]. We want to
181-
// avoid this method returning -1 and setting errno to a temporary error (like EAGAIN)
182-
// repeatedly because proper code should retry on temporary errors, leading to an
183-
// infinite loop.
184-
constexpr std::array listen_errnos{
185-
EADDRINUSE,
186-
EINVAL,
187-
EOPNOTSUPP,
188-
};
189-
if (m_fuzzed_data_provider.ConsumeBool()) {
190-
SetFuzzedErrNo(m_fuzzed_data_provider, listen_errnos);
191-
return -1;
192-
}
193-
return 0;
194-
}
195-
196-
std::unique_ptr<Sock> FuzzedSock::Accept(sockaddr* addr, socklen_t* addr_len) const
197-
{
198-
constexpr std::array accept_errnos{
199-
ECONNABORTED,
200-
EINTR,
201-
ENOMEM,
202-
};
203-
if (m_fuzzed_data_provider.ConsumeBool()) {
204-
SetFuzzedErrNo(m_fuzzed_data_provider, accept_errnos);
205-
return std::unique_ptr<FuzzedSock>();
206-
}
207-
return std::make_unique<FuzzedSock>(m_fuzzed_data_provider);
208-
}
209-
210-
int FuzzedSock::GetSockOpt(int level, int opt_name, void* opt_val, socklen_t* opt_len) const
211-
{
212-
constexpr std::array getsockopt_errnos{
213-
ENOMEM,
214-
ENOBUFS,
215-
};
216-
if (m_fuzzed_data_provider.ConsumeBool()) {
217-
SetFuzzedErrNo(m_fuzzed_data_provider, getsockopt_errnos);
218-
return -1;
219-
}
220-
if (opt_val == nullptr) {
221-
return 0;
222-
}
223-
std::memcpy(opt_val,
224-
ConsumeFixedLengthByteVector(m_fuzzed_data_provider, *opt_len).data(),
225-
*opt_len);
226-
return 0;
227-
}
228-
229-
int FuzzedSock::SetSockOpt(int, int, const void*, socklen_t) const
230-
{
231-
constexpr std::array setsockopt_errnos{
232-
ENOMEM,
233-
ENOBUFS,
234-
};
235-
if (m_fuzzed_data_provider.ConsumeBool()) {
236-
SetFuzzedErrNo(m_fuzzed_data_provider, setsockopt_errnos);
237-
return -1;
238-
}
239-
return 0;
240-
}
241-
242-
int FuzzedSock::GetSockName(sockaddr* name, socklen_t* name_len) const
243-
{
244-
constexpr std::array getsockname_errnos{
245-
ECONNRESET,
246-
ENOBUFS,
247-
};
248-
if (m_fuzzed_data_provider.ConsumeBool()) {
249-
SetFuzzedErrNo(m_fuzzed_data_provider, getsockname_errnos);
250-
return -1;
251-
}
252-
*name_len = m_fuzzed_data_provider.ConsumeData(name, *name_len);
253-
return 0;
254-
}
255-
256-
bool FuzzedSock::SetNonBlocking() const
257-
{
258-
constexpr std::array setnonblocking_errnos{
259-
EBADF,
260-
EPERM,
261-
};
262-
if (m_fuzzed_data_provider.ConsumeBool()) {
263-
SetFuzzedErrNo(m_fuzzed_data_provider, setnonblocking_errnos);
264-
return false;
265-
}
266-
return true;
267-
}
268-
269-
bool FuzzedSock::IsSelectable(bool is_select) const
270-
{
271-
return m_selectable;
272-
}
273-
274-
bool FuzzedSock::Wait(std::chrono::milliseconds timeout, Event requested, SocketEventsParams event_params, Event* occurred) const
275-
{
276-
constexpr std::array wait_errnos{
277-
EBADF,
278-
EINTR,
279-
EINVAL,
280-
};
281-
if (m_fuzzed_data_provider.ConsumeBool()) {
282-
SetFuzzedErrNo(m_fuzzed_data_provider, wait_errnos);
283-
return false;
284-
}
285-
if (occurred != nullptr) {
286-
*occurred = m_fuzzed_data_provider.ConsumeBool() ? requested : 0;
287-
}
288-
return true;
289-
}
290-
291-
bool FuzzedSock::WaitMany(std::chrono::milliseconds timeout, EventsPerSock& events_per_sock, SocketEventsParams event_params) const
292-
{
293-
for (auto& [sock, events] : events_per_sock) {
294-
(void)sock;
295-
events.occurred = m_fuzzed_data_provider.ConsumeBool() ? events.requested : 0;
296-
}
297-
return true;
298-
}
299-
300-
bool FuzzedSock::IsConnected(std::string& errmsg) const
301-
{
302-
if (m_fuzzed_data_provider.ConsumeBool()) {
303-
return true;
304-
}
305-
errmsg = "disconnected at random by the fuzzer";
306-
return false;
307-
}
308-
309-
void FillNode(FuzzedDataProvider& fuzzed_data_provider, ConnmanTestMsg& connman, CNode& node) noexcept
310-
{
311-
connman.Handshake(node,
312-
/*successfully_connected=*/fuzzed_data_provider.ConsumeBool(),
313-
/*remote_services=*/ConsumeWeakEnum(fuzzed_data_provider, ALL_SERVICE_FLAGS),
314-
/*local_services=*/ConsumeWeakEnum(fuzzed_data_provider, ALL_SERVICE_FLAGS),
315-
/*version=*/fuzzed_data_provider.ConsumeIntegralInRange<int32_t>(MIN_PEER_PROTO_VERSION, std::numeric_limits<int32_t>::max()),
316-
/*relay_txs=*/fuzzed_data_provider.ConsumeBool());
317-
}
318-
31916
CAmount ConsumeMoney(FuzzedDataProvider& fuzzed_data_provider, const std::optional<CAmount>& max) noexcept
32017
{
32118
return fuzzed_data_provider.ConsumeIntegralInRange<CAmount>(0, max.value_or(MAX_MONEY));
@@ -491,11 +188,6 @@ bool ContainsSpentInput(const CTransaction& tx, const CCoinsViewCache& inputs) n
491188
return false;
492189
}
493190

494-
CAddress ConsumeAddress(FuzzedDataProvider& fuzzed_data_provider) noexcept
495-
{
496-
return {ConsumeService(fuzzed_data_provider), ConsumeWeakEnum(fuzzed_data_provider, ALL_SERVICE_FLAGS), NodeSeconds{std::chrono::seconds{fuzzed_data_provider.ConsumeIntegral<uint32_t>()}}};
497-
}
498-
499191
FILE* FuzzedFileProvider::open()
500192
{
501193
SetFuzzedErrNo(m_fuzzed_data_provider);

0 commit comments

Comments
 (0)