Skip to content

Commit

Permalink
Support sdnotify for better systemd integration
Browse files Browse the repository at this point in the history
These changes introduce support for sdnotify allowing sshuttle to notify
systemd when it finishes connecting to the server and installing
firewall rules, and is ready to tunnel requests.
  • Loading branch information
vieira authored and brianmay committed Oct 24, 2016
1 parent 15b394d commit fbbcc05
Show file tree
Hide file tree
Showing 3 changed files with 44 additions and 0 deletions.
4 changes: 4 additions & 0 deletions sshuttle/client.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
import sshuttle.ssnet as ssnet
import sshuttle.ssh as ssh
import sshuttle.ssyslog as ssyslog
import sshuttle.sdnotify as sdnotify
import sys
import platform
from sshuttle.ssnet import SockWrapper, Handler, Proxy, Mux, MuxWrapper
Expand Down Expand Up @@ -503,6 +504,9 @@ def onhostlist(hostlist):
debug1('seed_hosts: %r\n' % seed_hosts)
mux.send(0, ssnet.CMD_HOST_REQ, str.encode('\n'.join(seed_hosts)))

sdnotify.send(sdnotify.ready(),
sdnotify.status('Connected to %s.' % remotename))

while 1:
rv = serverproc.poll()
if rv:
Expand Down
1 change: 1 addition & 0 deletions sshuttle/firewall.py
Original file line number Diff line number Diff line change
Expand Up @@ -221,6 +221,7 @@ def main(method_name, syslog):
break
finally:
try:
sdnotify.send(sdnotify.stop())
debug1('firewall manager: undoing changes.\n')
except:
pass
Expand Down
39 changes: 39 additions & 0 deletions sshuttle/sdnotify.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
import socket
import os
from sshuttle.helpers import debug1, debug2, debug3

def _notify(message):
addr = os.environ.get("NOTIFY_SOCKET", None)

if not addr or len(addr) == 1 or addr[0] not in ('/', '@'):
return False

addr = '\0' + addr[1:] if addr[0] == '@' else addr

try:
sock = socket.socket(socket.AF_UNIX, socket.SOCK_DGRAM)
except socket.error as e:
debug1("Error creating socket to notify to systemd: %s\n" % e)

if not (sock and message):
return False

assert isinstance(message, bytes)

try:
return (sock.sendto(message, addr) > 0)
except socket.error as e:
debug1("Error notifying systemd: %s\n" % e)
return False

def send(*messages):
return _notify(b'\n'.join(messages))

def ready():
return b"READY=1"

def stop():
return b"STOPPING=1"

def status(message):
return b"STATUS=%s" % message.encode('utf8')

0 comments on commit fbbcc05

Please sign in to comment.