Feature: add ssr support (#805)
* Refactor ssr stream cipher to expose iv and key References: https://github.com/Dreamacro/go-shadowsocks2 https://github.com/sh4d0wfiend/go-shadowsocksr2 * Implement ssr obfs Reference: https://github.com/mzz2017/shadowsocksR * Implement ssr protocol References: https://github.com/mzz2017/shadowsocksR https://github.com/shadowsocksRb/shadowsocksr-libev https://github.com/shadowsocksr-backup/shadowsocksr
This commit is contained in:
75
component/ssr/obfs/random_head.go
Normal file
75
component/ssr/obfs/random_head.go
Normal file
@ -0,0 +1,75 @@
|
||||
package obfs
|
||||
|
||||
import (
|
||||
"encoding/binary"
|
||||
"hash/crc32"
|
||||
"math/rand"
|
||||
)
|
||||
|
||||
type randomHead struct {
|
||||
*Base
|
||||
firstRequest bool
|
||||
firstResponse bool
|
||||
headerSent bool
|
||||
buffer []byte
|
||||
}
|
||||
|
||||
func init() {
|
||||
register("random_head", newRandomHead)
|
||||
}
|
||||
|
||||
func newRandomHead(b *Base) Obfs {
|
||||
return &randomHead{Base: b}
|
||||
}
|
||||
|
||||
func (r *randomHead) initForConn() Obfs {
|
||||
return &randomHead{
|
||||
Base: r.Base,
|
||||
firstRequest: true,
|
||||
firstResponse: true,
|
||||
}
|
||||
}
|
||||
|
||||
func (r *randomHead) GetObfsOverhead() int {
|
||||
return 0
|
||||
}
|
||||
|
||||
func (r *randomHead) Encode(b []byte) (encoded []byte, err error) {
|
||||
if !r.firstRequest {
|
||||
return b, nil
|
||||
}
|
||||
|
||||
bSize := len(b)
|
||||
if r.headerSent {
|
||||
if bSize > 0 {
|
||||
d := make([]byte, len(r.buffer)+bSize)
|
||||
copy(d, r.buffer)
|
||||
copy(d[len(r.buffer):], b)
|
||||
r.buffer = d
|
||||
} else {
|
||||
encoded = r.buffer
|
||||
r.buffer = nil
|
||||
r.firstRequest = false
|
||||
}
|
||||
} else {
|
||||
size := rand.Intn(96) + 8
|
||||
encoded = make([]byte, size)
|
||||
rand.Read(encoded)
|
||||
crc := (0xFFFFFFFF - crc32.ChecksumIEEE(encoded[:size-4])) & 0xFFFFFFFF
|
||||
binary.LittleEndian.PutUint32(encoded[size-4:], crc)
|
||||
|
||||
d := make([]byte, bSize)
|
||||
copy(d, b)
|
||||
r.buffer = d
|
||||
}
|
||||
r.headerSent = true
|
||||
return encoded, nil
|
||||
}
|
||||
|
||||
func (r *randomHead) Decode(b []byte) ([]byte, bool, error) {
|
||||
if r.firstResponse {
|
||||
r.firstResponse = false
|
||||
return b, true, nil
|
||||
}
|
||||
return b, false, nil
|
||||
}
|
Reference in New Issue
Block a user