github.com/metacubex/mihomo@v1.18.5/transport/hysteria/conns/wechat/obfs.go (about) 1 package wechat 2 3 import ( 4 "encoding/binary" 5 "net" 6 "sync" 7 "time" 8 9 "github.com/metacubex/mihomo/log" 10 "github.com/metacubex/mihomo/transport/hysteria/obfs" 11 12 "github.com/zhangyunhao116/fastrand" 13 ) 14 15 const udpBufferSize = 65535 16 17 type ObfsWeChatUDPConn struct { 18 orig net.PacketConn 19 obfs obfs.Obfuscator 20 readBuf []byte 21 readMutex sync.Mutex 22 writeBuf []byte 23 writeMutex sync.Mutex 24 sn uint32 25 } 26 27 func NewObfsWeChatUDPConn(orig net.PacketConn, obfs obfs.Obfuscator) *ObfsWeChatUDPConn { 28 log.Infoln("new wechat") 29 return &ObfsWeChatUDPConn{ 30 orig: orig, 31 obfs: obfs, 32 readBuf: make([]byte, udpBufferSize), 33 writeBuf: make([]byte, udpBufferSize), 34 sn: fastrand.Uint32() & 0xFFFF, 35 } 36 } 37 38 func (c *ObfsWeChatUDPConn) ReadFrom(p []byte) (int, net.Addr, error) { 39 for { 40 c.readMutex.Lock() 41 n, addr, err := c.orig.ReadFrom(c.readBuf) 42 if n <= 13 { 43 c.readMutex.Unlock() 44 return 0, addr, err 45 } 46 newN := c.obfs.Deobfuscate(c.readBuf[13:n], p) 47 c.readMutex.Unlock() 48 if newN > 0 { 49 // Valid packet 50 return newN, addr, err 51 } else if err != nil { 52 // Not valid and orig.ReadFrom had some error 53 return 0, addr, err 54 } 55 } 56 } 57 58 func (c *ObfsWeChatUDPConn) WriteTo(p []byte, addr net.Addr) (n int, err error) { 59 c.writeMutex.Lock() 60 c.writeBuf[0] = 0xa1 61 c.writeBuf[1] = 0x08 62 binary.BigEndian.PutUint32(c.writeBuf[2:], c.sn) 63 c.sn++ 64 c.writeBuf[6] = 0x00 65 c.writeBuf[7] = 0x10 66 c.writeBuf[8] = 0x11 67 c.writeBuf[9] = 0x18 68 c.writeBuf[10] = 0x30 69 c.writeBuf[11] = 0x22 70 c.writeBuf[12] = 0x30 71 bn := c.obfs.Obfuscate(p, c.writeBuf[13:]) 72 _, err = c.orig.WriteTo(c.writeBuf[:13+bn], addr) 73 c.writeMutex.Unlock() 74 if err != nil { 75 return 0, err 76 } else { 77 return len(p), nil 78 } 79 } 80 81 func (c *ObfsWeChatUDPConn) Close() error { 82 return c.orig.Close() 83 } 84 85 func (c *ObfsWeChatUDPConn) LocalAddr() net.Addr { 86 return c.orig.LocalAddr() 87 } 88 89 func (c *ObfsWeChatUDPConn) SetDeadline(t time.Time) error { 90 return c.orig.SetDeadline(t) 91 } 92 93 func (c *ObfsWeChatUDPConn) SetReadDeadline(t time.Time) error { 94 return c.orig.SetReadDeadline(t) 95 } 96 97 func (c *ObfsWeChatUDPConn) SetWriteDeadline(t time.Time) error { 98 return c.orig.SetWriteDeadline(t) 99 }