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
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
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
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
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}")
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)