pyatv icon indicating copy to clipboard operation
pyatv copied to clipboard

Not able to connect to Apple TV in different subnet

Open ITTV-tools opened this issue 4 years ago • 70 comments

Describe the bug I can not add ATV to my Home Assistant. My network is separated in multiple VLANs. The ATV is in VLAN 1 and Home Assistant in VLAN 2. Both can talk to each other. I use a MDNS repeater to use for example Homekit in other VLANs.

In older versions of the integration, HA could see the Apple TV and I got the text field to enter the PIN code. But the PIN was always wrong.

To Reproduce Place ATV in different subnet. (I guess) Expected behavior

System Setup (please complete the following information):

  • OS: Debian
  • Python: 3.7.3
  • pyatv: 0.7.0
  • Apple TV: Apple TV 4K tvOS 13.4.6

Additional context Traceback (most recent call last): File "/home/homeassistant/.homeassistant/custom_components/apple_tv/config_flow.py", line 144, in async_step_user await self.async_find_device() File "/home/homeassistant/.homeassistant/custom_components/apple_tv/config_flow.py", line 218, in async_find_device self.unique_id, self.hass.loop, cache=self.scan_result File "/home/homeassistant/.homeassistant/custom_components/apple_tv/config_flow.py", line 76, in device_scan scan_result = await scan(loop, hosts=hosts, timeout=timeout) File "/srv/homeassistant/lib/python3.7/site-packages/pyatv/init.py", line 49, in scan devices = (await scanner.discover(timeout)).values() File "/srv/homeassistant/lib/python3.7/site-packages/pyatv/support/scan.py", line 154, in discover *[self._get_services(host, timeout) for host in self.hosts] File "/srv/homeassistant/lib/python3.7/site-packages/pyatv/support/scan.py", line 167, in _get_services self.loop, str(host), ALL_SERVICES, port=port, timeout=timeout File "/srv/homeassistant/lib/python3.7/site-packages/pyatv/support/mdns.py", line 448, in unicast f"address {address} is not in any local subnet" pyatv.exceptions.NonLocalSubnetError: address 192.168.178.49 is not in any local subnet

ITTV-tools avatar Jul 15 '20 13:07 ITTV-tools

This might be a bug with the new scanning implementation, I have seen some issues myself that I will look in to. Adding via unicast (specifying IP address) will not work between VLANs. That's just how zeroconf is designed.

If you could not add because of invalid PIN, that's a separate issue we can deal with once scanning works. Can you provide some output from atvremote --debug scan?

postlund avatar Jul 15 '20 14:07 postlund

2020-07-15 16:06:58 DEBUG: Sending multicast DNS request to 224.0.0.251:5353 (Data=35ff012000040000000000000b5f6170706c6574762d7632045f746370056c6f63616c0000ff80010b5f746f7563682d61626c65045f746370056c6f63616c0000ff80010e5f6d6564696172656d6f74657476045f746370056c6f63616c0000ff8001085f616972706c6179045f746370056c6f63616c0000ff8001) 2020-07-15 16:06:59 DEBUG: Sending multicast DNS request to 224.0.0.251:5353 (Data=35ff012000040000000000000b5f6170706c6574762d7632045f746370056c6f63616c0000ff80010b5f746f7563682d61626c65045f746370056c6f63616c0000ff80010e5f6d6564696172656d6f74657476045f746370056c6f63616c0000ff8001085f616972706c6179045f746370056c6f63616c0000ff8001) 2020-07-15 16:07:00 DEBUG: Sending multicast DNS request to 224.0.0.251:5353 (Data=35ff012000040000000000000b5f6170706c6574762d7632045f746370056c6f63616c0000ff80010b5f746f7563682d61626c65045f746370056c6f63616c0000ff80010e5f6d6564696172656d6f74657476045f746370056c6f63616c0000ff8001085f616972706c6179045f746370056c6f63616c0000ff8001) Scan Results

ITTV-tools avatar Jul 15 '20 14:07 ITTV-tools

Ok, so no response at all. I guess other services are discovered in Home Assistant? Are you running in docker?

postlund avatar Jul 15 '20 14:07 postlund

Yes other services work. I use python virtual environment

ITTV-tools avatar Jul 15 '20 15:07 ITTV-tools

