-
Notifications
You must be signed in to change notification settings - Fork 38.7k
net: expand Sock and fuzz-test more of CConnman #21700
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
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 <[email protected]>
|
|
|
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.