Thread Rating:
  • 0 Votes - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
ohNet interface list should include RUNNING interfaces only
24-09-2013, 11:50 AM
Post: #1
ohNet interface list should include RUNNING interfaces only
When ohNet builds the interface list on Linux, it looks for interfaces with an IP address but doesn't check the RUNNING state of the interface. This is causing problems on Synology NAS models with two network ports where only one of these ports is connected. The unconnected port is not marked as RUNNING but it has an APIPA IP address, as shown in the following ifconfig output:

Code:
DS713> ifconfig
eth0      Link encap:Ethernet  HWaddr 00:11:32:22:6E:05
          inet addr:192.168.0.20  Bcast:192.168.0.255  Mask:255.255.255.0
          inet6 addr: fe80::211:32ff:fe22:6e05/64 Scope:Link
          UP BROADCAST NOTRAILERS RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:5249 errors:0 dropped:0 overruns:0 frame:0
          TX packets:3807 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000
          RX bytes:2430782 (2.3 MiB)  TX bytes:948727 (926.4 KiB)
          Interrupt:16 Memory:40300000-40320000

eth1      Link encap:Ethernet  HWaddr 00:11:32:22:6E:06
          inet addr:169.254.242.255  Bcast:169.254.255.255  Mask:255.255.0.0
          UP BROADCAST NOTRAILERS MULTICAST  MTU:1500  Metric:1
          RX packets:0 errors:0 dropped:0 overruns:0 frame:0
          TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000
          RX bytes:0 (0.0 B)  TX bytes:0 (0.0 B)
          Interrupt:17 Memory:40200000-40220000

lo        Link encap:Local Loopback
          inet addr:127.0.0.1  Mask:255.0.0.0
          inet6 addr: ::1/128 Scope:Host
          UP LOOPBACK RUNNING  MTU:16436  Metric:1
          RX packets:2726 errors:0 dropped:0 overruns:0 frame:0
          TX packets:2726 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:0
          RX bytes:343094 (335.0 KiB)  TX bytes:343094 (335.0 KiB)

When the ohNet device stack receives an M-SEARCH request on interface eth0, the Synology firmware sends this request to all listening interfaces. Because ohNet is listening on interface eth1 as well as eth0, it sends two responses to the M-SEARCH request, one for a device on address 192.168.0.20 (correct) and one for a device with same UDN on address 169.254.242.255 (incorrrect). Both these responses are delivered to the control point that sent the M-SEARCH request.

At this point, bad things are likely to happen, depending on:

1) how the control point handles multiple responses from devices with the same UDN and different IP addresses

2) how the user's router or switch routes requests with APIPA destinations

The observed symptom is that things randomly work or fail. In many cases, the first couple of tracks are played OK and subsequent tracks can't be played.

It is possible to work around this problem by calling setCurrentSubnet on the device stack. This prevent ohNet sending the bogus M-SEARCH response containing the APIPA address. However, this is not an acceptable fix because it requires every user with a Synology 2-port NAS to enter this configuration setting manually in order to make MinimServer work reliably.

The fix is to change ohNet's filtering when building the interface list so that interfaces that aren't marked as RUNNING are excluded from the interface list. This eliminates the bogus M-SEARCH response, and everything works correctly "out of the box" with no need for manual configuration. I can't think of any situation where excluding non-RUNNING interfaces from the interface list would cause any problems.

While investigating this problem, I came across another issue. I was puzzled that ohNet wasn't sending NOTIFY announcements for the bogus APIPA address even though it was sending M-SEARCH responses for this address. After some investigation, I discovered that the device stack uses a Bind call to ensure that NOTIFY announcements are sent on the specific network interface to which they relate, but there is no Bind call to do this for M-SEARCH responses. This could cause problems with a multihomed device receiving an M-SEARCH request on one interface and sending the response to this request on a different interface. Depending on how the interface subnets are routed through the network, this might mean that the M-SEARCH response could not be delivered to the M-SEARCH sender.

I am attaching a patch that fixes both these issues. These code changes have been tested by a number of MinimServer users with Synology 2-port devices and they have fixed the previous random failures without causing any other problems.


Attached File(s)
.zip  2port.zip (Size: 3.41 KB / Downloads: 2)
Find all posts by this user
24-09-2013, 04:32 PM
Post: #2
RE: ohNet interface list should include RUNNING interfaces only
Thanks for diagnosing this.

