Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ZeroConf() returns OSError: [Errno 48] Address already in use #967

Open
SudhindraAnegondhi opened this issue Aug 24, 2021 · 22 comments
Open

Comments

@SudhindraAnegondhi
Copy link

Zeroconf() fails on instantiation with OSError: [Errno 48] Address already in use

The code works perfectly well on Ubuntu 21.04 but fails with the following error on macOS Big Sur version 11.5 :
` ``csh

 File "/Users/sudhindra/projects/cloudphotoservice/browse.py", line 61, in <module>
    zeroconf = Zeroconf()
  File "/usr/local/lib/python3.9/site-packages/zeroconf/_core.py", line 410, in __init__
    listen_socket, respond_sockets = create_sockets(interfaces, unicast, ip_version, apple_p2p=apple_p2p)
  File "/usr/local/lib/python3.9/site-packages/zeroconf/_utils/net.py", line 360, in create_sockets
    respond_socket = new_respond_socket(i, apple_p2p=apple_p2p)
  File "/usr/local/lib/python3.9/site-packages/zeroconf/_utils/net.py", line 319, in new_respond_socket
    respond_socket = new_socket(
  File "/usr/local/lib/python3.9/site-packages/zeroconf/_utils/net.py", line 244, in new_socket
    s.bind((bind_addr[0], port, *bind_addr[1:]))
OSError: [Errno 48] Address already in use

As you can see Zeroconf() just creates an instance of the Zeroconf class. Neither Port nor IP address has been specified.

@bdraco
Copy link
Member

bdraco commented Aug 28, 2021

Can you post some more information about your network setup?

The default is to use on all network interfaces. You may need to limit that down to avoid the error.

I'm able to use it on my m1 laptop without the error but I don't have anything special setup.

@probonopd
Copy link

probonopd commented Sep 8, 2021

Running into the same issue on FreeBSD.

from zeroconf import ServiceBrowser, Zeroconf, InterfaceChoice
import zeroconf

class MyListener:

    def remove_service(self, zeroconf, type, name):
        print("Service %s removed" % (name,))

    def add_service(self, zeroconf, type, name):
        info = zeroconf.get_service_info(type, name)
        print("Service %s added, service info: %s" % (name, info))

# zeroconf = Zeroconf()
# OSError: [Errno 48] Address already in use

zeroconf = Zeroconf(interfaces=["192.168.0.14"])
# Still getting
# OSError: [Errno 48] Address already in use

listener = MyListener()
browser = ServiceBrowser(zeroconf, "_http._tcp.local.", listener)

try:
    input("Press enter to exit...\n\n")
finally:
    zeroconf.close()

More information:

FreeBSD% uname -v
FreeBSD 12.2-RELEASE r366954 GENERIC

FreeBSD% ifconfig 
em0: flags=8843<UP,BROADCAST,RUNNING,SIMPLEX,MULTICAST> metric 0 mtu 1500
        options=81249b<RXCSUM,TXCSUM,VLAN_MTU,VLAN_HWTAGGING,VLAN_HWCSUM,LRO,WOL_MAGIC,VLAN_HWFILTER>
        ether ...
        inet6 ... prefixlen 64 scopeid 0x1
        inet6 ... prefixlen 64 autoconf
        inet 192.168.0.14 netmask 0xffffff00 broadcast 192.168.0.255
        media: Ethernet autoselect (100baseTX <full-duplex>)
        status: active
        nd6 options=23<PERFORMNUD,ACCEPT_RTADV,AUTO_LINKLOCAL>
lo0: flags=8049<UP,LOOPBACK,RUNNING,MULTICAST> metric 0 mtu 16384
        options=680003<RXCSUM,TXCSUM,LINKSTATE,RXCSUM_IPV6,TXCSUM_IPV6>
        inet6 ::1 prefixlen 128
        inet6 fe80::1%lo0 prefixlen 64 scopeid 0x2
        inet 127.0.0.1 netmask 0xff000000
        groups: lo
        nd6 options=23<PERFORMNUD,ACCEPT_RTADV,AUTO_LINKLOCAL>

Is this related?

FreeBSD% hostname
FreeBSD

FreeBSD% ping FreeBSD       
ping: cannot resolve FreeBSD: Unknown host

FreeBSD% ping FreeBSD.local.
PING FreeBSD.local. (192.168.0.14): 56 data bytes
64 bytes from 192.168.0.14: icmp_seq=0 ttl=64 time=0.026 ms
>>> socket.gethostbyname(socket.gethostname())
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
socket.gaierror: [Errno 4] Non-recoverable failure in name resolution
>>> socket.gethostname()
'FreeBSD'

Any ideas how to fix this?

@bdraco
Copy link
Member

bdraco commented Sep 10, 2021

Can you try making the socket manually by calling https://github.com/jstasiak/python-zeroconf/blob/master/zeroconf/_utils/net.py#L214 and seeing where you hit the error?

@probonopd
Copy link

probonopd commented Sep 11, 2021

Thanks @bdraco - could you give me a concrete example on how to do this please?
By the way, the [Errno 4] Non-recoverable failure in name resolution seems unrelated to the issue. If I add the machine's hostname to /etc/hosts then the hostname of the local machine can be resolved, but the "Address already in use" error persists.

I should probably mention that avahi-daemon is also running on the same machine.

If I quit that, I don't get the "Address already in use" error.

Can only one Zeroconf client/browser be active on the same machine?

@bdraco
Copy link
Member

bdraco commented Sep 14, 2021

@bdraco
Copy link
Member

bdraco commented Sep 15, 2021

Are you by chance running in docker or have a docker file that replicates the issue?

@tbec
Copy link

tbec commented Oct 22, 2021

I had the same issue (macOS Big Sur 11.5.2) and was able to resolve the issue. The problem was indeed Apple's mDNS responder daemon. To fix the issue:

  1. First disable System Integrity Protection
  2. Unload the mDNSResponder daemon:
sudo launchctl unload /System/Library/LaunchDaemons/com.apple.mDNSResponder.plist
  1. Enable to flag for NoMulticastAdvertisements:
sudo defaults write /Library/Preferences/com.apple.mDNSResponder.plist NoMulticastAdvertisements -bool true
  1. Reload:
sudo launchctl load /System/Library/LaunchDaemons/com.apple.mDNSResponder.plist
  1. Check that the flag is enabled:
sudo /usr/bin/defaults read /Library/Preferences/com.apple.mDNSResponder | /usr/bin/grep NoMulticastAdvertisements

Should return 1.
6. Restart your computer. You should no longer see the port in use:

netstat -na | grep "5353"

Hope this helps someone.

@bdraco
Copy link
Member

bdraco commented Nov 18, 2021

closed via #1028

@bdraco bdraco closed this as completed Nov 18, 2021
@probonopd
Copy link

probonopd commented Nov 26, 2021

Using zeroconf-0.37.0, still getting "Address already in use" when running the browsing example from the README on a machine on which Avahi is running.

FreeBSD% sudo pip-3.8 install zeroconf            
Passwort: 
Collecting zeroconf
  Downloading zeroconf-0.37.0-py3-none-any.whl (105 kB)
     |████████████████████████████████| 105 kB 3.5 MB/s 
Collecting ifaddr>=0.1.7
  Downloading ifaddr-0.1.7-py2.py3-none-any.whl (10 kB)
Installing collected packages: ifaddr, zeroconf
Successfully installed ifaddr-0.1.7 zeroconf-0.37.0

FreeBSD% python3.8 ~/Desktop/browse.py
Traceback (most recent call last):
  File "/home/user/Desktop/browse.py", line 14, in <module>
    zeroconf = Zeroconf()
  File "/usr/local/lib/python3.8/site-packages/zeroconf/_core.py", line 448, in __init__
    listen_socket, respond_sockets = create_sockets(interfaces, unicast, ip_version, apple_p2p=apple_p2p)
  File "/usr/local/lib/python3.8/site-packages/zeroconf/_utils/net.py", line 358, in create_sockets
    listen_socket = new_socket(ip_version=ip_version, apple_p2p=apple_p2p, bind_addr=('',))
  File "/usr/local/lib/python3.8/site-packages/zeroconf/_utils/net.py", line 248, in new_socket
    s.bind(bind_tup)
OSError: [Errno 48] Address already in use

The problem only exsists if avahi-daemon is running (as it is, e.g., on most Linux machines by default).

@bdraco bdraco reopened this Nov 27, 2021
@bdraco
Copy link
Member

bdraco commented Nov 27, 2021

We only trap errno 49. Looks like your system throws 48

@bdraco
Copy link
Member

bdraco commented Nov 27, 2021

We could trap 48 as well but I don't think it will actually solve the issue as it's likely avahai is getting exclusive use of the port

@probonopd
Copy link

I'd be happy to test if you tell me how. Thanks!

@bdraco
Copy link
Member

bdraco commented Nov 28, 2021

If you adjust this line to trap Errno 48 https://github.com/jstasiak/python-zeroconf/blob/master/zeroconf/_utils/net.py#L250 that should be a good test

@bdraco
Copy link
Member

bdraco commented Nov 28, 2021

It should be errno.EADDRINUSE instead of errno.EADDRNOTAVAIL

@probonopd
Copy link

probonopd commented Nov 28, 2021

FreeBSD% sudo sed -i '' -e 's|errno.EADDRNOTAVAIL|errno.EADDRINUSE|g' /usr/local/lib/python3.8/site-packages/zeroconf/_utils/net.py
FreeBSD% cat ~/Desktop/browse.py 
from zeroconf import ServiceBrowser, Zeroconf


class MyListener:

    def remove_service(self, zeroconf, type, name):
        print("Service %s removed" % (name,))

    def add_service(self, zeroconf, type, name):
        info = zeroconf.get_service_info(type, name)
        print("Service %s added, service info: %s" % (name, info))


zeroconf = Zeroconf()
listener = MyListener()
browser = ServiceBrowser(zeroconf, "_http._tcp.local.", listener)
try:
    input("Press enter to exit...\n\n")
finally:
    zeroconf.close()
FreeBSD% python3 ~/Desktop/browse.py 
Traceback (most recent call last):
  File "/home/user/Desktop/browse.py", line 14, in <module>
    zeroconf = Zeroconf()
  File "/usr/local/lib/python3.8/site-packages/zeroconf/_core.py", line 448, in __init__
    listen_socket, respond_sockets = create_sockets(interfaces, unicast, ip_version, apple_p2p=apple_p2p)
  File "/usr/local/lib/python3.8/site-packages/zeroconf/_utils/net.py", line 373, in create_sockets
    if add_multicast_member(cast(socket.socket, listen_socket), i):
  File "/usr/local/lib/python3.8/site-packages/zeroconf/_utils/net.py", line 271, in add_multicast_member
    log.debug('Adding %r (socket %d) to multicast group', interface, listen_socket.fileno())
AttributeError: 'NoneType' object has no attribute 'fileno'

@bdraco
Copy link
Member

bdraco commented Nov 28, 2021

It looks like its not going to be able to listen while avahai is running since its getting exclusive use of the socket unless we have the flags wrong for sharing the port for FreeBSD. Unfortunately, I'm not a FreeBSD user so I can't comment on that.

@probonopd
Copy link

Does it work e.g., on Linux systems?

@swills
Copy link

swills commented Nov 29, 2021

It looks like its not going to be able to listen while avahai is running since its getting exclusive use of the socket unless we have the flags wrong for sharing the port for FreeBSD. Unfortunately, I'm not a FreeBSD user so I can't comment on that.

I believe the code may not have the right flags. See:

https://www.freebsd.org/cgi/man.cgi?query=setsockopt&apropos=0&sektion=0&manpath=FreeBSD+13.0-RELEASE+and+Ports&arch=default&format=html

FWIW, one need not install FreeBSD in order to read it's documentation, but if you wish to do so for testing, it should be fairly easy to setup a VM:

https://download.freebsd.org/ftp/releases/VM-IMAGES/13.0-RELEASE/amd64/Latest/

@systemcrash
Copy link

I run into this now from time to time. I only see it because I cranked up logging defaults.

I'm on macOS 10.15.7. Things seem to work out anyway, and stuff is advertised as expected.

@bdraco
Copy link
Member

bdraco commented Feb 13, 2022

We need to normalize the use of SO_REUSEADDR/SO_REUSEPORT since every OS seems to implement it slight differently. Its a bit of a portability nightmare

https://medium.com/uckey/the-behaviour-of-so-reuseport-addr-1-2-f8a440a35af6

@crees
Copy link

crees commented Mar 8, 2023

It appears to be undocumented, but FreeBSD does not allow reuse of ports by software running as a different user. You can test this by running avahi-daemon with --no-drop-root and it'll suddenly start happily sharing the port.

If you want to use SO_REUSEPORT, all the binding software must run under the same UID.

@tjuerges
Copy link

It appears to be undocumented, but FreeBSD does not allow reuse of ports by software running as a different user. You can test this by running avahi-daemon with --no-drop-root and it'll suddenly start happily sharing the port.

If you want to use SO_REUSEPORT, all the binding software must run under the same UID.

I can confirm that this is also true on macOS.

And sorry, but disabling a macOS system service is obviously not a solution but at most a temporary workaround until a proper solution has been implemented.

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

No branches or pull requests

8 participants