-
Notifications
You must be signed in to change notification settings - Fork 37.7k
net: add RAII socket and use it instead of bare SOCKET #20788
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
The following two PRs would benefit from this:
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
left a style comment, no other review. Feel free to ignore.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Concept ACK, was unable to build this pull @ 99b8e88
build error output
$ gcc --version
gcc (Debian 10.2.1-1) 10.2.1 20201207
.../...
AR qt/libbitcoinqt.a
/usr/bin/ld: libbitcoin_common.a(libbitcoin_common_a-netbase.o): in function `std::_MakeUniq<Sock>::__single_object std::make_unique<Sock, unsigned int&>(unsigned int&)':
/usr/include/c++/10/bits/unique_ptr.h:962: undefined reference to `Sock::Sock(unsigned int)'
CXXLD qt/bitcoin-qt
CXXLD bitcoin-gui
/usr/bin/ld: libbitcoin_common.a(libbitcoin_common_a-netbase.o): in function `std::_MakeUniq<Sock>::__single_object std::make_unique<Sock, unsigned int&>(unsigned int&)':
/usr/include/c++/10/bits/unique_ptr.h:962: undefined reference to `Sock::Sock(unsigned int)'
collect2: error: ld returned 1 exit status
make[2]: *** [Makefile:5503: bitcoin-node] Error 1
make[2]: *** Waiting for unfinished jobs....
collect2: error: ld returned 1 exit status
make[2]: *** [Makefile:5515: bitcoind] Error 1
/usr/bin/ld: libbitcoin_common.a(libbitcoin_common_a-netbase.o): in function `std::_MakeUniq<Sock>::__single_object std::make_unique<Sock, unsigned int&>(unsigned int&)':
/usr/include/c++/10/bits/unique_ptr.h:962: undefined reference to `Sock::Sock(unsigned int)'
/usr/bin/ld: libbitcoin_common.a(libbitcoin_common_a-netbase.o): in function `std::_MakeUniq<Sock>::__single_object std::make_unique<Sock, unsigned int&>(unsigned int&)':
/usr/include/c++/10/bits/unique_ptr.h:962: undefined reference to `Sock::Sock(unsigned int)'
collect2: error: ld returned 1 exit status
make[2]: *** [Makefile:5521: qt/bitcoin-qt] Error 1
collect2: error: ld returned 1 exit status
make[2]: *** [Makefile:5499: bitcoin-gui] Error 1
make[2]: Leaving directory '/home/jon/projects/bitcoin/bitcoin/src'
make[1]: *** [Makefile:14882: all-recursive] Error 1
make[1]: Leaving directory '/home/jon/projects/bitcoin/bitcoin/src'
make: *** [Makefile:806: all-recursive] Error 1
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. |
Strong concept ACK This abstraction would be extremely useful to have when fuzzing low-level networking code. |
99b8e88...408a947: moved the Another option would be to keep the |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Tested approach ACK 408a947 (modulo missing test coverage?)
- moving the Sock class to its own file and the common deps to a utility seems appealing, at least in principle, not sure in practice
- review of the diff would be easier and nicer, and there would be less unnecessary churn and risk of overlooking a regression, if unneeded formatting and line break changes were not added when only an argument in the function signature is being updated
- do you plan to add unit tests for the Sock class?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've finished the review. Only two comments.
Concept ACK. Is there any reason not to use the |
408a947...8fc63e3: fixed a typo and removed unused parameter |
I will try this. Opinions, anybody? That would mean:
I did not but any ideas are welcome. I think it may be required to create a TCP server and client and do some communication between them to check that I don't know how to reliably check if the socket was closed by the destructor, given that the same file descriptor number could be assigned to a newly created socket (or opened file) after we close it.
No, other than minimizing the size of this PR. See also #20788 (comment) :-) |
I agree with moving it to its own file and with adding UTs for it. I am not sure a real socket is necessary for testing this abstraction, could it be enough to simply mock btw, utACK 8fc63e3 |
0b11ea2
to
3fa2a11
Compare
|
This fixes: ```bash In file included from test/sock_tests.cpp:10: In file included from /usr/local/include/boost/test/unit_test.hpp:18: In file included from /usr/local/include/boost/test/test_tools.hpp:46: /usr/local/include/boost/test/tools/old/impl.hpp:107:17: warning: comparison of integers of different signs: 'const long' and 'const unsigned long' [-Wsign-compare] return left == right; ~~~~ ^ ~~~~~ ``` which was introduced in bitcoin#20788.
@vasild Thanks for making our socket handling mockable. This will be extremely useful when fuzzing! Similar to what you've done for TCP connections it would be really useful to be able to globally mock out DNS lookup to be able to have the responses be generated by a If you want to address this mocking need too you can find some inspiration in #19415 :) |
Just for reference: previous incarnations of this PR had the However this is needed in #20685, so that PR contains a tiny commit to re-introduce that functionality. |
9cc8e30 test: fix sign comparison warning in socket tests (fanquake) Pull request description: This fixes: ```bash In file included from test/sock_tests.cpp:10: In file included from /usr/local/include/boost/test/unit_test.hpp:18: In file included from /usr/local/include/boost/test/test_tools.hpp:46: /usr/local/include/boost/test/tools/old/impl.hpp:107:17: warning: comparison of integers of different signs: 'const long' and 'const unsigned long' [-Wsign-compare] return left == right; ~~~~ ^ ~~~~~ ``` which was introduced in #20788. ACKs for top commit: practicalswift: cr ACK 9cc8e30 vasild: ACK 9cc8e30 Tree-SHA512: 7069a4fde5cec01be03f8477fe396e53658f170efbf1d9ef3339d553bb90a2be9f4acd6b348127b14cd2f91426e0cd1fc35d2d3c9f201cf748c0cf50f47e46a5
9cc8e30 test: fix sign comparison warning in socket tests (fanquake) Pull request description: This fixes: ```bash In file included from test/sock_tests.cpp:10: In file included from /usr/local/include/boost/test/unit_test.hpp:18: In file included from /usr/local/include/boost/test/test_tools.hpp:46: /usr/local/include/boost/test/tools/old/impl.hpp:107:17: warning: comparison of integers of different signs: 'const long' and 'const unsigned long' [-Wsign-compare] return left == right; ~~~~ ^ ~~~~~ ``` which was introduced in bitcoin#20788. ACKs for top commit: practicalswift: cr ACK 9cc8e30 vasild: ACK 9cc8e30 Tree-SHA512: 7069a4fde5cec01be03f8477fe396e53658f170efbf1d9ef3339d553bb90a2be9f4acd6b348127b14cd2f91426e0cd1fc35d2d3c9f201cf748c0cf50f47e46a5
3174425 Cleanup headers after #20788 (Hennadii Stepanov) Pull request description: This is a header cleanup after #20788. ACKs for top commit: vasild: ACK 3174425 Tree-SHA512: 1c21b1ba43841880625289174f10e5b333f6eb857f448e1e4114b1ecdf32a6044ec91c5987c1d66806c1d408a4e3d46569eb41d69a0acb8296601d7c203d9f1d
3174425 Cleanup headers after bitcoin#20788 (Hennadii Stepanov) Pull request description: This is a header cleanup after bitcoin#20788. ACKs for top commit: vasild: ACK 3174425 Tree-SHA512: 1c21b1ba43841880625289174f10e5b333f6eb857f448e1e4114b1ecdf32a6044ec91c5987c1d66806c1d408a4e3d46569eb41d69a0acb8296601d7c203d9f1d
Summary: Move `MillisToTimeval()` from `netbase.{h,cpp}` to `src/util/system.{h,cpp}`. This is necessary in order to use `MillisToTimeval()` from a newly introduced `src/util/sock.{h,cpp}` which cannot depend on netbase because netbase will depend on it. This is a backport of [[bitcoin/bitcoin#20788 | [[bitcoin/bitcoin#20788 | core#20788]]]] [1/5] bitcoin/bitcoin@aa17a44 Test Plan: `ninja all check-all` Reviewers: #bitcoin_abc, Fabien Reviewed By: #bitcoin_abc, Fabien Differential Revision: https://reviews.bitcoinabc.org/D11003
Summary: Move `CloseSocket()` (and `NetworkErrorString()` which it uses) from `netbase.{h,cpp}` to newly added `src/util/sock.{h,cpp}`. This is necessary in order to use `CloseSocket()` from a newly introduced Sock class (which will live in `src/util/sock.{h,cpp}`). `sock.{h,cpp}` cannot depend on netbase because netbase will depend on it. This is a backport of [[bitcoin/bitcoin#20788 | core#20788]] [2/5] bitcoin/bitcoin@dec9b5e Depends on D11003 Test Plan: `ninja all check-all` Reviewers: #bitcoin_abc, Fabien Reviewed By: #bitcoin_abc, Fabien Differential Revision: https://reviews.bitcoinabc.org/D11004
Summary: Use the `Sock` class instead of `SOCKET` for `InterruptibleRecv()` and `Socks5()`. This way the `Socks5()` function can be tested by giving it a mocked instance of a socket. Co-authored-by: practicalswift <practicalswift@users.noreply.github.com> Note: Apply the same changes to seeder/bitcoin.cpp This is a backport of [[bitcoin/bitcoin#20788 | core#20788]] [4/5] bitcoin/bitcoin@04ae846 Depends on D11005 Test Plan: `ninja all check-all` Reviewers: #bitcoin_abc, Fabien Reviewed By: #bitcoin_abc, Fabien Differential Revision: https://reviews.bitcoinabc.org/D11006
Summary: In the arguments of `InterruptibleRecv()`, `Socks5()` and `ConnectThroughProxy()` the variable `hSocket` was previously of type `SOCKET`, but has been changed to `Sock`. Thus rename it to `sock` to imply its type, to distinguish from other `SOCKET` variables and to abide to the coding style wrt variables' names. This is a backport of [[bitcoin/bitcoin#20788 | core#20788]] [5/5] bitcoin/bitcoin@7bd21ce Depends on D11006 Test Plan: `ninja all check-all` Reviewers: #bitcoin_abc, Fabien Reviewed By: #bitcoin_abc, Fabien Subscribers: Fabien Differential Revision: https://reviews.bitcoinabc.org/D11007
Introduce a class to manage the lifetime of a socket - when the object
that contains the socket goes out of scope, the underlying socket will
be closed.
In addition, the new
Sock
class has aSend()
,Recv()
andWait()
methods that can be overridden by unit tests to mock the socket
operations.
The
Wait()
method also hides the#ifdef USE_POLL poll() #else select() #endif
technique from higherlevel code.