Skip to content
This repository has been archived by the owner on May 7, 2020. It is now read-only.

Core/Network: Allow IPv6 for default network interface. #4218

Merged
merged 1 commit into from Nov 17, 2017

Conversation

davidgraeff
Copy link
Contributor

@davidgraeff davidgraeff commented Sep 8, 2017

Clean up NetUtils. Fix NetworkConfigOptionProvider.

Fixes #4205

Signed-off-by: David Gräff david.graeff@web.de

Copy link
Contributor

@triller-telekom triller-telekom left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you for adding IPv6 support.

Please see my comment in line.

@@ -7,7 +7,7 @@
<config-description uri="system:network">
<parameter name="primaryAddress" type="text">
<label>Primary Address</label>
<description>A subnet (e.g. 192.168.1.0/24) <!-- or an IP address (e.g. 192.168.1.5) --></description>
<description>An IPv4/IPv6 CIDR notation (e.g. 192.168.1.0/24 or 192.168.1.12 or fe80:0:0:0:0:0:c0a8:11%eth0/120)</description>
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The idea was to have the NETWORK address here and not the IP address directly. The reason behind it is that if the ESH installation obtains its IP address via DHCP it might get a different one from the same network and we do not want to require the user to change the configuration if this happens. That's why the original implementation in #3930 calculated the NETWORK address and stored it as a configuration value.

I think we should restore this behavior and for IPv6 we would store the subnet, not the specific address as well. Because in IPv6 a host could use auto configuration and choose a different IP from the same subnet on every restart of the system (privacy extension).

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

you're right that there is an IP in the comment, that's my mistake

@davidgraeff
Copy link
Contributor Author

You need to read the changes carefully :) the user selects the current IP with network prefix length. So it works as before but is less confusing for the user because we show what is currently assigned and it works for ipv4 and ipv6. There is no such think as network address actually. It's always IP + prefix.

Copy link
Contributor

@triller-telekom triller-telekom left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You are right, I overlooked your inRange method.

One minor comment: Do we want to offer the user that he can select if he prefers ipv4 or ipv6?

Also I am curious how you tested the modified method of the NetUtil class, because without #4253 you cannot save a configuration through paperui. That was broken when we introduced the configuration-pid.

