-
Notifications
You must be signed in to change notification settings - Fork 37.7k
net, refactor: pass uint16 CService::port as uint16 #21328
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
net, refactor: pass uint16 CService::port as uint16 #21328
Conversation
4712830
to
f8b1c21
Compare
Just discovered #8394, will check if it contains anything I've overlooked. |
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.
ACK f8b1c21
I think this PR is good and safe as it is. Some non-blocker comments below. It would be even better if it adds some checks that ports given by the user are in range, like in https://github.com/bitcoin/bitcoin/pull/8394/files#diff-134ccc4e5308f84fb9c03a9a1e1599209560370e49e30c7f545fa7b9ba7e07deR153
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 Thanks for removing this implicit conversion gotcha :)
Somewhat related: #19415 (comment) |
I like the idea of using specific types. But if we're going to change this, I think I would feel slightly better defining a Anyhow concept ACK. |
f8b1c21
to
c373a87
Compare
Thank you @vasild, @practicalswift and @laanwj. Updated per all of your suggestions. |
7b93b54
to
6be9695
Compare
Not super excited by the introduction of The problem is probably best illustrated by this UB quiz: Q. Which of the two cases rely on undefined behaviour? // Snippet 1
Port p;
if (p != other_p) {
} // Snippet 2
uint16_t p;
if (p != other_p) {
} Click for answerBoth snippets rely on undefined behaviour (they are technically equivalent thanks to the But that's not the point. The point is that while the UB in snippet 2 is immediately clear (read of uninitialized Trying to make it as easy as possible to spot unsafe code is an important part of safe coding practice. Personally I find that the introduction of |
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.
ACK 9b7055f
Notice that this is not the last commit - I tend to agree with @practicalswift wrt uint16_t
vs Port
so I ACK the commit before those changes. Two more things to consider about Port
:
- The name
Port
may be too generic. I can imagine that "port" in some other context means something else, e.g. "usb port for connecting to a hardware wallet". MaybeIPPort
would be a better name. - At one place we do
Port n; ParseUInt16(..., &n);
which kind of defeats the purpose of thePort
abstraction. I don't see IP ports ever changing to something other than 16 bit unsigned integers.
Thanks for the feedback! I agree that No strong opinion, but here are a few reasons why I tend to agree with @laanwj and took the time to do it:
I'm not sure whether to wait for more feedback or separate the type alias to another pull. Keep the feedback coming 🙏 |
Ah, the fuzz CI is signalling a needed change since the merge of #19415: "UndefinedBehaviorSanitizer: implicit-signed-integer-truncation test/fuzz/netbase_dns_lookup.cpp:48:45". Will update. |
a057361
to
52dd40a
Compare
Thanks @vasild! Updated one line per +++ b/src/test/fuzz/netbase_dns_lookup.cpp
@@ -18,7 +18,7 @@ FUZZ_TARGET(netbase_dns_lookup)
const std::string name = fuzzed_data_provider.ConsumeRandomLengthString(512);
const unsigned int max_results = fuzzed_data_provider.ConsumeIntegral<unsigned int>();
const bool allow_lookup = fuzzed_data_provider.ConsumeBool();
- const int default_port = fuzzed_data_provider.ConsumeIntegral<int>();
+ const uint16_t default_port = fuzzed_data_provider.ConsumeIntegral<uint16_t>(); |
cr ACK 52dd40a: patch looks correct |
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.
ACK 52dd40a
Looks like
which seems unrelated to the changes I am testing there. Edit: also in another PR: https://cirrus-ci.com/task/6488952220680192?command=ci#L3334 |
@vasild Conversions to unsigned types are actually well-defined in the lamguage. Our sanitizer runs in sort of an over-eager mode and triggers on that because such conversions are often a sign of bugs. But here I suspect it's intentional, and valid. |
@sipa, I agree. However, a failing CI is a problem :) it would be fixed either by this PR or an explicit cast like |
cr ACK 52dd40a |
3d086f4 test: add ParseUInt16() test coverage (Jon Atack) Pull request description: `ParseUInt16()` was just added in bitcoin#21328. ACKs for top commit: practicalswift: cr ACK 3d086f4: patch looks correct & more coverage is better than less coverage Tree-SHA512: bf7f96deb7c1531419565907f0ea8a8e32b368d4b823a3e80928b2c118edbf643ea06e357b4b5504a89f855caeed289daa9f823c740231ed6ad1b8ed00285ce8
3d086f4 test: add ParseUInt16() test coverage (Jon Atack) Pull request description: `ParseUInt16()` was just added in bitcoin#21328. ACKs for top commit: practicalswift: cr ACK 3d086f4: patch looks correct & more coverage is better than less coverage Tree-SHA512: bf7f96deb7c1531419565907f0ea8a8e32b368d4b823a3e80928b2c118edbf643ea06e357b4b5504a89f855caeed289daa9f823c740231ed6ad1b8ed00285ce8
Summary: > As noticed during review of the I2P network support, `CService::port` is `uint16_t` but is passed around the codebase and into the ctors as `int`, which causes uneeded conversions and casts. We can avoid these (including in the incoming I2P code without further changes to it) by using ports with the correct type. The remaining conversions are pushed out to the user input boundaries where they can be range-checked and raise with user feedback in the next patch. This is a backport of [[bitcoin/bitcoin#21328 | core#21328]] [1/3] bitcoin/bitcoin@6423c81 Test Plan: `ninja all check-all` Reviewers: #bitcoin_abc, Fabien Reviewed By: #bitcoin_abc, Fabien Differential Revision: https://reviews.bitcoinabc.org/D11077
Summary: This is a backport of [[bitcoin/bitcoin#21328 | core#21328]] [2/3] and [[bitcoin/bitcoin#21488 | core#21488]] (unit tests) bitcoin/bitcoin@2875a76 Depends on D11077 and D11081 Test Plan: `ninja all check-all bitcoin-fuzzers` Reviewers: #bitcoin_abc, Fabien Reviewed By: #bitcoin_abc, Fabien Subscribers: Fabien Differential Revision: https://reviews.bitcoinabc.org/D11078
Summary: This is a backport of [[bitcoin/bitcoin#21328 | core#21328]] [3/3] bitcoin/bitcoin@52dd40a Depends on D11078 Test Plan: `ninja all check-all bitcoin-fuzzers` Reviewers: #bitcoin_abc, Fabien Reviewed By: #bitcoin_abc, Fabien Differential Revision: https://reviews.bitcoinabc.org/D11079
As noticed during review today in #20685 (comment) of the upcoming I2P network support,
CService::port
isuint16_t
but is passed around the codebase and into the ctors asint
, which causes uneeded conversions and casts. We can avoid these (including in the incoming I2P code without further changes to it) by using ports with the correct type. The remaining conversions are pushed out to the user input boundaries where they can be range-checked and raise with user feedback in the next patch.