Quellcode durchsuchen

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

tags/v1.0.4
9seconds vor 6 Jahren
Ursprung
Commit
8ccf61c23e

+ 5
- 2
README.md Datei anzeigen

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`.                                                                                                                                         |
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
 | `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`.                                                   |
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
 | `MTG_STATSD_TAGS`             | `--statsd-tags`              |                                   | Which tags should we send to statsd with our metrics. Please specify them as `key=value` pairs.                                                                                                                                                                                 |
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
 | `MTG_ANTIREPLAY_MAXSIZE`      | `--anti-replay-max-size`     | `128MB`                           | Max size of antireplay cache.                                                                                                                                                                                                                                                   |
199
 | `MTG_ANTIREPLAY_MAXSIZE`      | `--anti-replay-max-size`     | `128MB`                           | Max size of antireplay cache.                                                                                                                                                                                                                                                   |
200
 | `MTG_CLOAK_PORT`              | `--cloak-port`               | `443`                             | Which port we should use to connect to cloaked host in FakeTLS mode.                                                                                                                                                                                                            |
200
 | `MTG_CLOAK_PORT`              | `--cloak-port`               | `443`                             | Which port we should use to connect to cloaked host in FakeTLS mode.                                                                                                                                                                                                            |
201
 | `MTG_MULTIPLEX_PERCONNECTION` | `--multiplex-per-connection` | `50`                              | How many client connections can share a single Telegram connection in adtag mode                                                                                                                                                                                                |
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
 Usually you want to modify only read/write buffer sizes. If you feel
206
 Usually you want to modify only read/write buffer sizes. If you feel
204
 that proxy is slow, try to increase both sizes giving more priority to
207
 that proxy is slow, try to increase both sizes giving more priority to

+ 6
- 1
faketls/client_protocol.go Datei anzeigen

63
 		return fmt.Errorf("cannot read initial record: %w", err)
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
 	if err != nil {
72
 	if err != nil {
68
 		return fmt.Errorf("cannot parse client hello: %w", err)
73
 		return fmt.Errorf("cannot parse client hello: %w", err)
69
 	}
74
 	}

+ 11
- 8
faketls/cloak.go Datei anzeigen

28
 
28
 
29
 	wg.Add(2)
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
 	go func() {
35
 	go func() {
42
 		wg.Wait()
36
 		wg.Wait()
69
 
63
 
70
 	<-ctx.Done()
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 Datei anzeigen

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 Datei anzeigen

11
 	github.com/prometheus/procfs v0.0.11 // indirect
11
 	github.com/prometheus/procfs v0.0.11 // indirect
12
 	github.com/smira/go-statsd v1.3.1
12
 	github.com/smira/go-statsd v1.3.1
13
 	go.uber.org/zap v1.14.1
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
 	golang.org/x/lint v0.0.0-20200302205851-738671d3881b // indirect
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
 	golang.org/x/tools v0.0.0-20200319210407-521f4a0cd458 // indirect
18
 	golang.org/x/tools v0.0.0-20200319210407-521f4a0cd458 // indirect
19
 	gopkg.in/alecthomas/kingpin.v2 v2.2.6
19
 	gopkg.in/alecthomas/kingpin.v2 v2.2.6
20
 	honnef.co/go/tools v0.0.1-2020.1.3 // indirect
20
 	honnef.co/go/tools v0.0.1-2020.1.3 // indirect

+ 6
- 6
go.sum Datei anzeigen

123
 golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
123
 golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
124
 golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
124
 golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
125
 golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
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
 golang.org/x/lint v0.0.0-20190930215403-16217165b5de h1:5hukYrvBGR8/eNkX5mdUezrA6JiaEZDtJb9Ei+1LlBs=
128
 golang.org/x/lint v0.0.0-20190930215403-16217165b5de h1:5hukYrvBGR8/eNkX5mdUezrA6JiaEZDtJb9Ei+1LlBs=
129
 golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
129
 golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
130
 golang.org/x/lint v0.0.0-20200302205851-738671d3881b h1:Wh+f8QHJXR411sJR8/vRBTZ7YapZaRvUcLFFJhusH0k=
130
 golang.org/x/lint v0.0.0-20200302205851-738671d3881b h1:Wh+f8QHJXR411sJR8/vRBTZ7YapZaRvUcLFFJhusH0k=
140
 golang.org/x/net v0.0.0-20190613194153-d28f0bde5980/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
140
 golang.org/x/net v0.0.0-20190613194153-d28f0bde5980/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
141
 golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
141
 golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
142
 golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
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
 golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
145
 golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
146
 golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4 h1:YUO/7uOKsKeq9UokNS62b8FYywz3ker1l1vDZRCRefw=
146
 golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4 h1:YUO/7uOKsKeq9UokNS62b8FYywz3ker1l1vDZRCRefw=
147
 golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
147
 golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
154
 golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
154
 golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
155
 golang.org/x/sys v0.0.0-20200106162015-b016eb3dc98e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
155
 golang.org/x/sys v0.0.0-20200106162015-b016eb3dc98e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
156
 golang.org/x/sys v0.0.0-20200122134326-e047566fdf82/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
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
 golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
159
 golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
160
 golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
160
 golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
161
 golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
161
 golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=

+ 2
- 2
main.go Datei anzeigen

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

+ 4
- 3
proxy/direct.go Datei anzeigen

11
 	"github.com/9seconds/mtg/protocol"
11
 	"github.com/9seconds/mtg/protocol"
12
 )
12
 )
13
 
13
 
14
-const directPipeBufferSize = 1024 * 1024
14
+const directPipeBufferSize = 1024
15
 
15
 
16
 func directConnection(request *protocol.TelegramRequest) error {
16
 func directConnection(request *protocol.TelegramRequest) error {
17
 	telegramConnRaw, err := obfuscated2.TelegramProtocol(request)
17
 	telegramConnRaw, err := obfuscated2.TelegramProtocol(request)
42
 		wg.Done()
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
 		logger.Debugw("Cannot pump sockets", "error", err)
48
 		logger.Debugw("Cannot pump sockets", "error", err)
48
 	}
49
 	}
49
 }
50
 }

+ 1
- 1
tlstypes/client_hello.go Datei anzeigen

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

+ 10
- 3
tlstypes/consts.go Datei anzeigen

1
 package tlstypes
1
 package tlstypes
2
 
2
 
3
+import "io"
4
+
3
 type RecordType uint8
5
 type RecordType uint8
4
 
6
 
5
 const (
7
 const (
69
 )
71
 )
70
 
72
 
71
 type Byter interface {
73
 type Byter interface {
72
-	Bytes() []byte
74
+	WriteBytes(io.Writer)
75
+	Len() int
73
 }
76
 }
74
 
77
 
75
 type RawBytes []byte
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 Datei anzeigen

1
 package tlstypes
1
 package tlstypes
2
 
2
 
3
 import (
3
 import (
4
-	"bytes"
4
+	"io"
5
 
5
 
6
 	"github.com/9seconds/mtg/utils"
6
 	"github.com/9seconds/mtg/utils"
7
 )
7
 )
14
 	Tail      Byter
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
 	packetBuf.Write(h.Version.Bytes())
23
 	packetBuf.Write(h.Version.Bytes())
24
 	packetBuf.Write(h.Random[:])
24
 	packetBuf.Write(h.Random[:])
25
 	packetBuf.WriteByte(byte(len(h.SessionID)))
25
 	packetBuf.WriteByte(byte(len(h.SessionID)))
26
 	packetBuf.Write(h.SessionID)
26
 	packetBuf.Write(h.SessionID)
27
-	packetBuf.Write(h.Tail.Bytes())
27
+	h.Tail.WriteBytes(packetBuf)
28
 
28
 
29
 	sizeUint24 := utils.ToUint24(uint32(packetBuf.Len()))
29
 	sizeUint24 := utils.ToUint24(uint32(packetBuf.Len()))
30
 	sizeUint24Bytes := sizeUint24[:]
30
 	sizeUint24Bytes := sizeUint24[:]
31
 	sizeUint24Bytes[0], sizeUint24Bytes[2] = sizeUint24Bytes[2], sizeUint24Bytes[0]
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 Datei anzeigen

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 Datei anzeigen

15
 	Data    Byter
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
 func ReadRecord(reader io.Reader) (Record, error) {
29
 func ReadRecord(reader io.Reader) (Record, error) {

+ 6
- 3
tlstypes/server_hello.go Datei anzeigen

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

+ 11
- 0
utils/init_tcp.go Datei anzeigen

3
 import (
3
 import (
4
 	"fmt"
4
 	"fmt"
5
 	"net"
5
 	"net"
6
+	"time"
6
 
7
 
7
 	"github.com/9seconds/mtg/config"
8
 	"github.com/9seconds/mtg/config"
8
 )
9
 )
9
 
10
 
11
+const tcpKeepAlivePingPeriod = 2 * time.Second
12
+
10
 func InitTCP(conn net.Conn) error {
13
 func InitTCP(conn net.Conn) error {
11
 	tcpConn := conn.(*net.TCPConn)
14
 	tcpConn := conn.(*net.TCPConn)
12
 
15
 
22
 		return fmt.Errorf("cannot set write buffer size: %w", err)
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
 	return nil
36
 	return nil
26
 }
37
 }

+ 5
- 4
wrappers/packet/mtproto_frame.go Datei anzeigen

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

+ 23
- 0
wrappers/packet/pools.go Datei anzeigen

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 Datei anzeigen

88
 		return nil
88
 		return nil
89
 	case packetLength < clientAbridgedLargePacketLength:
89
 	case packetLength < clientAbridgedLargePacketLength:
90
 		length24 := utils.ToUint24(uint32(packetLength))
90
 		length24 := utils.ToUint24(uint32(packetLength))
91
-		buf := bytes.Buffer{}
91
+
92
+		buf := acquireClientBytesBuffer()
93
+		defer releaseClientBytesBuffer(buf)
92
 
94
 
93
 		buf.WriteByte(byte(clientAbridgedSmallPacketLength))
95
 		buf.WriteByte(byte(clientAbridgedSmallPacketLength))
94
 		buf.Write(length24[:])
96
 		buf.Write(length24[:])

+ 4
- 3
wrappers/packetack/client_intermediate_secure.go Datei anzeigen

1
 package packetack
1
 package packetack
2
 
2
 
3
 import (
3
 import (
4
-	"bytes"
5
 	"encoding/binary"
4
 	"encoding/binary"
6
 	"fmt"
5
 	"fmt"
7
 	"math/rand"
6
 	"math/rand"
35
 		return nil
34
 		return nil
36
 	}
35
 	}
37
 
36
 
38
-	buf := bytes.Buffer{}
37
+	buf := acquireClientBytesBuffer()
38
+	defer releaseClientBytesBuffer(buf)
39
+
39
 	paddingLength := rand.Intn(4)
40
 	paddingLength := rand.Intn(4)
40
 	buf.Grow(4 + len(packet) + paddingLength)
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
 	buf.Write(packet)
44
 	buf.Write(packet)
44
 	buf.Write(make([]byte, paddingLength))
45
 	buf.Write(make([]byte, paddingLength))
45
 
46
 

+ 23
- 0
wrappers/packetack/pools.go Datei anzeigen

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 Datei anzeigen

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

+ 13
- 3
wrappers/stream/faketls.go Datei anzeigen

1
 package stream
1
 package stream
2
 
2
 
3
 import (
3
 import (
4
+	"bytes"
4
 	"errors"
5
 	"errors"
5
 	"fmt"
6
 	"fmt"
6
 	"net"
7
 	"net"
39
 func (w *wrapperFakeTLS) write(p []byte, writeFunc func([]byte) (int, error)) (int, error) {
40
 func (w *wrapperFakeTLS) write(p []byte, writeFunc func([]byte) (int, error)) (int, error) {
40
 	sum := 0
41
 	sum := 0
41
 
42
 
43
+	buf := acquireBytesBuffer()
44
+	defer releaseBytesBuffer(buf)
45
+
42
 	for _, v := range tlstypes.MakeRecords(p) {
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
 		if err != nil {
51
 		if err != nil {
45
 			return sum, err
52
 			return sum, err
46
 		}
53
 		}
47
 
54
 
48
-		sum += len(v.Data.Bytes())
55
+		sum += v.Data.Len()
49
 	}
56
 	}
50
 
57
 
51
 	return sum, nil
58
 	return sum, nil
86
 			switch rec.Type {
93
 			switch rec.Type {
87
 			case tlstypes.RecordTypeChangeCipherSpec:
94
 			case tlstypes.RecordTypeChangeCipherSpec:
88
 			case tlstypes.RecordTypeApplicationData:
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
 			default:
100
 			default:
91
 				return nil, fmt.Errorf("unsupported record type %v", rec.Type)
101
 				return nil, fmt.Errorf("unsupported record type %v", rec.Type)
92
 			}
102
 			}

+ 3
- 2
wrappers/stream/mtproto_cipher.go Datei anzeigen

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

+ 14
- 4
wrappers/stream/obfuscated2.go Datei anzeigen

40
 }
40
 }
41
 
41
 
42
 func (w *wrapperObfuscated2) WriteTimeout(p []byte, timeout time.Duration) (int, error) {
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
 	w.encryptor.XORKeyStream(buf, buf)
50
 	w.encryptor.XORKeyStream(buf, buf)
46
 
51
 
47
 	return w.parent.WriteTimeout(buf, timeout)
52
 	return w.parent.WriteTimeout(buf, timeout)
48
 }
53
 }
49
 
54
 
50
 func (w *wrapperObfuscated2) Write(p []byte) (int, error) {
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
 	w.encryptor.XORKeyStream(buf, buf)
63
 	w.encryptor.XORKeyStream(buf, buf)
54
 
64
 
55
 	return w.parent.Write(buf)
65
 	return w.parent.Write(buf)

+ 23
- 0
wrappers/stream/pools.go Datei anzeigen

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
+}

Laden…
Abbrechen
Speichern