mDNS (Bonjour) Sleep Proxy Server implementation for Python
Provides the Wake on Demand service, similarly to Apple TV and Airport Express devices
SPS has been tested against SleepProxyClient, OSX 10.9's mDNSResponder, and OSX 10.10's discoveryd.
See Debugging instructions below to test other implementations.
Selective-port waking is not implemented, any TCP request to a sleep client will result in a wakeup attempt.
A port to C(++) or Go would be welcome for resource limited ARM devices.
The included server daemon, scripts/sleeproxyd, binds port 5353 and loops up some greenlets:
Being based on ZeroConf, SPS requires almost no configuration.
Just run it and clients will see its mDNS advertisement and register to it within their regular polling intervals and/or just before sleeping.
sudo pmset networkoversleep 1
may be necessary to ensure OSX clients will publish services at-all-costs.
You must ensure both SPS server and client use the same network-segment and IP subnet and that IP Multicast traffic between them is not blocked.
gevent 1.0 is required for its co-operative threading feature; its packaged in Debian jessie.
Because of this, SPS can't be run under python3 (FIXME: replace gevent with asyncio)
Debian 8.0+ (jessie) & Ubuntu 14.04+ (Trusty Tahr)
apt-get install python-scapy python-netifaces python-dbus python-gevent python-pip python-setuptools avahi-daemon git
pip install git+https://github.com/kfix/SleepProxyServer.git
nohup sleepproxyd >/dev/null 2>&1 &
#^put that in rc.local or an initscript or systemd-unit
oWRT asyncIO opkg install python3-asyncio
run a canned client-less server and test a with a mock registration
scripts/test
debug segfaults in cpython or gevent on Debian/Ubuntu
apt-get install gdb python2.7-dbg libc6-dbg python-dbus-dbg python-netifaces-dbg
cd SleepProxyServer/
python setup.py develop --exclude-scripts
gdb -ex r --args python2.7 scripts/sleepproxyd
play with scapy filters
scapy
sniff(tcpwatch, prn=lambda x: x.display(), filter='tcp[tcpflags] & tcp-syn != 0 and tcp[tcpflags] & tcp-ack = 0 and dst host 10.1.0.15', iface='eth0')
sniff(prn=lambda x: x.display(), filter='arp host 10.1.0.15', iface='eth0')
Watch OSX syslog for alll SPS-related actions (sudo-root required) Press Ctrl-T to sleep-wake-cycle your Mac, generating a SPS registration
scripts/sleepproxy_debug_osx
advertise services to SPS from your (Obj)C.app by unsetting service flag kDNSServiceFlagsWakeOnlyService