Beispiel #1
0
    async def _handle_stage_init(self, data):
        """
        初始化连接状态(握手后建立链接)

        doc:
        https://docs.python.org/3/library/asyncio-eventloop.html
        """
        from shadowsocks.tcpreply import RemoteTCP
        from shadowsocks.udpreply import RemoteUDP

        atype, dst_addr, dst_port, header_length = parse_header(data)
        if not dst_addr:
            logging.warning(f"not valid data atype:{atype} user: {self.user}")
            self.close()
            return
        else:
            payload = data[header_length:]

        # 获取事件循环
        loop = asyncio.get_event_loop()
        if self._transport_protocol == flag.TRANSPORT_TCP:
            self._stage = self.STAGE_CONNECT

            # 尝试建立tcp连接,成功的话将会返回 (transport,protocol)
            tcp_coro = loop.create_connection(
                lambda: RemoteTCP(dst_addr, dst_port, payload, self._method,
                                  self._key, self),
                dst_addr,
                dst_port,
            )
            try:
                remote_transport, remote_instance = await tcp_coro
                # 记录用户的tcp连接数
                self.user.tcp_count += 1
            except (IOError, OSError) as e:
                logging.debug(f"connection failed , {type(e)} e: {e}")
                self.close()
                self._stage = self.STAGE_DESTROY
            except Exception as e:
                logging.warning(f"connection failed, {type(e)} e: {e}")
                self._stage = self.STAGE_ERROR
                self.close()
            else:
                logging.debug(
                    f"connection established,remote {remote_instance}")
                self._remote = remote_instance
                self._stage = self.STAGE_STREAM
        elif self._transport_protocol == flag.TRANSPORT_UDP:
            self._stage = self.STAGE_INIT
            # 异步建立udp连接,并存入future对象
            udp_coro = loop.create_datagram_endpoint(
                lambda: RemoteUDP(dst_addr, dst_port, payload, self._method,
                                  self._key, self),
                remote_addr=(dst_addr, dst_port),
            )
            asyncio.create_task(udp_coro)
        else:
            raise NotImplementedError
Beispiel #2
0
    async def _handle_stage_init(self, data):
        if self._transport_protocol == flag.TRANSPORT_TCP:
            self._stage = self.STAGE_CONNECT
        addr_type, dst_addr, dst_port, header_length = parse_header(data)
        if not all([addr_type, dst_addr, dst_port, header_length]):
            logging.warning(
                f"parse error addr_type: {addr_type} port: {self.port}")
            self.close()
            return
        else:
            payload = data[header_length:]

        logging.debug(
            f"HEADER: {addr_type} - {dst_addr} - {dst_port} - {self._transport_protocol}"
        )

        if self._transport_protocol == flag.TRANSPORT_TCP:
            self._stage = self.STAGE_CONNECT
            tcp_coro = self.loop.create_connection(
                lambda: RemoteTCP(dst_addr, dst_port, payload, self), dst_addr,
                dst_port)

            try:
                _, remote_tcp = await tcp_coro
            except (IOError, OSError) as e:
                self.close()
                self._stage = self.STAGE_DESTROY
                logging.debug(f"connection failed , {type(e)} e: {e}")
            except Exception as e:
                self._stage = self.STAGE_ERROR
                self.close()
                logging.warning(f"connection failed, {type(e)} e: {e}")
            else:
                self._remote = remote_tcp
                self._stage = self.STAGE_STREAM
                self._remote.write(self._connect_buffer)
                logging.debug(
                    f"connection ok buffer lens:{len(self._connect_buffer)}")
                self.cipher.incr_user_tcp_num(1)
                self.cipher.record_user_ip(self._peername)

        elif self._transport_protocol == flag.TRANSPORT_UDP:
            udp_coro = self.loop.create_datagram_endpoint(
                lambda: RemoteUDP(dst_addr, dst_port, payload, self),
                remote_addr=(dst_addr, dst_port),
            )
            try:
                await udp_coro
            except (IOError, OSError) as e:
                self.close()
                self._stage = self.STAGE_DESTROY
                logging.debug(f"connection failed , {type(e)} e: {e}")
            except Exception as e:
                self._stage = self.STAGE_ERROR
                self.close()
                logging.warning(f"connection failed, {type(e)} e: {e}")
        else:
            raise NotImplementedError
