@@ -326,7 +326,7 @@ def close():
326326except Exception :
327327pass
328328writer .close = close
329- async def wait_open_connection (self , * args ):
329+ async def wait_quic_connection (self ):
330330if self .handshake is not None :
331331if not self .handshake .done ():
332332await self .handshake
@@ -340,27 +340,53 @@ def quic_event_received(s, event):
340340elif isinstance (event , aioquic .quic .events .ConnectionTerminated ):
341341self .handshake = None
342342self .quic_egress_acm = None
343+ elif isinstance (event , aioquic .quic .events .StreamDataReceived ):
344+ if event .stream_id in self .udpmap :
345+ self .udpmap [event .stream_id ](self .udp_packet_unpack (event .data ))
346+ return
343347super ().quic_event_received (event )
344348self .quic_egress_acm = aioquic .asyncio .connect (self .host_name , self .port , create_protocol = Protocol , configuration = self .quicclient )
345349conn = await self .quic_egress_acm .__aenter__ ()
346350await self .handshake
351+ async def udp_open_connection (self , host , port , data , addr , reply ):
352+ await self .wait_quic_connection ()
353+ conn = self .handshake .result ()
354+ if addr in self .udpmap :
355+ stream_id = self .udpmap [addr ]
356+ else :
357+ stream_id = conn ._quic .get_next_available_stream_id (False )
358+ self .udpmap [addr ] = stream_id
359+ self .udpmap [stream_id ] = reply
360+ conn ._quic ._get_or_create_stream_for_send (stream_id )
361+ conn ._quic .send_stream_data (stream_id , data , False )
362+ conn .transmit ()
363+ async def wait_open_connection (self , * args ):
364+ await self .wait_quic_connection ()
347365conn = self .handshake .result ()
348366stream_id = conn ._quic .get_next_available_stream_id (False )
349367conn ._quic ._get_or_create_stream_for_send (stream_id )
350368reader , writer = conn ._create_stream (stream_id )
351369self .patch_writer (writer )
352370return reader , writer
371+ async def udp_start_server (self , args ):
372+ import aioquic .asyncio , aioquic .quic .events
373+ class Protocol (aioquic .asyncio .QuicConnectionProtocol ):
374+ def quic_event_received (s , event ):
375+ if isinstance (event , aioquic .quic .events .StreamDataReceived ):
376+ stream_id = event .stream_id
377+ addr = ('quic ' + self .bind , stream_id )
378+ event .sendto = lambda data , addr : (s ._quic .send_stream_data (stream_id , data , False ), s .transmit ())
379+ event .get_extra_info = {}.get
380+ asyncio .ensure_future (datagram_handler (event , event .data , addr , ** vars (self ), ** args ))
381+ return
382+ super ().quic_event_received (event )
383+ return await aioquic .asyncio .serve (self .host_name , self .port , configuration = self .quicserver , create_protocol = Protocol ), None
353384def start_server (self , args , stream_handler = stream_handler ):
354385import aioquic .asyncio
355386def handler (reader , writer ):
356387self .patch_writer (writer )
357388asyncio .ensure_future (stream_handler (reader , writer , ** vars (self ), ** args ))
358- return aioquic .asyncio .serve (
359- self .host_name ,
360- self .port ,
361- configuration = self .quicserver ,
362- stream_handler = handler
363- )
389+ return aioquic .asyncio .serve (self .host_name , self .port , configuration = self .quicserver , stream_handler = handler )
364390
365391class ProxySSH (ProxySimple ):
366392def __init__ (self , ** kw ):
@@ -654,19 +680,19 @@ def main():
654680if option .sslclient :
655681option .sslclient .load_cert_chain (* sslfile )
656682option .sslserver .load_cert_chain (* sslfile )
657- for option in args .listen + args .rserver :
683+ for option in args .listen + args .ulisten + args . rserver + args . urserver :
658684if isinstance (option , ProxyQUIC ):
659685option .quicserver .load_cert_chain (* sslfile )
660686if isinstance (option , ProxyBackward ) and isinstance (option .backward , ProxyQUIC ):
661687option .backward .quicserver .load_cert_chain (* sslfile )
662- elif any (map (lambda o : o .sslclient or isinstance (o , ProxyQUIC ), args .listen )):
688+ elif any (map (lambda o : o .sslclient or isinstance (o , ProxyQUIC ), args .listen + args . ulisten )):
663689print ('You must specify --ssl to listen in ssl mode' )
664690return
665691if args .test :
666692asyncio .get_event_loop ().run_until_complete (test_url (args .test , args .rserver ))
667693return
668694if not args .listen and not args .ulisten :
669- args .listen .append (proxy_by_uri ('http+socks4+socks5://:8080/' ))
695+ args .listen .append (proxies_by_uri ('http+socks4+socks5://:8080/' ))
670696args .httpget = {}
671697if args .pac :
672698pactext = 'function FindProxyForURL(u,h){' + (f'var b=/^(:?{ args .block .__self__ .pattern } )$/i;if(b.test(h))return ""' if args .block else '' )
0 commit comments