github.com/metacubex/mihomo@v1.18.5/transport/hysteria/conns/udp/obfs.go (about) 1 package udp 2 3 import ( 4 "github.com/metacubex/mihomo/transport/hysteria/obfs" 5 "net" 6 "sync" 7 "time" 8 ) 9 10 const udpBufferSize = 65535 11 12 type ObfsUDPConn struct { 13 orig net.PacketConn 14 obfs obfs.Obfuscator 15 readBuf []byte 16 readMutex sync.Mutex 17 writeBuf []byte 18 writeMutex sync.Mutex 19 } 20 21 func NewObfsUDPConn(orig net.PacketConn, obfs obfs.Obfuscator) *ObfsUDPConn { 22 return &ObfsUDPConn{ 23 orig: orig, 24 obfs: obfs, 25 readBuf: make([]byte, udpBufferSize), 26 writeBuf: make([]byte, udpBufferSize), 27 } 28 } 29 30 func (c *ObfsUDPConn) ReadFrom(p []byte) (int, net.Addr, error) { 31 for { 32 c.readMutex.Lock() 33 n, addr, err := c.orig.ReadFrom(c.readBuf) 34 if n <= 0 { 35 c.readMutex.Unlock() 36 return 0, addr, err 37 } 38 newN := c.obfs.Deobfuscate(c.readBuf[:n], p) 39 c.readMutex.Unlock() 40 if newN > 0 { 41 // Valid packet 42 return newN, addr, err 43 } else if err != nil { 44 // Not valid and orig.ReadFrom had some error 45 return 0, addr, err 46 } 47 } 48 } 49 50 func (c *ObfsUDPConn) WriteTo(p []byte, addr net.Addr) (n int, err error) { 51 c.writeMutex.Lock() 52 bn := c.obfs.Obfuscate(p, c.writeBuf) 53 _, err = c.orig.WriteTo(c.writeBuf[:bn], addr) 54 c.writeMutex.Unlock() 55 if err != nil { 56 return 0, err 57 } else { 58 return len(p), nil 59 } 60 } 61 62 func (c *ObfsUDPConn) Close() error { 63 return c.orig.Close() 64 } 65 66 func (c *ObfsUDPConn) LocalAddr() net.Addr { 67 return c.orig.LocalAddr() 68 } 69 70 func (c *ObfsUDPConn) SetDeadline(t time.Time) error { 71 return c.orig.SetDeadline(t) 72 } 73 74 func (c *ObfsUDPConn) SetReadDeadline(t time.Time) error { 75 return c.orig.SetReadDeadline(t) 76 } 77 78 func (c *ObfsUDPConn) SetWriteDeadline(t time.Time) error { 79 return c.orig.SetWriteDeadline(t) 80 }