diff options
Diffstat (limited to 'Sshuttle VPN.app/Contents/Resources/sshuttle/ssnet.py')
-rw-r--r-- | Sshuttle VPN.app/Contents/Resources/sshuttle/ssnet.py | 32 |
1 files changed, 25 insertions, 7 deletions
diff --git a/Sshuttle VPN.app/Contents/Resources/sshuttle/ssnet.py b/Sshuttle VPN.app/Contents/Resources/sshuttle/ssnet.py index 2145431..b6d73c2 100644 --- a/Sshuttle VPN.app/Contents/Resources/sshuttle/ssnet.py +++ b/Sshuttle VPN.app/Contents/Resources/sshuttle/ssnet.py @@ -40,7 +40,11 @@ cmd_to_name = { CMD_DNS_REQ: 'DNS_REQ', CMD_DNS_RESPONSE: 'DNS_RESPONSE', } - + + +NET_ERRS = [errno.ECONNREFUSED, errno.ETIMEDOUT, + errno.EHOSTUNREACH, errno.ENETUNREACH, + errno.EHOSTDOWN, errno.ENETDOWN] def _add(l, elem): @@ -86,7 +90,7 @@ class SockWrapper: def __init__(self, rsock, wsock, connect_to=None, peername=None): global _swcount _swcount += 1 - debug3('creating new SockWrapper (%d now exist\n)' % _swcount) + debug3('creating new SockWrapper (%d now exist)\n' % _swcount) self.exc = None self.rsock = rsock self.wsock = wsock @@ -101,7 +105,7 @@ class SockWrapper: _swcount -= 1 debug1('%r: deleting (%d remain)\n' % (self, _swcount)) if self.exc: - debug1('%r: error was: %r\n' % (self, self.exc)) + debug1('%r: error was: %s\n' % (self, self.exc)) def __repr__(self): if self.rsock == self.wsock: @@ -124,20 +128,34 @@ class SockWrapper: return # already connected self.rsock.setblocking(False) debug3('%r: trying connect to %r\n' % (self, self.connect_to)) + if socket.inet_aton(self.connect_to[0])[0] == '\0': + self.seterr(Exception("Can't connect to %r: " + "IP address starts with zero\n" + % (self.connect_to,))) + self.connect_to = None + return try: self.rsock.connect(self.connect_to) # connected successfully (Linux) self.connect_to = None except socket.error, e: - debug3('%r: connect result: %r\n' % (self, e)) + debug3('%r: connect result: %s\n' % (self, e)) + if e.args[0] == errno.EINVAL: + # this is what happens when you call connect() on a socket + # that is now connected but returned EINPROGRESS last time, + # on BSD, on python pre-2.5.1. We need to use getsockopt() + # to get the "real" error. Later pythons do this + # automatically, so this code won't run. + realerr = self.rsock.getsockopt(socket.SOL_SOCKET, + socket.SO_ERROR) + e = socket.error(realerr, os.strerror(realerr)) + debug3('%r: fixed connect result: %s\n' % (self, e)) if e.args[0] in [errno.EINPROGRESS, errno.EALREADY]: pass # not connected yet elif e.args[0] == errno.EISCONN: # connected successfully (BSD) self.connect_to = None - elif e.args[0] in [errno.ECONNREFUSED, errno.ETIMEDOUT, - errno.EHOSTUNREACH, errno.ENETUNREACH, - errno.EACCES, errno.EPERM]: + elif e.args[0] in NET_ERRS + [errno.EACCES, errno.EPERM]: # a "normal" kind of error self.connect_to = None self.seterr(e) |