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

NetUtil: Netmask '32' is out of bounds #4205

Closed
maggu2810 opened this issue Sep 6, 2017 · 22 comments
Closed

NetUtil: Netmask '32' is out of bounds #4205

maggu2810 opened this issue Sep 6, 2017 · 22 comments

Comments

@maggu2810
Copy link
Contributor

Why is a netmask '32' out of bounds?

2017-09-06T16:36:00,581 | ERROR | qtp4338408-211   | NetworkConfigOptionProvider      | 184 - org.eclipse.smarthome.config.core - 0.9.0.foo | Could not calculate network address: Netmask '32' is out of bounds (1-31) Ignoring IP 10.39.0.21
java.lang.IllegalArgumentException: Netmask '32' is out of bounds (1-31)
	at org.eclipse.smarthome.core.net.NetUtil.getIpv4NetAddress(NetUtil.java:233) [188:org.eclipse.smarthome.core:0.9.0.foo]
	at org.eclipse.smarthome.config.core.net.internal.NetworkConfigOptionProvider.getIPv4Addresses(NetworkConfigOptionProvider.java:82) [184:org.eclipse.smarthome.config.core:0.9.0.foo]
	at org.eclipse.smarthome.config.core.net.internal.NetworkConfigOptionProvider.getParameterOptions(NetworkConfigOptionProvider.java:53) [184:org.eclipse.smarthome.config.core:0.9.0.foo]
	at org.eclipse.smarthome.config.core.ConfigDescriptionRegistry.getConfigOptions(ConfigDescriptionRegistry.java:212) [184:org.eclipse.smarthome.config.core:0.9.0.foo]
	at org.eclipse.smarthome.config.core.ConfigDescriptionRegistry.getConfigDescription(ConfigDescriptionRegistry.java:162) [184:org.eclipse.smarthome.config.core:0.9.0.foo]
	at org.eclipse.smarthome.io.rest.core.config.ConfigDescriptionResource.getByURI(ConfigDescriptionResource.java:80) [204:org.eclipse.smarthome.io.rest.core:0.9.0.foo]
	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.glassfish.jersey.server.model.internal.ResourceMethodInvocationHandlerFactory$1.invoke(ResourceMethodInvocationHandlerFactory.java:81) [249:org.glassfish.jersey.core.jersey-server:2.22.2]
	at org.glassfish.jersey.server.model.internal.AbstractJavaResourceMethodDispatcher$1.run(AbstractJavaResourceMethodDispatcher.java:144) [249:org.glassfish.jersey.core.jersey-server:2.22.2]
	at org.glassfish.jersey.server.model.internal.AbstractJavaResourceMethodDispatcher.invoke(AbstractJavaResourceMethodDispatcher.java:161) [249:org.glassfish.jersey.core.jersey-server:2.22.2]
	at org.glassfish.jersey.server.model.internal.JavaResourceMethodDispatcherProvider$ResponseOutInvoker.doDispatch(JavaResourceMethodDispatcherProvider.java:160) [249:org.glassfish.jersey.core.jersey-server:2.22.2]
	at org.glassfish.jersey.server.model.internal.AbstractJavaResourceMethodDispatcher.dispatch(AbstractJavaResourceMethodDispatcher.java:99) [249:org.glassfish.jersey.core.jersey-server:2.22.2]
	at org.glassfish.jersey.server.model.ResourceMethodInvoker.invoke(ResourceMethodInvoker.java:389) [249:org.glassfish.jersey.core.jersey-server:2.22.2]
	at org.glassfish.jersey.server.model.ResourceMethodInvoker.apply(ResourceMethodInvoker.java:347) [249:org.glassfish.jersey.core.jersey-server:2.22.2]
	at org.glassfish.jersey.server.model.ResourceMethodInvoker.apply(ResourceMethodInvoker.java:102) [249:org.glassfish.jersey.core.jersey-server:2.22.2]
	at org.glassfish.jersey.server.ServerRuntime$2.run(ServerRuntime.java:326) [249:org.glassfish.jersey.core.jersey-server:2.22.2]
	at org.glassfish.jersey.internal.Errors$1.call(Errors.java:271) [248:org.glassfish.jersey.core.jersey-common:2.22.2]
	at org.glassfish.jersey.internal.Errors$1.call(Errors.java:267) [248:org.glassfish.jersey.core.jersey-common:2.22.2]
	at org.glassfish.jersey.internal.Errors.process(Errors.java:315) [248:org.glassfish.jersey.core.jersey-common:2.22.2]
	at org.glassfish.jersey.internal.Errors.process(Errors.java:297) [248:org.glassfish.jersey.core.jersey-common:2.22.2]
	at org.glassfish.jersey.internal.Errors.process(Errors.java:267) [248:org.glassfish.jersey.core.jersey-common:2.22.2]
	at org.glassfish.jersey.process.internal.RequestScope.runInScope(RequestScope.java:317) [248:org.glassfish.jersey.core.jersey-common:2.22.2]
	at org.glassfish.jersey.server.ServerRuntime.process(ServerRuntime.java:305) [249:org.glassfish.jersey.core.jersey-server:2.22.2]
	at org.glassfish.jersey.server.ApplicationHandler.handle(ApplicationHandler.java:1154) [249:org.glassfish.jersey.core.jersey-server:2.22.2]
	at org.glassfish.jersey.servlet.WebComponent.serviceImpl(WebComponent.java:473) [246:org.glassfish.jersey.containers.jersey-container-servlet-core:2.22.2]
	at org.glassfish.jersey.servlet.WebComponent.service(WebComponent.java:427) [246:org.glassfish.jersey.containers.jersey-container-servlet-core:2.22.2]
	at org.glassfish.jersey.servlet.ServletContainer.service(ServletContainer.java:388) [246:org.glassfish.jersey.containers.jersey-container-servlet-core:2.22.2]
	at org.glassfish.jersey.servlet.ServletContainer.service(ServletContainer.java:341) [246:org.glassfish.jersey.containers.jersey-container-servlet-core:2.22.2]
	at org.glassfish.jersey.servlet.ServletContainer.service(ServletContainer.java:228) [246:org.glassfish.jersey.containers.jersey-container-servlet-core:2.22.2]
	at com.eclipsesource.jaxrs.publisher.internal.ServletContainerBridge.service(ServletContainerBridge.java:76) [42:com.eclipsesource.jaxrs.publisher:5.3.1.201602281253]
	at org.eclipse.jetty.servlet.ServletHolder.handle(ServletHolder.java:845) [157:org.eclipse.jetty.servlet:9.3.14.v20161028]
	at org.eclipse.jetty.servlet.ServletHandler.doHandle(ServletHandler.java:584) [157:org.eclipse.jetty.servlet:9.3.14.v20161028]
	at org.ops4j.pax.web.service.jetty.internal.HttpServiceServletHandler.doHandle(HttpServiceServletHandler.java:71) [267:org.ops4j.pax.web.pax-web-jetty:6.0.6]
	at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:143) [156:org.eclipse.jetty.server:9.3.14.v20161028]
	at org.eclipse.jetty.security.SecurityHandler.handle(SecurityHandler.java:548) [154:org.eclipse.jetty.security:9.3.14.v20161028]
	at org.eclipse.jetty.server.session.SessionHandler.doHandle(SessionHandler.java:226) [156:org.eclipse.jetty.server:9.3.14.v20161028]
	at org.eclipse.jetty.server.handler.ContextHandler.doHandle(ContextHandler.java:1180) [156:org.eclipse.jetty.server:9.3.14.v20161028]
	at org.ops4j.pax.web.service.jetty.internal.HttpServiceContext.doHandle(HttpServiceContext.java:284) [267:org.ops4j.pax.web.pax-web-jetty:6.0.6]
	at org.eclipse.jetty.servlet.ServletHandler.doScope(ServletHandler.java:512) [157:org.eclipse.jetty.servlet:9.3.14.v20161028]
	at org.eclipse.jetty.server.session.SessionHandler.doScope(SessionHandler.java:185) [156:org.eclipse.jetty.server:9.3.14.v20161028]
	at org.eclipse.jetty.server.handler.ContextHandler.doScope(ContextHandler.java:1112) [156:org.eclipse.jetty.server:9.3.14.v20161028]
	at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:141) [156:org.eclipse.jetty.server:9.3.14.v20161028]
	at org.ops4j.pax.web.service.jetty.internal.JettyServerHandlerCollection.handle(JettyServerHandlerCollection.java:80) [267:org.ops4j.pax.web.pax-web-jetty:6.0.6]
	at org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:134) [156:org.eclipse.jetty.server:9.3.14.v20161028]
	at org.eclipse.jetty.server.Server.handle(Server.java:534) [156:org.eclipse.jetty.server:9.3.14.v20161028]
	at org.eclipse.jetty.server.HttpChannel.handle(HttpChannel.java:320) [156:org.eclipse.jetty.server:9.3.14.v20161028]
	at org.eclipse.jetty.server.HttpConnection.onFillable(HttpConnection.java:251) [156:org.eclipse.jetty.server:9.3.14.v20161028]
	at org.eclipse.jetty.io.AbstractConnection$ReadCallback.succeeded(AbstractConnection.java:273) [148:org.eclipse.jetty.io:9.3.14.v20161028]
	at org.eclipse.jetty.io.FillInterest.fillable(FillInterest.java:95) [148:org.eclipse.jetty.io:9.3.14.v20161028]
	at org.eclipse.jetty.io.SelectChannelEndPoint$2.run(SelectChannelEndPoint.java:93) [148:org.eclipse.jetty.io:9.3.14.v20161028]
	at org.eclipse.jetty.util.thread.strategy.ExecuteProduceConsume.executeProduceConsume(ExecuteProduceConsume.java:303) [159:org.eclipse.jetty.util:9.3.14.v20161028]
	at org.eclipse.jetty.util.thread.strategy.ExecuteProduceConsume.produceConsume(ExecuteProduceConsume.java:148) [159:org.eclipse.jetty.util:9.3.14.v20161028]
	at org.eclipse.jetty.util.thread.strategy.ExecuteProduceConsume.run(ExecuteProduceConsume.java:136) [159:org.eclipse.jetty.util:9.3.14.v20161028]
	at org.eclipse.jetty.util.thread.QueuedThreadPool.runJob(QueuedThreadPool.java:671) [159:org.eclipse.jetty.util:9.3.14.v20161028]
	at org.eclipse.jetty.util.thread.QueuedThreadPool$2.run(QueuedThreadPool.java:589) [159:org.eclipse.jetty.util:9.3.14.v20161028]
	at java.lang.Thread.run(Thread.java:748) [?:?]
