0
0
Fork 0
mirror of https://github.com/bitcoin/bitcoin.git synced 2025-03-06 14:19:59 -05:00

net: convert standalone SetSocketNonBlocking() to Sock::SetNonBlocking()

This further encapsulates syscalls inside the `Sock` class.

Co-authored-by: practicalswift <practicalswift@users.noreply.github.com>
This commit is contained in:
Vasil Dimov 2021-04-19 11:35:09 +02:00
parent 29f66f7682
commit b527b54950
No known key found for this signature in database
GPG key ID: 54DF06F64B55CBBF
6 changed files with 37 additions and 14 deletions

View file

@ -304,8 +304,7 @@ enum class IntrRecvError {
* read. * read.
* *
* @see This function can be interrupted by calling InterruptSocks5(bool). * @see This function can be interrupted by calling InterruptSocks5(bool).
* Sockets can be made non-blocking with SetSocketNonBlocking(const * Sockets can be made non-blocking with Sock::SetNonBlocking().
* SOCKET&).
*/ */
static IntrRecvError InterruptibleRecv(uint8_t* data, size_t len, int timeout, const Sock& sock) static IntrRecvError InterruptibleRecv(uint8_t* data, size_t len, int timeout, const Sock& sock)
{ {
@ -525,7 +524,7 @@ std::unique_ptr<Sock> CreateSockTCP(const CService& address_family)
} }
// Set the non-blocking option on the socket. // Set the non-blocking option on the socket.
if (!SetSocketNonBlocking(sock->Get())) { if (!sock->SetNonBlocking()) {
LogPrintf("Error setting socket to non-blocking: %s\n", NetworkErrorString(WSAGetLastError())); LogPrintf("Error setting socket to non-blocking: %s\n", NetworkErrorString(WSAGetLastError()));
return nullptr; return nullptr;
} }

View file

@ -254,6 +254,19 @@ int FuzzedSock::GetSockName(sockaddr* name, socklen_t* name_len) const
return 0; return 0;
} }
bool FuzzedSock::SetNonBlocking() const
{
constexpr std::array setnonblocking_errnos{
EBADF,
EPERM,
};
if (m_fuzzed_data_provider.ConsumeBool()) {
SetFuzzedErrNo(m_fuzzed_data_provider, setnonblocking_errnos);
return false;
}
return true;
}
bool FuzzedSock::IsSelectable() const bool FuzzedSock::IsSelectable() const
{ {
return m_selectable; return m_selectable;

View file

@ -80,6 +80,8 @@ public:
int GetSockName(sockaddr* name, socklen_t* name_len) const override; int GetSockName(sockaddr* name, socklen_t* name_len) const override;
bool SetNonBlocking() const override;
bool IsSelectable() const override; bool IsSelectable() const override;
bool Wait(std::chrono::milliseconds timeout, Event requested, Event* occurred = nullptr) const override; bool Wait(std::chrono::milliseconds timeout, Event requested, Event* occurred = nullptr) const override;

View file

@ -166,6 +166,8 @@ public:
return 0; return 0;
} }
bool SetNonBlocking() const override { return true; }
bool IsSelectable() const override { return true; } bool IsSelectable() const override { return true; }
bool Wait(std::chrono::milliseconds timeout, bool Wait(std::chrono::milliseconds timeout,

View file

@ -117,18 +117,22 @@ int Sock::GetSockName(sockaddr* name, socklen_t* name_len) const
return getsockname(m_socket, name, name_len); return getsockname(m_socket, name, name_len);
} }
bool SetSocketNonBlocking(const SOCKET& hSocket) bool Sock::SetNonBlocking() const
{ {
#ifdef WIN32 #ifdef WIN32
u_long nOne = 1; u_long on{1};
if (ioctlsocket(hSocket, FIONBIO, &nOne) == SOCKET_ERROR) { if (ioctlsocket(m_socket, FIONBIO, &on) == SOCKET_ERROR) {
#else
int fFlags = fcntl(hSocket, F_GETFL, 0);
if (fcntl(hSocket, F_SETFL, fFlags | O_NONBLOCK) == SOCKET_ERROR) {
#endif
return false; return false;
} }
#else
const int flags{fcntl(m_socket, F_GETFL, 0)};
if (flags == SOCKET_ERROR) {
return false;
}
if (fcntl(m_socket, F_SETFL, flags | O_NONBLOCK) == SOCKET_ERROR) {
return false;
}
#endif
return true; return true;
} }

View file

@ -133,6 +133,12 @@ public:
*/ */
[[nodiscard]] virtual int GetSockName(sockaddr* name, socklen_t* name_len) const; [[nodiscard]] virtual int GetSockName(sockaddr* name, socklen_t* name_len) const;
/**
* Set the non-blocking option on the socket.
* @return true if set successfully
*/
[[nodiscard]] virtual bool SetNonBlocking() const;
/** /**
* Check if the underlying socket can be used for `select(2)` (or the `Wait()` method). * Check if the underlying socket can be used for `select(2)` (or the `Wait()` method).
* @return true if selectable * @return true if selectable
@ -273,9 +279,6 @@ private:
void Close(); void Close();
}; };
/** Enable non-blocking mode for a socket */
bool SetSocketNonBlocking(const SOCKET& hSocket);
/** Return readable error string for a network error code */ /** Return readable error string for a network error code */
std::string NetworkErrorString(int err); std::string NetworkErrorString(int err);