net: expand Sock and fuzz-test more of CConnman#21700
Conversation
This will help to increase `Sock` usage and make more code mockable.
|
Wow great work @vasild! Love it. Will review. Super strong Concept ACK obviously :) |
|
The following sections might be updated with supplementary metadata relevant to reviewers and maintainers. ConflictsReviewers, this pull request conflicts with the following ones:
If you consider this pull request important, please also help to review the conflicting pull requests. Ideally, start with the one that should be merged first. |
|
|
|
Random note: AFAICT the only remaining non-test usage of What about adding WDYT? :) |
|
I actually did that, but then removed this change because I realized it is not necessary - I think it is still useful to have |
|
More random notes: These are the direct uses of socket related syscalls and library functions with this PR applied: Great to see our socket related syscalls and library functions being further encapsulated by The remaining |
|
Moving Looking at the above list - it is not that many left! :) (btw |
Change `CConnman::CreateNodeFromAcceptedSocket()` to take a `Sock` argument instead of `SOCKET`. This makes the method mockable and also a little bit shorter as some `CloseSocket()` calls are removed (the socket will be closed automatically by the `Sock` destructor on early return).
This makes the callers mockable.
This makes the callers mockable.
This will help to increase `Sock` usage and make more code mockable.
This avoids the direct call to `getsockname()` and allows mocking.
|
|
|
Here is a patch that removes some unused code (+22 -30), further encapsulates socket operations to Feel free to use as you wish! :) diff --git a/src/netbase.cpp b/src/netbase.cpp
index b03fd1028..69ef63b0e 100644
--- a/src/netbase.cpp
+++ b/src/netbase.cpp
@@ -303,8 +303,7 @@ enum class IntrRecvError {
* read.
*
* @see This function can be interrupted by calling InterruptSocks5(bool).
- * Sockets can be made non-blocking with SetSocketNonBlocking(const
- * SOCKET&, bool).
+ * Sockets can be made non-blocking with Sock::SetNonBlocking().
*/
static IntrRecvError InterruptibleRecv(uint8_t* data, size_t len, int timeout, const Sock& sock)
{
@@ -520,7 +519,7 @@ std::unique_ptr<Sock> CreateSockTCP(const CService& address_family)
}
// Set the non-blocking option on the socket.
- if (!SetSocketNonBlocking(sock->Get(), true)) {
+ if (!sock->SetNonBlocking()) {
LogPrintf("Error setting socket to non-blocking: %s\n", NetworkErrorString(WSAGetLastError()));
return nullptr;
}
@@ -718,33 +717,6 @@ bool LookupSubNet(const std::string& strSubnet, CSubNet& ret, DNSLookupFn dns_lo
return false;
}
-bool SetSocketNonBlocking(const SOCKET& hSocket, bool fNonBlocking)
-{
- if (fNonBlocking) {
-#ifdef WIN32
- u_long nOne = 1;
- if (ioctlsocket(hSocket, FIONBIO, &nOne) == SOCKET_ERROR) {
-#else
- int fFlags = fcntl(hSocket, F_GETFL, 0);
- if (fcntl(hSocket, F_SETFL, fFlags | O_NONBLOCK) == SOCKET_ERROR) {
-#endif
- return false;
- }
- } else {
-#ifdef WIN32
- u_long nZero = 0;
- if (ioctlsocket(hSocket, FIONBIO, &nZero) == SOCKET_ERROR) {
-#else
- int fFlags = fcntl(hSocket, F_GETFL, 0);
- if (fcntl(hSocket, F_SETFL, fFlags & ~O_NONBLOCK) == SOCKET_ERROR) {
-#endif
- return false;
- }
- }
-
- return true;
-}
-
void InterruptSocks5(bool interrupt)
{
interruptSocks5Recv = interrupt;
diff --git a/src/util/sock.cpp b/src/util/sock.cpp
index e560f5b90..7f9b6d17c 100644
--- a/src/util/sock.cpp
+++ b/src/util/sock.cpp
@@ -107,6 +107,20 @@ bool Sock::SetNoDelay() const
return SetSockOpt(IPPROTO_TCP, TCP_NODELAY, &on, sizeof(on)) == 0;
}
+bool Sock::SetNonBlocking() const
+{
+#ifdef WIN32
+ const u_long one{1};
+ if (ioctlsocket(m_socket, FIONBIO, &nOne) == SOCKET_ERROR) {
+#else
+ const int flags{fcntl(m_socket, F_GETFL, 0)};
+ if (fcntl(m_socket, F_SETFL, flags | O_NONBLOCK) == SOCKET_ERROR) {
+#endif
+ return false;
+ }
+ return true;
+}
+
bool Sock::IsSelectable() const
{
#if defined(USE_POLL) || defined(WIN32)
diff --git a/src/util/sock.h b/src/util/sock.h
index 0ce2decd8..9e33b9159 100644
--- a/src/util/sock.h
+++ b/src/util/sock.h
@@ -140,6 +140,12 @@ public:
*/
[[nodiscard]] virtual bool SetNoDelay() 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).
* @return true if selectable |
This will help to increase `Sock` usage and make more code mockable.
This will help to increase `Sock` usage and make more code mockable.
|
This PR is reviewable and mergeable in its current state. I will see what it takes to remove |
This further encapsulates syscalls inside the `Sock` class. Co-authored-by: practicalswift <practicalswift@users.noreply.github.com>
|
|
|
Concept ACK |
|
Closing: superseded by #21878 which replaces all usage of |
Sockclasssetsockopt(),getsockname(),bind()andlisten()SetSocketNoDelay()andIsSelectableSocket()toSockmethodsSock:CConnman::CreateNodeFromAcceptedSocket()andGetBindAddress()changed to takeSockas an argument instead ofSOCKETOpenNetworkConnection(),CreateNodeFromAcceptedSocket()andInitBinds()CConnmanmethods.