Beispiel #3
0
    async def _handle_stage_init(self, data):
        try:
            addr_type, dst_addr, dst_port, header_length = parse_header(data)
        except Exception as e:
            self.close()
            logging.warning(f"parse header error: {str(e)}")
            return
        if not dst_addr:
            self.close()
            logging.warning(
                "can't parse addr_type: {} user: {} CMD: {}".format(
                    addr_type, self.user, self._transport_protocol
                )
            )
            return
        else:
            payload = data[header_length:]
        loop = asyncio.get_event_loop()
        if self._transport_protocol == flag.TRANSPORT_TCP:
            self._stage = self.STAGE_CONNECT
            tcp_coro = loop.create_connection(
                lambda: RemoteTCP(dst_addr, dst_port, payload, self), dst_addr, dst_port
            )
            try:
                _, remote_tcp = await tcp_coro
            except (IOError, OSError) as e:
                self.close()
                self._stage = self.STAGE_DESTROY
                logging.debug(f"connection failed , {type(e)} e: {e}")
            except Exception as e:
                self._stage = self.STAGE_ERROR
                self.close()
                logging.warning(f"connection failed, {type(e)} e: {e}")
            else:
                self._remote = remote_tcp
                self._stage = self.STAGE_STREAM
                self._remote.write(self._connect_buffer)
                logging.debug(f"connection ok buffer lens:{len(self._connect_buffer)}")

        elif self._transport_protocol == flag.TRANSPORT_UDP:
            self._stage = self.STAGE_INIT
            udp_coro = loop.create_datagram_endpoint(
                lambda: RemoteUDP(dst_addr, dst_port, payload, self),
                remote_addr=(dst_addr, dst_port),
            )
            try:
                await udp_coro
            except (IOError, OSError) as e:
                self.close()
                self._stage = self.STAGE_DESTROY
                logging.debug(f"connection failed , {type(e)} e: {e}")
            except Exception as e:
                self._stage = self.STAGE_ERROR
                self.close()
                logging.warning(f"connection failed, {type(e)} e: {e}")
        else:
            raise NotImplementedError
Beispiel #4
0
    async def _handle_stage_init(self, data):
        atype, dst_addr, dst_port, header_length = parse_header(data)
        if not all([atype, dst_addr, dst_port, header_length]):
            logging.warning(
                f"parse_header_error atype={flag.get_atype_for_human(atype)} port={self.port}"
            )
            self.close()
            return
        else:
            logging.info(
                "parse_header_success flag={} atype={} from={} dst={}:{}".format(
                    self._transport_protocol,
                    flag.get_atype_for_human(atype),
                    f"{self._peername[0]}:{self._peername[1]}",
                    dst_addr,
                    dst_port,
                )
            )
            payload = data[header_length:]

        loop = asyncio.get_running_loop()
        if self._transport_protocol == flag.TRANSPORT_TCP:
            self._stage = self.STAGE_CONNECT
            self._handle_stage_connect(payload)
            try:
                task = loop.create_connection(
                    lambda: RemoteTCP(self), dst_addr, dst_port
                )
                _, remote_tcp = await asyncio.wait_for(task, 5)
            except Exception as e:
                self._stage = self.STAGE_ERROR
                self.close()
                logging.warning(
                    f"connection_failed, {type(e)} e: {dst_addr}:{dst_port}"
                )
            else:
                self._remote = remote_tcp
        else:
            try:
                task = loop.create_datagram_endpoint(
                    lambda: RemoteUDP(dst_addr, dst_port, payload, self),
                    remote_addr=(dst_addr, dst_port),
                )
                _, remote_udp = await asyncio.wait_for(task, 5)
            except Exception as e:
                self._stage = self.STAGE_ERROR
                logging.warning(
                    f"connection_failed, {type(e)} e: {dst_addr}:{dst_port}"
                )
                self.close()
            else:
                self._remote = remote_udp
                self._stage = self.STAGE_STREAM
Beispiel #5
0
    async def _handle_stage_init(self, data):
        self.cipher.incr_user_tcp_num(1)
        addr_type, dst_addr, dst_port, header_length = parse_header(data)
        if not all([addr_type, dst_addr, dst_port, header_length]):
            logging.warning(
                f"parse error addr_type: {addr_type} port: {self.port}")
            self.close()
            return
        else:
            payload = data[header_length:]
        logging.debug(
            f"HEADER: {addr_type} - {dst_addr} - {dst_port} - {self._transport_protocol}"
        )

        loop = asyncio.get_running_loop()
        if self._transport_protocol == flag.TRANSPORT_TCP:
            self._stage = self.STAGE_CONNECT
            self._handle_stage_connect(payload)
            try:
                _, remote_tcp = await loop.create_connection(
                    lambda: RemoteTCP(self), dst_addr, dst_port)
            except Exception as e:
                self._stage = self.STAGE_ERROR
                self.close()
                logging.warning(f"connection failed, {type(e)} e: {e}")
            else:
                self._remote = remote_tcp
                self.cipher.record_user_ip(self._peername)
        else:
            try:
                await loop.create_datagram_endpoint(
                    lambda: RemoteUDP(dst_addr, dst_port, payload, self),
                    remote_addr=(dst_addr, dst_port),
                )
            except Exception as e:
                self._stage = self.STAGE_ERROR
                self.close()
                logging.warning(f"connection failed, {type(e)} e: {e}")
Beispiel #6
0
 def _handle_stage_stream(self, data):
     if self._transport_protocol == flag.TRANSPORT_UDP:
         # NOTE 区分udp和tcp,tcp的可以直接转发,udp的需要去掉header
         _, _, _, header_length = parse_header(data)
         data = data[header_length:]
     self._remote.write(data)