Skip to content

Commit 18738f5

Browse files
committed
merge bitcoin#25421: convert standalone IsSelectableSocket() and SetSocketNonBlocking() to Sock methods
1 parent 8782575 commit 18738f5

File tree

10 files changed

+80
-34
lines changed

10 files changed

+80
-34
lines changed

src/compat/compat.h

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -109,14 +109,6 @@ typedef char* sockopt_arg_type;
109109
#define USE_KQUEUE
110110
#endif
111111

112-
bool static inline IsSelectableSocket(const SOCKET& s) {
113-
#if defined(USE_POLL) || defined(WIN32)
114-
return true;
115-
#else
116-
return (s < FD_SETSIZE);
117-
#endif
118-
}
119-
120112
// MSG_NOSIGNAL is not available on some platforms, if it doesn't exist define it as 0
121113
#if !defined(MSG_NOSIGNAL)
122114
#define MSG_NOSIGNAL 0

src/masternode/node.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -162,7 +162,7 @@ void CActiveMasternodeManager::InitInternal(const CBlockIndex* pindex)
162162
LogPrintf("CActiveMasternodeManager::Init -- ERROR: %s\n", m_error);
163163
return;
164164
}
165-
bool fConnected = ConnectSocketDirectly(m_info.service, *sock, nConnectTimeout, true) && IsSelectableSocket(sock->Get());
165+
bool fConnected = ConnectSocketDirectly(m_info.service, *sock, nConnectTimeout, true) && sock->IsSelectable();
166166
sock->Reset();
167167

