示例#1
0
 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)
示例#2
0
文件: server.py 项目: upsuper/usocks
 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)
示例#3
0
 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 = {}
示例#4
0
文件: client.py 项目: upsuper/usocks
 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 = {}
示例#5
0
文件: client.py 项目: upsuper/usocks
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]
示例#6
0
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]