return hostAddress;
} catch (SocketException ex) {
LOGGER.error("Could not retrieve network interface: {}", ex.getMessage(), ex);
private CidrAddress getAnyAssignedIPAddress(boolean preferIPv4) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You are only calling this method with true which is hardcoded in the sources. Should we offer this parameter as an option for the user to choose?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The API can be used for both yes. And in the future we will probably switch the default to IPv6. But this is the default address that we pick here, that is used if the user didn't configure anything. Why should this be configurable?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Because the user might prefer to use IPv6 now? And if you only want to provide this option in the future, then please remove the parameter for now.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If the user wants ipv6 then he just chooses from the list that we present in paperui. Personally I would just pick the first IP we get from java to bind to. I just tried to be backwards compatible here by selecting an ipv4. Please be aware that no matter if we pick ipv4 or ipv6 as default, both protocols will work anyway.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If that is the case then I do not see the need for this parameter. I it's only about backward compatibility that you prefer IPv4 here then you can remove this parameter and prefer IPv4 nevertheless. In my opinion a method with a boolean parameter that is only called with true is superfluous.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The idea is to remove the parameter and to not prefer any IP version. I do not see why ipv4 should be preferred here, I know some pretty good ipv6 only setup. And the IP version doesn't actually matter, it is the interface that we bind to. At least on Linux such a socket works for ipv4+ipv6.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fine for me. But please have a look at my netmask comment below.

if (prefix % 2 != 0) {
throw new IllegalArgumentException("Not a valid prefix. This must be valid: prefix mod 2 == 0");
}
if (prefix < 0 || prefix >= address.getAddress().length * 8) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

One error that I also have done in my previous PR: RFC1878 allows a prefix of 32 for a single host route, so you should test prefix > address.getAddress().length * 8

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@davidgraeff Did you see this comment regarding the 32 bit netmask?

@davidgraeff
Copy link
Contributor Author

Regarding testing: I didn't test with paperui, that needs to be done. I maybe should add a unit test for modified.

@triller-telekom
Copy link
Contributor

PR #4253 has been merged, please rebase your branch.

It would be nice to have a test for the modified method. How about giving the user an option to set the preference for ipv4 vs ipv6? And please have a look at my comment regarding RFC1878.

@kaikreuzer
Copy link
Contributor

What's the current status here? If I get it correctly, we are waiting for updates from @davidgraeff, right?

@triller-telekom
Copy link
Contributor

Ye sit is about my comment regarding the 32 bit netmask here.

@davidgraeff
Copy link
Contributor Author

done, no time for the modified test, though

@triller-telekom
Copy link
Contributor

Travis failed: @davidgraeff Can you please have a look?

outOfBoundsPrefix(org.eclipse.smarthome.core.net.CidrTest)  Time elapsed: 0.002 sec  <<< FAILURE!
java.lang.AssertionError: Expected exception: java.lang.IllegalArgumentException
	at org.junit.internal.runners.statements.ExpectException.evaluate(ExpectException.java:32)
	at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325)
	at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:78)
	at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:57)
	at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
	at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
	at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
	at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
	at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
	at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
	at org.apache.maven.surefire.junit4.JUnit4Provider.execute(JUnit4Provider.java:264)
	at org.apache.maven.surefire.junit4.JUnit4Provider.executeTestSet(JUnit4Provider.java:153)
	at org.apache.maven.surefire.junit4.JUnit4Provider.invoke(JUnit4Provider.java:124)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.lang.reflect.Method.invoke(Method.java:498)
	at org.apache.maven.surefire.util.ReflectionUtils.invokeMethodWithArray2(ReflectionUtils.java:208)
	at org.apache.maven.surefire.booter.ProviderFactory$ProviderProxy.invoke(ProviderFactory.java:156)
	at org.apache.maven.surefire.booter.ProviderFactory.invokeProvider(ProviderFactory.java:82)
	at org.eclipse.tycho.surefire.osgibooter.OsgiSurefireBooter.run(OsgiSurefireBooter.java:95)
	at org.eclipse.tycho.surefire.osgibooter.HeadlessTestApplication.run(HeadlessTestApplication.java:21)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.lang.reflect.Method.invoke(Method.java:498)
	at org.eclipse.equinox.internal.app.EclipseAppContainer.callMethodWithException(EclipseAppContainer.java:587)
	at org.eclipse.equinox.internal.app.EclipseAppHandle.run(EclipseAppHandle.java:198)
	at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.runApplication(EclipseAppLauncher.java:134)
	at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.start(EclipseAppLauncher.java:104)
	at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:388)
	at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:243)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.lang.reflect.Method.invoke(Method.java:498)
	at org.eclipse.equinox.launcher.Main.invokeFramework(Main.java:653)
	at org.eclipse.equinox.launcher.Main.basicRun(Main.java:590)
	at org.eclipse.equinox.launcher.Main.run(Main.java:1499)
	at org.eclipse.equinox.launcher.Main.main(Main.java:1472)

private static final Pattern IPV6PATTERN = Pattern
.compile("^(([0-9a-fA-F]{1,4}:){7}([0-9a-fA-F]){1,4}(%[\\S]*)?)$");

public CidrAddress(@NonNull InetAddress address, int networkPrefixLength) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

public constructors also should have some javadoc

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done

return m2.matches();
}