@maggu2810
Copy link
Contributor Author

@triller-telekom You implemented this in #3930 could you give me some background?

@kaikreuzer
Copy link
Contributor

According to https://askubuntu.com/a/709497, this is no valid netmask for a local subnet. What is your use case here?

@kaikreuzer
Copy link
Contributor

Anyhow, the NetworkConfigOptionProvider implementation has just been completely changed by #4189 - so I would suggest to test against the latest master.

@maggu2810
Copy link
Contributor Author

Anyhow, the NetworkConfigOptionProvider implementation has just been completely changed by #4189 - so I would suggest to test against the latest master.

I did not realize any change of the method getIpv4NetAddress in that PR.

According to https://askubuntu.com/a/709497, this is no valid netmask for a local subnet. What is your use case here?

The machine is part of a VPN network and that address has been assigned to the client by the VPN server. I didn't realize any other tool that complains about the network configuration. The communication between different VPN clients work as expected.

All the time I open Configuration, Services in the Paper UI the log is filled with that stacktrace.

@maggu2810
Copy link
Contributor Author

Ah, I should have a deeper look at the stack trace...
Will test it again.

@davidgraeff
Copy link
Contributor

Hm, I finally read the JavaDoc for NetworkConfigOptionProvider

Provides a list of IPv4 addresses of the local machine and shows the user which interface belongs to which IP address

