-
Notifications
You must be signed in to change notification settings - Fork 695
GEODE-9235: Allow binding to all addresses #6435
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
c1adfef to
0a7cb21
Compare
0a7cb21 to
8c08aab
Compare
...gfsh/src/main/java/org/apache/geode/management/internal/cli/commands/StartServerCommand.java
Outdated
Show resolved
Hide resolved
dschneider-pivotal
left a comment
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 didn't see any problems with this change. Consider the minor refactor I suggested
|
Great description! |
|
@dschneider-pivotal I have implemented your suggestion. I was waiting some days to do it in case more reviews with suggestions were added. Thanks! |
|
CI failed due to flaky test (https://issues.apache.org/jira/browse/GEODE-9242 ) |
886ac86 to
f2ef6cd
Compare
|
rebase done in order to fix conflicts |
Bill
left a comment
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 PR @alb3rtobr !! In addition to comments and requests below please update the command-line options help for LocatorLauncher (bind-address) and ServerLauncher (bind-address, server-bind-address).
The bigger issue is that I don't see a test that verifies that if --bind-address=* on a multi-homed host, that both (health monitor) and (client's cache) services bind on all interfaces. I realize this isn't possible in a plain old DUnit test. But what about a Dockerized one along the lines of SingleServerSNIAcceptanceTest?
FYI and for other reviewers, this is my summary of endpoint configuration before/after this ticket:
...va/org/apache/geode/management/internal/cli/commands/StartLocatorCommandIntegrationTest.java
Show resolved
Hide resolved
| } | ||
|
|
||
| public static boolean isWildcardAddress(String address) { | ||
| return "0.0.0.0".equals(address) || "::".equals(address) || isWildcardCharacter(address); |
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.
The first two clauses in the disjunction reiterate logic already in InetAddress.isAnyLocalAddress(). Is there a reason to not construct an InetAddress and use isAnyLocalAddress()?
It's documented to do this (and the two subclasses for IPV4 and IPV6 seem to do the right thing):
/**
* Utility routine to check if the InetAddress in a wildcard address.
* @return a {@code boolean} indicating if the Inetaddress is
* a wildcard address.
* @since 1.4
*/
public boolean isAnyLocalAddress() {
return false;
}| } | ||
| } | ||
| } else { | ||
| if (isWildcardAddress(host.toString())) { |
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.
Please reduce one level of nesting by moving this if up as an else if. Then the return isLocalHost… could be its own else block as before this PR.
| return "0.0.0.0".equals(address) || "::".equals(address) || isWildcardCharacter(address); | ||
| } | ||
|
|
||
| public static boolean isWildcardCharacter(String address) { |
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 believe this method returns true if the string is the wildcard character defined ServerLauncher and LocatorLauncher's --bind-address (command line parameter).
Please add method-level javadoc explaining the context in which this is a "wildcard character".
Need same explanation of context in javadoc on isWildcardAddress() too.
| address = LocalHostUtil.getAnyLocalAddress(); | ||
| } else { | ||
| address = InetAddress.getByName(addressString); | ||
| } |
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.
If no bind address is specified we set bindAddress to null. Apparently, elsewhere in the code, we will interpret that null as a wildcard (per the documentation for the gfsh start locator --bind-address option.
How come we have two different paths in this method? Shouldn't we do the same thing if the user specifies * as if the user specifies nothing at all?
| Properties gemfireProperties = new Properties(); | ||
|
|
||
| StartMemberUtils.setPropertyIfNotNull(gemfireProperties, ConfigurationProperties.BIND_ADDRESS, | ||
| bindAddress); |
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 thought it was odd that we had to call setPropertyIfNotNull() in this method (doStartLocator()) but we did not over in StartServerCommand.doStartServer(). Looks like it was already being called over in that other method.
Does that mean that before this code change here, we had a bug where gfsh start locator would ignore the bind address (before this PR)?
| serverSocket = createServerSocket(localAddress.getInetAddress(), | ||
| services.getConfig().getMembershipPortRange()); | ||
| InetAddress address = localAddress.getInetAddress(); | ||
| String bindAddrStr = services.getConfig().getBindAddress(); |
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.
Ooh good catch remembering to fix the health monitor endpoint too!
| String str = config.getBindAddress(); | ||
| // JGroups UDP protocol requires a bind address | ||
| if (str == null || str.length() == 0) { | ||
| if (str == null || str.length() == 0 || LocalHostUtil.isWildcardAddress(str)) { |
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.
yes!
.../src/main/java/org/apache/geode/distributed/internal/membership/gms/fd/GMSHealthMonitor.java
Show resolved
Hide resolved
|
Thanks for the review @Bill . I will try the dockerized test. In the meanwhile Im moving the PR to draft. |

AS A geode contributor
I WANT TO be able to start members with option
--bind-address=0.0.0.0,--bind-address=::or--bind-address=*SO THAT all TCP endpoints are bound to all interfaces.
It is not currently possible to start cluster members binding to all interfaces. That is using
--bind-address=0.0.0.0for ipv4 or--bind-address=::for ipv6.Geode binds the locator and server traffic port by default to
0.0.0.0, but the membership ports are bound by default to the local address.Changing the default membership binding is not the best option, as it could cause problems in existing Geode deployments. But using
--bind-address=0.0.0.0,--bind-address=::or--bind-address=*should be accepted.There is a use case that needs this binding, that is using Istio with Geode. One of the requirements set by Istio towards applications trying to integrate with it is that the application listening ports need to be bound to 0.0.0.0 address (which listens on all interfaces).
It is currently not possible to start a cluster using wildcard address due to if
--bind-addressis specified, its value will be used for all tcp endpoints and the udp membership endpoint created by JGroups. And as JGroups does not accept binding to all addresses, and exception is thrown. This behavior can be verified withWildcardAddressBindingDUnitTest.javatests.