I understand the motivation for the change to OsNetworkListAdapters but will have to do some tests to see whether it causes problems with adapterChangeObserverThread. (I'm not sure that a cable being (un)plugged will count as a change in this function so the adapter list will get out of date.)

I understand what the change to SsdpMsearchResponder and MsearchResponse does but I'm not sure why it's necessary. If we don't specify which adapter a message should be sent over, the network stack should use its routing table to select an adapter which can reach the target address. Do you know that the 169 adapter is being selected to (try to) send unicast messages to a 192 destination? Or do you have another example of a problem the current code causes? (I don't think that your suggested changes are wrong; I'm just not sure whether they'll improve ohNet's behaviour.)
Find all posts by this user
24-09-2013, 06:56 PM (This post was last modified: 24-09-2013 08:16 PM by simoncn.)
Post: #3
RE: ohNet interface list should include RUNNING interfaces only
(24-09-2013 04:32 PM)simonc Wrote:  Thanks for diagnosing this.

I understand the motivation for the change to OsNetworkListAdapters but will have to do some tests to see whether it causes problems with adapterChangeObserverThread. (I'm not sure that a cable being (un)plugged will count as a change in this function so the adapter list will get out of date.)

I have tested this, and removing or inserting the cable does cause a change to be notified. I also found some information on the web to confirm that this will happen. Sorry that I didn't mention this in my original post.

Here's an example of a post saying this.

Quote:I understand what the change to SsdpMsearchResponder and MsearchResponse does but I'm not sure why it's necessary. If we don't specify which adapter a message should be sent over, the network stack should use its routing table to select an adapter which can reach the target address. Do you know that the 169 adapter is being selected to (try to) send unicast messages to a 192 destination? Or do you have another example of a problem the current code causes? (I don't think that your suggested changes are wrong; I'm just not sure whether they'll improve ohNet's behaviour.)

From section 1.3.3 (Search response) in the UPnP Device Architecture 1.1 document:

Multi-homed devices MUST send the search response using the same UPnP-enabled interface on which the search request was received.
Find all posts by this user
25-09-2013, 03:59 PM
Post: #4
RE: ohNet interface list should include RUNNING interfaces only
(24-09-2013 06:56 PM)simoncn Wrote:  I have tested this, and removing or inserting the cable does cause a change to be notified. I also found some information on the web to confirm that this will happen. Sorry that I didn't mention this in my original post.

Thanks, I've committed this now.

(24-09-2013 06:56 PM)simoncn Wrote:  From section 1.3.3 (Search response) in the UPnP Device Architecture 1.1 document:

Multi-homed devices MUST send the search response using the same UPnP-enabled interface on which the search request was received.

Fair point, I've committed this now.

As an aside, note that we deliberately disregard recommended behaviour on multi-homed devices elsewhere by only running on a single interface per subnet. A consequence of this is that I think we'll always have replied to msearches on the interface that received them anyway but it can't hurt (famous last wprds!) to apply changes which guarantee this.
Find all posts by this user
25-09-2013, 04:56 PM
Post: #5
RE: ohNet interface list should include RUNNING interfaces only
(25-09-2013 03:59 PM)simonc Wrote:  
(24-09-2013 06:56 PM)simoncn Wrote:  I have tested this, and removing or inserting the cable does cause a change to be notified. I also found some information on the web to confirm that this will happen. Sorry that I didn't mention this in my original post.

Thanks, I've committed this now.

Thanks very much!

Quote:
(24-09-2013 06:56 PM)simoncn Wrote:  From section 1.3.3 (Search response) in the UPnP Device Architecture 1.1 document:

Multi-homed devices MUST send the search response using the same UPnP-enabled interface on which the search request was received.

Fair point, I've committed this now.

As an aside, note that we deliberately disregard recommended behaviour on multi-homed devices elsewhere by only running on a single interface per subnet. A consequence of this is that I think we'll always have replied to msearches on the interface that received them anyway but it can't hurt (famous last wprds!) to apply changes which guarantee this.

OK, thanks. My instinct is that there might be some weird corner case where sending the response on a different interface does cause a problem, so it's good to make sure this can't happen.

What happens if a device has two interfaces that are both bound to the same subnet with different IP addresses? Will ohNet pick one at random and ignore the other completely? Or might ohNet sometimes use one and sometimes use the other?
Find all posts by this user
26-09-2013, 08:24 AM
Post: #6
RE: ohNet interface list should include RUNNING interfaces only
(25-09-2013 04:56 PM)simoncn Wrote:  What happens if a device has two interfaces that are both bound to the same subnet with different IP addresses? Will ohNet pick one at random and ignore the other completely? Or might ohNet sometimes use one and sometimes use the other?

ohNet iterates through the list returned from OsNetworkListAdapters, selecting the first interface from each subnet. So, if OSes returned their interfaces in random order, ohNet would choose different interfaces on different runs. In practice, it seems that OSes return their interfaces in predictable order, meaning that ohNet will also choose a predictable interface.
Find all posts by this user


Forum Jump: