Clean up SockWrapper.peername stuff.

Some fds don't have peernames, and sometimes the peername isn't very
helpful, so let's fill it in by hand when appropriate.
This commit is contained in:
Avery Pennarun 2010-05-02 01:52:05 -04:00
parent ea12048418
commit 10069f99e2
2 changed files with 27 additions and 12 deletions

2
ssh.py
View File

@ -20,7 +20,7 @@ def connect(rhost):
cmd = r""" cmd = r"""
sh -c PATH=%s:'$PATH exec sshuttle --server' sh -c PATH=%s:'$PATH exec sshuttle --server'
""" % (escapedir,) """ % (escapedir,)
argv = ['ssh', '-v', rhost, '--', cmd.strip()] argv = ['ssh', rhost, '--', cmd.strip()]
print repr(argv) print repr(argv)
(s1,s2) = socket.socketpair() (s1,s2) = socket.socketpair()
def setup(): def setup():

View File

@ -36,27 +36,35 @@ def _nb_clean(func, *args):
def _try_peername(sock): def _try_peername(sock):
try: try:
return sock.getpeername() pn = sock.getpeername()
if pn:
return '%s:%s' % (pn[0], pn[1])
except socket.error, e: except socket.error, e:
if e.args[0] not in (errno.ENOTCONN, errno.ENOTSOCK): if e.args[0] not in (errno.ENOTCONN, errno.ENOTSOCK):
raise raise
else: return 'unknown'
return ('0.0.0.0',0)
class SockWrapper: class SockWrapper:
def __init__(self, rsock, wsock): def __init__(self, rsock, wsock, peername=None):
self.exc = None
self.rsock = rsock self.rsock = rsock
self.wsock = wsock self.wsock = wsock
self.peername = _try_peername(self.rsock)
self.shut_read = self.shut_write = False self.shut_read = self.shut_write = False
self.buf = [] self.buf = []
self.peername = peername or _try_peername(self.rsock)
def __del__(self): def __del__(self):
log('%r: deleting\n' % self) log('%r: deleting\n' % self)
if self.exc:
log('%r: error was: %r\n' % (self, self.exc))
def __repr__(self): def __repr__(self):
return 'SW%r' % (self.peername,) return 'SW:%s' % (self.peername,)
def seterr(self, e):
if not self.exc:
self.exc = e
def noread(self): def noread(self):
if not self.shut_read: if not self.shut_read:
@ -70,15 +78,16 @@ class SockWrapper:
self.shut_write = True self.shut_write = True
try: try:
self.wsock.shutdown(socket.SHUT_WR) self.wsock.shutdown(socket.SHUT_WR)
except socket.error: except socket.error, e:
pass self.seterr(e)
def uwrite(self, buf): def uwrite(self, buf):
self.wsock.setblocking(False) self.wsock.setblocking(False)
try: try:
return _nb_clean(os.write, self.wsock.fileno(), buf) return _nb_clean(os.write, self.wsock.fileno(), buf)
except OSError: except OSError, e:
# unexpected error... stream is dead # unexpected error... stream is dead
self.seterr(e)
self.nowrite() self.nowrite()
self.noread() self.noread()
return 0 return 0
@ -93,7 +102,8 @@ class SockWrapper:
self.rsock.setblocking(False) self.rsock.setblocking(False)
try: try:
return _nb_clean(os.read, self.rsock.fileno(), 65536) return _nb_clean(os.read, self.rsock.fileno(), 65536)
except OSError: except OSError, e:
self.seterr(e)
return '' # unexpected error... we'll call it EOF return '' # unexpected error... we'll call it EOF
def fill(self): def fill(self):
@ -312,11 +322,16 @@ class MuxWrapper(SockWrapper):
def connect_dst(ip, port): def connect_dst(ip, port):
log('Connecting to %s:%d\n' % (ip, port))
outsock = socket.socket() outsock = socket.socket()
outsock.setsockopt(socket.SOL_IP, socket.IP_TTL, 42) outsock.setsockopt(socket.SOL_IP, socket.IP_TTL, 42)
e = None
try: try:
outsock.connect((ip,port)) outsock.connect((ip,port))
except socket.error, e: except socket.error, e:
if e.args[0] not in [errno.ECONNREFUSED]: if e.args[0] not in [errno.ECONNREFUSED]:
raise raise
return SockWrapper(outsock,outsock) sw = SockWrapper(outsock, outsock, peername = '%s:%d' % (ip,port))
if e:
sw.seterr(e)
return sw