-
Notifications
You must be signed in to change notification settings - Fork 37.7k
Add Binds, WhiteBinds, Whitelistedrange to CConnman::Options #10496
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
Pinging @theuni |
@@ -64,6 +64,14 @@ | |||
#endif | |||
#endif | |||
|
|||
/** Used to pass flags to the Bind() function */ | |||
enum BindFlags { |
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.
Minor nit, but what about switching to C++11 strongly typed enumerations (enum class
) while we are at it?
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.
Great idea, but unfortunately, bitwise operations don't work with those (unless you manually add those functions to the class) :(
See http://blog.bitwigglers.org/using-enum-classes-as-type-safe-bitmasks/
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.
Ah, of course. Sorry!
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.
utACK 7313bfec5354f44571929249ee3672b8c38675a3. This seems like an improvement, though I also think it might be a little better if the connman options were vectors of strings, so AppInit would only be dealing with translating arguments (and the loops could be eliminated), and connman would deal with everything network related (lookups).
@ryanofsky thanks. I actually did it like this in a first iteration, but changed it because I figured that the arguments should be evaluated as much as possible before entering ConnMan. After all, ConnMan doesn't particularly care about the command line string representation. It was a bit weird having the error messages that relate to Edit: I see the point though that |
I believe this is OK. I have a PR coming up which (after lots of thought) moves resolving into its own class, of which CConnman is one user. This way other layers are able to use the resolver without necessarily having to go through CConnman. So, concept ACK. Reviewing. |
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. Thanks for working on this!
@@ -1644,6 +1594,28 @@ bool AppInitMain(boost::thread_group& threadGroup, CScheduler& scheduler) | |||
connOptions.nMaxOutboundTimeframe = nMaxOutboundTimeframe; | |||
connOptions.nMaxOutboundLimit = nMaxOutboundLimit; | |||
|
|||
if (gArgs.IsArgSet("-bind")) { |
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.
This looks like a change in behavior when setting "-bind=foo -listen=0". Granted, that combination makes no sense.
I think we should probably just check for that combination, and exit with an error in that case.
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.
Done.
src/net.cpp
Outdated
} | ||
|
||
bool CConnman::InitBinds(const std::vector<CService>& binds, const std::vector<CService>& whiteBinds) { | ||
if (fListen) { |
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.
See other comment. It doesn't make sense to have binds/whitebinds set at all if !fListen.
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.
Done.
src/net.cpp
Outdated
bool CConnman::InitBinds(const std::vector<CService>& binds, const std::vector<CService>& whiteBinds) { | ||
if (fListen) { | ||
bool fBound = false; | ||
for (const auto& addrBind : binds) { |
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.
Mm, this moves the logic away from the caller and into CConnman, which is what we're trying to avoid by adding the heaps of options.
I think I'd prefer to see flags passed in along with CServices, so that CConnman can just do what it's told. So either a tiny struct, or just a pair.
Then, CConnman will try to bind the BF_EXPLICIT addresses, and if it fails, tries to bind the rest.
Also, in that case, the last failed bind wouldn't need to have BF_REPORT_ERROR set, we'd just notice the false return and act on it accordingly.
Sound reasonable?
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.
Mm, this moves the logic away from the caller and into CConnman, which is what we're trying to avoid by adding the heaps of options.
I think I'd prefer to see flags passed in along with CServices, so that CConnman can just do what it's told. So either a tiny struct, or just a pair.
The logic would be in CConnman
all the same, just the data structure you pass the info with is changed from two vectors to one vector of pairs, which is equivalent. The code looks more complicated from what I can tell. Or did I misunderstand your request?
I added this in a separate commit to see the diff, I drop it again if needed.
Then, CConnman will try to bind the BF_EXPLICIT addresses, and if it fails, tries to bind the rest.
At the moment, the rest is only attempted if no explicit binds are specified. If they fail, all fails, which makes sense to me.
Also, in that case, the last failed bind wouldn't need to have BF_REPORT_ERROR set, we'd just notice the false return and act on it accordingly.
Act how, apart from reporting the error (which this flag does)?
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.
Mm, this moves the logic away from the caller and into CConnman, which is what we're trying to avoid by adding the heaps of options.
I think I'd prefer to see flags passed in along with CServices, so that CConnman can just do what it's told. So either a tiny struct, or just a pair.
The logic would be in CConnman all the same, just the data structure you pass the info with is changed from two vectors to one vector of pairs, which is equivalent. The code looks more complicated from what I can tell. Or did I misunderstand your request?
The logic would still be in CConnman, but the caller would have the ability to dictate exactly how the binds are setup. For example, there's no way to specify "listen on this address as well as the localhost fallbacks".
I think this is ok for now, though. We can add options as things come up.
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.
For example, there's no way to specify "listen on this address as well as the localhost fallbacks".
But that wasn't possible before either.
Do you prefer the commit which passes the whitelist flag in the pair (768c7f7), or should I drop it? I don't mind either way, but the new code seems less readable than the code before, but it is semantically exactly the same.
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.
But that wasn't possible before either.
Sure, but we've been slowly moving these config options out to the caller so that less is hard-coded.
In the near-future, I'm looking forward to creating 2 CConnman instances and running them against each-other for testing. The more we can control via setup options, the better. I have no problem with adding those options incrementally, I'd just like to make sure we're not making future changes tougher.
As for the whitelist flag, either way is fine for this PR. Whichever you think is more readable. We'll expand on the options when needed.
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 reverted it as I find the previous version more readable.
@theuni Can you check whether your requested changes are addressed? |
return false; | ||
std::string strError; | ||
if (!BindListenPort(addr, strError, (flags & BF_WHITELIST) != 0)) { | ||
if ((flags & BF_REPORT_ERROR) && clientInterface) { |
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.
Well done! Thanks for using the local instance.
src/net.cpp
Outdated
flags |= BF_WHITELIST; | ||
fBound |= Bind(addrBind.first, flags); | ||
} | ||
if (binds.empty()) { |
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.
Looks like there's no way to run without listening now.
Sorry for not being more clear here: #10496 (comment). I was suggesting that we shouldn't get into InitBinds in the first place if binding isn't allowed.
We'll either need to change this so that its caller uses the ugly global as before:
if(fListen && !InitBinds(...)) {
...
}
or add a flag for fallback connections, which InitBinds() only uses if nothing else is already bound.
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.
Oops, was a bit too eager here. Re-added the fListen
check as you suggested.
src/net.cpp
Outdated
clientInterface = connOptions.uiInterface; | ||
|
||
if (!InitBinds(connOptions.vBinds)) { | ||
strError = _("Failed to listen on any port. Use -listen=0 if you want 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.
This strError param is clunky (my fault!). We should do away with it and just use clientInterface->InitError() directly. That can be done as a follow-up though.
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.
Done.
src/init.cpp
Outdated
size_t nUserBind = | ||
(gArgs.IsArgSet("-bind") ? gArgs.GetArgs("-bind").size() : 0) + | ||
(gArgs.IsArgSet("-whitebind") ? gArgs.GetArgs("-whitebind").size() : 0); | ||
if (nUserBind != 0 && !GetBoolArg("-listen", DEFAULT_LISTEN)) { |
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.
s/GetBoolArg/gArgs.GetBoolArg/
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.
GetBoolArg() is simply wrapping gArgs.GetBoolArg(), and both variants are already used in the function. Could make that consistent in a separate PR.
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.
gArgs is the new (as of very recently) way of handling these args, it'd be helpful if new code didn't reintroduce the former usage as I assume the wrappers are intended to be temporary.
looks good aside from those few issues. |
@theuni thanks for the feedback. I added a new commit for easier review, I will squash in the end. |
@theuni addressed the GetBoolArgs issue and squashed. |
Part of a series of changes to clean up the instantiation of connman by decoupling the command line arguments.
Part of a series of changes to clean up the instantiation of connman by decoupling the command line arguments. We also now abort with an error when explicit binds are set with -listen=0.
Rebased. |
utACK 07b2afe |
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.
utACK 07b2afe. There were many changes since last review, all discussed above.
utACK 07b2afe |
Subset of #9897, with the goal to decouple command line arg parsing and make AppInitMain() smaller.