def _process_backend(self): inst = self.backend.accept() if not inst: return record_conn = RecordConnection(self.key, inst) tunnel = TunnelConnection(record_conn) tunnel.address = inst.address self.tunnels[tunnel] = {} info("connected", 'backend', inst.address)
def __init__(self, config): self.local_conn = Connection(socket.socket(), -1) # read config if 'address' in config: self.address = config['address'] if 'port' in config: self.port = config['port'] # initialize local port self.local_conn.conn.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) self.local_conn.bind((self.address, self.port)) self.local_conn.listen(10) # initialize backend & record layer Backend = import_backend(config).ClientBackend self.backend = Backend(**config['backend']) self.record_conn = RecordConnection(config['key'], self.backend) self.tunnel = TunnelConnection(self.record_conn) # initialize connection dict self.conns = {}
def __init__(self, config): self.local_conn = Connection(socket.socket(), -1) # read config if 'address' in config: self.address = config['address'] if 'port' in config: self.port = config['port'] # initialize local port self.local_conn.conn.setsockopt( socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) self.local_conn.bind((self.address, self.port)) self.local_conn.listen(10) # initialize backend & record layer Backend = import_backend(config).ClientBackend self.backend = Backend(**config['backend']) self.record_conn = RecordConnection(config['key'], self.backend) self.tunnel = TunnelConnection(self.record_conn) # initialize connection dict self.conns = {}
class TunnelClient(object): address = "localhost" port = 8000 def __init__(self, config): self.local_conn = Connection(socket.socket(), -1) # read config if 'address' in config: self.address = config['address'] if 'port' in config: self.port = config['port'] # initialize local port self.local_conn.conn.setsockopt( socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) self.local_conn.bind((self.address, self.port)) self.local_conn.listen(10) # initialize backend & record layer Backend = import_backend(config).ClientBackend self.backend = Backend(**config['backend']) self.record_conn = RecordConnection(config['key'], self.backend) self.tunnel = TunnelConnection(self.record_conn) # initialize connection dict self.conns = {} def run(self): self.running = True while self.running: self._process() # close connections self.local_conn.close() for conn in self.conns.itervalues(): conn.close() self.record_conn.close() while True: wlist = self.record_conn.get_wlist() if not wlist: break select.select([], wlist, []) self.record_conn.continue_sending() self.backend.close() def _process(self): rlist, rdict = get_select_list('get_rlist', self.tunnel, self.local_conn, self.conns.itervalues() if self.tunnel.available else []) wlist, wdict = get_select_list('get_wlist', self.tunnel, self.conns.itervalues()) try: rlist, wlist, _ = select.select(rlist, wlist, []) except select.error as e: if e[0] == errno.EINTR: return raise for fileno in rlist: conn = rdict[fileno] if conn is self.tunnel: self._process_tunnel() elif conn is self.local_conn: self._process_listening() elif conn.conn_id in self.conns: self._process_connection(conn) written_conns = ObjectSet() for fileno in wlist: conn = wdict[fileno] if conn in written_conns: continue written_conns.add(conn) self._process_sending(conn) def _process_tunnel(self): try: for conn_id, control, data in self.tunnel.receive_packets(): if conn_id not in self.conns: continue conn = self.conns[conn_id] if control & StatusControl.rst: self._close_connection(conn_id, True) if control & StatusControl.dat: conn.send(data) if control & StatusControl.fin: self._close_connection(conn_id) except record.ConnectionClosedException: self.running = False def _process_listening(self): conn, address = self.local_conn.accept() conn_id = self.tunnel.new_connection() conn = Connection(conn, conn_id) self.conns[conn_id] = conn def _process_connection(self, conn): conn_id = conn.conn_id try: data = conn.recv(4096) except socket.error as e: if e.errno == errno.ECONNRESET: self.tunnel.reset_connection(conn_id) self._close_connection(conn_id) return raise if not data: self.tunnel.close_connection(conn_id) self._close_connection(conn_id) else: self.tunnel.send_packet(conn_id, data) def _process_sending(self, conn): if conn is self.tunnel: conn.continue_sending() elif conn.conn_id in self.conns: conn.send() def _close_connection(self, conn_id, reset=False): if reset: self.conns[conn_id].reset() else: self.conns[conn_id].close() del self.conns[conn_id]
class TunnelClient(object): address = "localhost" port = 8000 def __init__(self, config): self.local_conn = Connection(socket.socket(), -1) # read config if 'address' in config: self.address = config['address'] if 'port' in config: self.port = config['port'] # initialize local port self.local_conn.conn.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) self.local_conn.bind((self.address, self.port)) self.local_conn.listen(10) # initialize backend & record layer Backend = import_backend(config).ClientBackend self.backend = Backend(**config['backend']) self.record_conn = RecordConnection(config['key'], self.backend) self.tunnel = TunnelConnection(self.record_conn) # initialize connection dict self.conns = {} def run(self): self.running = True while self.running: self._process() # close connections self.local_conn.close() for conn in self.conns.itervalues(): conn.close() self.record_conn.close() while True: wlist = self.record_conn.get_wlist() if not wlist: break select.select([], wlist, []) self.record_conn.continue_sending() self.backend.close() def _process(self): rlist, rdict = get_select_list( 'get_rlist', self.tunnel, self.local_conn, self.conns.itervalues() if self.tunnel.available else []) wlist, wdict = get_select_list('get_wlist', self.tunnel, self.conns.itervalues()) try: rlist, wlist, _ = select.select(rlist, wlist, []) except select.error as e: if e[0] == errno.EINTR: return raise for fileno in rlist: conn = rdict[fileno] if conn is self.tunnel: self._process_tunnel() elif conn is self.local_conn: self._process_listening() elif conn.conn_id in self.conns: self._process_connection(conn) written_conns = ObjectSet() for fileno in wlist: conn = wdict[fileno] if conn in written_conns: continue written_conns.add(conn) self._process_sending(conn) def _process_tunnel(self): try: for conn_id, control, data in self.tunnel.receive_packets(): if conn_id not in self.conns: continue conn = self.conns[conn_id] if control & StatusControl.rst: self._close_connection(conn_id, True) if control & StatusControl.dat: conn.send(data) if control & StatusControl.fin: self._close_connection(conn_id) except record.ConnectionClosedException: self.running = False def _process_listening(self): conn, address = self.local_conn.accept() conn_id = self.tunnel.new_connection() conn = Connection(conn, conn_id) self.conns[conn_id] = conn def _process_connection(self, conn): conn_id = conn.conn_id try: data = conn.recv(4096) except socket.error as e: if e.errno == errno.ECONNRESET: self.tunnel.reset_connection(conn_id) self._close_connection(conn_id) return raise if not data: self.tunnel.close_connection(conn_id) self._close_connection(conn_id) else: self.tunnel.send_packet(conn_id, data) def _process_sending(self, conn): if conn is self.tunnel: conn.continue_sending() elif conn.conn_id in self.conns: conn.send() def _close_connection(self, conn_id, reset=False): if reset: self.conns[conn_id].reset() else: self.conns[conn_id].close() del self.conns[conn_id]