public CidrAddress(String cidrNotation) throws IllegalArgumentException {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

dito

primaryAddress = primaryAddressConf;
try {
primaryAddress = new CidrAddress(primaryAddressConf);
} catch (IllegalArgumentException e) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Wouldn't it make sense to at least log a warning? I mean, in the end it's the user who accidentally made a mistake/typo, the service silently "accepts" this configuration but it somehow does not really work as expected. Or did I miss anything?

return null;
}
public static @Nullable String getLocalIpv4HostAddress() {
return new NetUtil().getPrimaryIpv4HostAddress();
Copy link
Contributor

@sjsf sjsf Sep 26, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In this case, the user's configured primaryAddress will never be taken into account. This might not meet expectations...

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is why this method is deprecated. It is a static method, we have no bundle configuration, so the user selected address is not available.


@Test(expected = IllegalArgumentException.class)
public void outOfBoundsPrefix() {
new CidrAddress("192.168.5.8/33");
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does this work for IPv6 addresses? (i.e. is "2001:db8:0:0:8:800:200c:417a/33" valid)?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have added test cases for IPv6

@sjsf
Copy link
Contributor

sjsf commented Oct 2, 2017

Please have a look at the build failure

@davidgraeff
Copy link
Contributor Author

[INFO] Eclipse SmartHome LIRC Binding ..................... SUCCESS [ 2.265 s]
[INFO] Eclipse SmartHome NTP Binding ...................... SUCCESS [ 2.119 s]
[INFO] Eclipse SmartHome NTP Binding Tests ................ SUCCESS [ 6.387 s]
[INFO] Eclipse SmartHome Sonos Binding .................... FAILURE [ 0.319 s]
[INFO] Tradfri Binding .................................... SKIPPED
[INFO] Tradfri Binding Tests .............................. SKIPPED

@sjsf
Copy link
Contributor

sjsf commented Oct 2, 2017

A few lines below you can find the details:

[ERROR] Failed to execute goal org.eclipse.tycho:tycho-compiler-plugin:1.0.0:compile (default-compile) on project org.eclipse.smarthome.binding.sonos: Compilation failure: Compilation failure: 
[ERROR] /home/travis/build/eclipse/smarthome/extensions/binding/org.eclipse.smarthome.binding.sonos/src/main/java/org/eclipse/smarthome/binding/sonos/internal/SonosHandlerFactory.java:[125] 
[ERROR] 	final int port = HttpServiceUtil.getHttpServicePort(bundleContext);
[ERROR] 	                                                    ^^^^^^^^^^^^^
[ERROR] Null type mismatch (type annotations): required '@NonNull BundleContext' but this expression has type '@Nullable BundleContext'

Therefore it is related to your change of adding the null annotations to HttpServiceUtil.

@davidgraeff
Copy link
Contributor Author

I agree. Should the null annotation be removed again? Or the failing bindings be fixed in this PR?

@sjsf
Copy link
Contributor

sjsf commented Oct 5, 2017

Either way is fine - if it's just this one case then maybe it's forth fixing the binding right away. However, if you end up needing to fix pretty much everything everywhere, then I'd rather suggest going back. I'd leave the decision to you.

@triller-telekom
Copy link
Contributor

@davidgraeff I think for now it would be best to remove this annotation and afterwards we can merge this PR. Blocking a PR for so long just because of this annotation is not really worth it in my opinion.

@davidgraeff
Copy link
Contributor Author

I agree. I'm just not at home at the moment, I might have time on the weekend for all my open PRs.

@openhab-bot
Copy link
Contributor

This pull request has been mentioned on openHAB Community. There might be relevant details there:

https://community.openhab.org/t/neeo-remote-binding-transport/33408/59

…tils. Fix NetworkConfigOptionProvider

Signed-off-by: David Graeff <david.graeff@web.de>
@davidgraeff
Copy link
Contributor Author

@triller-telekom @SJKA Problematic annotation removed

Copy link
Contributor

@kaikreuzer kaikreuzer left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks, @davidgraeff!

@kaikreuzer kaikreuzer merged commit 753a771 into eclipse-archived:master Nov 17, 2017
kaikreuzer added a commit that referenced this pull request Nov 18, 2017
… up NetUtils. Fix NetworkConfigOptionProvider (#4218)"

This reverts commit 753a771.
kaikreuzer added a commit that referenced this pull request Nov 18, 2017
… up NetUtils. Fix NetworkConfigOptionProvider (#4218)"

This reverts commit 753a771.
kaikreuzer added a commit that referenced this pull request Nov 20, 2017
…e. Clean up NetUtils. Fix NetworkConfigOptionProvider (#4218)""

This reverts commit 0be827d.
@davidgraeff
Copy link
Contributor Author

I consider this closed with #4616

@kaikreuzer kaikreuzer added this to the 0.9.0 milestone Nov 30, 2017
@davidgraeff davidgraeff deleted the netutils3 branch July 9, 2018 10:38
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

5 participants