velolala / touchosc2midi

a (linux compatible) TouchOSC Midi Bridge written in python
MIT License
111 stars 22 forks source link

Fix crash in main_ip on macOS #11

Closed h3xl3r closed 7 years ago

h3xl3r commented 7 years ago

On macOS when run without --ip it fails in main_ip:

Traceback (most recent call last):
  File "/usr/local/bin/touchosc2midi", line 11, in <module>
    load_entry_point('touchosc2midi==0.0.10a0', 'console_scripts', 'touchosc2midi')()
  File "/usr/local/lib/python2.7/site-packages/touchosc2midi/touchosc2midi.py", line 160, in main
    psa = Advertisement(ip=options.get('--ip'))
  File "/usr/local/lib/python2.7/site-packages/touchosc2midi/advertise.py", line 54, in __init__
    self.info = build_service_info(ip=ip or main_ip())
  File "/usr/local/lib/python2.7/site-packages/touchosc2midi/advertise.py", line 25, in main_ip
    sock.connect(("192.0.2.0", 0))
  File "/usr/local/Cellar/python/2.7.13/Frameworks/Python.framework/Versions/2.7/lib/python2.7/socket.py", line 228, in meth
    return getattr(self._sock,name)(*args)
socket.error: [Errno 49] Can't assign requested address

Changing the port from 0 to anything else fixes this.

I also tested on Raspian and Debian and both seem to be fine with any port number, so it seems a harmless change that brings more macOS compatibility.

velolala commented 7 years ago

Thanks for checking out/improving OSX compatibility @h3xl3r! Your contribution made me revisit the IP/interface guessing mechanism and I learned there probably is a cleaner way :) Can you check if the branch from #12 also solves your problem?

h3xl3r commented 7 years ago

I think you forgot a main_ip in touchosc2midi.py:

Traceback (most recent call last):
  File "/usr/local/bin/touchosc2midi", line 11, in <module>
    load_entry_point('touchosc2midi==0.0.10a0', 'console_scripts', 'touchosc2midi')()
  File "/usr/local/lib/python2.7/site-packages/pkg_resources/__init__.py", line 561, in load_entry_point
    return get_distribution(dist).load_entry_point(group, name)
  File "/usr/local/lib/python2.7/site-packages/pkg_resources/__init__.py", line 2631, in load_entry_point
    return ep.load()
  File "/usr/local/lib/python2.7/site-packages/pkg_resources/__init__.py", line 2291, in load
    return self.resolve()
  File "/usr/local/lib/python2.7/site-packages/pkg_resources/__init__.py", line 2297, in resolve
    module = __import__(self.module_name, fromlist=['__name__'], level=0)
  File "/usr/local/lib/python2.7/site-packages/touchosc2midi/touchosc2midi.py", line 30, in <module>
    from .advertise import PORT, main_ip, Advertisement
ImportError: cannot import name main_ip

Why rename anyway? Usually more trouble than it's worth, as proven here :)

P.S.: Guess this comment should be at #12 instead of here ....

h3xl3r commented 7 years ago

Btw, I hope your new way also works when there's no internet connection, I also almost proposed a different method, but then realized it requires access to proper DNS, so I actually thought the old way was better and just changed one number :)

velolala commented 7 years ago

Btw, I hope your new way also works when there's no internet connection, I also almost proposed a different method, but then realized it requires access to proper DNS, so I actually thought the old way was better and just changed one number :)

The new way works should work equally good/bad as the old way. The old way will fail like this when not connected to any external network (with or without internet):

Traceback (most recent call last):
  File "/home/konrad/.virtualenvs/touchosc3midi/bin/touchosc2midi", line 11, in <module>
    load_entry_point('touchosc2midi==0.0.10a0', 'console_scripts', 'touchosc2midi')()
  File "/home/konrad/.virtualenvs/touchosc3midi/lib/python3.5/site-packages/touchosc2midi/touchosc2midi.py", line 160, in main
    psa = Advertisement(ip=options.get('--ip'))
  File "/home/konrad/.virtualenvs/touchosc3midi/lib/python3.5/site-packages/touchosc2midi/advertise.py", line 54, in __init__
    self.info = build_service_info(ip=ip or main_ip())
  File "/home/konrad/.virtualenvs/touchosc3midi/lib/python3.5/site-packages/touchosc2midi/advertise.py", line 25, in main_ip
    sock.connect(("192.0.2.0", 0))
OSError: [Errno 101] Network is unreachable

As far as I understand, both rely on the same prerequisite: there needs to be a default route set up. Finding the associated interface without opening a socket seems to be a lot cleaner imo.

h3xl3r commented 7 years ago

It's fine now an returns the correct address!

velolala commented 7 years ago

Thank you for testing! I'll merge #12 then.