Преглед изворни кода

Merge remote-tracking branch 'origin/master' into stable

tags/v1.0.4
9seconds пре 6 година
родитељ
комит
8ccf61c23e

+ 5
- 2
README.md Прегледај датотеку

@@ -194,11 +194,14 @@ supported environment variables:
194 194
 | `MTG_STATSD_PREFIX`           | `--statsd-prefix`            | `mtg`                             | Which bucket prefix we should use. For example, if you set `mtg`, then metric `traffic.ingress` would be send as `mtg.traffic.ingress`.                                                                                                                                         |
195 195
 | `MTG_STATSD_TAGS_FORMAT`      | `--statsd-tags-format`       |                                   | Which tags format we should use. By default, we are using default vanilla statsd tags format but if you want to send directly to InfluxDB or Datadog, please specify it there. Possible options are `influxdb` and `datadog`.                                                   |
196 196
 | `MTG_STATSD_TAGS`             | `--statsd-tags`              |                                   | Which tags should we send to statsd with our metrics. Please specify them as `key=value` pairs.                                                                                                                                                                                 |
197
-| `MTG_BUFFER_WRITE`            | `-w`, `--write-buffer`       | `64KB`                           | The size of TCP write buffer in bytes. Write buffer is the buffer for messages which are going from client to Telegram.                                                                                                                                                         |
198
-| `MTG_BUFFER_READ`             | `-r`, `--read-buffer`        | `128KB`                          | The size of TCP read buffer in bytes. Read buffer is the buffer for messages from Telegram to client.                                                                                                                                                                           |
197
+| `MTG_BUFFER_WRITE`            | `-w`, `--write-buffer`       | `32KB`                            | The size of TCP write buffer in bytes. Write buffer is the buffer for messages which are going from client to Telegram.                                                                                                                                                         |
198
+| `MTG_BUFFER_READ`             | `-r`, `--read-buffer`        | `32KB`                            | The size of TCP read buffer in bytes. Read buffer is the buffer for messages from Telegram to client.                                                                                                                                                                           |
199 199
 | `MTG_ANTIREPLAY_MAXSIZE`      | `--anti-replay-max-size`     | `128MB`                           | Max size of antireplay cache.                                                                                                                                                                                                                                                   |
200 200
 | `MTG_CLOAK_PORT`              | `--cloak-port`               | `443`                             | Which port we should use to connect to cloaked host in FakeTLS mode.                                                                                                                                                                                                            |
201 201
 | `MTG_MULTIPLEX_PERCONNECTION` | `--multiplex-per-connection` | `50`                              | How many client connections can share a single Telegram connection in adtag mode                                                                                                                                                                                                |
202
+| `MTG_NTP_SERVERS`             | `--ntp-server`               | default pool                      | A list of NTP servers to use.                                                                                                                                                                                                                                                   |
203
+| `MTG_PREFER_DIRECT_IP`        | `--prefer-ip`                | `ipv6`                            | Which IP protocol to prefer if possible. Works mostly in direct mode.                                                                                                                                                                                                           |
204
+
202 205
 
203 206
 Usually you want to modify only read/write buffer sizes. If you feel
204 207
 that proxy is slow, try to increase both sizes giving more priority to

+ 6
- 1
faketls/client_protocol.go Прегледај датотеку

@@ -63,7 +63,12 @@ func (c *ClientProtocol) tlsHandshake(conn io.ReadWriter) error {
63 63
 		return fmt.Errorf("cannot read initial record: %w", err)
64 64
 	}
65 65
 
66
-	clientHello, err := tlstypes.ParseClientHello(helloRecord.Data.Bytes())
66
+	buf := acquireBytesBuffer()
67
+	defer releaseBytesBuffer(buf)
68
+
69
+	helloRecord.Data.WriteBytes(buf)
70
+
71
+	clientHello, err := tlstypes.ParseClientHello(buf.Bytes())
67 72
 	if err != nil {
68 73
 		return fmt.Errorf("cannot parse client hello: %w", err)
69 74
 	}

+ 11
- 8
faketls/cloak.go Прегледај датотеку

