@@ -57,7 +57,7 @@ async def channel(self, reader, writer, stat_bytes, stat_conn):
5757 try :
5858 stat_conn (1 )
5959 while True :
60- data = await reader .read_ ( )
60+ data = await reader .read ( 65536 )
6161 if not data :
6262 break
6363 if stat_bytes is None :
@@ -327,7 +327,7 @@ async def http_channel(self, reader, writer, stat_bytes, stat_conn):
327327 try :
328328 stat_conn (1 )
329329 while True :
330- data = await reader .read_ ( )
330+ data = await reader .read ( 65536 )
331331 if not data :
332332 break
333333 if b'\r \n ' in data and HTTP_LINE .match (data .split (b'\r \n ' , 1 )[0 ].decode ()):
@@ -513,85 +513,6 @@ class Echo(Transparent):
513513 def query_remote (self , sock ):
514514 return 'echo' , 0
515515
516- class Pack (BaseProtocol ):
517- def reuse (self ):
518- return True
519- def get_handler (self , reader , writer , verbose , tcp_handler = None , udp_handler = None ):
520- class Handler :
521- def __init__ (self ):
522- self .sessions = {}
523- self .udpmap = {}
524- self .closed = False
525- self .ready = False
526- asyncio .ensure_future (self .reader_handler ())
527- def __bool__ (self ):
528- return not self .closed
529- async def reader_handler (self ):
530- try :
531- while True :
532- try :
533- header = (await reader .readexactly (1 ))[0 ]
534- except Exception :
535- raise Exception ('Connection closed' )
536- sid = await reader .read_n (8 )
537- if header in (0x01 , 0x03 , 0x04 , 0x11 , 0x13 , 0x14 ):
538- host_name , port , _ = await socks_address_stream (reader , header )
539- if (header & 0x10 == 0 ) and tcp_handler :
540- remote_reader , remote_writer = self .get_streams (sid )
541- asyncio .ensure_future (tcp_handler (remote_reader , remote_writer , host_name , port ))
542- elif (header & 0x10 != 0 ) and udp_handler :
543- self .get_datagram (sid , host_name , port )
544- elif header in (0x20 , 0x30 ):
545- datalen = int .from_bytes (await reader .read_n (2 ), 'big' )
546- data = await reader .read_n (datalen )
547- if header == 0x20 and sid in self .sessions :
548- self .sessions [sid ].feed_data (data )
549- elif header == 0x30 and sid in self .udpmap and udp_handler :
550- host_name , port , sendto = self .udpmap [sid ]
551- asyncio .ensure_future (udp_handler (sendto , data , host_name , port , sid ))
552- elif header == 0x40 :
553- if sid in self .sessions :
554- self .sessions .pop (sid ).feed_eof ()
555- else :
556- raise Exception (f'Unknown header { header } ' )
557- except Exception as ex :
558- if not isinstance (ex , asyncio .TimeoutError ) and not str (ex ).startswith ('Connection closed' ):
559- verbose (f'{ str (ex ) or "Unsupported protocol" } ' )
560- finally :
561- for sid , session in self .sessions .items ():
562- session .feed_eof ()
563- try : writer .close ()
564- except Exception : pass
565- self .closed = True
566- def get_streams (self , sid ):
567- self .sessions [sid ] = asyncio .StreamReader ()
568- class Writer ():
569- def write (self , data ):
570- while len (data ) >= 32 * 1024 :
571- writer .write (b'\x20 ' + sid + (32 * 1024 ).to_bytes (2 ,'big' )+ data [:32 * 1024 ])
572- data = data [32 * 1024 :]
573- if data :
574- writer .write (b'\x20 ' + sid + len (data ).to_bytes (2 ,'big' )+ data )
575- def drain (self ):
576- return writer .drain ()
577- def close (self ):
578- if not writer .transport .is_closing ():
579- writer .write (b'\x40 ' + sid )
580- return self .sessions [sid ], Writer ()
581- def connect (self , host_name , port ):
582- self .ready = True
583- sid = os .urandom (8 )
584- writer .write (b'\x03 ' + sid + packstr (host_name .encode ()) + port .to_bytes (2 , 'big' ))
585- return self .get_streams (sid )
586- def get_datagram (self , sid , host_name , port ):
587- def sendto (data ):
588- if data :
589- writer .write (b'\x30 ' + sid + len (data ).to_bytes (2 ,'big' )+ data )
590- self .udpmap [sid ] = (host_name , port , sendto )
591- return self .udpmap [sid ]
592- writer .get_extra_info ('socket' ).setsockopt (socket .SOL_SOCKET , socket .SO_KEEPALIVE , 1 )
593- return Handler ()
594-
595516async def accept (protos , reader , ** kw ):
596517 for proto in protos :
597518 try :
@@ -612,7 +533,7 @@ def udp_accept(protos, data, **kw):
612533 return (proto ,) + ret
613534 raise Exception (f'Unsupported protocol { data [:10 ]} ' )
614535
615- MAPPINGS = dict (direct = Direct , http = HTTP , httponly = HTTPOnly , ssh = SSH , socks5 = Socks5 , socks4 = Socks4 , socks = Socks5 , ss = SS , ssr = SSR , redir = Redir , pf = Pf , tunnel = Tunnel , echo = Echo , pack = Pack , ws = WS , trojan = Trojan , ssl = '' , secure = '' )
536+ MAPPINGS = dict (direct = Direct , http = HTTP , httponly = HTTPOnly , ssh = SSH , socks5 = Socks5 , socks4 = Socks4 , socks = Socks5 , ss = SS , ssr = SSR , redir = Redir , pf = Pf , tunnel = Tunnel , echo = Echo , ws = WS , trojan = Trojan , ssl = '' , secure = '' , quic = '' )
616537MAPPINGS ['in' ] = ''
617538
618539def get_protos (rawprotos ):
@@ -662,7 +583,7 @@ def abort(self):
662583 async def channel ():
663584 try :
664585 while True :
665- data = await reader .read_ ( )
586+ data = await reader .read ( 65536 )
666587 if not data :
667588 break
668589 ssl .data_received (data )
0 commit comments