coding standards

This commit is contained in:
Yann Leboulanger 2008-11-24 17:00:20 +00:00
parent 482cb1ee1d
commit 04e88bab3c
1 changed files with 142 additions and 145 deletions

View File

@ -68,7 +68,7 @@ class SocksQueue:
self.error_cb = error_cb
self.on_success = None
self.on_failure = None
def start_listener(self, port, sha_str, sha_handler, sid):
''' start waiting for incomming connections on (host, port)
and do a socks5 authentication using sid for generated sha
@ -87,16 +87,16 @@ class SocksQueue:
return None
self.connected += 1
return self.listener
def send_success_reply(self, file_props, streamhost):
if 'streamhost-used' in file_props and \
file_props['streamhost-used'] is True:
if 'proxyhosts' in file_props:
for proxy in file_props['proxyhosts']:
if proxy == streamhost:
self.on_success(streamhost)
return 2
return 0
file_props['streamhost-used'] is True:
if 'proxyhosts' in file_props:
for proxy in file_props['proxyhosts']:
if proxy == streamhost:
self.on_success(streamhost)
return 2
return 0
if 'streamhosts' in file_props:
for host in file_props['streamhosts']:
if streamhost['state'] == 1:
@ -105,22 +105,21 @@ class SocksQueue:
self.on_success(streamhost)
return 1
return 0
def connect_to_hosts(self, account, sid, on_success = None,
on_failure = None):
def connect_to_hosts(self, account, sid, on_success=None, on_failure=None):
self.on_success = on_success
self.on_failure = on_failure
file_props = self.files_props[account][sid]
file_props['failure_cb'] = on_failure
# add streamhosts to the queue
# add streamhosts to the queue
for streamhost in file_props['streamhosts']:
receiver = Socks5Receiver(self.idlequeue, streamhost, sid, file_props)
self.add_receiver(account, receiver)
streamhost['idx'] = receiver.queue_idx
def _socket_connected(self, streamhost, file_props):
''' called when there is a host connected to one of the
''' called when there is a host connected to one of the
senders's streamhosts. Stop othere attempts for connections '''
for host in file_props['streamhosts']:
if host != streamhost and 'idx' in host:
@ -130,14 +129,14 @@ class SocksQueue:
return
# set state -2, meaning that this streamhost is stopped,
# but it may be connectected later
if host['state'] >=0:
if host['state'] >= 0:
self.remove_receiver(host['idx'])
host['idx'] = -1
host['state'] = -2
def reconnect_receiver(self, receiver, streamhost):
''' Check the state of all streamhosts and if all has failed, then
emit connection failure cb. If there are some which are still
''' Check the state of all streamhosts and if all has failed, then
emit connection failure cb. If there are some which are still
not connected try to establish connection to one of them.
'''
self.idlequeue.remove_timeout(receiver.fd)
@ -156,7 +155,8 @@ class SocksQueue:
for host in file_props['streamhosts']:
if host['state'] == -2:
host['state'] = 0
receiver = Socks5Receiver(self.idlequeue, host, host['sid'], file_props)
receiver = Socks5Receiver(self.idlequeue, host, host['sid'],
file_props)
self.add_receiver(receiver.account, receiver)
host['idx'] = receiver.queue_idx
# we still have chances to connect
@ -169,7 +169,7 @@ class SocksQueue:
receiver.disconnect()
file_props['error'] = -1
self.process_result(-1, receiver)
def _connection_refused(self, streamhost, file_props, idx):
''' cb, called when we loose connection during transfer'''
if file_props is None:
@ -182,10 +182,10 @@ class SocksQueue:
return
# failure_cb exists - this means that it has never been called
if 'failure_cb' in file_props and file_props['failure_cb']:
file_props['failure_cb'](streamhost['initiator'], streamhost['id'],
file_props['failure_cb'](streamhost['initiator'], streamhost['id'],
file_props['sid'], code = 404)
del(file_props['failure_cb'])
def add_receiver(self, account, sock5_receiver):
''' add new file request '''
self.readers[self.idx] = sock5_receiver
@ -200,23 +200,21 @@ class SocksQueue:
self.process_result(result, sock5_receiver)
return 1
return None
def get_file_from_sender(self, file_props, account):
if file_props is None:
return
if 'hash' in file_props and \
file_props['hash'] in self.senders:
if 'hash' in file_props and file_props['hash'] in self.senders:
sender = self.senders[file_props['hash']]
sender.account = account
result = self.get_file_contents(0)
self.process_result(result, sender)
def result_sha(self, sha_str, idx):
if sha_str in self.sha_handlers:
props = self.sha_handlers[sha_str]
props[0](props[1], idx)
def activate_proxy(self, idx):
if idx not in self.readers:
return
@ -242,15 +240,14 @@ class SocksQueue:
self.idlequeue.plug_idle(reader, True, False)
result = reader.write_next()
self.process_result(result, reader)
def send_file(self, file_props, account):
if 'hash' in file_props and \
file_props['hash'] in self.senders:
if 'hash' in file_props and file_props['hash'] in self.senders:
sender = self.senders[file_props['hash']]
file_props['streamhost-used'] = True
sender.account = account
if file_props['type'] == 's':
sender.file_props = file_props
sender.file_props = file_props
result = sender.send_file()
self.process_result(result, sender)
else:
@ -258,28 +255,27 @@ class SocksQueue:
file_props['last-time'] = self.idlequeue.current_time()
file_props['received-len'] = 0
sender.file_props = file_props
def add_file_props(self, account, file_props):
''' file_prop to the dict of current file_props.
It is identified by account name and sid
'''
if file_props is None or \
('sid' in file_props) is False:
if file_props is None or ('sid' in file_props) is False:
return
_id = file_props['sid']
if account not in self.files_props:
self.files_props[account] = {}
self.files_props[account][_id] = file_props
def remove_file_props(self, account, sid):
if account in self.files_props:
fl_props = self.files_props[account]
if sid in fl_props:
del(fl_props[sid])
if len(self.files_props) == 0:
self.connected = 0
def get_file_props(self, account, sid):
''' get fil_prop by account name and session id '''
if account in self.files_props:
@ -287,14 +283,14 @@ class SocksQueue:
if sid in fl_props:
return fl_props[sid]
return None
def on_connection_accepted(self, sock):
sock_hash = sock.__hash__()
sock_hash = sock.__hash__()
if sock_hash not in self.senders:
self.senders[sock_hash] = Socks5Sender(self.idlequeue,
sock_hash, self, sock[0], sock[1][0], sock[1][1])
self.senders[sock_hash] = Socks5Sender(self.idlequeue, sock_hash, self,
sock[0], sock[1][0], sock[1][1])
self.connected += 1
def process_result(self, result, actor):
''' Take appropriate actions upon the result:
[ 0, - 1 ] complete/end transfer
@ -310,9 +306,9 @@ class SocksQueue:
self.complete_transfer_cb(account, actor.file_props)
elif self.progress_transfer_cb is not None:
self.progress_transfer_cb(actor.account, actor.file_props)
def remove_receiver(self, idx, do_disconnect = True):
''' Remove reciver from the list and decrease
def remove_receiver(self, idx, do_disconnect=True):
''' Remove reciver from the list and decrease
the number of active connections with 1'''
if idx != -1:
if idx in self.readers:
@ -323,11 +319,11 @@ class SocksQueue:
reader.disconnect()
else:
if reader.streamhost is not None:
reader.streamhost['state'] = -1
reader.streamhost['state'] = -1
del(self.readers[idx])
def remove_sender(self, idx, do_disconnect = True):
''' Remove sender from the list of senders and decrease the
def remove_sender(self, idx, do_disconnect=True):
''' Remove sender from the list of senders and decrease the
number of active connections with 1'''
if idx != -1:
if idx in self.senders:
@ -342,13 +338,14 @@ class SocksQueue:
self.listener.disconnect()
self.listener = None
self.connected -= 1
class Socks5:
def __init__(self, idlequeue, host, port, initiator, target, sid):
if host is not None:
try:
self.host = host
self.ais = socket.getaddrinfo(host, port, socket.AF_UNSPEC, socket.SOCK_STREAM)
self.ais = socket.getaddrinfo(host, port, socket.AF_UNSPEC,
socket.SOCK_STREAM)
except socket.gaierror:
self.ais = None
self.idlequeue = idlequeue
@ -364,7 +361,7 @@ class Socks5:
self.size = 0
self.remaining_buff = ''
self.file = None
def open_file_for_reading(self):
if self.file is None:
try:
@ -376,7 +373,7 @@ class Socks5:
except IOError, e:
self.close_file()
raise IOError, e
def close_file(self):
if self.file:
if not self.file.closed:
@ -385,7 +382,7 @@ class Socks5:
except Exception:
pass
self.file = None
def get_fd(self):
''' Test if file is already open and return its fd,
or just open the file and return the fd.
@ -404,7 +401,7 @@ class Socks5:
self.file_props['last-time'] = self.idlequeue.current_time()
self.file_props['received-len'] = offset
return fd
def rem_fd(self, fd):
if 'fd' in self.file_props:
del(self.file_props['fd'])
@ -412,21 +409,20 @@ class Socks5:
fd.close()
except Exception:
pass
def receive(self):
''' Reads small chunks of data.
''' Reads small chunks of data.
Calls owner's disconnected() method if appropriate.'''
received = ''
try:
try:
add = self._recv(64)
except Exception, e:
add=''
received +=add
except Exception, e:
add = ''
received += add
if len(add) == 0:
self.disconnect()
return add
def send_raw(self,raw_data):
''' Writes raw outgoing data. '''
try:
@ -434,7 +430,7 @@ class Socks5:
except Exception, e:
self.disconnect()
return len(raw_data)
def write_next(self):
if self.remaining_buff != '':
buff = self.remaining_buff
@ -483,12 +479,10 @@ class Socks5:
self.state = 8 # end connection
self.disconnect()
return -1
def get_file_contents(self, timeout):
''' read file contents from socket and write them to file ''', \
self.file_props['type'], self.file_props['sid']
if self.file_props is None or \
('file-name' in self.file_props) is False:
''' read file contents from socket and write them to file '''
if self.file_props is None or ('file-name' in self.file_props) is False:
self.file_props['error'] = -2
return None
fd = None
@ -510,7 +504,7 @@ class Socks5:
return 0
else:
fd = self.get_fd()
try:
try:
buff = self._recv(MAX_BUFF_LEN)
except Exception, e:
buff = ''
@ -549,7 +543,7 @@ class Socks5:
if self.file_props['received-len'] != 0:
return self.file_props['received-len']
return None
def disconnect(self):
''' Closes open descriptors and remover socket descr. from idleque '''
# be sure that we don't leave open file
@ -565,12 +559,12 @@ class Socks5:
self.connected = False
self.fd = -1
self.state = -1
def _get_auth_buff(self):
''' Message, that we support 1 one auth mechanism:
''' Message, that we support 1 one auth mechanism:
the 'no auth' mechanism. '''
return struct.pack('!BBB', 0x05, 0x01, 0x00)
def _parse_auth_buff(self, buff):
''' Parse the initial message and create a list of auth
mechanisms '''
@ -583,30 +577,31 @@ class Socks5:
except Exception:
return None
return auth_mechanisms
def _get_auth_response(self):
''' socks version(5), number of extra auth methods (we send
0x00 - no auth
) '''
return struct.pack('!BB', 0x05, 0x00)
def _get_connect_buff(self):
''' Connect request by domain name '''
buff = struct.pack('!BBBBB%dsBB' % len(self.host),
0x05, 0x01, 0x00, 0x03, len(self.host), self.host,
buff = struct.pack('!BBBBB%dsBB' % len(self.host),
0x05, 0x01, 0x00, 0x03, len(self.host), self.host,
self.port >> 8, self.port & 0xff)
return buff
def _get_request_buff(self, msg, command = 0x01):
''' Connect request by domain name,
''' Connect request by domain name,
sid sha, instead of domain name (jep 0096) '''
buff = struct.pack('!BBBBB%dsBB' % len(msg),
buff = struct.pack('!BBBBB%dsBB' % len(msg),
0x05, command, 0x00, 0x03, len(msg), msg, 0, 0)
return buff
def _parse_request_buff(self, buff):
try: # don't trust on what comes from the outside
version, req_type, reserved, host_type, = \
struct.unpack('!BBBB', buff[:4])
version, req_type, reserved, host_type, = struct.unpack('!BBBB',
buff[:4])
if host_type == 0x01:
host_arr = struct.unpack('!iiii', buff[4:8])
host, = '.'.join(str(s) for s in host_arr)
@ -615,18 +610,18 @@ class Socks5:
host_len, = struct.unpack('!B' , buff[4])
host, = struct.unpack('!%ds' % host_len, buff[5:5 + host_len])
portlen = len(buff[host_len + 5:])
if portlen == 1:
if portlen == 1:
port, = struct.unpack('!B', buff[host_len + 5])
elif portlen == 2:
elif portlen == 2:
port, = struct.unpack('!H', buff[host_len + 5:])
# file data, comes with auth message (Gaim bug)
else:
else:
port, = struct.unpack('!H', buff[host_len + 5: host_len + 7])
self.remaining_buff = buff[host_len + 7:]
except Exception:
return (None, None, None)
return (req_type, host, port)
def read_connect(self):
''' connect responce: version, auth method '''
buff = self._recv()
@ -636,7 +631,7 @@ class Socks5:
version, method = None, None
if version != 0x05 or method == 0xff:
self.disconnect()
def continue_paused_transfer(self):
if self.state < 5:
return
@ -644,18 +639,20 @@ class Socks5:
self.idlequeue.plug_idle(self, False, True)
else:
self.idlequeue.plug_idle(self, True, False)
def _get_sha1_auth(self):
''' get sha of sid + Initiator jid + Target jid '''
if 'is_a_proxy' in self.file_props:
del(self.file_props['is_a_proxy'])
return sha.new('%s%s%s' % (self.sid, self.file_props['proxy_sender'],
return sha.new('%s%s%s' % (self.sid, self.file_props['proxy_sender'],
self.file_props['proxy_receiver'])).hexdigest()
return sha.new('%s%s%s' % (self.sid, self.initiator, self.target)).hexdigest()
return sha.new('%s%s%s' % (self.sid, self.initiator, self.target)).\
hexdigest()
class Socks5Sender(Socks5, IdleObject):
''' class for sending file to socket over socks5 '''
def __init__(self, idlequeue, sock_hash, parent, _sock, host = None, port = None):
def __init__(self, idlequeue, sock_hash, parent, _sock, host=None,
port=None):
self.queue_idx = sock_hash
self.queue = parent
Socks5.__init__(self, idlequeue, host, port, None, None, None)
@ -669,7 +666,7 @@ class Socks5Sender(Socks5, IdleObject):
self.file_props = None
# start waiting for data
self.idlequeue.plug_idle(self, False, True)
def read_timeout(self):
self.idlequeue.remove_timeout(self.fd)
if self.state > 5:
@ -680,9 +677,9 @@ class Socks5Sender(Socks5, IdleObject):
if SEND_TIMEOUT > 0:
self.idlequeue.set_read_timeout(self.fd, SEND_TIMEOUT)
else:
# stop transfer, there is no error code for this
# stop transfer, there is no error code for this
self.pollend()
def pollout(self):
if not self.connected:
self.disconnect()
@ -696,7 +693,7 @@ class Socks5Sender(Socks5, IdleObject):
if self.file_props['paused']:
self.file_props['continue_cb'] = self.continue_paused_transfer
self.idlequeue.plug_idle(self, False, False)
return
return
result = self.write_next()
self.queue.process_result(result, self)
if result is None or result <= 0:
@ -712,13 +709,13 @@ class Socks5Sender(Socks5, IdleObject):
self.state += 1
# unplug and plug this time for reading
self.idlequeue.plug_idle(self, False, True)
def pollend(self):
self.state = 8 # end connection
self.disconnect()
self.file_props['error'] = -1
self.queue.process_result(-1, self)
def pollin(self):
if self.connected:
if self.state < 5:
@ -727,17 +724,16 @@ class Socks5Sender(Socks5, IdleObject):
self.queue.result_sha(self.sha_msg, self.queue_idx)
if result == -1:
self.disconnect()
elif self.state == 5:
if self.file_props is not None and \
self.file_props['type'] == 'r':
if self.file_props is not None and self.file_props['type'] == 'r':
result = self.get_file_contents(0)
self.queue.process_result(result, self)
else:
self.disconnect()
def send_file(self):
''' start sending the file over verified connection '''
''' start sending the file over verified connection '''
if self.file_props['started']:
return
self.file_props['error'] = 0
@ -756,7 +752,7 @@ class Socks5Sender(Socks5, IdleObject):
# plug for writing
self.idlequeue.plug_idle(self, True, False)
return self.write_next() # initial for nl byte
def main(self):
''' initial requests for verifying the connection '''
if self.state == 1: # initial read
@ -775,8 +771,8 @@ class Socks5Sender(Socks5, IdleObject):
# unplug & plug for writing
self.idlequeue.plug_idle(self, True, False)
return None
def disconnect(self, cb = True):
def disconnect(self, cb=True):
''' Closes the socket. '''
# close connection and remove us from the queue
Socks5.disconnect(self)
@ -788,20 +784,20 @@ class Socks5Sender(Socks5, IdleObject):
class Socks5Listener(IdleObject):
def __init__(self, idlequeue, port):
''' handle all incomming connections on (0.0.0.0, port)
''' handle all incomming connections on (0.0.0.0, port)
This class implements IdleObject, but we will expect
only pollin events though
'''
self.port = port
self.ais = socket.getaddrinfo(None, port, socket.AF_UNSPEC,
socket.SOCK_STREAM, socket.SOL_TCP, socket.AI_PASSIVE)
self.queue_idx = -1
socket.SOCK_STREAM, socket.SOL_TCP, socket.AI_PASSIVE)
self.queue_idx = -1
self.idlequeue = idlequeue
self.queue = None
self.started = False
self._sock = None
self.fd = -1
def bind(self):
for ai in self.ais:
#try the different possibilities (ipv6, ipv4, etc.)
@ -825,16 +821,16 @@ class Socks5Listener(IdleObject):
self.fd = self._serv.fileno()
self.idlequeue.plug_idle(self, False, True)
self.started = True
def pollend(self):
''' called when we stop listening on (host, port) '''
self.disconnect()
def pollin(self):
''' accept a new incomming connection and notify queue'''
sock = self.accept_conn()
self.queue.on_connection_accepted(sock)
def disconnect(self):
''' free all resources, we are not listening anymore '''
self.idlequeue.remove_timeout(self.fd)
@ -846,13 +842,13 @@ class Socks5Listener(IdleObject):
self._serv.close()
except Exception:
pass
def accept_conn(self):
''' accepts a new incomming connection '''
_sock = self._serv.accept()
_sock[0].setblocking(False)
return _sock
class Socks5Receiver(Socks5, IdleObject):
def __init__(self, idlequeue, streamhost, sid, file_props = None):
self.queue_idx = -1
@ -871,9 +867,10 @@ class Socks5Receiver(Socks5, IdleObject):
self.file_props['paused'] = False
self.file_props['continue_cb'] = self.continue_paused_transfer
self.file_props['stalled'] = False
Socks5.__init__(self, idlequeue, streamhost['host'], int(streamhost['port']),
streamhost['initiator'], streamhost['target'], sid)
Socks5.__init__(self, idlequeue, streamhost['host'],
int(streamhost['port']), streamhost['initiator'], streamhost['target'],
sid)
def read_timeout(self):
self.idlequeue.remove_timeout(self.fd)
if self.state > 5:
@ -886,11 +883,11 @@ class Socks5Receiver(Socks5, IdleObject):
if READ_TIMEOUT > 0:
self.idlequeue.set_read_timeout(self.fd, READ_TIMEOUT)
else:
# stop transfer, there is no error code for this
# stop transfer, there is no error code for this
self.pollend()
else:
self.queue.reconnect_receiver(self, self.streamhost)
def connect(self):
''' create the socket and plug it to the idlequeue '''
if self.ais is None:
@ -898,10 +895,10 @@ class Socks5Receiver(Socks5, IdleObject):
for ai in self.ais:
try:
self._sock=socket.socket(*ai[:3])
self._sock = socket.socket(*ai[:3])
# this will not block the GUI
self._sock.setblocking(False)
self._server=ai[4]
self._server = ai[4]
break
except Exception:
if sys.exc_value[0] == errno.EINPROGRESS:
@ -914,11 +911,12 @@ class Socks5Receiver(Socks5, IdleObject):
self.do_connect()
self.idlequeue.set_read_timeout(self.fd, CONNECT_TIMEOUT)
return None
def _is_connected(self):
if self.state < 5:
return False
return True
def pollout(self):
self.idlequeue.remove_timeout(self.fd)
if self.state == 0:
@ -939,7 +937,7 @@ class Socks5Receiver(Socks5, IdleObject):
# unplug and plug for reading
self.idlequeue.plug_idle(self, False, True)
self.idlequeue.set_read_timeout(self.fd, CONNECT_TIMEOUT)
def pollend(self):
if self.state >= 5:
# error during transfer
@ -948,7 +946,7 @@ class Socks5Receiver(Socks5, IdleObject):
self.queue.process_result(-1, self)
else:
self.queue.reconnect_receiver(self, self.streamhost)
def pollin(self):
self.idlequeue.remove_timeout(self.fd)
if self.connected:
@ -965,10 +963,9 @@ class Socks5Receiver(Socks5, IdleObject):
self.idlequeue.set_read_timeout(self.fd, STALLED_TIMEOUT)
result = self.get_file_contents(0)
self.queue.process_result(result, self)
else:
self.disconnect()
def do_connect(self):
try:
self._sock.connect(self._server)
@ -979,7 +976,7 @@ class Socks5Receiver(Socks5, IdleObject):
(errnum, errstr) = ee
self.connect_timeout += 1
if errnum == 111 or self.connect_timeout > 1000:
self.queue._connection_refused(self.streamhost,
self.queue._connection_refused(self.streamhost,
self.file_props, self.queue_idx)
return None
# win32 needs this
@ -994,13 +991,13 @@ class Socks5Receiver(Socks5, IdleObject):
self.file_props['connected'] = True
self.file_props['disconnect_cb'] = self.disconnect
self.state = 1 # connected
# stop all others connections to sender's streamhosts
self.queue._socket_connected(self.streamhost, self.file_props)
self.idlequeue.plug_idle(self, True, False)
return 1 # we are connected
def main(self, timeout = 0):
def main(self, timeout=0):
''' begin negotiation. on success 'address' != 0 '''
result = 1
buff = self.receive()
@ -1008,7 +1005,7 @@ class Socks5Receiver(Socks5, IdleObject):
# end connection
self.pollend()
return
if self.state == 2: # read auth response
if buff is None or len(buff) != 2:
return None
@ -1027,7 +1024,7 @@ class Socks5Receiver(Socks5, IdleObject):
addrlen = ord(buff[4])
address = struct.unpack('!%ds' % addrlen, buff[5:addrlen + 5])
portlen = len(buff[addrlen + 5:])
if portlen == 1:
if portlen == 1:
port, = struct.unpack('!B', buff[addrlen + 5])
elif portlen == 2:
port, = struct.unpack('!H', buff[addrlen + 5:])
@ -1036,14 +1033,14 @@ class Socks5Receiver(Socks5, IdleObject):
self.remaining_buff = buff[addrlen + 7:]
self.state = 5 # for senders: init file_props and send '\n'
if self.queue.on_success:
result = self.queue.send_success_reply(self.file_props,
result = self.queue.send_success_reply(self.file_props,
self.streamhost)
if result == 0:
self.state = 8
self.disconnect()
# for senders: init file_props
if result == 1 and self.state == 5:
# for senders: init file_props
if result == 1 and self.state == 5:
if self.file_props['type'] == 's':
self.file_props['error'] = 0
self.file_props['disconnect_cb'] = self.disconnect
@ -1063,15 +1060,15 @@ class Socks5Receiver(Socks5, IdleObject):
self.idlequeue.plug_idle(self, False, True)
self.file_props['continue_cb'] = self.continue_paused_transfer
# we have set up the connection, next - retrieve file
self.state = 6
self.state = 6
if self.state < 5:
self.idlequeue.plug_idle(self, True, False)
self.state += 1
return None
def disconnect(self, cb = True):
def disconnect(self, cb=True):
''' Closes the socket. Remove self from queue if cb is True'''
# close connection
# close connection
Socks5.disconnect(self)
if cb is True:
self.file_props['disconnect_cb'] = None