Ok, so, I have a theory. Been looking at the code for python-zeroconf to try to understand what is happening. The problem I have is that proxies set up by atvproxy are not picked up by a scan. I use python-zeroconf to publish services for these proxies. What I can see is that requests are received just fine, but no responses are sent. The reason for this is that the source port is not one of 53 (DNS) or 5353 (MDNS), which is a pretty strict constraint (but probably according to standard). Since I just send a unicast request to a multicast address, a random source port are used so this is reasonable. When implementing a full zeroconf client, it would also listen on port 5353 in which case it would make sense to use 5353 as source port. The Apple TV's does not seem to care about this and treat my requests as unicast requests and answer. But as I said, python-zeroconf does not and your MDNS responder probably does not either. This is likely the reason why it doesn't work. So, I guess I will have to investigate how much work is needed to fix this.

Sorry about the long post. Here, have a 🌮

postlund avatar Jul 15 '20 19:07 postlund

Did some testing last night and I think my theory might be right. It seemed to work when binding to port 5353, but there will be problems if another zeroconf client is doing the same. It's no problem binding to the same address and port, assuming the other client did the same, but received messages will be load balanced between the processes. So pyatv will miss some responses and receive other responses. It will only work properly if one zeroconf client is used at the same time. Will have to think about this a bit...

postlund avatar Jul 16 '20 05:07 postlund

I've got the same problem, although running in a docker container (NOT host network mode).

pyatv.exceptions.NonLocalSubnetError: address X.X.X.X is not in any local subnet

Used to work with older versions though.

loopway avatar Jul 18 '20 21:07 loopway

What are you entering when adding the device? Not sure exactly how I ended up doing it, but I think you need to specify either device name or identifier when using a repeat. IP address will not work. Since current scanning is somewhat broken, it might not work still. Looking into that.

postlund avatar Jul 19 '20 10:07 postlund

I'm pretty sure I used to add it with entering the IP address. Now it doesn't work anymore, neither does it with the device name. (probably as expected, since I don't use a repeater)

loopway avatar Jul 19 '20 22:07 loopway

So i am also having similar issue except that my Apple TV (4K) and home assistant server are on the same subnet. I tried adding the Apple TV via name (for which it said "Device could not be found on network, please try again."). But when I tried adding through the IP address it gave me the following error:

Unexpected exception
Traceback (most recent call last):
  File "/config/custom_components/apple_tv/config_flow.py", line 144, in async_step_user
    await self.async_find_device()
  File "/config/custom_components/apple_tv/config_flow.py", line 218, in async_find_device
    self.unique_id, self.hass.loop, cache=self.scan_result
  File "/config/custom_components/apple_tv/config_flow.py", line 76, in device_scan
    scan_result = await scan(loop, hosts=hosts, timeout=timeout)
  File "/usr/local/lib/python3.7/site-packages/pyatv/__init__.py", line 49, in scan
    devices = (await scanner.discover(timeout)).values()
  File "/usr/local/lib/python3.7/site-packages/pyatv/support/scan.py", line 154, in discover
    *[self._get_services(host, timeout) for host in self.hosts]
  File "/usr/local/lib/python3.7/site-packages/pyatv/support/scan.py", line 167, in _get_services
    self.loop, str(host), ALL_SERVICES, port=port, timeout=timeout
  File "/usr/local/lib/python3.7/site-packages/pyatv/support/mdns.py", line 448, in unicast
    f"address {address} is not in any local subnet"
pyatv.exceptions.NonLocalSubnetError: address 192.168.1.247 is not in any local subnet
Home Assistant has started!

giricgoyal avatar Jul 20 '20 03:07 giricgoyal

How are you running your Home Assistant instances? The edge case I can think of where it would potentially work is if the network is in NAT mode. When the Apple TV receives the request it must come from an IP address on the same network or it will be ignored.

postlund avatar Jul 20 '20 04:07 postlund

I am running HA in docker on windows and used --net=host while bringing up the container.

giricgoyal avatar Jul 20 '20 04:07 giricgoyal

Just checked the docker and it was in "bridge" mode. So I recreated the docker container using host net config, but now I now I cant seem to access HA itself. And since host network is not supported on windows I would need to go back to bridge mode. So is there a way to integrate apple tv with HA in bridged mode?

giricgoyal avatar Jul 20 '20 04:07 giricgoyal

Right, so host mode should of course work as long as the host is on the same network as the Apple TV. But it definitely uses NAT as means for network access (it has another IP address inside the container which is translated to the host address outside of the container). This is a problematic edge case where my check will fail. I might have to remove the check to remedy this.

postlund avatar Jul 20 '20 05:07 postlund

Removing local subnet check is probably the safest bet until I get scanning to work as expected. I can try to make that happen and make a release later tonight.

postlund avatar Jul 20 '20 05:07 postlund

That would be great @postlund . I can try again once you release the update. Thanks

giricgoyal avatar Jul 20 '20 05:07 giricgoyal

@giricgoyal I'll let you know when it's done. Created #775 for the change.

postlund avatar Jul 20 '20 05:07 postlund

@giricgoyal I have not forgotten about you, just wanted to spend some additional time fiddling with the mdns implementation. I think I have hacky prototype that solves the base problem. Will need some time to make it presentable, but hopefully within the next couple of days. Time to get some sleep.

postlund avatar Jul 21 '20 20:07 postlund

@postlund is it possible for you to create a release with #775 in the mean time, and include it in a version of the hass component? I have applied that change locally and it works for me, but it would be nice to have it included automatically so I don't have to do it again 😄

radhus avatar Aug 12 '20 14:08 radhus

@radhus There will be a release very soon 😊 Just had a short break ("vacation") from pyatv, will take up development again albeit with a lower pace. I'm just finishing up #777 (will merge that tonight) and after that I will try to sort out #780. That is what I'm planning for next release, should be able to finish that today or tomorrow. After that I will continue updating the integration and also re-submit PR so I can finally have it updated in Home Assistant. Been putting that of intentionally due to bugs.

postlund avatar Aug 12 '20 17:08 postlund

@postlund great! No stress :) Let me know if there's anything special to test and I'll help out :)

