github.com/Asutorufa/yuhaiin@v0.3.6-0.20240502055049-7984da7023a0/pkg/net/proxy/shadowsocksr/obfs/random_head.go (about) 1 package obfs 2 3 import ( 4 crand "crypto/rand" 5 "math/rand/v2" 6 "net" 7 8 ssr "github.com/Asutorufa/yuhaiin/pkg/net/proxy/shadowsocksr/utils" 9 "github.com/Asutorufa/yuhaiin/pkg/utils/pool" 10 ) 11 12 type randomHead struct { 13 rawTransSent bool 14 rawTransReceived bool 15 hasSentHeader bool 16 dataBuffer []byte 17 18 net.Conn 19 } 20 21 func newRandomHead(conn net.Conn, _ Obfs) net.Conn { return &randomHead{Conn: conn} } 22 23 func (r *randomHead) encode(data []byte) (encodedData []byte) { 24 if r.rawTransSent { 25 return data 26 } 27 28 if r.hasSentHeader { 29 if len(data) > 0 { 30 r.dataBuffer = append(r.dataBuffer, data...) 31 } else { 32 encodedData = r.dataBuffer 33 r.dataBuffer = nil 34 r.rawTransSent = true 35 } 36 37 return 38 } 39 40 size := rand.IntN(96) + 8 41 encodedData = make([]byte, size) 42 _, _ = crand.Read(encodedData) 43 ssr.SetCRC32(encodedData, size) 44 r.dataBuffer = append(r.dataBuffer, data...) 45 r.hasSentHeader = true 46 return 47 } 48 49 func (r *randomHead) Write(b []byte) (int, error) { 50 if r.rawTransSent { 51 return r.Conn.Write(b) 52 } 53 54 _, err := r.Conn.Write(r.encode(b)) 55 return len(b), err 56 } 57 58 func (r *randomHead) Read(b []byte) (n int, err error) { 59 if r.rawTransReceived { 60 return r.Conn.Read(b) 61 } 62 63 buf := pool.GetBytes(pool.DefaultSize) 64 defer pool.PutBytes(buf) 65 r.Conn.Read(buf) 66 r.rawTransReceived = true 67 r.Conn.Write(nil) 68 return 0, nil 69 } 70 71 func (r *randomHead) GetOverhead() int { return 0 }