Closed tuxedo0801 closed 8 years ago
Investigation is still in progress, but my current guess is: calimero is using - due to the same metrik - the 192.168.56.1 network interface instead of 192.168.0.21.
By default, the default network interface is used (not the route metric for mcasts)
Is there a way to tell calimero which networkinterface is the rigth one?
If you create a network link, you can specify the local socket (tunneling) or the network interface (routing) you want to use. This does not work? From what I see it would surprise me if, e.g., tunneling datagrams sent from local socket 192.168.0.21 don't use the nforce interface.
Is calimero able to detect the right networkinterface automatically?
In theory yes, but since that would stop to work reliably if you have several devices or some "interesting" network setup, it doesn't do that.
Or is this in any case a weird setup and user has to fix the metric by himself?!
I would only change the system route metrics if there is a general problem with multicasts, as it affects every program. Or, e.g., if he specifically wants to always route any 224.x.x.x over a single interface only.
By default, the default network interface is used (not the route metric for mcasts)
The question is: Which one is the default network interface? If I do not specify a network interface explicitly, I guess it depends on the routing table. That's what my experience + google tells me. Please correct me (with details) if I'm wrong.
If you create a network link, you can specify the local socket (tunneling) or the network interface (routing) you want to use.
I just use routing... And there I didn't specify any networkinterface yet. On systems with less network-interfaces and with systems with optimal metric, this works.
Have to test what happens if I specify the right interface. Should work, I guess.
In theory yes, but since that would stop to work reliably if you have several devices or some "interesting" network setup, it doesn't do that.
How about the discovery? If I enumerate over all network interfaces and do an discovery on each, this might bring up the correct knx routing/tunneling device + network interface. --> have to test this.
That's what my experience + google tells me. Please correct me (with details) if I'm wrong.
It's been years since i did kernel/nw stuff on windows, so my guess is as good as yours. It might as well be that on windows -- as you pointed out -- the top-most entry is used in case of ambiguity. Easy to verify, switch the entries. It's just something i would not rely on, or wonder if that stops working.
I just use routing... And there I didn't specify any networkinterface yet
the local socket/netif parameters are exactly for multi-host systems.
How about the discovery? If I enumerate over all network interfaces and do an discovery on each, this might bring up the correct knx routing/tunneling device + network interface. --> have to test this.
I thought you used that anyway, it's the standard way to discover devices ... discovery checks all active network interfaces by default, you don't need to enumerate.
So, finally to come to an conclusion:
There are two options:
1) let the user of the application select the network interface 2) use discovery to configure/set the knx interface
Right now, my application lets the user just choose between routing (with no nw-if and hardcoded mc-adr), tunneling (with input field for knx interface's IP) and TPUART.
So I will add the auto-discovery ...
I tried to use the Discoverer-class. Works great. My IP Router is discovered without any issues.
BUT... What do I do with these informations?! How can I use on of the SearchResponses to establish a working KNX connection?! I get the type of the device, as well as t it's IP and what not, but I don't get any hint on which network interface the device was found. So even if I parse the search response for the type to know which kind of connection I could open, I have no clue on which network interface this has to be done.
Is there some code that you can point me on that shows something in this direction?!
Tried the following workaround:
iterate myself over the network interfaces (to know on which interfaces a device has been discovered, so that I can open a connection on the proper interface) and called discoverer.startSearch(myNetworkInterface, 20, true)
... Result:
Discoverer.java line 570 throws an KNXException, telling me:
failed to create socket in myhost/127.0.1.1:0, Die angeforderte Adresse kann nicht zugewiesen werden
If I have a look at the startSearch() implementation which iterates internally over the network interfaces, interface-adresses like localhost are skipped.
So,
:-(
You can try if the vm argument java.net.preferIPv4Stack=true
makes a difference
failed to create socket in myhost/127.0.1.1:0
from your setup i don't see a reason why you would want to use a loopback address
interface-adresses like localhost are skipped
and where exactly do you see that? discoverer does the opposite
- [...]
?
[edit: spaces]
Could you please give an answer/recommendation to this:
I tried to use the Discoverer-class. Works great. My IP Router is discovered without any issues.
BUT... What do I do with these informations?! How can I use on of the SearchResponses to establish a working KNX connection?! I get the type of the device, as well as t it's IP and what not, but I don't get any hint on which network interface the device was found. So even if I parse the search response for the type to know which kind of connection I could open, I have no clue on which network interface this has to be done.
Is there some code that you can point me on that shows something in this direction?!
??
Regarding my experiments with the mentioned workaround (due to the problem that I do not get any networkinterface information from the SearchResponse) :
I will try preferIPv4Stack, but I fear that this does not solve the issue, as the error is about ipv4 and not ipv6.
from your setup i don't see a reason why you would want to use a loopback address
If I create the discoverer like this
Discoverer discoverer = new Discoverer(0, false);
discoverer.startSearch(myNetworkInterface, 20, true)
my host name (not "localhost", but "myhost") is choosen automatically. And this resolves (on my linux developer system, which also has multiple network interfaces) to 127.0.1.1 ...
If course I can use another constructor and give a valid IP address for each discovery on each network interface. But that makes things more complicated.
So final question is:
How to use the Discoverer to find out
and where exactly do you see that?
Sorry, misinterpretation from my side. Just ignore it.
Do subnet matching (using netmask / cidr notation) for the relevant interfaces. Or, in j8, calimero uses a slightly different api which actually returns the outgoing ip/netif (note that there could be more than one result). Just patch your lib ...
I do not get any networkinterface information from the SearchResponse
A search response contains the information as listed in the knx spec, that's why.
I will try preferIPv4Stack, but I fear that this does not solve the issue, as the error is about ipv4 and not ipv6.
There are certain problems in java on windows platforms, if interfaces use ip4v but also have ipv6 addresses. One is that setting the network interface might fail ...
(I tested on a win7 host, and included win7 in a workaround ... maybe that exact problem hit you, 946a40cdeb)
How to use the Discoverer to find out
- any knx interface/router/...
run default search, which will use all interfaces applicable at the start time of the discovery
- and on which network interface it is reachable...
See first part; as there could be more than one netif, the decision is up to you which one you want to select.
Final answer/solution (at least for me):
My code iterates over all network interfaces. if iface is down or loopback, it's skipped. It then iterates over all ipv4 adresses (ipv6 is skipped) of each interface and creates a Discoverer object:
Discoverer d = new Discoverer(interfaceAddr.getAddress(), 0, 0, false, false);
and starts discovery
d.startSearch(ni, 5, true);
If a result is found that indicates an IP router, the current networkinterfaces and the device's multicastaddress is used to create the matching KNXNetworkLinkIP instance.
Works for me ...
I have a nasty problem with one of my customer's installations. The symptoms:
I think I found the root-cause: The customer is having multiple network interfaces:
from "ipconfig /all":
from "route print":
The network he is using (=has access to the KNX routing/tunneling interface) is the "NVIDIA nForce-Netzwerkcontroller" with 192.168.0.x IP address range.
If I check the routing table for 224-Multicast addresses, I see that
a) 192.168.56.1 and 192.168.0.21 have the same metric: 266 b) 192.168.56.1 is listed BEFORE the correct network 192.168.0.21
Investigation is still in progress, but my current guess is: calimero is using - due to the same metrik - the 192.168.56.1 network interface instead of 192.168.0.21.
Question is: