Просмотр исходного кода

Updates for go 1.18

tags/v1.0.11
9seconds 4 лет назад
Родитель
Сommit
e74726af70

+ 2
- 5
.github/workflows/ci.yaml Просмотреть файл

30
     strategy:
30
     strategy:
31
       matrix:
31
       matrix:
32
         go_version:
32
         go_version:
33
-          - ~1.14
34
-          - ~1.15
35
-          - ~1.16
36
-          - ^1.17
33
+          - ^1.18
37
     steps:
34
     steps:
38
       - name: Checkout
35
       - name: Checkout
39
         uses: actions/checkout@v2
36
         uses: actions/checkout@v2
73
       - name: Run linter
70
       - name: Run linter
74
         uses: golangci/golangci-lint-action@v2
71
         uses: golangci/golangci-lint-action@v2
75
         with:
72
         with:
76
-          version: v1.42.0
73
+          version: v1.45.0
77
 
74
 
78
   docker:
75
   docker:
79
     name: Docker
76
     name: Docker

+ 1
- 2
.golangci.toml Просмотреть файл

3
 deadline = "2m"
3
 deadline = "2m"
4
 tests = true
4
 tests = true
5
 skip-dirs = ["vendor"]
5
 skip-dirs = ["vendor"]
6
-skip-files = ["version.go"]
7
 
6
 
8
 [output]
7
 [output]
9
 format = "colored-line-number"
8
 format = "colored-line-number"
10
 
9
 
11
 [linters]
10
 [linters]
12
 enable-all = true
11
 enable-all = true
13
-disable = ["gochecknoglobals", "gas", "gomnd", "goerr113", "exhaustivestruct"]
12
+disable = ["thelper", "ireturn", "varnamelen", "gochecknoglobals", "gas", "goerr113", "exhaustivestruct", "containedctx"]

+ 1
- 1
Makefile Просмотреть файл

4
 
4
 
5
 CC_BINARIES  := $(shell bash -c "echo -n $(APP_NAME)-{linux,freebsd,openbsd}-{386,amd64} $(APP_NAME)-linux-{arm,arm64}")
5
 CC_BINARIES  := $(shell bash -c "echo -n $(APP_NAME)-{linux,freebsd,openbsd}-{386,amd64} $(APP_NAME)-linux-{arm,arm64}")
6
 
6
 
7
-GOLANGCI_LINT_VERSION := v1.42.0
7
+GOLANGCI_LINT_VERSION := v1.45.0
8
 
8
 
9
 VERSION_GO         := $(shell go version)
9
 VERSION_GO         := $(shell go version)
10
 VERSION_DATE       := $(shell date -Ru)
10
 VERSION_DATE       := $(shell date -Ru)

+ 6
- 6
config/config.go Просмотреть файл

146
 
146
 
147
 	fvalue := float64(value)
147
 	fvalue := float64(value)
148
 
148
 
149
-	newValue := fvalue * 2 * math.Log(float64(c.MultiplexPerConnection))
149
+	newValue := fvalue * 2 * math.Log(float64(c.MultiplexPerConnection)) // nolint: gomnd
150
 	newValue = math.Ceil(newValue)
150
 	newValue = math.Ceil(newValue)
151
 	newValue = math.Max(fvalue, newValue)
151
 	newValue = math.Max(fvalue, newValue)
152
 
152
 
208
 		case OptionTypeStatsdTags:
208
 		case OptionTypeStatsdTags:
209
 			C.StatsdTags = opt.Value.(map[string]string) // nolint: forcetypeassert
209
 			C.StatsdTags = opt.Value.(map[string]string) // nolint: forcetypeassert
210
 		case OptionTypeWriteBufferSize:
210
 		case OptionTypeWriteBufferSize:
211
-			C.WriteBuffer = int(opt.Value.(units.Base2Bytes))
211
+			C.WriteBuffer = int(opt.Value.(units.Base2Bytes)) // nolint: forcetypeassert
212
 		case OptionTypeReadBufferSize:
212
 		case OptionTypeReadBufferSize:
213
-			C.ReadBuffer = int(opt.Value.(units.Base2Bytes))
213
+			C.ReadBuffer = int(opt.Value.(units.Base2Bytes)) // nolint: forcetypeassert
214
 		case OptionTypeCloakPort:
214
 		case OptionTypeCloakPort:
215
-			C.CloakPort = int(opt.Value.(uint16))
215
+			C.CloakPort = int(opt.Value.(uint16)) // nolint: forcetypeassert
216
 		case OptionTypeAntiReplayMaxSize:
216
 		case OptionTypeAntiReplayMaxSize:
217
-			C.AntiReplayMaxSize = int(opt.Value.(units.Base2Bytes))
217
+			C.AntiReplayMaxSize = int(opt.Value.(units.Base2Bytes)) // nolint: forcetypeassert
218
 		case OptionTypeMultiplexPerConnection:
218
 		case OptionTypeMultiplexPerConnection:
219
-			C.MultiplexPerConnection = int(opt.Value.(uint))
219
+			C.MultiplexPerConnection = int(opt.Value.(uint)) // nolint: forcetypeassert
220
 		case OptionTypeNTPServers:
220
 		case OptionTypeNTPServers:
221
 			C.NTPServers = opt.Value.([]string) // nolint: forcetypeassert
221
 			C.NTPServers = opt.Value.([]string) // nolint: forcetypeassert
222
 			if len(C.NTPServers) == 0 {
222
 			if len(C.NTPServers) == 0 {

+ 1
- 1
faketls/cloak.go Просмотреть файл

26
 	another = rwc.NewPing(ctx, another, channelPing)
26
 	another = rwc.NewPing(ctx, another, channelPing)
27
 	wg := &sync.WaitGroup{}
27
 	wg := &sync.WaitGroup{}
28
 
28
 
29
-	wg.Add(2)
29
+	wg.Add(2) // nolint: gomnd
30
 
30
 
31
 	go cloakPipe(one, another, wg)
31
 	go cloakPipe(one, another, wg)
32
 
32
 

+ 7
- 4
go.mod Просмотреть файл

13
 	github.com/smira/go-statsd v1.3.2
13
 	github.com/smira/go-statsd v1.3.2
14
 	go.uber.org/multierr v1.7.0 // indirect
14
 	go.uber.org/multierr v1.7.0 // indirect
15
 	go.uber.org/zap v1.19.0
15
 	go.uber.org/zap v1.19.0
16
-	golang.org/x/crypto v0.0.0-20210220033148-5ea612d1eb83
17
-	golang.org/x/net v0.0.0-20210525063256-abc453219eb5 // indirect
18
-	golang.org/x/sys v0.0.0-20210603081109-ebe580a85c40
19
-	golang.org/x/tools v0.1.0 // indirect
16
+	golang.org/x/crypto v0.0.0-20210921155107-089bfa567519
17
+	golang.org/x/net v0.0.0-20220225172249-27dd8689420f // indirect
18
+	golang.org/x/sys v0.0.0-20220318055525-2edf467146b5
19
+	golang.org/x/tools v0.1.10 // indirect
20
 	google.golang.org/protobuf v1.27.1 // indirect
20
 	google.golang.org/protobuf v1.27.1 // indirect
21
 	gopkg.in/alecthomas/kingpin.v2 v2.2.6
21
 	gopkg.in/alecthomas/kingpin.v2 v2.2.6
22
 )
22
 )
28
 	github.com/golang/protobuf v1.5.2 // indirect
28
 	github.com/golang/protobuf v1.5.2 // indirect
29
 	github.com/matttproud/golang_protobuf_extensions v1.0.1 // indirect
29
 	github.com/matttproud/golang_protobuf_extensions v1.0.1 // indirect
30
 	github.com/prometheus/client_model v0.2.0 // indirect
30
 	github.com/prometheus/client_model v0.2.0 // indirect
31
+	github.com/yuin/goldmark v1.4.10 // indirect
31
 	go.uber.org/atomic v1.9.0 // indirect
32
 	go.uber.org/atomic v1.9.0 // indirect
33
+	golang.org/x/mod v0.6.0-dev.0.20220106191415-9b9b3d81d5e3 // indirect
34
+	golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 // indirect
32
 )
35
 )

+ 12
- 0
go.sum Просмотреть файл

206
 github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
206
 github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
207
 github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
207
 github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
208
 github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
208
 github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
209
+github.com/yuin/goldmark v1.4.10 h1:+WgKGo8CQrlMTRJpGCFCyNddOhW801TKC2QijVV9QVg=
210
+github.com/yuin/goldmark v1.4.10/go.mod h1:rmuwmfZ0+bvzB24eSC//bk1R1Zp3hM0OXYv/G2LIilg=
209
 go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU=
211
 go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU=
210
 go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8=
212
 go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8=
211
 go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
213
 go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
229
 golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
231
 golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
230
 golang.org/x/crypto v0.0.0-20210220033148-5ea612d1eb83 h1:/ZScEX8SfEmUGRHs0gxpqteO5nfNW6axyZbBdw9A12g=
232
 golang.org/x/crypto v0.0.0-20210220033148-5ea612d1eb83 h1:/ZScEX8SfEmUGRHs0gxpqteO5nfNW6axyZbBdw9A12g=
231
 golang.org/x/crypto v0.0.0-20210220033148-5ea612d1eb83/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I=
233
 golang.org/x/crypto v0.0.0-20210220033148-5ea612d1eb83/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I=
234
+golang.org/x/crypto v0.0.0-20210921155107-089bfa567519 h1:7I4JAnoQBe7ZtJcBaYHi5UtiO8tQHbUSXxL+pnGRANg=
235
+golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
232
 golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
236
 golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
233
 golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
237
 golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
234
 golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8=
238
 golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8=
260
 golang.org/x/mod v0.1.1-0.20191107180719-034126e5016b/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg=
264
 golang.org/x/mod v0.1.1-0.20191107180719-034126e5016b/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg=
261
 golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
265
 golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
262
 golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
266
 golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
267
+golang.org/x/mod v0.6.0-dev.0.20220106191415-9b9b3d81d5e3 h1:kQgndtyPBW/JIYERgdxfwMYh3AVStj88WQTlNDi2a+o=
268
+golang.org/x/mod v0.6.0-dev.0.20220106191415-9b9b3d81d5e3/go.mod h1:3p9vT2HGsQu2K1YbXdKPJLVgG5VJdoTa1poYQBtP1AY=
263
 golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
269
 golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
264
 golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
270
 golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
265
 golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
271
 golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
291
 golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
297
 golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
292
 golang.org/x/net v0.0.0-20210525063256-abc453219eb5 h1:wjuX4b5yYQnEQHzd+CBcrcC6OVR2J1CN6mUy0oSxIPo=
298
 golang.org/x/net v0.0.0-20210525063256-abc453219eb5 h1:wjuX4b5yYQnEQHzd+CBcrcC6OVR2J1CN6mUy0oSxIPo=
293
 golang.org/x/net v0.0.0-20210525063256-abc453219eb5/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
299
 golang.org/x/net v0.0.0-20210525063256-abc453219eb5/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
300
+golang.org/x/net v0.0.0-20220225172249-27dd8689420f h1:oA4XRj0qtSt8Yo1Zms0CUlsT3KG69V2UGQWPBxujDmc=
301
+golang.org/x/net v0.0.0-20220225172249-27dd8689420f/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk=
294
 golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
302
 golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
295
 golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
303
 golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
296
 golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
304
 golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
347
 golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
355
 golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
348
 golang.org/x/sys v0.0.0-20210603081109-ebe580a85c40 h1:JWgyZ1qgdTaF3N3oxC+MdTV7qvEEgHo3otj+HB5CM7Q=
356
 golang.org/x/sys v0.0.0-20210603081109-ebe580a85c40 h1:JWgyZ1qgdTaF3N3oxC+MdTV7qvEEgHo3otj+HB5CM7Q=
349
 golang.org/x/sys v0.0.0-20210603081109-ebe580a85c40/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
357
 golang.org/x/sys v0.0.0-20210603081109-ebe580a85c40/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
358
+golang.org/x/sys v0.0.0-20220318055525-2edf467146b5 h1:saXMvIOKvRFwbOMicHXr0B1uwoxq9dGmLe5ExMES6c4=
359
+golang.org/x/sys v0.0.0-20220318055525-2edf467146b5/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
350
 golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw=
360
 golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw=
351
 golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
361
 golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
352
 golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
362
 golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
401
 golang.org/x/tools v0.0.0-20200825202427-b303f430e36d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA=
411
 golang.org/x/tools v0.0.0-20200825202427-b303f430e36d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA=
402
 golang.org/x/tools v0.1.0 h1:po9/4sTYwZU9lPhi1tOrb4hCv3qrhiQ77LZfGa2OjwY=
412
 golang.org/x/tools v0.1.0 h1:po9/4sTYwZU9lPhi1tOrb4hCv3qrhiQ77LZfGa2OjwY=
403
 golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0=
413
 golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0=
414
+golang.org/x/tools v0.1.10 h1:QjFRCZxdOhBJ/UNgnBZLbNV13DlbnK0quyivTnXJM20=
415
+golang.org/x/tools v0.1.10/go.mod h1:Uh6Zz+xoGYZom868N8YTex3t7RhtHDBrE8Gzo9bV56E=
404
 golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
416
 golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
405
 golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
417
 golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
406
 golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
418
 golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=

+ 1
- 1
hub/hub.go Просмотреть файл

18
 }
18
 }
19
 
19
 
20
 func (h *hub) getMux(req *protocol.TelegramRequest) *mux {
20
 func (h *hub) getMux(req *protocol.TelegramRequest) *mux {
21
-	key := 32767 + int32(req.ClientProtocol.DC()) + 100000*int32(req.ClientProtocol.ConnectionProtocol())
21
+	key := 32767 + int32(req.ClientProtocol.DC()) + 100000*int32(req.ClientProtocol.ConnectionProtocol()) // nolint: gomnd
22
 
22
 
23
 	h.mutex.RLock()
23
 	h.mutex.RLock()
24
 	m, ok := h.muxes[key]
24
 	m, ok := h.muxes[key]

+ 1
- 1
mtproto/rpc/handshake_response.go Просмотреть файл

41
 // NewHandshakeResponse constructs new handshake response from the given
41
 // NewHandshakeResponse constructs new handshake response from the given
42
 // data.
42
 // data.
43
 func NewHandshakeResponse(data []byte) (*HandshakeResponse, error) {
43
 func NewHandshakeResponse(data []byte) (*HandshakeResponse, error) {
44
-	if len(data) != 32 {
44
+	if len(data) != 32 { // nolint: gomnd
45
 		return nil, fmt.Errorf("incorrect handshake response length %d", len(data))
45
 		return nil, fmt.Errorf("incorrect handshake response length %d", len(data))
46
 	}
46
 	}
47
 
47
 

+ 5
- 5
mtproto/rpc/nonce_request.go Просмотреть файл

29
 
29
 
30
 // NewNonceRequest builds new none request based on proxy secret.
30
 // NewNonceRequest builds new none request based on proxy secret.
31
 func NewNonceRequest(proxySecret []byte) (*NonceRequest, error) {
31
 func NewNonceRequest(proxySecret []byte) (*NonceRequest, error) {
32
-	nonce := make([]byte, 16)
33
-	keySelector := make([]byte, 4)
34
-	cryptoTS := make([]byte, 4)
32
+	nonce := make([]byte, 16)      // nolint: gomnd
33
+	keySelector := make([]byte, 4) // nolint: gomnd
34
+	cryptoTS := make([]byte, 4)    // nolint: gomnd
35
 
35
 
36
 	if _, err := rand.Read(nonce); err != nil {
36
 	if _, err := rand.Read(nonce); err != nil {
37
 		return nil, fmt.Errorf("cannot generate nonce: %w", err)
37
 		return nil, fmt.Errorf("cannot generate nonce: %w", err)
38
 	}
38
 	}
39
 
39
 
40
 	copy(keySelector, proxySecret)
40
 	copy(keySelector, proxySecret)
41
-
42
-	timestamp := time.Now().Truncate(time.Second).Unix() % 4294967296 // 256 ^ 4 - do not know how to name
41
+	// 256 ^ 4 - do not know how to name
42
+	timestamp := time.Now().Truncate(time.Second).Unix() % 4294967296 // nolint: gomnd
43
 	binary.LittleEndian.PutUint32(cryptoTS, uint32(timestamp))
43
 	binary.LittleEndian.PutUint32(cryptoTS, uint32(timestamp))
44
 
44
 
45
 	return &NonceRequest{
45
 	return &NonceRequest{

+ 1
- 1
mtproto/rpc/nonce_response.go Просмотреть файл

44
 
44
 
45
 // NewNonceResponse build new nonce response based on the given data.
45
 // NewNonceResponse build new nonce response based on the given data.
46
 func NewNonceResponse(data []byte) (*NonceResponse, error) {
46
 func NewNonceResponse(data []byte) (*NonceResponse, error) {
47
-	if len(data) != 32 {
47
+	if len(data) != 32 { // nolint: gomnd
48
 		return nil, fmt.Errorf("unexpected message length %d", len(data))
48
 		return nil, fmt.Errorf("unexpected message length %d", len(data))
49
 	}
49
 	}
50
 
50
 

+ 2
- 2
mtproto/rpc/proxy_flags.go Просмотреть файл

21
 var ProxyRequestFlagsEncryptedPrefix [8]byte
21
 var ProxyRequestFlagsEncryptedPrefix [8]byte
22
 
22
 
23
 func (r ProxyRequestFlags) Bytes() []byte {
23
 func (r ProxyRequestFlags) Bytes() []byte {
24
-	converted := make([]byte, 4)
24
+	converted := make([]byte, 4) // nolint: gomnd
25
 	binary.LittleEndian.PutUint32(converted, uint32(r))
25
 	binary.LittleEndian.PutUint32(converted, uint32(r))
26
 
26
 
27
 	return converted
27
 	return converted
28
 }
28
 }
29
 
29
 
30
 func (r ProxyRequestFlags) String() string {
30
 func (r ProxyRequestFlags) String() string {
31
-	flags := make([]string, 0, 7)
31
+	flags := make([]string, 0, 7) // nolint: gomnd
32
 
32
 
33
 	if r&ProxyRequestFlagsHasAdTag != 0 {
33
 	if r&ProxyRequestFlagsHasAdTag != 0 {
34
 		flags = append(flags, "HAS_AD_TAG")
34
 		flags = append(flags, "HAS_AD_TAG")

+ 1
- 1
mtproto/rpc/proxy_response.go Просмотреть файл

24
 func ParseProxyResponse(packet conntypes.Packet) (*ProxyResponse, error) {
24
 func ParseProxyResponse(packet conntypes.Packet) (*ProxyResponse, error) {
25
 	var response ProxyResponse
25
 	var response ProxyResponse
26
 
26
 
27
-	if len(packet) < 4 {
27
+	if len(packet) < 4 { // nolint: gomnd
28
 		return nil, fmt.Errorf("incorrect packet length: %d", len(packet))
28
 		return nil, fmt.Errorf("incorrect packet length: %d", len(packet))
29
 	}
29
 	}
30
 
30
 

+ 5
- 5
obfuscated2/telegram_protocol.go Просмотреть файл

47
 			continue
47
 			continue
48
 		}
48
 		}
49
 
49
 
50
-		if data[0] == 0xef {
50
+		if data[0] == 0xef { // nolint: gomnd
51
 			continue
51
 			continue
52
 		}
52
 		}
53
 
53
 
54
-		val := (uint32(data[3]) << 24) | (uint32(data[2]) << 16) | (uint32(data[1]) << 8) | uint32(data[0])
55
-		if val == 0x44414548 || val == 0x54534f50 || val == 0x20544547 || val == 0x4954504f || val == 0xeeeeeeee {
54
+		val := (uint32(data[3]) << 24) | (uint32(data[2]) << 16) | (uint32(data[1]) << 8) | uint32(data[0])        // nolint: gomnd, lll
55
+		if val == 0x44414548 || val == 0x54534f50 || val == 0x20544547 || val == 0x4954504f || val == 0xeeeeeeee { // nolint: lll
56
 			continue
56
 			continue
57
 		}
57
 		}
58
 
58
 
59
-		val = (uint32(data[7]) << 24) | (uint32(data[6]) << 16) | (uint32(data[5]) << 8) | uint32(data[4])
60
-		if val == 0x00000000 {
59
+		val = (uint32(data[7]) << 24) | (uint32(data[6]) << 16) | (uint32(data[5]) << 8) | uint32(data[4]) // nolint: gomnd
60
+		if val == 0x00000000 {                                                                             // nolint: gomnd
61
 			continue
61
 			continue
62
 		}
62
 		}
63
 
63
 

+ 1
- 1
proxy/direct.go Просмотреть файл

20
 	defer telegramConnRaw.Close()
20
 	defer telegramConnRaw.Close()
21
 
21
 
22
 	wg := &sync.WaitGroup{}
22
 	wg := &sync.WaitGroup{}
23
-	wg.Add(2)
23
+	wg.Add(2) // nolint: gomnd
24
 
24
 
25
 	go directPipe(telegramConnRaw, request.ClientConn, wg, request.Logger)
25
 	go directPipe(telegramConnRaw, request.ClientConn, wg, request.Logger)
26
 
26
 

+ 1
- 1
proxy/middle.go Просмотреть файл

32
 	}
32
 	}
33
 
33
 
34
 	wg := &sync.WaitGroup{}
34
 	wg := &sync.WaitGroup{}
35
-	wg.Add(2)
35
+	wg.Add(2) // nolint: gomnd
36
 
36
 
37
 	go middlePipe(telegramConn, clientConn, wg, request.Logger)
37
 	go middlePipe(telegramConn, clientConn, wg, request.Logger)
38
 
38
 

+ 1
- 1
stats/stats.go Просмотреть файл

32
 
32
 
33
 	go func() {
33
 	go func() {
34
 		<-ctx.Done()
34
 		<-ctx.Done()
35
-		srv.Shutdown(context.Background()) // nolint: errcheck
35
+		srv.Shutdown(context.Background()) // nolint: errcheck, contextcheck
36
 	}()
36
 	}()
37
 
37
 
38
 	Stats = multiStats(stats)
38
 	Stats = multiStats(stats)

+ 3
- 3
stats/stats_statsd.go Просмотреть файл

83
 }
83
 }
84
 
84
 
85
 func (s *statsStatsd) changeConnections(connectionType conntypes.ConnectionType, addr *net.TCPAddr, increment int64) {
85
 func (s *statsStatsd) changeConnections(connectionType conntypes.ConnectionType, addr *net.TCPAddr, increment int64) {
86
-	tags := make([]*statsStatsdTag, 0, 2)
86
+	tags := make([]*statsStatsdTag, 0, 2) // nolint: gomnd
87
 
87
 
88
 	switch connectionType {
88
 	switch connectionType {
89
 	case conntypes.ConnectionTypeAbridged:
89
 	case conntypes.ConnectionTypeAbridged:
194
 	return &statsStatsd{
194
 	return &statsStatsd{
195
 		seen: make(map[string]struct{}),
195
 		seen: make(map[string]struct{}),
196
 		client: statsd.NewClient(config.C.StatsdAddr.String(),
196
 		client: statsd.NewClient(config.C.StatsdAddr.String(),
197
-			statsd.SendLoopCount(2),
198
-			statsd.ReconnectInterval(10*time.Second),
197
+			statsd.SendLoopCount(2),                  // nolint: gomnd
198
+			statsd.ReconnectInterval(10*time.Second), // nolint: gomnd
199
 			statsd.Logger(logger),
199
 			statsd.Logger(logger),
200
 			statsd.MetricPrefix(prefix),
200
 			statsd.MetricPrefix(prefix),
201
 			statsd.TagStyle(config.C.StatsdTagsFormat),
201
 			statsd.TagStyle(config.C.StatsdTagsFormat),

+ 4
- 4
telegram/api/addresses.go Просмотреть файл

74
 }
74
 }
75
 
75
 
76
 func addressesParseProxyFor(text string) (string, conntypes.DC, error) {
76
 func addressesParseProxyFor(text string) (string, conntypes.DC, error) {
77
-	chunks := addressesProxyForSplitter.Split(text, 3)
77
+	chunks := addressesProxyForSplitter.Split(text, 3) // nolint: gomnd
78
 	if len(chunks) != 3 || chunks[0] != "proxy_for" {
78
 	if len(chunks) != 3 || chunks[0] != "proxy_for" {
79
 		return "", 0, fmt.Errorf("incorrect config %s", text)
79
 		return "", 0, fmt.Errorf("incorrect config %s", text)
80
 	}
80
 	}
81
 
81
 
82
-	dc, err := strconv.ParseInt(chunks[1], 10, 16)
82
+	dc, err := strconv.ParseInt(chunks[1], 10, 16) // nolint: gomnd
83
 	if err != nil {
83
 	if err != nil {
84
 		return "", 0, fmt.Errorf("incorrect config '%s': %w", text, err)
84
 		return "", 0, fmt.Errorf("incorrect config '%s': %w", text, err)
85
 	}
85
 	}
93
 }
93
 }
94
 
94
 
95
 func addressesParseDefault(text string) (conntypes.DC, error) {
95
 func addressesParseDefault(text string) (conntypes.DC, error) {
96
-	chunks := addressesProxyForSplitter.Split(text, 2)
96
+	chunks := addressesProxyForSplitter.Split(text, 2) // nolint: gomnd
97
 	if len(chunks) != 2 || chunks[0] != "default" {
97
 	if len(chunks) != 2 || chunks[0] != "default" {
98
 		return 0, fmt.Errorf("incorrect config '%s'", text)
98
 		return 0, fmt.Errorf("incorrect config '%s'", text)
99
 	}
99
 	}
100
 
100
 
101
 	dcString := strings.TrimRight(chunks[1], ";")
101
 	dcString := strings.TrimRight(chunks[1], ";")
102
 
102
 
103
-	dc, err := strconv.ParseInt(dcString, 10, 16)
103
+	dc, err := strconv.ParseInt(dcString, 10, 16) // nolint: gomnd
104
 	if err != nil {
104
 	if err != nil {
105
 		return 0, fmt.Errorf("incorrect config '%s': %w", text, err)
105
 		return 0, fmt.Errorf("incorrect config '%s': %w", text, err)
106
 	}
106
 	}

+ 1
- 1
telegram/base.go Просмотреть файл

51
 }
51
 }
52
 
52
 
53
 func (b *baseTelegram) getAddresses(dc conntypes.DC, protocol conntypes.ConnectionProtocol) []string {
53
 func (b *baseTelegram) getAddresses(dc conntypes.DC, protocol conntypes.ConnectionProtocol) []string {
54
-	addresses := make([]string, 0, 2)
54
+	addresses := make([]string, 0, 2) // nolint: gomnd
55
 	protos := []conntypes.ConnectionProtocol{
55
 	protos := []conntypes.ConnectionProtocol{
56
 		conntypes.ConnectionProtocolIPv6,
56
 		conntypes.ConnectionProtocolIPv6,
57
 		conntypes.ConnectionProtocolIPv4,
57
 		conntypes.ConnectionProtocolIPv4,

+ 2
- 2
tlstypes/server_hello.go Просмотреть файл

36
 	}
36
 	}
37
 	recChangeCipher.WriteBytes(buf)
37
 	recChangeCipher.WriteBytes(buf)
38
 
38
 
39
-	hostCert := make([]byte, 1024+mrand.Intn(3092)) // nolint: gosec
39
+	hostCert := make([]byte, 1024+mrand.Intn(3092)) // nolint: gosec, gomnd
40
 	rand.Read(hostCert)                             // nolint: errcheck
40
 	rand.Read(hostCert)                             // nolint: errcheck
41
 
41
 
42
 	recData := Record{
42
 	recData := Record{
67
 	copy(rv.SessionID, clientHello.SessionID)
67
 	copy(rv.SessionID, clientHello.SessionID)
68
 
68
 
69
 	tail := bytes.NewBuffer(CipherSuiteType_TLS_AES_128_GCM_SHA256_Bytes)
69
 	tail := bytes.NewBuffer(CipherSuiteType_TLS_AES_128_GCM_SHA256_Bytes)
70
-	tail.WriteByte(0x00) // no compression
70
+	tail.WriteByte(0x00) // nolint: gomnd // no compression
71
 	makeTLSExtensions(tail)
71
 	makeTLSExtensions(tail)
72
 	rv.Tail = RawBytes(tail.Bytes())
72
 	rv.Tail = RawBytes(tail.Bytes())
73
 
73
 

+ 1
- 1
utils/reverse_bytes.go Просмотреть файл

6
 	rv := make([]byte, dataLen)
6
 	rv := make([]byte, dataLen)
7
 	rv[dataLen/2] = data[dataLen/2]
7
 	rv[dataLen/2] = data[dataLen/2]
8
 
8
 
9
-	for i := dataLen/2 - 1; i >= 0; i-- {
9
+	for i := dataLen/2 - 1; i >= 0; i-- { // nolint: gomnd
10
 		opp := dataLen - i - 1
10
 		opp := dataLen - i - 1
11
 		rv[i], rv[opp] = data[opp], data[i]
11
 		rv[i], rv[opp] = data[opp], data[i]
12
 	}
12
 	}

+ 2
- 2
utils/uint24.go Просмотреть файл

3
 type Uint24 [3]byte
3
 type Uint24 [3]byte
4
 
4
 
5
 func ToUint24(number uint32) Uint24 {
5
 func ToUint24(number uint32) Uint24 {
6
-	return Uint24{byte(number), byte(number >> 8), byte(number >> 16)}
6
+	return Uint24{byte(number), byte(number >> 8), byte(number >> 16)} // nolint: gomnd
7
 }
7
 }
8
 
8
 
9
 func FromUint24(number Uint24) uint32 {
9
 func FromUint24(number Uint24) uint32 {
10
-	return uint32(number[0]) + (uint32(number[1]) << 8) + (uint32(number[2]) << 16)
10
+	return uint32(number[0]) + (uint32(number[1]) << 8) + (uint32(number[2]) << 16) // nolint: gomnd
11
 }
11
 }

+ 6
- 6
wrappers/packet/mtproto_frame.go Просмотреть файл

50
 		buf.Reset()
50
 		buf.Reset()
51
 		sum.Reset()
51
 		sum.Reset()
52
 
52
 
53
-		if _, err := io.CopyN(writer, w.parent, 4); err != nil {
53
+		if _, err := io.CopyN(writer, w.parent, 4); err != nil { // nolint: gomnd
54
 			return nil, fmt.Errorf("cannot read frame padding: %w", err)
54
 			return nil, fmt.Errorf("cannot read frame padding: %w", err)
55
 		}
55
 		}
56
 
56
 
72
 
72
 
73
 	buf.Reset()
73
 	buf.Reset()
74
 
74
 
75
-	if _, err := io.CopyN(writer, w.parent, int64(messageLength)-4-4); err != nil {
75
+	if _, err := io.CopyN(writer, w.parent, int64(messageLength)-4-4); err != nil { // nolint: gomnd
76
 		return nil, fmt.Errorf("cannot read the message frame: %w", err)
76
 		return nil, fmt.Errorf("cannot read the message frame: %w", err)
77
 	}
77
 	}
78
 
78
 
88
 	buf.Reset()
88
 	buf.Reset()
89
 	// write to buf, not to writer. This is because we are going to fetch
89
 	// write to buf, not to writer. This is because we are going to fetch
90
 	// crc32 checksum.
90
 	// crc32 checksum.
91
-	if _, err := io.CopyN(buf, w.parent, 4); err != nil {
91
+	if _, err := io.CopyN(buf, w.parent, 4); err != nil { // nolint: gomnd
92
 		return nil, fmt.Errorf("cannot read checksum: %w", err)
92
 		return nil, fmt.Errorf("cannot read checksum: %w", err)
93
 	}
93
 	}
94
 
94
 
109
 }
109
 }
110
 
110
 
111
 func (w *wrapperMtprotoFrame) Write(p conntypes.Packet) error {
111
 func (w *wrapperMtprotoFrame) Write(p conntypes.Packet) error {
112
-	messageLength := 4 + 4 + len(p) + 4
112
+	messageLength := 4 + 4 + len(p) + 4 // nolint: gomnd
113
 	paddingLength := (aes.BlockSize - messageLength%aes.BlockSize) % aes.BlockSize
113
 	paddingLength := (aes.BlockSize - messageLength%aes.BlockSize) % aes.BlockSize
114
 
114
 
115
 	buf := &bytes.Buffer{}
115
 	buf := &bytes.Buffer{}
119
 	buf.Write(p)
119
 	buf.Write(p)
120
 
120
 
121
 	checksum := crc32.ChecksumIEEE(buf.Bytes())
121
 	checksum := crc32.ChecksumIEEE(buf.Bytes())
122
-	binary.Write(buf, binary.LittleEndian, checksum) // nolint: errcheck
123
-	buf.Write(bytes.Repeat(mtprotoFramePadding, paddingLength/4))
122
+	binary.Write(buf, binary.LittleEndian, checksum)              // nolint: errcheck
123
+	buf.Write(bytes.Repeat(mtprotoFramePadding, paddingLength/4)) // nolint: gomnd
124
 
124
 
125
 	w.logger.Debugw("Write MTProto frame",
125
 	w.logger.Debugw("Write MTProto frame",
126
 		"length", len(p),
126
 		"length", len(p),

+ 3
- 3
wrappers/packetack/client_abridged.go Просмотреть файл

39
 	}
39
 	}
40
 
40
 
41
 	if msgLength == clientAbridgedSmallPacketLength {
41
 	if msgLength == clientAbridgedSmallPacketLength {
42
-		buf.Grow(3)
42
+		buf.Grow(3) // nolint: gomnd
43
 
43
 
44
-		if _, err := io.CopyN(&buf, w.parent, 3); err != nil {
44
+		if _, err := io.CopyN(&buf, w.parent, 3); err != nil { // nolint: gomnd
45
 			return nil, fmt.Errorf("cannot read correct message length: %w", err)
45
 			return nil, fmt.Errorf("cannot read correct message length: %w", err)
46
 		}
46
 		}
47
 
47
 
75
 		return nil
75
 		return nil
76
 	}
76
 	}
77
 
77
 
78
-	packetLength := len(packet) / 4
78
+	packetLength := len(packet) / 4 // nolint: gomnd
79
 
79
 
80
 	switch {
80
 	switch {
81
 	case packetLength < clientAbridgedSmallPacketLength:
81
 	case packetLength < clientAbridgedSmallPacketLength:

+ 2
- 2
wrappers/packetack/client_intermediate.go Просмотреть файл

20
 func (w *wrapperClientIntermediate) Read(acks *conntypes.ConnectionAcks) (conntypes.Packet, error) {
20
 func (w *wrapperClientIntermediate) Read(acks *conntypes.ConnectionAcks) (conntypes.Packet, error) {
21
 	buf := bytes.Buffer{}
21
 	buf := bytes.Buffer{}
22
 
22
 
23
-	buf.Grow(4)
23
+	buf.Grow(4) // nolint: gomnd
24
 
24
 
25
-	if _, err := io.CopyN(&buf, w.parent, 4); err != nil {
25
+	if _, err := io.CopyN(&buf, w.parent, 4); err != nil { // nolint: gomnd
26
 		return nil, fmt.Errorf("cannot read message length: %w", err)
26
 		return nil, fmt.Errorf("cannot read message length: %w", err)
27
 	}
27
 	}
28
 
28
 

+ 2
- 2
wrappers/packetack/client_intermediate_secure.go Просмотреть файл

20
 		return nil, err
20
 		return nil, err
21
 	}
21
 	}
22
 
22
 
23
-	length := len(data) - (len(data) % 4)
23
+	length := len(data) - (len(data) % 4) // nolint: gomnd
24
 
24
 
25
 	return data[:length], nil
25
 	return data[:length], nil
26
 }
26
 }
35
 	}
35
 	}
36
 
36
 
37
 	buf := &bytes.Buffer{}
37
 	buf := &bytes.Buffer{}
38
-	paddingLength := rand.Intn(4) // nolint: gosec
38
+	paddingLength := rand.Intn(4) // nolint: gosec, gomnd
39
 
39
 
40
 	buf.Grow(4 + len(packet) + paddingLength)
40
 	buf.Grow(4 + len(packet) + paddingLength)
41
 
41
 

+ 1
- 1
wrappers/packetack/proxy.go Просмотреть файл

42
 	buf.Write(rpc.ProxyRequestProxyTag)
42
 	buf.Write(rpc.ProxyRequestProxyTag)
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)) // nolint: gomnd
46
 	buf.Grow(len(packet))
46
 	buf.Grow(len(packet))
47
 	buf.Write(packet)
47
 	buf.Write(packet)
48
 
48
 

+ 3
- 3
wrappers/stream/conn.go Просмотреть файл

93
 	connID conntypes.ConnID,
93
 	connID conntypes.ConnID,
94
 	purpose connPurpose,
94
 	purpose connPurpose,
95
 ) conntypes.StreamReadWriteCloser {
95
 ) conntypes.StreamReadWriteCloser {
96
-	localAddr := *parent.LocalAddr().(*net.TCPAddr)
96
+	localAddr := *parent.LocalAddr().(*net.TCPAddr) // nolint: forcetypeassert
97
 
97
 
98
-	if parent.RemoteAddr().(*net.TCPAddr).IP.To4() != nil {
98
+	if parent.RemoteAddr().(*net.TCPAddr).IP.To4() != nil { // nolint: forcetypeassert
99
 		if config.C.PublicIPv4.IP != nil {
99
 		if config.C.PublicIPv4.IP != nil {
100
 			localAddr.IP = config.C.PublicIPv4.IP
100
 			localAddr.IP = config.C.PublicIPv4.IP
101
 		}
101
 		}
118
 		parent:     parent,
118
 		parent:     parent,
119
 		connID:     connID,
119
 		connID:     connID,
120
 		logger:     logger,
120
 		logger:     logger,
121
-		remoteAddr: parent.RemoteAddr().(*net.TCPAddr),
121
+		remoteAddr: parent.RemoteAddr().(*net.TCPAddr), // nolint: forcetypeassert
122
 		localAddr:  &localAddr,
122
 		localAddr:  &localAddr,
123
 	}
123
 	}
124
 }
124
 }

Загрузка…
Отмена
Сохранить