Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
S
sshuttle
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
pub
sshuttle
Commits
d5c3aa61
Commit
d5c3aa61
authored
Jan 09, 2012
by
Avery Pennarun
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
MacOS precompiled app package for sshuttle-0.60
parent
5b57de24
Changes
12
Hide whitespace changes
Inline
Side-by-side
Showing
12 changed files
with
205 additions
and
90 deletions
+205
-90
Sshuttle
Sshuttle VPN.app/Contents/MacOS/Sshuttle
+0
-0
MainMenu.nib
...tle VPN.app/Contents/Resources/English.lproj/MainMenu.nib
+0
-0
askpass.pyc
Sshuttle VPN.app/Contents/Resources/askpass.pyc
+0
-0
main.py
Sshuttle VPN.app/Contents/Resources/main.py
+9
-1
models.py
Sshuttle VPN.app/Contents/Resources/models.py
+4
-3
models.pyc
Sshuttle VPN.app/Contents/Resources/models.pyc
+0
-0
my.pyc
Sshuttle VPN.app/Contents/Resources/my.pyc
+0
-0
client.py
Sshuttle VPN.app/Contents/Resources/sshuttle/client.py
+65
-57
firewall.py
Sshuttle VPN.app/Contents/Resources/sshuttle/firewall.py
+102
-28
helpers.py
Sshuttle VPN.app/Contents/Resources/sshuttle/helpers.py
+6
-1
main.py
Sshuttle VPN.app/Contents/Resources/sshuttle/main.py
+8
-0
ssnet.py
Sshuttle VPN.app/Contents/Resources/sshuttle/ssnet.py
+11
-0
No files found.
Sshuttle VPN.app/Contents/MacOS/Sshuttle
View file @
d5c3aa61
No preview for this file type
Sshuttle VPN.app/Contents/Resources/English.lproj/MainMenu.nib
View file @
d5c3aa61
No preview for this file type
Sshuttle VPN.app/Contents/Resources/askpass.pyc
deleted
100644 → 0
View file @
5b57de24
File deleted
Sshuttle VPN.app/Contents/Resources/main.py
View file @
d5c3aa61
...
...
@@ -78,6 +78,11 @@ class Runner:
if
pid
==
self
.
pid
:
if
os
.
WIFEXITED
(
code
):
self
.
rv
=
os
.
WEXITSTATUS
(
code
)
if
self
.
rv
==
111
:
NSRunAlertPanel
(
'Sshuttle'
,
'Please restart your computer to finish '
'installing Sshuttle.'
,
'Restart Later'
,
None
,
None
)
else
:
self
.
rv
=
-
os
.
WSTOPSIG
(
code
)
self
.
serverobj
.
setConnected_
(
False
)
...
...
@@ -87,7 +92,10 @@ class Runner:
return
self
.
rv
def
wait
(
self
):
return
self
.
_try_wait
(
0
)
rv
=
None
while
rv
is
None
:
self
.
gotdata
(
None
)
rv
=
self
.
_try_wait
(
os
.
WNOHANG
)
def
poll
(
self
):
return
self
.
_try_wait
(
os
.
WNOHANG
)
...
...
Sshuttle VPN.app/Contents/Resources/models.py
View file @
d5c3aa61
...
...
@@ -3,6 +3,7 @@ import my
configchange_callback
=
setconnect_callback
=
None
objc_validator
=
objc
.
signature
(
'@@:N^@o^@'
)
def
config_changed
():
...
...
@@ -39,7 +40,7 @@ class SshuttleNet(NSObject):
def
setSubnet_
(
self
,
v
):
self
.
_k_subnet
=
v
config_changed
()
@
objc
.
access
or
@
objc
_validat
or
def
validateSubnet_error_
(
self
,
value
,
error
):
#print 'validateSubnet!'
return
True
,
_validate_ip
(
value
),
error
...
...
@@ -49,7 +50,7 @@ class SshuttleNet(NSObject):
def
setWidth_
(
self
,
v
):
self
.
_k_width
=
v
config_changed
()
@
objc
.
access
or
@
objc
_validat
or
def
validateWidth_error_
(
self
,
value
,
error
):
#print 'validateWidth!'
return
True
,
_validate_width
(
value
),
error
...
...
@@ -118,7 +119,7 @@ class SshuttleServer(NSObject):
self
.
_k_host
=
v
self
.
setTitle_
(
None
)
config_changed
()
@
objc
.
access
or
@
objc
_validat
or
def
validateHost_error_
(
self
,
value
,
error
):
#print 'validatehost! %r %r %r' % (self, value, error)
while
value
.
startswith
(
'-'
):
...
...
Sshuttle VPN.app/Contents/Resources/models.pyc
deleted
100644 → 0
View file @
5b57de24
File deleted
Sshuttle VPN.app/Contents/Resources/my.pyc
deleted
100644 → 0
View file @
5b57de24
File deleted
Sshuttle VPN.app/Contents/Resources/sshuttle/client.py
View file @
d5c3aa61
...
...
@@ -171,10 +171,71 @@ class FirewallClient:
def
done
(
self
):
self
.
pfile
.
close
()
rv
=
self
.
p
.
wait
()
if
rv
:
if
rv
==
EXITCODE_NEEDS_REBOOT
:
raise
FatalNeedsReboot
()
elif
rv
:
raise
Fatal
(
'cleanup:
%
r returned
%
d'
%
(
self
.
argv
,
rv
))
def
onaccept
(
listener
,
mux
,
handlers
):
global
_extra_fd
try
:
sock
,
srcip
=
listener
.
accept
()
except
socket
.
error
,
e
:
if
e
.
args
[
0
]
in
[
errno
.
EMFILE
,
errno
.
ENFILE
]:
debug1
(
'Rejected incoming connection: too many open files!
\n
'
)
# free up an fd so we can eat the connection
os
.
close
(
_extra_fd
)
try
:
sock
,
srcip
=
listener
.
accept
()
sock
.
close
()
finally
:
_extra_fd
=
os
.
open
(
'/dev/null'
,
os
.
O_RDONLY
)
return
else
:
raise
dstip
=
original_dst
(
sock
)
debug1
(
'Accept:
%
s:
%
r ->
%
s:
%
r.
\n
'
%
(
srcip
[
0
],
srcip
[
1
],
dstip
[
0
],
dstip
[
1
]))
if
dstip
[
1
]
==
listener
.
getsockname
()[
1
]
and
islocal
(
dstip
[
0
]):
debug1
(
"-- ignored: that's my address!
\n
"
)
sock
.
close
()
return
chan
=
mux
.
next_channel
()
if
not
chan
:
log
(
'warning: too many open channels. Discarded connection.
\n
'
)
sock
.
close
()
return
mux
.
send
(
chan
,
ssnet
.
CMD_CONNECT
,
'
%
s,
%
s'
%
dstip
)
outwrap
=
MuxWrapper
(
mux
,
chan
)
handlers
.
append
(
Proxy
(
SockWrapper
(
sock
,
sock
),
outwrap
))
dnsreqs
=
{}
def
dns_done
(
chan
,
data
):
peer
,
sock
,
timeout
=
dnsreqs
.
get
(
chan
)
or
(
None
,
None
,
None
)
debug3
(
'dns_done: channel=
%
r peer=
%
r
\n
'
%
(
chan
,
peer
))
if
peer
:
del
dnsreqs
[
chan
]
debug3
(
'doing sendto
%
r
\n
'
%
(
peer
,))
sock
.
sendto
(
data
,
peer
)
def
ondns
(
listener
,
mux
,
handlers
):
pkt
,
peer
=
listener
.
recvfrom
(
4096
)
now
=
time
.
time
()
if
pkt
:
debug1
(
'DNS request from
%
r:
%
d bytes
\n
'
%
(
peer
,
len
(
pkt
)))
chan
=
mux
.
next_channel
()
dnsreqs
[
chan
]
=
peer
,
listener
,
now
+
30
mux
.
send
(
chan
,
ssnet
.
CMD_DNS_REQ
,
pkt
)
mux
.
channels
[
chan
]
=
lambda
cmd
,
data
:
dns_done
(
chan
,
data
)
for
chan
,(
peer
,
sock
,
timeout
)
in
dnsreqs
.
items
():
if
timeout
<
now
:
del
dnsreqs
[
chan
]
debug3
(
'Remaining DNS requests:
%
d
\n
'
%
len
(
dnsreqs
))
def
_main
(
listener
,
fw
,
ssh_cmd
,
remotename
,
python
,
latency_control
,
dnslistener
,
seed_hosts
,
auto_nets
,
syslog
,
daemon
):
...
...
@@ -255,63 +316,10 @@ def _main(listener, fw, ssh_cmd, remotename, python, latency_control,
fw
.
sethostip
(
name
,
ip
)
mux
.
got_host_list
=
onhostlist
def
onaccept
():
global
_extra_fd
try
:
sock
,
srcip
=
listener
.
accept
()
except
socket
.
error
,
e
:
if
e
.
args
[
0
]
in
[
errno
.
EMFILE
,
errno
.
ENFILE
]:
debug1
(
'Rejected incoming connection: too many open files!
\n
'
)
# free up an fd so we can eat the connection
os
.
close
(
_extra_fd
)
try
:
sock
,
srcip
=
listener
.
accept
()
sock
.
close
()
finally
:
_extra_fd
=
os
.
open
(
'/dev/null'
,
os
.
O_RDONLY
)
return
else
:
raise
dstip
=
original_dst
(
sock
)
debug1
(
'Accept:
%
s:
%
r ->
%
s:
%
r.
\n
'
%
(
srcip
[
0
],
srcip
[
1
],
dstip
[
0
],
dstip
[
1
]))
if
dstip
[
1
]
==
listener
.
getsockname
()[
1
]
and
islocal
(
dstip
[
0
]):
debug1
(
"-- ignored: that's my address!
\n
"
)
sock
.
close
()
return
chan
=
mux
.
next_channel
()
if
not
chan
:
log
(
'warning: too many open channels. Discarded connection.
\n
'
)
sock
.
close
()
return
mux
.
send
(
chan
,
ssnet
.
CMD_CONNECT
,
'
%
s,
%
s'
%
dstip
)
outwrap
=
MuxWrapper
(
mux
,
chan
)
handlers
.
append
(
Proxy
(
SockWrapper
(
sock
,
sock
),
outwrap
))
handlers
.
append
(
Handler
([
listener
],
onaccept
))
dnsreqs
=
{}
def
dns_done
(
chan
,
data
):
peer
,
timeout
=
dnsreqs
.
get
(
chan
)
or
(
None
,
None
)
debug3
(
'dns_done: channel=
%
r peer=
%
r
\n
'
%
(
chan
,
peer
))
if
peer
:
del
dnsreqs
[
chan
]
debug3
(
'doing sendto
%
r
\n
'
%
(
peer
,))
dnslistener
.
sendto
(
data
,
peer
)
def
ondns
():
pkt
,
peer
=
dnslistener
.
recvfrom
(
4096
)
now
=
time
.
time
()
if
pkt
:
debug1
(
'DNS request from
%
r:
%
d bytes
\n
'
%
(
peer
,
len
(
pkt
)))
chan
=
mux
.
next_channel
()
dnsreqs
[
chan
]
=
peer
,
now
+
30
mux
.
send
(
chan
,
ssnet
.
CMD_DNS_REQ
,
pkt
)
mux
.
channels
[
chan
]
=
lambda
cmd
,
data
:
dns_done
(
chan
,
data
)
for
chan
,(
peer
,
timeout
)
in
dnsreqs
.
items
():
if
timeout
<
now
:
del
dnsreqs
[
chan
]
debug3
(
'Remaining DNS requests:
%
d
\n
'
%
len
(
dnsreqs
))
handlers
.
append
(
Handler
([
listener
],
lambda
:
onaccept
(
listener
,
mux
,
handlers
)))
if
dnslistener
:
handlers
.
append
(
Handler
([
dnslistener
],
ondns
))
handlers
.
append
(
Handler
([
dnslistener
],
lambda
:
ondns
(
dnslistener
,
mux
,
handlers
)
))
if
seed_hosts
!=
None
:
debug1
(
'seed_hosts:
%
r
\n
'
%
seed_hosts
)
...
...
Sshuttle VPN.app/Contents/Resources/sshuttle/firewall.py
View file @
d5c3aa61
import
re
,
errno
,
socket
,
select
,
struct
import
re
,
errno
,
socket
,
select
,
s
ignal
,
s
truct
import
compat.ssubprocess
as
ssubprocess
import
helpers
,
ssyslog
from
helpers
import
*
...
...
@@ -6,6 +6,12 @@ from helpers import *
# python doesn't have a definition for this
IPPROTO_DIVERT
=
254
# return values from sysctl_set
SUCCESS
=
0
SAME
=
1
FAILED
=
-
1
NONEXIST
=
-
2
def
nonfatal
(
func
,
*
args
):
try
:
...
...
@@ -14,6 +20,14 @@ def nonfatal(func, *args):
log
(
'error:
%
s
\n
'
%
e
)
def
_call
(
argv
):
debug1
(
'>>
%
s
\n
'
%
' '
.
join
(
argv
))
rv
=
ssubprocess
.
call
(
argv
)
if
rv
:
raise
Fatal
(
'
%
r returned
%
d'
%
(
argv
,
rv
))
return
rv
def
ipt_chain_exists
(
name
):
argv
=
[
'iptables'
,
'-t'
,
'nat'
,
'-nL'
]
p
=
ssubprocess
.
Popen
(
argv
,
stdout
=
ssubprocess
.
PIPE
)
...
...
@@ -27,10 +41,7 @@ def ipt_chain_exists(name):
def
ipt
(
*
args
):
argv
=
[
'iptables'
,
'-t'
,
'nat'
]
+
list
(
args
)
debug1
(
'>>
%
s
\n
'
%
' '
.
join
(
argv
))
rv
=
ssubprocess
.
call
(
argv
)
if
rv
:
raise
Fatal
(
'
%
r returned
%
d'
%
(
argv
,
rv
))
_call
(
argv
)
_no_ttl_module
=
False
...
...
@@ -135,6 +146,42 @@ def _fill_oldctls(prefix):
raise
Fatal
(
'
%
r returned no data'
%
(
argv
,))
KERNEL_FLAGS_PATH
=
'/Library/Preferences/SystemConfiguration/com.apple.Boot'
KERNEL_FLAGS_NAME
=
'Kernel Flags'
def
_defaults_read_kernel_flags
():
argv
=
[
'defaults'
,
'read'
,
KERNEL_FLAGS_PATH
,
KERNEL_FLAGS_NAME
]
debug1
(
'>>
%
s
\n
'
%
' '
.
join
(
argv
))
p
=
ssubprocess
.
Popen
(
argv
,
stdout
=
ssubprocess
.
PIPE
)
flagstr
=
p
.
stdout
.
read
()
.
strip
()
rv
=
p
.
wait
()
if
rv
:
raise
Fatal
(
'
%
r returned
%
d'
%
(
argv
,
rv
))
flags
=
flagstr
and
flagstr
.
split
(
' '
)
or
[]
return
flags
def
_defaults_write_kernel_flags
(
flags
):
flagstr
=
' '
.
join
(
flags
)
argv
=
[
'defaults'
,
'write'
,
KERNEL_FLAGS_PATH
,
KERNEL_FLAGS_NAME
,
flagstr
]
_call
(
argv
)
argv
=
[
'plutil'
,
'-convert'
,
'xml1'
,
KERNEL_FLAGS_PATH
+
'.plist'
]
_call
(
argv
)
def
defaults_write_kernel_flag
(
name
,
val
):
flags
=
_defaults_read_kernel_flags
()
found
=
0
for
i
in
range
(
len
(
flags
)):
if
flags
[
i
]
.
startswith
(
'
%
s='
%
name
):
found
+=
1
flags
[
i
]
=
'
%
s=
%
s'
%
(
name
,
val
)
if
not
found
:
flags
.
insert
(
0
,
'
%
s=
%
s'
%
(
name
,
val
))
_defaults_write_kernel_flags
(
flags
)
def
_sysctl_set
(
name
,
val
):
argv
=
[
'sysctl'
,
'-w'
,
'
%
s=
%
s'
%
(
name
,
val
)]
debug1
(
'>>
%
s
\n
'
%
' '
.
join
(
argv
))
...
...
@@ -150,20 +197,24 @@ def sysctl_set(name, val, permanent=False):
_fill_oldctls
(
PREFIX
)
if
not
(
name
in
_oldctls
):
debug1
(
'>> No such sysctl:
%
r
\n
'
%
name
)
return
False
return
NONEXIST
oldval
=
_oldctls
[
name
]
if
val
!=
oldval
:
rv
=
_sysctl_set
(
name
,
val
)
if
rv
==
0
and
permanent
:
debug1
(
'>> ...saving permanently in /etc/sysctl.conf
\n
'
)
f
=
open
(
'/etc/sysctl.conf'
,
'a'
)
f
.
write
(
'
\n
'
'# Added by sshuttle
\n
'
'
%
s=
%
s
\n
'
%
(
name
,
val
))
f
.
close
()
else
:
_changedctls
.
append
(
name
)
return
True
if
val
==
oldval
:
return
SAME
rv
=
_sysctl_set
(
name
,
val
)
if
rv
!=
0
:
return
FAILED
if
permanent
:
debug1
(
'>> ...saving permanently in /etc/sysctl.conf
\n
'
)
f
=
open
(
'/etc/sysctl.conf'
,
'a'
)
f
.
write
(
'
\n
'
'# Added by sshuttle
\n
'
'
%
s=
%
s
\n
'
%
(
name
,
val
))
f
.
close
()
else
:
_changedctls
.
append
(
name
)
return
SUCCESS
def
_udp_unpack
(
p
):
...
...
@@ -201,10 +252,7 @@ def _handle_diversion(divertsock, dnsport):
def
ipfw
(
*
args
):
argv
=
[
'ipfw'
,
'-q'
]
+
list
(
args
)
debug1
(
'>>
%
s
\n
'
%
' '
.
join
(
argv
))
rv
=
ssubprocess
.
call
(
argv
)
if
rv
:
raise
Fatal
(
'
%
r returned
%
d'
%
(
argv
,
rv
))
_call
(
argv
)
def
do_ipfw
(
port
,
dnsport
,
subnets
):
...
...
@@ -222,8 +270,14 @@ def do_ipfw(port, dnsport, subnets):
if
subnets
or
dnsport
:
sysctl_set
(
'net.inet.ip.fw.enable'
,
1
)
changed
=
sysctl_set
(
'net.inet.ip.scopedroute'
,
0
,
permanent
=
True
)
if
changed
:
# This seems to be needed on MacOS 10.6 and 10.7. For more
# information, see:
# http://groups.google.com/group/sshuttle/browse_thread/thread/bc32562e17987b25/6d3aa2bb30a1edab
# and
# http://serverfault.com/questions/138622/transparent-proxying-leaves-sockets-with-syn-rcvd-in-macos-x-10-6-snow-leopard
changeflag
=
sysctl_set
(
'net.inet.ip.scopedroute'
,
0
,
permanent
=
True
)
if
changeflag
==
SUCCESS
:
log
(
"
\n
"
" WARNING: ONE-TIME NETWORK DISRUPTION:
\n
"
" =====================================
\n
"
...
...
@@ -234,6 +288,21 @@ def do_ipfw(port, dnsport, subnets):
"ethernet port) NOW, then restart sshuttle. The fix is
\n
"
"permanent; you only have to do this once.
\n\n
"
)
sys
.
exit
(
1
)
elif
changeflag
==
FAILED
:
# On MacOS 10.7, the scopedroute sysctl became read-only, so
# we have to fix it using a kernel boot parameter instead,
# which requires rebooting. For more, see:
# http://groups.google.com/group/sshuttle/browse_thread/thread/a42505ca33e1de80/e5e8f3e5a92d25f7
log
(
'Updating kernel boot flags.
\n
'
)
defaults_write_kernel_flag
(
'net.inet.ip.scopedroute'
,
0
)
log
(
"
\n
"
" YOU MUST REBOOT TO USE SSHUTTLE
\n
"
" ===============================
\n
"
"sshuttle has changed a MacOS kernel boot-time setting
\n
"
"to work around a bug in MacOS 10.7 Lion. You will need
\n
"
"to reboot before it takes effect. You only have to
\n
"
"do this once.
\n\n
"
)
sys
.
exit
(
EXITCODE_NEEDS_REBOOT
)
ipfw
(
'add'
,
sport
,
'check-state'
,
'ip'
,
'from'
,
'any'
,
'to'
,
'any'
)
...
...
@@ -243,11 +312,11 @@ def do_ipfw(port, dnsport, subnets):
for
swidth
,
sexclude
,
snet
in
sorted
(
subnets
,
reverse
=
True
):
if
sexclude
:
ipfw
(
'add'
,
sport
,
'skipto'
,
xsport
,
'
log'
,
'
tcp'
,
'tcp'
,
'from'
,
'any'
,
'to'
,
'
%
s/
%
s'
%
(
snet
,
swidth
))
else
:
ipfw
(
'add'
,
sport
,
'fwd'
,
'127.0.0.1,
%
d'
%
port
,
'
log'
,
'
tcp'
,
'tcp'
,
'from'
,
'any'
,
'to'
,
'
%
s/
%
s'
%
(
snet
,
swidth
),
'not'
,
'ipttl'
,
'42'
,
'keep-state'
,
'setup'
)
...
...
@@ -289,12 +358,12 @@ def do_ipfw(port, dnsport, subnets):
for
ip
in
nslist
:
# relabel and then catch outgoing DNS requests
ipfw
(
'add'
,
sport
,
'divert'
,
sport
,
'
log'
,
'
udp'
,
'udp'
,
'from'
,
'any'
,
'to'
,
'
%
s/32'
%
ip
,
'53'
,
'not'
,
'ipttl'
,
'42'
)
# relabel DNS responses
ipfw
(
'add'
,
sport
,
'divert'
,
sport
,
'
log'
,
'
udp'
,
'udp'
,
'from'
,
'any'
,
str
(
dnsport
),
'to'
,
'any'
,
'not'
,
'ipttl'
,
'42'
)
...
...
@@ -398,6 +467,11 @@ def main(port, dnsport, syslog):
sys
.
stdout
.
write
(
'READY
\n
'
)
sys
.
stdout
.
flush
()
# don't disappear if our controlling terminal or stdout/stderr
# disappears; we still have to clean up.
signal
.
signal
(
signal
.
SIGHUP
,
signal
.
SIG_IGN
)
signal
.
signal
(
signal
.
SIGPIPE
,
signal
.
SIG_IGN
)
# ctrl-c shouldn't be passed along to me. When the main sshuttle dies,
# I'll die automatically.
os
.
setsid
()
...
...
Sshuttle VPN.app/Contents/Resources/sshuttle/helpers.py
View file @
d5c3aa61
import
sys
,
os
,
socket
import
sys
,
os
,
socket
,
errno
logprefix
=
''
verbose
=
0
...
...
@@ -30,6 +30,11 @@ class Fatal(Exception):
pass
EXITCODE_NEEDS_REBOOT
=
111
class
FatalNeedsReboot
(
Fatal
):
pass
def
list_contains_any
(
l
,
sub
):
for
i
in
sub
:
if
i
in
l
:
...
...
Sshuttle VPN.app/Contents/Resources/sshuttle/main.py
100644 → 100755
View file @
d5c3aa61
...
...
@@ -63,6 +63,7 @@ seed-hosts= with -H, use these hostnames for initial scan (comma-separated)
no-latency-control sacrifice latency to improve bandwidth benchmarks
wrap= restart counting channel numbers after this number (for testing)
D,daemon run in the background as a daemon
V,version print sshuttle's version number
syslog send log messages to syslog (default if you use --daemon)
pidfile= pidfile name (only if using --daemon) [./sshuttle.pid]
server (internal use only)
...
...
@@ -72,6 +73,10 @@ hostwatch (internal use only)
o
=
options
.
Options
(
optspec
)
(
opt
,
flags
,
extra
)
=
o
.
parse
(
sys
.
argv
[
2
:])
if
opt
.
version
:
import
version
print
version
.
TAG
sys
.
exit
(
0
)
if
opt
.
daemon
:
opt
.
syslog
=
1
if
opt
.
wrap
:
...
...
@@ -121,6 +126,9 @@ try:
parse_subnets
(
includes
),
parse_subnets
(
excludes
),
opt
.
syslog
,
opt
.
daemon
,
opt
.
pidfile
))
except
FatalNeedsReboot
,
e
:
log
(
'You must reboot before using sshuttle.
\n
'
)
sys
.
exit
(
EXITCODE_NEEDS_REBOOT
)
except
Fatal
,
e
:
log
(
'fatal:
%
s
\n
'
%
e
)
sys
.
exit
(
99
)
...
...
Sshuttle VPN.app/Contents/Resources/sshuttle/ssnet.py
View file @
d5c3aa61
...
...
@@ -152,6 +152,17 @@ class SockWrapper:
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
]
==
0
:
# connected successfully (weird Linux bug?)
# Sometimes Linux seems to return EINVAL when it isn't
# invalid. This *may* be caused by a race condition
# between connect() and getsockopt(SO_ERROR) (ie. it
# finishes connecting in between the two, so there is no
# longer an error). However, I'm not sure of that.
#
# I did get at least one report that the problem went away
# when we added this, however.
self
.
connect_to
=
None
elif
e
.
args
[
0
]
==
errno
.
EISCONN
:
# connected successfully (BSD)
self
.
connect_to
=
None
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment