-
Notifications
You must be signed in to change notification settings - Fork 45
/
splitter.go
66 lines (62 loc) · 1.8 KB
/
splitter.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
package internal
import (
"bytes"
"math/rand"
"time"
)
// SNISplitter splits input such that SNI is splitted across
// a bunch of different output buffers.
func SNISplitter(input []byte, sni []byte) (output [][]byte) {
idx := bytes.Index(input, sni)
if idx < 0 {
output = append(output, input)
return
}
output = append(output, input[:idx])
// TODO(bassosimone): splitting every three bytes causes
// a bunch of Unicode chatacters (e.g., in Chinese) to be
// sent as part of the same segment. Is that OK?
const segmentsize = 3
var buf []byte
for _, chr := range input[idx : idx+len(sni)] {
buf = append(buf, chr)
if len(buf) == segmentsize {
output = append(output, buf)
buf = nil
}
}
if len(buf) > 0 {
output = append(output, buf)
}
output = append(output, input[idx+len(sni):])
return
}
// Splitter84rest segments the specified buffer into three
// sub-buffers containing respectively 8 bytes, 4 bytes, and
// the rest of the buffer. This segment technique has been
// described by Kevin Bock during the Internet Measurements
// Village 2020: https://youtu.be/ksojSRFLbBM?t=1140.
func Splitter84rest(input []byte) (output [][]byte) {
if len(input) <= 12 {
output = append(output, input)
return
}
output = append(output, input[:8])
output = append(output, input[8:12])
output = append(output, input[12:])
return
}
// Splitter3264rand splits the specified buffer at a random
// offset between 32 and 64 bytes. This is the methodology used
// by github.com/Jigsaw-Code/outline-go-tun2socks.
func Splitter3264rand(input []byte) (output [][]byte) {
if len(input) <= 64 {
output = append(output, input)
return
}
rnd := rand.New(rand.NewSource(time.Now().UnixNano()))
offset := rnd.Intn(32) + 32
output = append(output, input[:offset])
output = append(output, input[offset:])
return
}