168168
if (!fConnected && Params().RequireRoutableExternalIP()) {

src/net.cpp

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2020,8 +2020,7 @@ void CConnman::CreateNodeFromAcceptedSocket(std::unique_ptr<Sock>&& sock,
20202020
return;
20212021
}
20222022

2023-
if (!IsSelectableSocket(sock->Get()))
2024-
{
2023+
if (!sock->IsSelectable()) {
20252024
LogPrintf("%s: non-selectable socket\n", strDropped);
20262025
return;
20272026
}

src/netbase.cpp

Lines changed: 3 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -288,8 +288,7 @@ enum class IntrRecvError {
288288
* read.
289289
*
290290
* @see This function can be interrupted by calling InterruptSocks5(bool).
291-
* Sockets can be made non-blocking with SetSocketNonBlocking(const
292-
* SOCKET&).
291+
* Sockets can be made non-blocking with Sock::SetNonBlocking().
293292
*/
294293
static IntrRecvError InterruptibleRecv(uint8_t* data, size_t len, int timeout, const Sock& sock)
295294
{
@@ -487,7 +486,7 @@ std::unique_ptr<Sock> CreateSockTCP(const CService& address_family)
487486

488487
// Ensure that waiting for I/O on this socket won't result in undefined
489488
// behavior.
490-
if (!IsSelectableSocket(sock->Get())) {
489+
if (!sock->IsSelectable()) {
491490
LogPrintf("Cannot create connection: non-selectable socket created (fd >= FD_SETSIZE ?)\n");
492491
return nullptr;
493492
}
@@ -509,7 +508,7 @@ std::unique_ptr<Sock> CreateSockTCP(const CService& address_family)
509508
}
510509

511510
// Set the non-blocking option on the socket.
512-
if (!SetSocketNonBlocking(sock->Get())) {
511+
if (!sock->SetNonBlocking()) {
513512
LogPrintf("Error setting socket to non-blocking: %s\n", NetworkErrorString(WSAGetLastError()));
514513
return nullptr;
515514
}
@@ -701,21 +700,6 @@ bool LookupSubNet(const std::string& subnet_str, CSubNet& subnet_out)
701700
return false;
702701
}
703702

704-
bool SetSocketNonBlocking(const SOCKET& hSocket)
705-
{
706-
#ifdef WIN32
707-
u_long nOne = 1;
708-
if (ioctlsocket(hSocket, FIONBIO, &nOne) == SOCKET_ERROR) {
709-
#else
710-
int fFlags = fcntl(hSocket, F_GETFL, 0);
711-
if (fcntl(hSocket, F_SETFL, fFlags | O_NONBLOCK) == SOCKET_ERROR) {
712-
#endif
713-
return false;
714-
}
715-
716-
return true;
717-
}
718-
719703
void InterruptSocks5(bool interrupt)
720704
{
721705
interruptSocks5Recv = interrupt;

src/netbase.h

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -224,8 +224,6 @@ bool ConnectSocketDirectly(const CService &addrConnect, const Sock& sock, int nT
224224
*/
225225
bool ConnectThroughProxy(const Proxy& proxy, const std::string& strDest, uint16_t port, const Sock& sock, int nTimeout, bool& outProxyConnectionFailed);
226226

227-
/** Enable non-blocking mode for a socket */
228-
bool SetSocketNonBlocking(const SOCKET& hSocket);
229227
void InterruptSocks5(bool interrupt);
230228

231229
/**

src/test/fuzz/util.cpp

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414
#include <memory>
1515

1616
FuzzedSock::FuzzedSock(FuzzedDataProvider& fuzzed_data_provider)
17-
: m_fuzzed_data_provider{fuzzed_data_provider}
17+
: m_fuzzed_data_provider{fuzzed_data_provider}, m_selectable{fuzzed_data_provider.ConsumeBool()}
1818
{
1919
m_socket = fuzzed_data_provider.ConsumeIntegralInRange<SOCKET>(INVALID_SOCKET - 1, INVALID_SOCKET);
2020
}
@@ -257,6 +257,24 @@ int FuzzedSock::GetSockName(sockaddr* name, socklen_t* name_len) const
257257
return 0;
258258
}
259259

260+
bool FuzzedSock::SetNonBlocking() const
261+
{
262+
constexpr std::array setnonblocking_errnos{
263+
EBADF,
264+
EPERM,
265+
};
266+
if (m_fuzzed_data_provider.ConsumeBool()) {
267+
SetFuzzedErrNo(m_fuzzed_data_provider, setnonblocking_errnos);
268+
return false;
269+
}
270+
return true;
271+
}
272+
273+
bool FuzzedSock::IsSelectable() const
274+
{
275+
return m_selectable;
276+
}
277+
260278
bool FuzzedSock::Wait(std::chrono::milliseconds timeout, Event requested, Event* occurred) const
261279
{
262280
constexpr std::array wait_errnos{

src/test/fuzz/util.h

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,13 @@ class FuzzedSock : public Sock
5353
*/
5454
mutable std::optional<uint8_t> m_peek_data;
5555

56+
/**
57+
* Whether to pretend that the socket is select(2)-able. This is randomly set in the
58+
* constructor. It should remain constant so that repeated calls to `IsSelectable()`
59+
* return the same value.
60+
*/
61+
const bool m_selectable;
62+
5663
public:
5764
explicit FuzzedSock(FuzzedDataProvider& fuzzed_data_provider);
5865

@@ -80,6 +87,10 @@ class FuzzedSock : public Sock
8087

8188
int GetSockName(sockaddr* name, socklen_t* name_len) const override;
8289

90+
bool SetNonBlocking() const override;
91+
92+
bool IsSelectable() const override;
93+
8394
bool Wait(std::chrono::milliseconds timeout, Event requested, Event* occurred = nullptr) const override;
8495

8596
bool IsConnected(std::string& errmsg) const override;

src/test/util/net.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -201,6 +201,10 @@ class StaticContentsSock : public Sock
201201
return 0;
202202
}
203203

204+
bool SetNonBlocking() const override { return true; }
205+
206+
bool IsSelectable() const override { return true; }
207+
204208
bool Wait(std::chrono::milliseconds timeout,
205209
Event requested,
206210
Event* occurred = nullptr) const override

src/util/sock.cpp

Lines changed: 29 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -125,6 +125,34 @@ int Sock::GetSockName(sockaddr* name, socklen_t* name_len) const
125125
return getsockname(m_socket, name, name_len);
126126
}
127127

128+
bool Sock::SetNonBlocking() const
129+
{
130+
#ifdef WIN32
131+
u_long on{1};
132+
if (ioctlsocket(m_socket, FIONBIO, &on) == SOCKET_ERROR) {
133+
return false;
134+
}
135+
#else
136+
const int flags{fcntl(m_socket, F_GETFL, 0)};
137+
if (flags == SOCKET_ERROR) {
138+
return false;
139+
}
140+
if (fcntl(m_socket, F_SETFL, flags | O_NONBLOCK) == SOCKET_ERROR) {
141+
return false;
142+
}
143+
#endif
144+
return true;
145+
}
146+
147+
bool Sock::IsSelectable() const
148+
{
149+
#if defined(USE_POLL) || defined(WIN32)
150+
return true;
151+
#else
152+
return m_socket < FD_SETSIZE;
153+
#endif
154+
}
155+
128156
bool Sock::Wait(std::chrono::milliseconds timeout, Event requested, Event* occurred) const
129157
{
130158
#ifdef USE_POLL
@@ -154,7 +182,7 @@ bool Sock::Wait(std::chrono::milliseconds timeout, Event requested, Event* occur
154182

155183
return true;
156184
#else
157-
if (!IsSelectableSocket(m_socket)) {
185+
if (!IsSelectable()) {
158186
return false;
159187
}
160188

src/util/sock.h

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -190,6 +190,18 @@ class Sock
190190
*/
191191
[[nodiscard]] virtual int GetSockName(sockaddr* name, socklen_t* name_len) const;
192192

193+
/**
194+
* Set the non-blocking option on the socket.
195+
* @return true if set successfully
196+
*/
197+
[[nodiscard]] virtual bool SetNonBlocking() const;
198+
199+
/**
200+
* Check if the underlying socket can be used for `select(2)` (or the `Wait()` method).
201+
* @return true if selectable
202+
*/
203+
[[nodiscard]] virtual bool IsSelectable() const;
204+
193205
using Event = uint8_t;
194206

195207
/**

0 commit comments

Comments
 (0)