summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBrian May <brian@linuxpenguins.xyz>2016-01-30 11:28:59 +1100
committerBrian May <brian@linuxpenguins.xyz>2016-01-30 11:28:59 +1100
commitba8e948c0d7da960184daea1fa4fea0f7ffb9810 (patch)
treeb516a43f1e8c3bb7fe7fec392c94bdddbac7977c
parente06f0240cb38b954b412257baa815ef8a8534ebf (diff)
Don't allocate socket until we need it
Wew were trying to allocate an IPv6 socket even though we weren't using IPv6, causing failures on systems without IPv6 support available. This change means a number of methods on MultiListener, e.g. setsockopt, should not be called until after the bind call. Closes #68
-rw-r--r--sshuttle/client.py19
1 files changed, 15 insertions, 4 deletions
diff --git a/sshuttle/client.py b/sshuttle/client.py
index bc07d6e..2561433 100644
--- a/sshuttle/client.py
+++ b/sshuttle/client.py
@@ -95,16 +95,21 @@ def daemon_cleanup():
class MultiListener:
def __init__(self, type=socket.SOCK_STREAM, proto=0):
- self.v6 = socket.socket(socket.AF_INET6, type, proto)
- self.v4 = socket.socket(socket.AF_INET, type, proto)
+ self.type = type
+ self.proto = proto
+ self.v6 = None
+ self.v4 = None
+ self.bind_called = False
def setsockopt(self, level, optname, value):
+ assert(self.bind_called)
if self.v6:
self.v6.setsockopt(level, optname, value)
if self.v4:
self.v4.setsockopt(level, optname, value)
def add_handler(self, handlers, callback, method, mux):
+ assert(self.bind_called)
socks = []
if self.v6:
socks.append(self.v6)
@@ -119,6 +124,7 @@ class MultiListener:
)
def listen(self, backlog):
+ assert(self.bind_called)
if self.v6:
self.v6.listen(backlog)
if self.v4:
@@ -133,16 +139,23 @@ class MultiListener:
raise e
def bind(self, address_v6, address_v4):
+ assert(not self.bind_called)
+ self.bind_called = True
if address_v6 and self.v6:
+ self.v6 = socket.socket(socket.AF_INET6, self.type, self.proto)
+ self.v6.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
self.v6.bind(address_v6)
else:
self.v6 = None
if address_v4 and self.v4:
+ self.v4 = socket.socket(socket.AF_INET, self.type, self.proto)
+ self.v4.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
self.v4.bind(address_v4)
else:
self.v4 = None
def print_listening(self, what):
+ assert(self.bind_called)
if self.v6:
listenip = self.v6.getsockname()
debug1('%s listening on %r.\n' % (what, listenip))
@@ -569,11 +582,9 @@ def main(listenip_v6, listenip_v4,
for port in ports:
debug2(' %d' % port)
tcp_listener = MultiListener()
- tcp_listener.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
if required.udp:
udp_listener = MultiListener(socket.SOCK_DGRAM)
- udp_listener.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
else:
udp_listener = None