Skip to content

Commit 44fc05c

Browse files
authored
Refactor socks5 udp handler
1 parent 663b539 commit 44fc05c

File tree

1 file changed

+54
-58
lines changed

1 file changed

+54
-58
lines changed

daze.go

Lines changed: 54 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ import (
2222
"net/url"
2323
"os"
2424
"path/filepath"
25+
"slices"
2526
"strconv"
2627
"strings"
2728
"sync"
@@ -280,15 +281,15 @@ func (l *Locale) ServeSocks4(ctx *Context, cli io.ReadWriteCloser) error {
280281
Closer: cli,
281282
}
282283
var (
283-
fCode uint8
284-
fDstPort = make([]byte, 2)
285-
fDstIP = make([]byte, 4)
286-
fHostName []byte
287284
dstHost string
288285
dstPort uint16
289286
dst string
290-
srv io.ReadWriteCloser
291287
err error
288+
fCode uint8
289+
fDstIP = make([]byte, 4)
290+
fDstPort = make([]byte, 2)
291+
fHostName []byte
292+
srv io.ReadWriteCloser
292293
)
293294
cliReader.Discard(1)
294295
fCode, err = cliReader.ReadByte()
@@ -344,15 +345,15 @@ func (l *Locale) ServeSocks5(ctx *Context, cli io.ReadWriteCloser) error {
344345
Closer: cli,
345346
}
346347
var (
347-
fN uint8
348-
fCmd uint8
349-
fAT uint8
350-
fDstAddr []byte
351-
fDstPort = make([]byte, 2)
352348
dstHost string
353349
dstPort uint16
354350
dst string
355351
err error
352+
fAT uint8
353+
fCmd uint8
354+
fDstAddr []byte
355+
fDstPort = make([]byte, 2)
356+
fN uint8
356357
)
357358
cliReader.Discard(1)
358359
fN = doa.Val(cliReader.ReadByte())
@@ -411,21 +412,20 @@ func (l *Locale) ServeSocks5TCP(ctx *Context, cli io.ReadWriteCloser, dst string
411412
// ServeSocks5UDP serves socks5 UDP protocol.
412413
func (l *Locale) ServeSocks5UDP(ctx *Context, cli io.ReadWriteCloser) error {
413414
var (
414-
bndAddr *net.UDPAddr
415-
bndPort uint16
416-
bnd *net.UDPConn
417415
appAddr *net.UDPAddr
418-
appSize int
419416
appHeadSize int
420417
appHead []byte
418+
appSize int
419+
bndAddr *net.UDPAddr
420+
bndPort uint16
421+
bnd *net.UDPConn
422+
buf = make([]byte, 2048)
423+
cpl = map[string]io.ReadWriteCloser{}
421424
dstHost string
422425
dstPort uint16
423426
dst string
424-
srv io.ReadWriteCloser
425-
b bool
426-
cpl = map[string]io.ReadWriteCloser{}
427-
buf = make([]byte, 2048)
428427
err error
428+
srv io.ReadWriteCloser
429429
)
430430
bndAddr = doa.Try(net.ResolveUDPAddr("udp", "127.0.0.1:0"))
431431
bnd = doa.Try(net.ListenUDP("udp", bndAddr))
@@ -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
}
@@ -1047,12 +1024,31 @@ type RandomReader struct{}
10471024

10481025
// Read implements io.Reader.
10491026
func (r *RandomReader) Read(p []byte) (int, error) {
1050-
for i := 0; i < len(p); i++ {
1027+
for i := range len(p) {
10511028
p[i] = byte(rand.Uint64())
10521029
}
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.
10571053
func Salt(s string) []byte {
10581054
h := sha256.Sum256([]byte(s))

0 commit comments

Comments
 (0)