radhus avatar Aug 12 '20 19:08 radhus

@radhus Just pushed an update to the component, give it a go and let me know if it works 😊

postlund avatar Aug 16 '20 05:08 postlund

With the newest version I get no connection at all grafik grafik

ITTV-tools avatar Aug 16 '20 10:08 ITTV-tools

@ITTV-tools Interesting that you get that. Please enable logging and provide the pyatv log, perhaps I can implement that.

postlund avatar Aug 16 '20 12:08 postlund

I see the same behavior

geekofweek avatar Aug 17 '20 15:08 geekofweek

@postlund upgrade worked, then removed and added the apple-tv again (with IP address) and it worked fine. 👍

radhus avatar Aug 17 '20 16:08 radhus

@geekofweek Do you have the possibility to reproduce this with PYATV_BINARY_MAX_LINE=10000 atvremote --debug -s <ip> playing? I started to create a fix in #802, but I'm not sure that fixes the problem. I'm afraid that it removes the exception but no device would still be found. So complete logs are needed for debugging.

postlund avatar Aug 17 '20 20:08 postlund

Home Assistant sits on 192.168.101.0/24, it has all ports opened to the AppleTVs through the firewall so nothing should be blocking it.

# PYATV_BINARY_MAX_LINE=10000 atvremote --debug -s 192.168.100.11 playing
2020-08-17 15:39:58 DEBUG: Knocking at port 3689 on 192.168.100.11
2020-08-17 15:39:58 DEBUG: Knocking at port 7000 on 192.168.100.11
2020-08-17 15:39:58 DEBUG: Knocking at port 49152 on 192.168.100.11
2020-08-17 15:39:58 DEBUG: Knocking at port 32498 on 192.168.100.11
2020-08-17 15:40:00 DEBUG: Knocking at port 3689 on 192.168.100.11
2020-08-17 15:40:00 DEBUG: Knocking at port 7000 on 192.168.100.11
2020-08-17 15:40:00 DEBUG: Knocking at port 49152 on 192.168.100.11
2020-08-17 15:40:00 DEBUG: Knocking at port 32498 on 192.168.100.11
2020-08-17 15:40:01 DEBUG: Cleaning up after UDNS request
2020-08-17 15:40:01 DEBUG: Cleaning up after UDNS request
2020-08-17 15:40:01 ERROR: Could not find any Apple TV on current network

geekofweek avatar Aug 17 '20 20:08 geekofweek

Yeah, that won't work. The Apple TV will drop packets from other subnets. That's part of the specification (although it's possible to be lax about it, that's how Apple Implemented it). Only way for this to work is to use an mdns relayer and rely on regular scanning (not unicast like was used here).

postlund avatar Aug 17 '20 20:08 postlund

I have mdns forwarding configured, which I assume is how it works on the previous versions.

geekofweek avatar Aug 17 '20 20:08 geekofweek