@@ -28,15 +28,9 @@ func cloak(one, another io.ReadWriteCloser) {
28 28
 
29 29
 	wg.Add(2)
30 30
 
31
-	go func() {
32
-		defer wg.Done()
33
-		io.Copy(one, another) // nolint: errcheck
34
-	}()
31
+	go cloakPipe(one, another, wg)
35 32
 
36
-	go func() {
37
-		defer wg.Done()
38
-		io.Copy(another, one) // nolint: errcheck
39
-	}()
33
+	go cloakPipe(another, one, wg)
40 34
 
41 35
 	go func() {
42 36
 		wg.Wait()
@@ -69,3 +63,12 @@ func cloak(one, another io.ReadWriteCloser) {
69 63
 
70 64
 	<-ctx.Done()
71 65
 }
66
+
67
+func cloakPipe(one io.Writer, another io.Reader, wg *sync.WaitGroup) {
68
+	defer wg.Done()
69
+
70
+	buf := acquireCloakBuffer()
71
+	defer releaseCloakBuffer(buf)
72
+
73
+	io.CopyBuffer(one, another, *buf) // nolint: errcheck
74
+}

+ 39
- 0
faketls/pools.go Прегледај датотеку

@@ -0,0 +1,39 @@
1
+package faketls
2
+
3
+import (
4
+	"bytes"
5
+	"sync"
6
+)
7
+
8
+const cloakBufferSize = 1024
9
+
10
+var (
11
+	poolBytesBuffer = sync.Pool{
12
+		New: func() interface{} {
13
+			return &bytes.Buffer{}
14
+		},
15
+	}
16
+	poolCloakBuffer = sync.Pool{
17
+		New: func() interface{} {
18
+			rv := make([]byte, cloakBufferSize)
19
+			return &rv
20
+		},
21
+	}
22
+)
23
+
24
+func acquireBytesBuffer() *bytes.Buffer {
25
+	return poolBytesBuffer.Get().(*bytes.Buffer)
26
+}
27
+
28
+func acquireCloakBuffer() *[]byte {
29
+	return poolCloakBuffer.Get().(*[]byte)
30
+}
31
+
32
+func releaseBytesBuffer(buf *bytes.Buffer) {
33
+	buf.Reset()
34
+	poolBytesBuffer.Put(buf)
35
+}
36
+
37
+func releaseCloakBuffer(buf *[]byte) {
38
+	poolCloakBuffer.Put(buf)
39
+}

+ 3
- 3
go.mod Прегледај датотеку

@@ -11,10 +11,10 @@ require (
11 11
 	github.com/prometheus/procfs v0.0.11 // indirect
12 12
 	github.com/smira/go-statsd v1.3.1
13 13
 	go.uber.org/zap v1.14.1
14
-	golang.org/x/crypto v0.0.0-20200317142112-1b76d66859c6
14
+	golang.org/x/crypto v0.0.0-20200323165209-0ec3e9974c59
15 15
 	golang.org/x/lint v0.0.0-20200302205851-738671d3881b // indirect
16
-	golang.org/x/net v0.0.0-20200319234117-63522dbf7eec // indirect
17
-	golang.org/x/sys v0.0.0-20200317113312-5766fd39f98d
16
+	golang.org/x/net v0.0.0-20200324143707-d3edc9973b7e // indirect
17
+	golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd
18 18
 	golang.org/x/tools v0.0.0-20200319210407-521f4a0cd458 // indirect
19 19
 	gopkg.in/alecthomas/kingpin.v2 v2.2.6
20 20
 	honnef.co/go/tools v0.0.1-2020.1.3 // indirect

+ 6
- 6
go.sum Прегледај датотеку

@@ -123,8 +123,8 @@ golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2 h1:VklqNMn3ovrHsnt90Pveol
123 123
 golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
124 124
 golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
125 125
 golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
126
-golang.org/x/crypto v0.0.0-20200317142112-1b76d66859c6 h1:TjszyFsQsyZNHwdVdZ5m7bjmreu0znc2kRYsEml9/Ww=
127
-golang.org/x/crypto v0.0.0-20200317142112-1b76d66859c6/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
126
+golang.org/x/crypto v0.0.0-20200323165209-0ec3e9974c59 h1:3zb4D3T4G8jdExgVU/95+vQXfpEPiMdCaZgmGVxjNHM=
127
+golang.org/x/crypto v0.0.0-20200323165209-0ec3e9974c59/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
128 128
 golang.org/x/lint v0.0.0-20190930215403-16217165b5de h1:5hukYrvBGR8/eNkX5mdUezrA6JiaEZDtJb9Ei+1LlBs=
129 129
 golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
130 130
 golang.org/x/lint v0.0.0-20200302205851-738671d3881b h1:Wh+f8QHJXR411sJR8/vRBTZ7YapZaRvUcLFFJhusH0k=
@@ -140,8 +140,8 @@ golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn
140 140
 golang.org/x/net v0.0.0-20190613194153-d28f0bde5980/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
141 141
 golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
142 142
 golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
143
-golang.org/x/net v0.0.0-20200319234117-63522dbf7eec h1:w0SItUiQ4sBiXBAwWNkyu8Fu2Qpn/dtDIcoPkPDqjRw=
144
-golang.org/x/net v0.0.0-20200319234117-63522dbf7eec/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
143
+golang.org/x/net v0.0.0-20200324143707-d3edc9973b7e h1:3G+cUijn7XD+S4eJFddp53Pv7+slrESplyjG25HgL+k=
144
+golang.org/x/net v0.0.0-20200324143707-d3edc9973b7e/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
145 145
 golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
146 146
 golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4 h1:YUO/7uOKsKeq9UokNS62b8FYywz3ker1l1vDZRCRefw=
147 147
 golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
@@ -154,8 +154,8 @@ golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7w
154 154
 golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
155 155
 golang.org/x/sys v0.0.0-20200106162015-b016eb3dc98e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
156 156
 golang.org/x/sys v0.0.0-20200122134326-e047566fdf82/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
157
-golang.org/x/sys v0.0.0-20200317113312-5766fd39f98d h1:62ap6LNOjDU6uGmKXHJbSfciMoV+FeI1sRXx/pLDL44=
158
-golang.org/x/sys v0.0.0-20200317113312-5766fd39f98d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
157
+golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd h1:xhmwyvizuTgC2qz7ZlMluP20uW+C3Rm0FD/WLDX8884=
158
+golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
159 159
 golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
160 160
 golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
161 161
 golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=

+ 2
- 2
main.go Прегледај датотеку

@@ -92,13 +92,13 @@ var (
92 92
 		"Write buffer size. You can think about it as a buffer from client to Telegram.").
93 93
 		Short('w').
94 94
 		Envar("MTG_BUFFER_WRITE").
95
-		Default("64KB").
95
+		Default("32KB").
96 96
 		Bytes()
97 97
 	runReadBufferSize = runCommand.Flag("read-buffer",
98 98
 		"Read buffer size. You can think about it as a buffer from Telegram to client.").
99 99
 		Short('r').
100 100
 		Envar("MTG_BUFFER_READ").
101
-		Default("128KB").
101
+		Default("32KB").
102 102
 		Bytes()
103 103
 	runTLSCloakPort = runCommand.Flag("cloak-port",
104 104
 		"Port which should be used for host cloaking.").

+ 4
- 3
proxy/direct.go Прегледај датотеку

@@ -11,7 +11,7 @@ import (
11 11
 	"github.com/9seconds/mtg/protocol"
12 12
 )
13 13
 
14
-const directPipeBufferSize = 1024 * 1024
14
+const directPipeBufferSize = 1024
15 15
 
16 16
 func directConnection(request *protocol.TelegramRequest) error {
17 17
 	telegramConnRaw, err := obfuscated2.TelegramProtocol(request)
@@ -42,8 +42,9 @@ func directPipe(dst io.WriteCloser, src io.ReadCloser, wg *sync.WaitGroup, logge
42 42
 		wg.Done()
43 43
 	}()
44 44
 
45
-	buf := make([]byte, directPipeBufferSize)
46
-	if _, err := io.CopyBuffer(dst, src, buf); err != nil {
45
+	buf := [directPipeBufferSize]byte{}
46
+
47
+	if _, err := io.CopyBuffer(dst, src, buf[:]); err != nil {
47 48
 		logger.Debugw("Cannot pump sockets", "error", err)
48 49
 	}
49 50
 }

+ 1
- 1
tlstypes/client_hello.go Прегледај датотеку

@@ -25,7 +25,7 @@ func (c ClientHello) Digest() []byte {
25 25
 	}
26 26
 
27 27
 	mac := hmac.New(sha256.New, config.C.Secret)
28
-	mac.Write(rec.Bytes()) // nolint: errcheck
28
+	rec.WriteBytes(mac)
29 29
 	computedDigest := mac.Sum(nil)
30 30
 
31 31
 	for i := range computedDigest {

+ 10
- 3
tlstypes/consts.go Прегледај датотеку

@@ -1,5 +1,7 @@
1 1
 package tlstypes
2 2
 
3
+import "io"
4
+
3 5
 type RecordType uint8
4 6
 
5 7
 const (
@@ -69,11 +71,16 @@ var (
69 71
 )
70 72
 
71 73
 type Byter interface {
72
-	Bytes() []byte
74
+	WriteBytes(io.Writer)
75
+	Len() int
73 76
 }
74 77
 
75 78
 type RawBytes []byte
76 79
 
77
-func (r RawBytes) Bytes() []byte {
78
-	return []byte(r)
80
+func (r RawBytes) WriteBytes(writer io.Writer) {
81
+	writer.Write(r) // nolint: errcheck
82
+}
83
+
84
+func (r RawBytes) Len() int {
85
+	return len(r)
79 86
 }

+ 16
- 9
tlstypes/handshake.go Прегледај датотеку

@@ -1,7 +1,7 @@
1 1
 package tlstypes
2 2
 
3 3
 import (
4
-	"bytes"
4
+	"io"
5 5
 
6 6
 	"github.com/9seconds/mtg/utils"
7 7
 )
@@ -14,24 +14,31 @@ type Handshake struct {
14 14
 	Tail      Byter
15 15
 }
16 16
 
17
-func (h *Handshake) Bytes() []byte {
18
-	buf := bytes.Buffer{}
19
-	packetBuf := bytes.Buffer{}
17
+func (h *Handshake) WriteBytes(writer io.Writer) {
18
+	packetBuf := acquireBytesBuffer()
19
+	defer releaseBytesBuffer(packetBuf)
20 20
 
21
-	buf.WriteByte(byte(h.Type))
21
+	writer.Write([]byte{byte(h.Type)}) // nolint: errcheck
22 22
 
23 23
 	packetBuf.Write(h.Version.Bytes())
24 24
 	packetBuf.Write(h.Random[:])
25 25
 	packetBuf.WriteByte(byte(len(h.SessionID)))
26 26
 	packetBuf.Write(h.SessionID)
27
-	packetBuf.Write(h.Tail.Bytes())
27
+	h.Tail.WriteBytes(packetBuf)
28 28
 
29 29
 	sizeUint24 := utils.ToUint24(uint32(packetBuf.Len()))
30 30
 	sizeUint24Bytes := sizeUint24[:]
31 31
 	sizeUint24Bytes[0], sizeUint24Bytes[2] = sizeUint24Bytes[2], sizeUint24Bytes[0]
32 32
 
33
-	buf.Write(sizeUint24Bytes)
34
-	packetBuf.WriteTo(&buf) // nolint: errcheck
33
+	writer.Write(sizeUint24Bytes) // nolint: errcheck
34
+	packetBuf.WriteTo(writer)     // nolint: errcheck
35
+}
36
+
37
+func (h *Handshake) Len() int {
38
+	buf := acquireBytesBuffer()
39
+	defer releaseBytesBuffer(buf)
40
+
41
+	h.WriteBytes(buf)
35 42
 
36
-	return buf.Bytes()
43
+	return buf.Len()
37 44
 }

+ 23
- 0
tlstypes/pools.go Прегледај датотеку

@@ -0,0 +1,23 @@
1
+package tlstypes
2
+
3
+import (
4
+	"bytes"
5
+	"sync"
6
+)
7
+
8
+var (
9
+	poolBytesBuffer = sync.Pool{
10
+		New: func() interface{} {
11
+			return &bytes.Buffer{}
12
+		},
13
+	}
14
+)
15
+
16
+func acquireBytesBuffer() *bytes.Buffer {
17
+	return poolBytesBuffer.Get().(*bytes.Buffer)
18
+}
19
+
20
+func releaseBytesBuffer(buf *bytes.Buffer) {
21
+	buf.Reset()
22
+	poolBytesBuffer.Put(buf)
23
+}

+ 8
- 9
tlstypes/record.go Прегледај датотеку

@@ -15,16 +15,15 @@ type Record struct {
15 15
 	Data    Byter
16 16
 }
17 17
 
18
-func (r Record) Bytes() []byte {
19
-	buf := bytes.Buffer{}
20
-	data := r.Data.Bytes()
21
-
22
-	buf.WriteByte(byte(r.Type))
23
-	buf.Write(r.Version.Bytes())
24
-	binary.Write(&buf, binary.BigEndian, uint16(len(data))) // nolint: errcheck
25
-	buf.Write(data)
18
+func (r Record) WriteBytes(writer io.Writer) {
19
+	writer.Write([]byte{byte(r.Type)})                           // nolint: errcheck
20
+	writer.Write(r.Version.Bytes())                              // nolint: errcheck
21
+	binary.Write(writer, binary.BigEndian, uint16(r.Data.Len())) // nolint: errcheck
22
+	r.Data.WriteBytes(writer)
23
+}
26 24
 
27
-	return buf.Bytes()
25
+func (r Record) Len() int {
26
+	return 1 + 2 + 2 + r.Data.Len()
28 27
 }
29 28
 
30 29
 func ReadRecord(reader io.Reader) (Record, error) {

+ 6
- 3
tlstypes/server_hello.go Прегледај датотеку

@@ -20,20 +20,22 @@ type ServerHello struct {
20 20
 }
21 21
 
22 22
 func (s ServerHello) WelcomePacket() []byte {
23
+	buf := &bytes.Buffer{}
24
+
23 25
 	s.Random = [32]byte{}
24 26
 	rec := Record{
25 27
 		Type:    RecordTypeHandshake,
26 28
 		Version: Version12,
27 29
 		Data:    &s,
28 30
 	}
29
-	buf := bytes.NewBuffer(rec.Bytes())
31
+	rec.WriteBytes(buf)
30 32
 
31 33
 	recChangeCipher := Record{
32 34
 		Type:    RecordTypeChangeCipherSpec,
33 35
 		Version: Version12,
34 36
 		Data:    RawBytes([]byte{0x01}),
35 37
 	}
36
-	buf.Write(recChangeCipher.Bytes())
38
+	recChangeCipher.WriteBytes(buf)
37 39
 
38 40
 	hostCert := make([]byte, 1024+mrand.Intn(3092))
39 41
 	rand.Read(hostCert) // nolint: errcheck
@@ -43,7 +45,8 @@ func (s ServerHello) WelcomePacket() []byte {
43 45
 		Version: Version12,
44 46
 		Data:    RawBytes(hostCert),
45 47
 	}
46
-	buf.Write(recData.Bytes())
48
+	recData.WriteBytes(buf)
49
+
47 50
 	packet := buf.Bytes()
48 51
 
49 52
 	mac := hmac.New(sha256.New, config.C.Secret)

+ 11
- 0
utils/init_tcp.go Прегледај датотеку

@@ -3,10 +3,13 @@ package utils
3 3
 import (
4 4
 	"fmt"
5 5
 	"net"
6
+	"time"
6 7
 
7 8
 	"github.com/9seconds/mtg/config"
8 9
 )
9 10
 
11
+const tcpKeepAlivePingPeriod = 2 * time.Second
12
+
10 13
 func InitTCP(conn net.Conn) error {
11 14
 	tcpConn := conn.(*net.TCPConn)
12 15
 
@@ -22,5 +25,13 @@ func InitTCP(conn net.Conn) error {
22 25
 		return fmt.Errorf("cannot set write buffer size: %w", err)
23 26
 	}
24 27
 
28
+	if err := tcpConn.SetKeepAlive(true); err != nil {
29
+		return fmt.Errorf("cannot enable keep-alive: %w", err)
30
+	}
31
+
32
+	if err := tcpConn.SetKeepAlivePeriod(tcpKeepAlivePingPeriod); err != nil {
33
+		return fmt.Errorf("cannot set keep-alive period: %w", err)
34
+	}
35
+
25 36
 	return nil
26 37
 }

+ 5
- 4
wrappers/packet/mtproto_frame.go Прегледај датотеку

@@ -42,7 +42,9 @@ type wrapperMtprotoFrame struct {
42 42
 }
43 43
 
44 44
 func (w *wrapperMtprotoFrame) Read() (conntypes.Packet, error) { // nolint: funlen
45
-	buf := &bytes.Buffer{}
45
+	buf := acquireMtprotoFrameBytesBuffer()
46
+	defer releaseMtprotoFrameBytesBuffer(buf)
47
+
46 48
 	sum := crc32.NewIEEE()
47 49
 	writer := io.MultiWriter(buf, sum)
48 50
 
@@ -71,7 +73,6 @@ func (w *wrapperMtprotoFrame) Read() (conntypes.Packet, error) { // nolint: funl
71 73
 	}
72 74
 
73 75
 	buf.Reset()
74
-	buf.Grow(int(messageLength) - 4 - 4)
75 76
 
76 77
 	if _, err := io.CopyN(writer, w.parent, int64(messageLength)-4-4); err != nil {
77 78
 		return nil, fmt.Errorf("cannot read the message frame: %w", err)
@@ -113,8 +114,8 @@ func (w *wrapperMtprotoFrame) Write(p conntypes.Packet) error {
113 114
 	messageLength := 4 + 4 + len(p) + 4
114 115
 	paddingLength := (aes.BlockSize - messageLength%aes.BlockSize) % aes.BlockSize
115 116
 
116
-	buf := &bytes.Buffer{}
117
-	buf.Grow(messageLength + paddingLength)
117
+	buf := acquireMtprotoFrameBytesBuffer()
118
+	defer releaseMtprotoFrameBytesBuffer(buf)
118 119
 
119 120
 	binary.Write(buf, binary.LittleEndian, uint32(messageLength)) // nolint: errcheck
120 121
 	binary.Write(buf, binary.LittleEndian, w.writeSeqNo)          // nolint: errcheck

+ 23
- 0
wrappers/packet/pools.go Прегледај датотеку

@@ -0,0 +1,23 @@
1
+package packet
2
+
3
+import (
4
+	"bytes"
5
+	"sync"
6
+)
7
+
8
+var (
9
+	poolMtprotoFrameBytesBuffer = sync.Pool{
10
+		New: func() interface{} {
11
+			return &bytes.Buffer{}
12
+		},
13
+	}
14
+)
15
+
16
+func acquireMtprotoFrameBytesBuffer() *bytes.Buffer {
17
+	return poolMtprotoFrameBytesBuffer.Get().(*bytes.Buffer)
18
+}
19
+
20
+func releaseMtprotoFrameBytesBuffer(buf *bytes.Buffer) {
21
+	buf.Reset()
22
+	poolMtprotoFrameBytesBuffer.Put(buf)
23
+}

+ 3
- 1
wrappers/packetack/client_abridged.go Прегледај датотеку

@@ -88,7 +88,9 @@ func (w *wrapperClientAbridged) Write(packet conntypes.Packet, acks *conntypes.C
88 88
 		return nil
89 89
 	case packetLength < clientAbridgedLargePacketLength:
90 90
 		length24 := utils.ToUint24(uint32(packetLength))
91
-		buf := bytes.Buffer{}
91
+
92
+		buf := acquireClientBytesBuffer()
93
+		defer releaseClientBytesBuffer(buf)
92 94
 
93 95
 		buf.WriteByte(byte(clientAbridgedSmallPacketLength))
94 96
 		buf.Write(length24[:])

+ 4
- 3
wrappers/packetack/client_intermediate_secure.go Прегледај датотеку

@@ -1,7 +1,6 @@
1 1
 package packetack
2 2
 
3 3
 import (
4
-	"bytes"
5 4
 	"encoding/binary"
6 5
 	"fmt"
7 6
 	"math/rand"
@@ -35,11 +34,13 @@ func (w *wrapperClientIntermediateSecure) Write(packet conntypes.Packet, acks *c
35 34
 		return nil
36 35
 	}
37 36
 
38
-	buf := bytes.Buffer{}
37
+	buf := acquireClientBytesBuffer()
38
+	defer releaseClientBytesBuffer(buf)
39
+
39 40
 	paddingLength := rand.Intn(4)
40 41
 	buf.Grow(4 + len(packet) + paddingLength)
41 42
 
42
-	binary.Write(&buf, binary.LittleEndian, uint32(len(packet)+paddingLength)) // nolint: errcheck
43
+	binary.Write(buf, binary.LittleEndian, uint32(len(packet)+paddingLength)) // nolint: errcheck
43 44
 	buf.Write(packet)
44 45
 	buf.Write(make([]byte, paddingLength))
45 46
 

+ 23
- 0
wrappers/packetack/pools.go Прегледај датотеку

@@ -0,0 +1,23 @@
1
+package packetack
2
+
3
+import (
4
+	"bytes"
5
+	"sync"
6
+)
7
+
8
+var (
9
+	poolClientBytesBuffer = sync.Pool{
10
+		New: func() interface{} {
11
+			return &bytes.Buffer{}
12
+		},
13
+	}
14
+)
15
+
16
+func acquireClientBytesBuffer() *bytes.Buffer {
17
+	return poolClientBytesBuffer.Get().(*bytes.Buffer)
18
+}
19
+
20
+func releaseClientBytesBuffer(buf *bytes.Buffer) {
21
+	buf.Reset()
22
+	poolClientBytesBuffer.Put(buf)
23
+}

+ 2
- 1
wrappers/packetack/proxy.go Прегледај датотеку

@@ -23,8 +23,8 @@ type wrapperProxy struct {
23 23
 
24 24
 func (w *wrapperProxy) Write(packet conntypes.Packet, acks *conntypes.ConnectionAcks) error {
25 25
 	buf := bytes.Buffer{}
26
-
27 26
 	flags := w.flags
27
+
28 28
 	if acks.Quick {
29 29
 		flags |= rpc.ProxyRequestFlagsQuickAck
30 30
 	}
@@ -43,6 +43,7 @@ func (w *wrapperProxy) Write(packet conntypes.Packet, acks *conntypes.Connection
43 43
 	buf.WriteByte(byte(len(config.C.AdTag)))
44 44
 	buf.Write(config.C.AdTag)
45 45
 	buf.Write(make([]byte, (4-buf.Len()%4)%4))
46
+	buf.Grow(len(packet))
46 47
 	buf.Write(packet)
47 48
 
48 49
 	return w.proxy.Write(buf.Bytes())

+ 13
- 3
wrappers/stream/faketls.go Прегледај датотеку

@@ -1,6 +1,7 @@
1 1
 package stream
2 2
 
3 3
 import (
4
+	"bytes"
4 5
 	"errors"
5 6
 	"fmt"
6 7
 	"net"
@@ -39,13 +40,19 @@ func (w *wrapperFakeTLS) WriteTimeout(p []byte, timeout time.Duration) (int, err
39 40
 func (w *wrapperFakeTLS) write(p []byte, writeFunc func([]byte) (int, error)) (int, error) {
40 41
 	sum := 0
41 42
 
43
+	buf := acquireBytesBuffer()
44
+	defer releaseBytesBuffer(buf)
45
+
42 46
 	for _, v := range tlstypes.MakeRecords(p) {
43
-		_, err := writeFunc(v.Bytes())
47
+		buf.Reset()
48
+		v.WriteBytes(buf)
49
+
50
+		_, err := writeFunc(buf.Bytes())
44 51
 		if err != nil {
45 52
 			return sum, err
46 53
 		}
47 54
 
48
-		sum += len(v.Data.Bytes())
55
+		sum += v.Data.Len()
49 56
 	}
50 57
 
51 58
 	return sum, nil
@@ -86,7 +93,10 @@ func NewFakeTLS(socket conntypes.StreamReadWriteCloser) conntypes.StreamReadWrit
86 93
 			switch rec.Type {
87 94
 			case tlstypes.RecordTypeChangeCipherSpec:
88 95
 			case tlstypes.RecordTypeApplicationData:
89
-				return rec.Data.Bytes(), nil
96
+				buf := &bytes.Buffer{}
97
+				rec.Data.WriteBytes(buf)
98
+
99
+				return buf.Bytes(), nil
90 100
 			default:
91 101
 				return nil, fmt.Errorf("unsupported record type %v", rec.Type)
92 102
 			}

+ 3
- 2
wrappers/stream/mtproto_cipher.go Прегледај датотеку

@@ -1,7 +1,6 @@
1 1
 package stream
2 2
 
3 3
 import (
4
-	"bytes"
5 4
 	"crypto/aes"
6 5
 	"crypto/cipher"
7 6
 	"crypto/md5"  // nolint: gosec
@@ -54,7 +53,9 @@ func mtprotoDeriveKeys(purpose mtprotoCipherPurpose,
54 53
 	resp *rpc.NonceResponse,
55 54
 	client, remote *net.TCPAddr,
56 55
 	secret []byte) ([]byte, []byte) {
57
-	message := bytes.Buffer{}
56
+	message := acquireBytesBuffer()
57
+	defer releaseBytesBuffer(message)
58
+
58 59
 	message.Write(resp.Nonce)   // nolint: gosec
59 60
 	message.Write(req.Nonce)    // nolint: gosec
60 61
 	message.Write(req.CryptoTS) // nolint: gosec

+ 14
- 4
wrappers/stream/obfuscated2.go Прегледај датотеку

@@ -40,16 +40,26 @@ func (w *wrapperObfuscated2) Read(p []byte) (int, error) {
40 40
 }
41 41
 
42 42
 func (w *wrapperObfuscated2) WriteTimeout(p []byte, timeout time.Duration) (int, error) {
43
-	buf := make([]byte, len(p))
44
-	copy(buf, p)
43
+	buffer := acquireBytesBuffer()
44
+	defer releaseBytesBuffer(buffer)
45
+
46
+	buffer.Write(p)
47
+
48
+	buf := buffer.Bytes()
49
+
45 50
 	w.encryptor.XORKeyStream(buf, buf)
46 51
 
47 52
 	return w.parent.WriteTimeout(buf, timeout)
48 53
 }
49 54
 
50 55
 func (w *wrapperObfuscated2) Write(p []byte) (int, error) {
51
-	buf := make([]byte, len(p))
52
-	copy(buf, p)
56
+	buffer := acquireBytesBuffer()
57
+	defer releaseBytesBuffer(buffer)
58
+
59
+	buffer.Write(p)
60
+
61
+	buf := buffer.Bytes()
62
+
53 63
 	w.encryptor.XORKeyStream(buf, buf)
54 64
 
55 65
 	return w.parent.Write(buf)

+ 23
- 0
wrappers/stream/pools.go Прегледај датотеку

@@ -0,0 +1,23 @@
1
+package stream
2
+
3
+import (
4
+	"bytes"
5
+	"sync"
6
+)
7
+
8
+var (
9
+	poolBytesBuffer = sync.Pool{
10
+		New: func() interface{} {
11
+			return &bytes.Buffer{}
12
+		},
13
+	}
14
+)
15
+
16
+func acquireBytesBuffer() *bytes.Buffer {
17
+	return poolBytesBuffer.Get().(*bytes.Buffer)
18
+}
19
+
20
+func releaseBytesBuffer(buf *bytes.Buffer) {
21
+	buf.Reset()
22
+	poolBytesBuffer.Put(buf)
23
+}

Loading…
Откажи
Сачувај