@@ -22,6 +22,7 @@ import (
2222 "net/url"
2323 "os"
2424 "path/filepath"
25+ "slices"
2526 "strconv"
2627 "strings"
2728 "sync"
@@ -419,7 +420,6 @@ func (l *Locale) ServeSocks5UDP(ctx *Context, cli io.ReadWriteCloser) error {
419420 bndPort uint16
420421 bnd * net.UDPConn
421422 buf = make ([]byte , 2048 )
422- b bool
423423 cpl = map [string ]io.ReadWriteCloser {}
424424 dstHost string
425425 dstPort uint16
@@ -478,10 +478,7 @@ func (l *Locale) ServeSocks5UDP(ctx *Context, cli io.ReadWriteCloser) error {
478478 case 0x04 :
479479 appHeadSize = 22
480480 }
481-
482- appHead = make ([]byte , appHeadSize )
483- copy (appHead , buf [0 :appHeadSize ])
484-
481+ appHead = buf [0 :appHeadSize ]
485482 switch appHead [3 ] {
486483 case 0x01 :
487484 dstHost = net .IP (appHead [4 :8 ]).String ()
@@ -495,45 +492,25 @@ func (l *Locale) ServeSocks5UDP(ctx *Context, cli io.ReadWriteCloser) error {
495492 dstPort = binary .BigEndian .Uint16 (appHead [20 :22 ])
496493 }
497494 dst = dstHost + ":" + strconv .Itoa (int (dstPort ))
498-
499- srv , b = cpl [dst ]
500- if b {
501- goto send
502- } else {
503- goto init
504- }
505- init:
506- log .Printf ("conn: %08x proto format=socks5" , ctx .Cid )
507- srv , err = l .Dialer .Dial (ctx , "udp" , dst )
508- if err != nil {
509- log .Printf ("conn: %08x error %s" , ctx .Cid , err )
510- continue
511- }
512- cpl [dst ] = srv
513- go func (srv io.ReadWriteCloser , appHead []byte , appAddr * net.UDPAddr ) error {
514- var (
515- buf = make ([]byte , 2048 )
516- l = len (appHead )
517- n int
518- err error
519- )
520- copy (buf , appHead )
521- for {
522- n , err = srv .Read (buf [l :])
523- if err != nil {
524- break
525- }
526- _ , err = bnd .WriteToUDP (buf [:l + n ], appAddr )
527- if err != nil {
528- break
529- }
495+ srv = cpl [dst ]
496+ if srv == nil {
497+ log .Printf ("conn: %08x proto format=socks5" , ctx .Cid )
498+ srv , err = l .Dialer .Dial (ctx , "udp" , dst )
499+ if err != nil {
500+ log .Printf ("conn: %08x error %s" , ctx .Cid , err )
501+ continue
530502 }
531- return err
532- }(srv , appHead , appAddr )
533- send:
503+ cpl [dst ] = srv
504+ retHead := slices .Clone (appHead )
505+ go ReadCall (srv , func (data []byte ) error {
506+ return doa .Err (bnd .WriteToUDP (append (retHead , data ... ), appAddr ))
507+ })
508+ }
534509 _ , err = srv .Write (buf [appHeadSize :appSize ])
535510 if err != nil {
536511 log .Printf ("conn: %08x error %s" , ctx .Cid , err )
512+ srv .Close ()
513+ delete (cpl , dst )
537514 continue
538515 }
539516 }
@@ -1053,6 +1030,25 @@ func (r *RandomReader) Read(p []byte) (int, error) {
10531030 return len (p ), nil
10541031}
10551032
1033+ // ReadCall reads data from the given io.Reader and passes it to the provided call function.
1034+ func ReadCall (conn io.Reader , call func ([]byte ) error ) error {
1035+ var (
1036+ buf = make ([]byte , 2048 )
1037+ err error
1038+ n int
1039+ )
1040+ for {
1041+ n , err = conn .Read (buf )
1042+ if err != nil {
1043+ break
1044+ }
1045+ if err = call (buf [:n ]); err != nil {
1046+ break
1047+ }
1048+ }
1049+ return err
1050+ }
1051+
10561052// Salt converts the stupid password passed in by the user to 32-sized byte array.
10571053func Salt (s string ) []byte {
10581054 h := sha256 .Sum256 ([]byte (s ))
0 commit comments