We don't show the user the interface name though, only the IP address. A way to change this is to extend CidrAddress with an optional NetworkInterface field and in the loop where we create the options we would say:
cidrAddress -> new ParameterOption(cidrAddress.toString(), cidrAddress.getNetworkInterface().getDisplayName()+" ("+cidrAddress.toString()+")"
or similar.

@triller-telekom
Copy link
Contributor

Hmm yes indeed we do not show the user the interface name. The fact that it is (still) in the javadoc is because of the discussions before I implemented that option. The original idea was to let the user select an interface name, but then he doesn't know which IP address this is and also the user does not care which name it is, other operating systems might even create very long names...

In the end we decided to let the user select the network address in case its a dynamic one assigned through DHCP, so he does not need to change the configuration if the system gets a different IP assigned.

That's why I am wondering why #4189 has changed this behavior and I should now select an IP address and not a network anymore.

@davidgraeff
Copy link
Contributor

davidgraeff commented Sep 7, 2017

I forgot to add the call to the conversion method, because I didn't understand the purpose at first.

Why do we only allow IPv4 here?

And we should use apache/commons/net/util/SubnetUtils.java. As I understood Guava goes, but the apache library stays, so can and should be used here.

@triller-telekom
Copy link
Contributor

I forgot to add the call to the conversion method, because I didn't understand the purpose at first.

Maybe I should have left a comment there or paid some attention on your PR, sorry for noticing this late. Will you change it in a follow-up PR please?

Why do we only allow IPv4 here?

It's the first implementation since most people still have IPv4. But our intention was that IPv6 support should be added there too, at some point in time.

And we should use apache/commons/net/util/SubnetUtils.java

I wanted to use that method, but @kaikreuzer complained that we should not add such a dependency to our "core" bundle... :(

@davidgraeff
Copy link
Contributor

We use apache felix :D A lot of Guava code can be replaced by Java8 and soon Java9, but the apache library is really helpful.

IPv6 would work differently, because we need the zone index additionally (fe80::3%eth0). Which is the network interface name on linux/macOS and the network interface number on Windows.

@davidgraeff
Copy link
Contributor

I would say, we show the user the CIDR notation (including ipv6 zone index) and store it as value as well.

The networkAdressService would find the network interface for IPv4 like at the moment (computing the subnet mask etc) and for IPv6 the zone index is used.

@triller-telekom
Copy link
Contributor

But you still want to have the IPv6 configuration as a separate field, right? So the user can select the subnet to be used for IPv4 and in addition can configure the zone for IPv6. If that is what you suggest, I am fine with that.

@davidgraeff
Copy link
Contributor

davidgraeff commented Sep 7, 2017

Nope, no separate field. The user will be presented with all assigned IP addresses (IPv4+IPv6) in the list. This is because you are using IPv4 or IPv6 to bind your network services, not both. Of course the respective other protocol works as well on the bound network interface.

So the user can select the subnet to be used for IPv4

Hm, the user should not select a subnet. He selects an "IP/prefix%zone" which is unique and can be used to find the corresponding network interface and assigned IP again (even if DHCP/NDPv6 changed addresses in between).

@davidgraeff
Copy link
Contributor

I will create a pr tomorrow

@triller-telekom
Copy link
Contributor

Nope, no separate field. The user will be presented with all assigned IP addresses (IPv4+IPv6) in the list. This is because you are using IPv4 or IPv6 to bind your network services, not both. Of course the respective other protocol works as well on the bound network interface.

I disagree! A user might want to use IPv6 on one interface and IPv4 on another, so this should be 2 fields.

@davidgraeff
Copy link
Contributor

davidgraeff commented Sep 8, 2017

This would mean, that every service (all netty, jetty instances and any other service) would need to start two times and bind to two interface addresses if the user selects an IPv4 and IPv6 address?

@davidgraeff
Copy link
Contributor

davidgraeff commented Sep 8, 2017

I have created a PR (#4218). Of course we need to discuss and agree first on what we mean and what use case each of us have in mind.

@kaikreuzer
Copy link
Contributor

Hm, seems I should have tested #4218 before merging.
With that change, I now get

19:24:47.842 [WARN ] [rg.eclipse.smarthome.core.net.NetUtil] - Invalid address 'null', will use first interface instead.
19:24:47.844 [INFO ] [i.dashboard.internal.DashboardService] - Started dashboard at http://fe80:0:0:0:b501:8ee5:6c1e:9a7b%utun1:8080

at openHAB startup (even if I start with -Djava.net.preferIPv4Stack=true).

Note that the dashboard calls the (now deprecated) getPrimaryIpv4HostAddress() method - from which I would have expected in any case to return an IPv4 address.

@davidgraeff Could you please check this?

@kaikreuzer kaikreuzer reopened this Nov 17, 2017
@kaikreuzer
Copy link
Contributor

Note that the logged warning is also a regression, this wasn't logged before.

@davidgraeff
Copy link
Contributor

It was the originally implemented behaviour of the pr to first select an ipv4, but was changed in between to remove ipv4/ipv6 distinction.
The preferipv4 flag should be respected though, that's true.

@kaikreuzer
Copy link
Contributor

As this caused a regression, I have reverted the commit/PR for now.

Of course we need to discuss and agree first on what we mean and what use case each of us have in mind.

I don't see any substantial discussion on the PR and I acknowledge that I failed to get involved in such - so my apologies for having merged it prematurely.

I think that IPv4 should be the prominent setting in any case, because that is what people are using and what they are familiar with. Imho IPv6 should only be an advanced option, possibly only to be turned on, if desired, so that the standard UI options are sensible.

triller-telekom added a commit to triller-telekom/smarthome that referenced this issue Nov 23, 2017
Fixes eclipse-archived#4205

Signed-off-by: Stefan Triller <stefan.triller@telekom.de>
sjsf pushed a commit that referenced this issue Nov 23, 2017
* Accept 32bit netmask in config for point-to-point connections

Fixes #4205
Signed-off-by: Stefan Triller <stefan.triller@telekom.de>
@davidgraeff
Copy link
Contributor

I think IPv6 should work as good as IPv4 with ESH. IPv4 can be the preferred protocol, but that setting should be made in a very prominent way and not buried in the implementation (methods with the name ....IPv4only..., ...preferredIPv4... etc). Even in Germany we already have a cable company providing IPv6 addresses only, and IPv4 works via tunneling ("IPv4Lite"). In my opinion, it should be in the developer guidelines for ESH to write protocol agnostic IP utility methods only, if applicable.

I think, with the references PR I proved that an implementation is possible and even simpler (fewer lines of code). I would have wished that others test the PR for their IPv4 network, which didn't happen before the merge. Missing features like considering the "java.net.preferIPv4Stack" flag or a GUI option for an easy choice would have been noticed earlier.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants