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

Merge pull request #277 from 9seconds/go1.19

tags/v2.1.7^2
Sergey Arkhipov пре 3 година
родитељ
комит
db2be4001b
No account linked to committer's email address
91 измењених фајлова са 675 додато и 653 уклоњено
  1. 3
    3
      .github/workflows/ci.yaml
  2. 11
    1
      .golangci.toml
  3. 1
    1
      Dockerfile
  4. 1
    1
      Makefile
  5. 8
    8
      antireplay/init.go
  6. 2
    3
      antireplay/noop.go
  7. 9
    9
      antireplay/stable_bloom_filter.go
  8. 84
    0
      buildinfo.go
  9. 3
    3
      essentials/conns.go
  10. 2
    2
      events/event_stream.go
  11. 20
    20
      events/init.go
  12. 17
    16
      go.mod
  13. 48
    38
      go.sum
  14. 12
    12
      internal/cli/access.go
  15. 2
    2
      internal/cli/generate_secret.go
  16. 1
    1
      internal/cli/run.go
  17. 13
    8
      internal/cli/run_proxy.go
  18. 11
    11
      internal/cli/simple_run.go
  19. 2
    2
      internal/config/type_concurrency.go
  20. 2
    2
      internal/config/type_error_rate.go
  21. 1
    1
      internal/config/type_hostport.go
  22. 1
    1
      internal/config/type_port.go
  23. 1
    1
      internal/testlib/capture_output.go
  24. 3
    3
      internal/testlib/mtglib_network_mock.go
  25. 8
    8
      internal/testlib/net_conn_mock.go
  26. 1
    1
      internal/utils/net_listener.go
  27. 0
    25
      internal/utils/rlimit.go
  28. 0
    8
      internal/utils/rlimit_windows.go
  29. 8
    0
      ipblocklist/files/doc.go
  30. 3
    1
      ipblocklist/files/http.go
  31. 1
    1
      ipblocklist/files/http_test.go
  32. 7
    0
      ipblocklist/files/init.go
  33. 2
    1
      ipblocklist/files/local.go
  34. 1
    0
      ipblocklist/files/mem.go
  35. 16
    14
      ipblocklist/firehol.go
  36. 1
    1
      ipblocklist/firehol_test.go
  37. 5
    5
      ipblocklist/init.go
  38. 1
    2
      ipblocklist/noop.go
  39. 6
    8
      logger/init.go
  40. 1
    1
      logger/zerolog_test.go
  41. 1
    37
      main.go
  42. 3
    3
      mtglib/conns.go
  43. 3
    3
      mtglib/conns_internal_test.go
  44. 17
    17
      mtglib/events.go
  45. 124
    139
      mtglib/init.go
  46. 3
    3
      mtglib/internal/faketls/client_hello.go
  47. 6
    6
      mtglib/internal/faketls/conn.go
  48. 7
    7
      mtglib/internal/faketls/conn_test.go
  49. 1
    1
      mtglib/internal/faketls/pools.go
  50. 1
    1
      mtglib/internal/faketls/record/pools.go
  51. 7
    7
      mtglib/internal/faketls/welcome.go
  52. 1
    1
      mtglib/internal/obfuscated2/client_handshake_test.go
  53. 2
    2
      mtglib/internal/obfuscated2/conn.go
  54. 8
    8
      mtglib/internal/obfuscated2/handshake_frame.go
  55. 1
    1
      mtglib/internal/obfuscated2/handshake_frame_internal_test.go
  56. 2
    2
      mtglib/internal/obfuscated2/pools.go
  57. 2
    2
      mtglib/internal/obfuscated2/server_handshake.go
  58. 2
    2
      mtglib/internal/obfuscated2/server_handshake_fuzz_test.go
  59. 2
    2
      mtglib/internal/obfuscated2/server_handshake_test.go
  60. 1
    1
      mtglib/internal/relay/pools.go
  61. 2
    2
      mtglib/internal/relay/relay.go
  62. 7
    7
      mtglib/proxy.go
  63. 25
    29
      mtglib/proxy_opts.go
  64. 4
    4
      mtglib/proxy_test.go
  65. 18
    19
      mtglib/secret.go
  66. 2
    2
      mtglib/stream_context.go
  67. 1
    1
      mtglib/stream_context_internal_test.go
  68. 5
    5
      network/circuit_breaker.go
  69. 4
    4
      network/circuit_breaker_internal_test.go
  70. 2
    2
      network/default.go
  71. 1
    1
      network/default_test.go
  72. 2
    4
      network/dns_resolver.go
  73. 32
    42
      network/init.go
  74. 2
    2
      network/init_internal_test.go
  75. 4
    4
      network/init_test.go
  76. 6
    8
      network/load_balanced_socks5.go
  77. 1
    1
      network/load_balanced_socks5_test.go
  78. 3
    3
      network/network.go
  79. 4
    4
      network/network_test.go
  80. 1
    1
      network/proxy_dialer.go
  81. 5
    5
      network/proxy_dialer_internal_test.go
  82. 2
    2
      network/sockopts.go
  83. 3
    3
      network/sockopts_unix.go
  84. 3
    3
      network/socks5.go
  85. 2
    2
      network/socks5_test.go
  86. 1
    1
      stats/init.go
  87. 1
    1
      stats/pools.go
  88. 6
    7
      stats/prometheus.go
  89. 4
    4
      stats/prometheus_test.go
  90. 8
    9
      stats/statsd.go
  91. 1
    1
      stats/statsd_test.go

+ 3
- 3
.github/workflows/ci.yaml Прегледај датотеку

42
     strategy:
42
     strategy:
43
       matrix:
43
       matrix:
44
         go_version:
44
         go_version:
45
-          - ^1.18
45
+          - ^1.19
46
     steps:
46
     steps:
47
       - name: Checkout
47
       - name: Checkout
48
         uses: actions/checkout@v2
48
         uses: actions/checkout@v2
114
       - name: Setup Go
114
       - name: Setup Go
115
         uses: actions/setup-go@v2
115
         uses: actions/setup-go@v2
116
         with:
116
         with:
117
-          go-version: ^1.18
117
+          go-version: ^1.19
118
 
118
 
119
       - name: Run linter
119
       - name: Run linter
120
         uses: golangci/golangci-lint-action@v3
120
         uses: golangci/golangci-lint-action@v3
121
         with:
121
         with:
122
-          version: v1.45.0
122
+          version: v1.48.0
123
 
123
 
124
   docker:
124
   docker:
125
     name: Docker
125
     name: Docker

+ 11
- 1
.golangci.toml Прегледај датотеку

9
 
9
 
10
 [linters]
10
 [linters]
11
 enable-all = true
11
 enable-all = true
12
-disable = ["thelper", "ireturn", "varnamelen", "gochecknoglobals", "gas", "goerr113", "exhaustivestruct", "containedctx"]
12
+disable = [
13
+    "containedctx",
14
+    "exhaustivestruct",
15
+    "exhaustruct",
16
+    "gas",
17
+    "gochecknoglobals",
18
+    "goerr113",
19
+    "ireturn",
20
+    "thelper",
21
+    "varnamelen",
22
+]

+ 1
- 1
Dockerfile Прегледај датотеку

1
 ###############################################################################
1
 ###############################################################################
2
 # BUILD STAGE
2
 # BUILD STAGE
3
 
3
 
4
-FROM golang:1.18-alpine AS build
4
+FROM golang:1.19-alpine AS build
5
 
5
 
6
 RUN set -x \
6
 RUN set -x \
7
   && apk --no-cache --update add \
7
   && apk --no-cache --update add \

+ 1
- 1
Makefile Прегледај датотеку

2
 IMAGE_NAME   := mtg
2
 IMAGE_NAME   := mtg
3
 APP_NAME     := $(IMAGE_NAME)
3
 APP_NAME     := $(IMAGE_NAME)
4
 
4
 
5
-GOLANGCI_LINT_VERSION := v1.45.0
5
+GOLANGCI_LINT_VERSION := v1.48.0
6
 
6
 
7
 VERSION            := $(shell git describe --exact-match HEAD 2>/dev/null || git describe --tags --always)
7
 VERSION            := $(shell git describe --exact-match HEAD 2>/dev/null || git describe --tags --always)
8
 COMMON_BUILD_FLAGS := -trimpath -mod=readonly -ldflags="-extldflags '-static' -s -w -X 'main.version=$(VERSION)'"
8
 COMMON_BUILD_FLAGS := -trimpath -mod=readonly -ldflags="-extldflags '-static' -s -w -X 'main.version=$(VERSION)'"

+ 8
- 8
antireplay/init.go Прегледај датотеку

1
-// Antireplay package has cache implementations that are effective
2
-// against replay attacks.
1
+// Antireplay package has cache implementations that are effective against
2
+// replay attacks.
3
 //
3
 //
4
-// To understand more about replay attacks, please read documentation
5
-// for mtglib.AntiReplayCache interface. This package has a list of some
4
+// To understand more about replay attacks, please read documentation for
5
+// [mtglib.AntiReplayCache] interface. This package has a list of some
6
 // implementations of this interface.
6
 // implementations of this interface.
7
 package antireplay
7
 package antireplay
8
 
8
 
9
 const (
9
 const (
10
-	// DefaultStableBloomFilterMaxSize is a recommended byte size for a
11
-	// stable bloom filter.
10
+	// DefaultStableBloomFilterMaxSize is a recommended byte size for a stable
11
+	// bloom filter.
12
 	DefaultStableBloomFilterMaxSize = 1024 * 1024 // 1MiB
12
 	DefaultStableBloomFilterMaxSize = 1024 * 1024 // 1MiB
13
 
13
 
14
-	// DefaultStableBloomFilterErrorRate is a recommended default error
15
-	// rate for a stable bloom filter.
14
+	// DefaultStableBloomFilterErrorRate is a recommended default error rate for a
15
+	// stable bloom filter.
16
 	DefaultStableBloomFilterErrorRate = 0.001
16
 	DefaultStableBloomFilterErrorRate = 0.001
17
 )
17
 )

+ 2
- 3
antireplay/noop.go Прегледај датотеку

6
 
6
 
7
 func (n noop) SeenBefore(_ []byte) bool { return false }
7
 func (n noop) SeenBefore(_ []byte) bool { return false }
8
 
8
 
9
-// NewNoop returns an implementation that does nothing. A corresponding
10
-// method always returns false, so this cache accepts everything you
11
-// pass to it.
9
+// NewNoop returns an implementation that does nothing. A corresponding method
10
+// always returns false, so this cache accepts everything you pass to it.
12
 func NewNoop() mtglib.AntiReplayCache {
11
 func NewNoop() mtglib.AntiReplayCache {
13
 	return noop{}
12
 	return noop{}
14
 }
13
 }

+ 9
- 9
antireplay/stable_bloom_filter.go Прегледај датотеку

20
 	return s.filter.TestAndAdd(digest)
20
 	return s.filter.TestAndAdd(digest)
21
 }
21
 }
22
 
22
 
23
-// NewStableBloomFilter returns an implementation of AntiReplayCache
24
-// based on stable bloom filter.
23
+// NewStableBloomFilter returns an implementation of AntiReplayCache based on
24
+// stable bloom filter.
25
 //
25
 //
26
 // http://webdocs.cs.ualberta.ca/~drafiei/papers/DupDet06Sigmod.pdf
26
 // http://webdocs.cs.ualberta.ca/~drafiei/papers/DupDet06Sigmod.pdf
27
 //
27
 //
28
-// The basic idea of a stable bloom filter is quite simple: each time
29
-// when you set a new element, you randomly reset P elements. There is a
30
-// hardcore math which proves that if you choose this P correctly, you
31
-// can maintain the same error rate for a stream of elements.
28
+// The basic idea of a stable bloom filter is quite simple: each time when you
29
+// set a new element, you randomly reset P elements. There is a hardcore math
30
+// which proves that if you choose this P correctly, you can maintain the same
31
+// error rate for a stream of elements.
32
 //
32
 //
33
 // byteSize is the number of bytes you want to give to a bloom filter.
33
 // byteSize is the number of bytes you want to give to a bloom filter.
34
-// errorRate is desired false-positive error rate. If you want to use
35
-// default values, please pass 0 for byteSize and <0 for errorRate.
34
+// errorRate is desired false-positive error rate. If you want to use default
35
+// values, please pass 0 for byteSize and <0 for errorRate.
36
 func NewStableBloomFilter(byteSize uint, errorRate float64) mtglib.AntiReplayCache {
36
 func NewStableBloomFilter(byteSize uint, errorRate float64) mtglib.AntiReplayCache {
37
 	if byteSize == 0 {
37
 	if byteSize == 0 {
38
 		byteSize = DefaultStableBloomFilterMaxSize
38
 		byteSize = DefaultStableBloomFilterMaxSize
42
 		errorRate = DefaultStableBloomFilterErrorRate
42
 		errorRate = DefaultStableBloomFilterErrorRate
43
 	}
43
 	}
44
 
44
 
45
-	sf := boom.NewDefaultStableBloomFilter(byteSize*8, errorRate) // nolint: gomnd
45
+	sf := boom.NewDefaultStableBloomFilter(byteSize*8, errorRate) //nolint: gomnd
46
 	sf.SetHash(xxhash.New64())
46
 	sf.SetHash(xxhash.New64())
47
 
47
 
48
 	return &stableBloomFilter{
48
 	return &stableBloomFilter{

+ 84
- 0
buildinfo.go Прегледај датотеку

1
+package main
2
+
3
+import (
4
+	"crypto/sha256"
5
+	"encoding/base64"
6
+	"encoding/binary"
7
+	"fmt"
8
+	"io"
9
+	"runtime/debug"
10
+	"sort"
11
+	"strconv"
12
+	"time"
13
+)
14
+
15
+var version = "dev" // has to be set by ldflags
16
+
17
+const (
18
+	buildInfoModuleStart byte = iota
19
+	buildInfoModuleFinish
20
+	buildInfoModuleDelimeter
21
+)
22
+
23
+func getVersion() string {
24
+	buildInfo, ok := debug.ReadBuildInfo()
25
+	if !ok {
26
+		return version
27
+	}
28
+
29
+	date := time.Now()
30
+	commit := ""
31
+	goVersion := buildInfo.GoVersion
32
+	dirtySuffix := ""
33
+
34
+	for _, setting := range buildInfo.Settings {
35
+		switch setting.Key {
36
+		case "vcs.time":
37
+			date, _ = time.Parse(time.RFC3339, setting.Value)
38
+		case "vcs.revision":
39
+			commit = setting.Value
40
+		case "vcs.modified":
41
+			if dirty, _ := strconv.ParseBool(setting.Value); dirty {
42
+				dirtySuffix = " [dirty]"
43
+			}
44
+		}
45
+	}
46
+
47
+	hasher := sha256.New()
48
+
49
+	checksumModule := func(mod *debug.Module) {
50
+		hasher.Write([]byte{buildInfoModuleStart})
51
+
52
+		io.WriteString(hasher, mod.Path) //nolint: errcheck
53
+		hasher.Write([]byte{buildInfoModuleDelimeter})
54
+
55
+		io.WriteString(hasher, mod.Version) //nolint: errcheck
56
+		hasher.Write([]byte{buildInfoModuleDelimeter})
57
+
58
+		io.WriteString(hasher, mod.Sum) //nolint: errcheck
59
+
60
+		hasher.Write([]byte{buildInfoModuleFinish})
61
+	}
62
+
63
+	io.WriteString(hasher, buildInfo.Path) //nolint: errcheck
64
+
65
+	binary.Write(hasher, binary.LittleEndian, uint64(1+len(buildInfo.Deps))) //nolint: errcheck
66
+
67
+	sort.Slice(buildInfo.Deps, func(i, j int) bool {
68
+		return buildInfo.Deps[i].Path > buildInfo.Deps[j].Path
69
+	})
70
+
71
+	checksumModule(&buildInfo.Main)
72
+
73
+	for _, module := range buildInfo.Deps {
74
+		checksumModule(module)
75
+	}
76
+
77
+	return fmt.Sprintf("%s (%s: %s on %s%s, modules checksum %s)",
78
+		version,
79
+		goVersion,
80
+		date.Format(time.RFC3339),
81
+		commit,
82
+		dirtySuffix,
83
+		base64.StdEncoding.EncodeToString(hasher.Sum(nil)))
84
+}

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

5
 	"net"
5
 	"net"
6
 )
6
 )
7
 
7
 
8
-// CloseableReader is a reader interface that can close its reading end.
8
+// CloseableReader is an [io.Reader] interface that can close its reading end.
9
 type CloseableReader interface {
9
 type CloseableReader interface {
10
 	io.Reader
10
 	io.Reader
11
 	CloseRead() error
11
 	CloseRead() error
12
 }
12
 }
13
 
13
 
14
-// CloseableWriter is a writer that can close its writing end.
14
+// CloseableWriter is an [io.Writer] that can close its writing end.
15
 type CloseableWriter interface {
15
 type CloseableWriter interface {
16
 	io.Writer
16
 	io.Writer
17
 	CloseWrite() error
17
 	CloseWrite() error
18
 }
18
 }
19
 
19
 
20
-// Conn is an extension of net.Conn that can close its ends. This mostly
20
+// Conn is an extension of [net.Conn] that can close its ends. This mostly
21
 // implies TCP connections.
21
 // implies TCP connections.
22
 type Conn interface {
22
 type Conn interface {
23
 	net.Conn
23
 	net.Conn

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

9
 	"github.com/OneOfOne/xxhash"
9
 	"github.com/OneOfOne/xxhash"
10
 )
10
 )
11
 
11
 
12
-// EventStream is a default implementation of the mtglib.EventStream
12
+// EventStream is a default implementation of the [mtglib.EventStream]
13
 // interface.
13
 // interface.
14
 //
14
 //
15
 // EventStream manages a set of goroutines, observers. Main
15
 // EventStream manages a set of goroutines, observers. Main
77
 	return rv
77
 	return rv
78
 }
78
 }
79
 
79
 
80
-func eventStreamProcessor(ctx context.Context, eventChan <-chan mtglib.Event, observer Observer) { // nolint: cyclop
80
+func eventStreamProcessor(ctx context.Context, eventChan <-chan mtglib.Event, observer Observer) { //nolint: cyclop
81
 	defer observer.Shutdown()
81
 	defer observer.Shutdown()
82
 
82
 
83
 	for {
83
 	for {

+ 20
- 20
events/init.go Прегледај датотеку

1
 // Events has a default implementations of EventStream for mtglib.
1
 // Events has a default implementations of EventStream for mtglib.
2
 //
2
 //
3
-// Please see documentation for mtglib.EventStream interface to get an
4
-// idea of such an abstraction. This package has implementations for the
5
-// default event stream.
3
+// Please see documentation for [mtglib.EventStream] interface to get an idea
4
+// of such an abstraction. This package has implementations for the default
5
+// event stream.
6
 //
6
 //
7
-// Default event stream has a list of its own concepts. First, all it
8
-// does is a routing of messages to known observers. It takes an event,
9
-// defines its type and pass this message to a method of the observer.
7
+// Default event stream has a list of its own concepts. First, all it does is a
8
+// routing of messages to known observers. It takes an event, defines its type
9
+// and pass this message to a method of the observer.
10
 //
10
 //
11
-// There might be many observers, but default event stream has a
12
-// guarantee though. It uses StreamID as a sharding key and guarantees
13
-// that a message with the same StreamID will be devlivered to the same
14
-// observer instance. So, each producer is guarateed to get all relevant
15
-// messages related to the same session. It is not possible that it will
16
-// get EventFinish if it has not seen EventStart for that session yet.
11
+// There might be many observers, but default event stream has a guarantee
12
+// though. It uses StreamID as a sharding key and guarantees that a message
13
+// with the same StreamID will be devlivered to the same observer instance. So,
14
+// each producer is guarateed to get all relevant messages related to the same
15
+// session. It is not possible that it will get EventFinish if it has not seen
16
+// EventStart for that session yet.
17
 package events
17
 package events
18
 
18
 
19
 import "github.com/9seconds/mtg/v2/mtglib"
19
 import "github.com/9seconds/mtg/v2/mtglib"
21
 // Observer is an instance that listens for the incoming events.
21
 // Observer is an instance that listens for the incoming events.
22
 //
22
 //
23
 // As it is said in the package description, the default event stream
23
 // As it is said in the package description, the default event stream
24
-// guarantees that all events with the same StreamID are going to be
25
-// routed to the same instance of the observer. So, there is no need
26
-// to synchronize information about streams between many observers
27
-// instances, they can have their local storage.
24
+// guarantees that all events with the same StreamID are going to be routed to
25
+// the same instance of the observer. So, there is no need to synchronize
26
+// information about streams between many observers instances, they can have
27
+// their local storage.
28
 type Observer interface {
28
 type Observer interface {
29
 	// EventStart reacts on incoming mtglib.EventStart event.
29
 	// EventStart reacts on incoming mtglib.EventStart event.
30
 	EventStart(mtglib.EventStart)
30
 	EventStart(mtglib.EventStart)
65
 
65
 
66
 // ObserverFactory creates a new instance of the observer.
66
 // ObserverFactory creates a new instance of the observer.
67
 //
67
 //
68
-// Default event stream creates a small set of goroutines to manage
69
-// incoming messages. Each message is routed to an appropriate observer
70
-// based on a sharding key, stream id. So, it is possible that an
71
-// instance of mtg will have many observer instances, not a single one.
68
+// Default event stream creates a small set of goroutines to manage incoming
69
+// messages. Each message is routed to an appropriate observer based on a
70
+// sharding key, stream id. So, it is possible that an instance of mtg will
71
+// have many observer instances, not a single one.
72
 type ObserverFactory func() Observer
72
 type ObserverFactory func() Observer

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

4
 
4
 
5
 require (
5
 require (
6
 	github.com/OneOfOne/xxhash v1.2.8
6
 	github.com/OneOfOne/xxhash v1.2.8
7
-	github.com/alecthomas/kong v0.5.0
7
+	github.com/alecthomas/kong v0.6.1
8
 	github.com/alecthomas/units v0.0.0-20211218093645-b94a6e3cc137
8
 	github.com/alecthomas/units v0.0.0-20211218093645-b94a6e3cc137
9
 	github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5
9
 	github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5
10
 	github.com/babolivier/go-doh-client v0.0.0-20201028162107-a76cff4cb8b6
10
 	github.com/babolivier/go-doh-client v0.0.0-20201028162107-a76cff4cb8b6
13
 	github.com/gotd/td v0.34.0
13
 	github.com/gotd/td v0.34.0
14
 	github.com/jarcoal/httpmock v1.0.8
14
 	github.com/jarcoal/httpmock v1.0.8
15
 	github.com/mccutchen/go-httpbin v1.1.1
15
 	github.com/mccutchen/go-httpbin v1.1.1
16
-	github.com/panjf2000/ants/v2 v2.4.8
17
-	github.com/pelletier/go-toml v1.9.4
18
-	github.com/prometheus/client_golang v1.12.1
19
-	github.com/prometheus/common v0.32.1 // indirect
20
-	github.com/prometheus/procfs v0.7.3 // indirect
21
-	github.com/rs/zerolog v1.26.1
16
+	github.com/panjf2000/ants/v2 v2.5.0
17
+	github.com/pelletier/go-toml v1.9.5
18
+	github.com/prometheus/client_golang v1.13.0
19
+	github.com/prometheus/common v0.37.0 // indirect
20
+	github.com/prometheus/procfs v0.8.0 // indirect
21
+	github.com/rs/zerolog v1.27.0
22
 	github.com/smira/go-statsd v1.3.2
22
 	github.com/smira/go-statsd v1.3.2
23
 	github.com/stretchr/objx v0.3.0 // indirect
23
 	github.com/stretchr/objx v0.3.0 // indirect
24
-	github.com/stretchr/testify v1.7.0
24
+	github.com/stretchr/testify v1.7.2
25
 	github.com/tylertreat/BoomFilters v0.0.0-20210315201527-1a82519a3e43
25
 	github.com/tylertreat/BoomFilters v0.0.0-20210315201527-1a82519a3e43
26
-	golang.org/x/crypto v0.0.0-20220315160706-3147a52a75dd
27
-	golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2 // indirect
28
-	golang.org/x/sys v0.0.0-20220319134239-a9b59b0215f8
29
-	google.golang.org/protobuf v1.27.1 // indirect
26
+	golang.org/x/crypto v0.0.0-20220722155217-630584e8d5aa
27
+	golang.org/x/net v0.0.0-20220225172249-27dd8689420f // indirect
28
+	golang.org/x/sys v0.0.0-20220804214406-8e32c043e418
29
+	google.golang.org/protobuf v1.28.1 // indirect
30
 )
30
 )
31
 
31
 
32
 require (
32
 require (
33
-	github.com/txthinking/socks5 v0.0.0-20220212043548-414499347d4a
33
+	github.com/txthinking/socks5 v0.0.0-20220615051428-39268faee3e6
34
 	github.com/yl2chen/cidranger v1.0.2
34
 	github.com/yl2chen/cidranger v1.0.2
35
 )
35
 )
36
 
36
 
41
 	github.com/davecgh/go-spew v1.1.1 // indirect
41
 	github.com/davecgh/go-spew v1.1.1 // indirect
42
 	github.com/gotd/ige v0.1.5 // indirect
42
 	github.com/gotd/ige v0.1.5 // indirect
43
 	github.com/gotd/xor v0.1.1 // indirect
43
 	github.com/gotd/xor v0.1.1 // indirect
44
+	github.com/mattn/go-colorable v0.1.12 // indirect
45
+	github.com/mattn/go-isatty v0.0.14 // indirect
44
 	github.com/matttproud/golang_protobuf_extensions v1.0.1 // indirect
46
 	github.com/matttproud/golang_protobuf_extensions v1.0.1 // indirect
45
 	github.com/patrickmn/go-cache v2.1.0+incompatible // indirect
47
 	github.com/patrickmn/go-cache v2.1.0+incompatible // indirect
46
-	github.com/pkg/errors v0.9.1 // indirect
47
 	github.com/pmezard/go-difflib v1.0.0 // indirect
48
 	github.com/pmezard/go-difflib v1.0.0 // indirect
48
 	github.com/prometheus/client_model v0.2.0 // indirect
49
 	github.com/prometheus/client_model v0.2.0 // indirect
49
 	github.com/txthinking/runnergroup v0.0.0-20220212043759-8da8edb7dae8 // indirect
50
 	github.com/txthinking/runnergroup v0.0.0-20220212043759-8da8edb7dae8 // indirect
51
 	go.uber.org/atomic v1.7.0 // indirect
52
 	go.uber.org/atomic v1.7.0 // indirect
52
 	go.uber.org/multierr v1.6.0 // indirect
53
 	go.uber.org/multierr v1.6.0 // indirect
53
 	go.uber.org/zap v1.16.0 // indirect
54
 	go.uber.org/zap v1.16.0 // indirect
54
-	golang.org/x/sync v0.0.0-20210220032951-036812b2e83c // indirect
55
+	golang.org/x/sync v0.0.0-20220601150217-0de741cfad7f // indirect
55
 	golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 // indirect
56
 	golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 // indirect
56
-	gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b // indirect
57
+	gopkg.in/yaml.v3 v3.0.1 // indirect
57
 )
58
 )

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

37
 github.com/OneOfOne/xxhash v1.2.8 h1:31czK/TI9sNkxIKfaUfGlU47BAxQ0ztGgd9vPyqimf8=
37
 github.com/OneOfOne/xxhash v1.2.8 h1:31czK/TI9sNkxIKfaUfGlU47BAxQ0ztGgd9vPyqimf8=
38
 github.com/OneOfOne/xxhash v1.2.8/go.mod h1:eZbhyaAYD41SGSSsnmcpxVoRiQ/MPUTjUdIIOT9Um7Q=
38
 github.com/OneOfOne/xxhash v1.2.8/go.mod h1:eZbhyaAYD41SGSSsnmcpxVoRiQ/MPUTjUdIIOT9Um7Q=
39
 github.com/PuerkitoBio/goquery v1.6.1/go.mod h1:GsLWisAFVj4WgDibEWF4pvYnkVQBpKBKeU+7zCJoLcc=
39
 github.com/PuerkitoBio/goquery v1.6.1/go.mod h1:GsLWisAFVj4WgDibEWF4pvYnkVQBpKBKeU+7zCJoLcc=
40
-github.com/alecthomas/kong v0.5.0 h1:u8Kdw+eeml93qtMZ04iei0CFYve/WPcA5IFh+9wSskE=
41
-github.com/alecthomas/kong v0.5.0/go.mod h1:uzxf/HUh0tj43x1AyJROl3JT7SgsZ5m+icOv1csRhc0=
40
+github.com/alecthomas/kong v0.6.1 h1:1kNhcFepkR+HmasQpbiKDLylIL8yh5B5y1zPp5bJimA=
41
+github.com/alecthomas/kong v0.6.1/go.mod h1:JfHWDzLmbh/puW6I3V7uWenoh56YNVONW+w8eKeUr9I=
42
 github.com/alecthomas/repr v0.0.0-20210801044451-80ca428c5142 h1:8Uy0oSf5co/NZXje7U1z8Mpep++QJOldL2hs/sBQf48=
42
 github.com/alecthomas/repr v0.0.0-20210801044451-80ca428c5142 h1:8Uy0oSf5co/NZXje7U1z8Mpep++QJOldL2hs/sBQf48=
43
 github.com/alecthomas/repr v0.0.0-20210801044451-80ca428c5142/go.mod h1:2kn6fqh/zIyPLmm3ugklbEi5hg5wS435eygvNfaDQL8=
43
 github.com/alecthomas/repr v0.0.0-20210801044451-80ca428c5142/go.mod h1:2kn6fqh/zIyPLmm3ugklbEi5hg5wS435eygvNfaDQL8=
44
 github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=
44
 github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=
69
 github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU=
69
 github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU=
70
 github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
70
 github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
71
 github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc=
71
 github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc=
72
-github.com/coreos/go-systemd/v22 v22.3.2/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc=
72
+github.com/coreos/go-systemd/v22 v22.3.3-0.20220203105225-a9a7ef127534/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc=
73
 github.com/d4l3k/messagediff v1.2.1 h1:ZcAIMYsUg0EAp9X+tt8/enBE/Q8Yd5kzPynLyKptt9U=
73
 github.com/d4l3k/messagediff v1.2.1 h1:ZcAIMYsUg0EAp9X+tt8/enBE/Q8Yd5kzPynLyKptt9U=
74
 github.com/d4l3k/messagediff v1.2.1/go.mod h1:Oozbb1TVXFac9FtSIxHBMnBCq2qeH/2KkEQxENCrlLo=
74
 github.com/d4l3k/messagediff v1.2.1/go.mod h1:Oozbb1TVXFac9FtSIxHBMnBCq2qeH/2KkEQxENCrlLo=
75
 github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
75
 github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
85
 github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as=
85
 github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as=
86
 github.com/go-kit/kit v0.9.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as=
86
 github.com/go-kit/kit v0.9.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as=
87
 github.com/go-kit/log v0.1.0/go.mod h1:zbhenjAZHb184qTLMA9ZjW7ThYL0H2mk7Q6pNt4vbaY=
87
 github.com/go-kit/log v0.1.0/go.mod h1:zbhenjAZHb184qTLMA9ZjW7ThYL0H2mk7Q6pNt4vbaY=
88
+github.com/go-kit/log v0.2.0/go.mod h1:NwTd00d/i8cPZ3xOwwiv2PO5MOcx78fFErGNcVmBjv0=
88
 github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE=
89
 github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE=
89
 github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk=
90
 github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk=
90
 github.com/go-logfmt/logfmt v0.5.0/go.mod h1:wCYkCAKZfumFQihp8CzCvQ3paCTfi41vtzG1KdI/P7A=
91
 github.com/go-logfmt/logfmt v0.5.0/go.mod h1:wCYkCAKZfumFQihp8CzCvQ3paCTfi41vtzG1KdI/P7A=
92
+github.com/go-logfmt/logfmt v0.5.1/go.mod h1:WYhtIu8zTZfxdn5+rREduYbwxfcBr/Vr6KEVveWlfTs=
91
 github.com/go-openapi/inflect v0.19.0/go.mod h1:lHpZVlpIQqLyKwJ4N+YSc9hchQy/i12fJykb83CRBH4=
93
 github.com/go-openapi/inflect v0.19.0/go.mod h1:lHpZVlpIQqLyKwJ4N+YSc9hchQy/i12fJykb83CRBH4=
92
 github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY=
94
 github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY=
93
 github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA=
95
 github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA=
130
 github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
132
 github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
131
 github.com/google/go-cmp v0.5.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
133
 github.com/google/go-cmp v0.5.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
132
 github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
134
 github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
133
-github.com/google/go-cmp v0.5.5 h1:Khx7svrCpmxxtHBq5j2mp/xVjsi8hQMfNLvJFAlrGgU=
134
 github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
135
 github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
136
+github.com/google/go-cmp v0.5.8 h1:e6P7q2lk1O+qJJb4BtCQXlK8vWEO8V1ZeuEdJNOqZyg=
135
 github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
137
 github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
136
 github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs=
138
 github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs=
137
 github.com/google/martian/v3 v3.0.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0=
139
 github.com/google/martian/v3 v3.0.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0=
182
 github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE=
184
 github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE=
183
 github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
185
 github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
184
 github.com/mattn/go-colorable v0.1.2/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE=
186
 github.com/mattn/go-colorable v0.1.2/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE=
187
+github.com/mattn/go-colorable v0.1.12 h1:jF+Du6AlPIjs2BiUiQlKOX0rt3SujHxPnksPKZbaA40=
188
+github.com/mattn/go-colorable v0.1.12/go.mod h1:u5H1YNBxpqRaxsYJYSkiCWKzEfiAb1Gb520KVy5xxl4=
185
 github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s=
189
 github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s=
186
 github.com/mattn/go-isatty v0.0.9/go.mod h1:YNRxwqDuOph6SZLI9vUUz6OYw3QyUt7WiY2yME+cCiQ=
190
 github.com/mattn/go-isatty v0.0.9/go.mod h1:YNRxwqDuOph6SZLI9vUUz6OYw3QyUt7WiY2yME+cCiQ=
191
+github.com/mattn/go-isatty v0.0.14 h1:yVuAays6BHfxijgZPzw+3Zlu5yQgKGP2/hcQbHb7S9Y=
192
+github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94=
187
 github.com/matttproud/golang_protobuf_extensions v1.0.1 h1:4hp9jkHxhMHkqkrB3Ix0jegS5sx/RkqARlsWZ6pIwiU=
193
 github.com/matttproud/golang_protobuf_extensions v1.0.1 h1:4hp9jkHxhMHkqkrB3Ix0jegS5sx/RkqARlsWZ6pIwiU=
188
 github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0=
194
 github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0=
189
 github.com/mccutchen/go-httpbin v1.1.1 h1:aEws49HEJEyXHLDnshQVswfUlCVoS8g6h9YaDyaW7RE=
195
 github.com/mccutchen/go-httpbin v1.1.1 h1:aEws49HEJEyXHLDnshQVswfUlCVoS8g6h9YaDyaW7RE=
195
 github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk=
201
 github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk=
196
 github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U=
202
 github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U=
197
 github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U=
203
 github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U=
198
-github.com/panjf2000/ants/v2 v2.4.8 h1:JgTbolX6K6RreZ4+bfctI0Ifs+3mrE5BIHudQxUDQ9k=
199
-github.com/panjf2000/ants/v2 v2.4.8/go.mod h1:f6F0NZVFsGCp5A7QW/Zj/m92atWwOkY0OIhFxRNFr4A=
204
+github.com/panjf2000/ants/v2 v2.5.0 h1:1rWGWSnxCsQBga+nQbA4/iY6VMeNoOIAM0ZWh9u3q2Q=
205
+github.com/panjf2000/ants/v2 v2.5.0/go.mod h1:cU93usDlihJZ5CfRGNDYsiBYvoilLvBF5Qp/BT2GNRE=
200
 github.com/patrickmn/go-cache v2.1.0+incompatible h1:HRMgzkcYKYpi3C8ajMPV8OFXaaRUnok+kx1WdO15EQc=
206
 github.com/patrickmn/go-cache v2.1.0+incompatible h1:HRMgzkcYKYpi3C8ajMPV8OFXaaRUnok+kx1WdO15EQc=
201
 github.com/patrickmn/go-cache v2.1.0+incompatible/go.mod h1:3Qf8kWWT7OJRJbdiICTKqZju1ZixQ/KpMGzzAfe6+WQ=
207
 github.com/patrickmn/go-cache v2.1.0+incompatible/go.mod h1:3Qf8kWWT7OJRJbdiICTKqZju1ZixQ/KpMGzzAfe6+WQ=
202
-github.com/pelletier/go-toml v1.9.4 h1:tjENF6MfZAg8e4ZmZTeWaWiT2vXtsoO6+iuOjFhECwM=
203
-github.com/pelletier/go-toml v1.9.4/go.mod h1:u1nR/EPcESfeI/szUZKdtJ0xRNbUoANCkoOuaOx1Y+c=
208
+github.com/pelletier/go-toml v1.9.5 h1:4yBQzkHv+7BHq2PQUZF3Mx0IYxG7LsP222s7Agd3ve8=
209
+github.com/pelletier/go-toml v1.9.5/go.mod h1:u1nR/EPcESfeI/szUZKdtJ0xRNbUoANCkoOuaOx1Y+c=
204
 github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e/go.mod h1:pJLUxLENpZxwdsKMEsNbx1VGcRFpLqf3715MtcvvzbA=
210
 github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e/go.mod h1:pJLUxLENpZxwdsKMEsNbx1VGcRFpLqf3715MtcvvzbA=
205
 github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
211
 github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
206
 github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
212
 github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
212
 github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5FsnadC4Ky3P0J6CfImo=
218
 github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5FsnadC4Ky3P0J6CfImo=
213
 github.com/prometheus/client_golang v1.7.1/go.mod h1:PY5Wy2awLA44sXw4AOSfFBetzPP4j5+D6mVACh+pe2M=
219
 github.com/prometheus/client_golang v1.7.1/go.mod h1:PY5Wy2awLA44sXw4AOSfFBetzPP4j5+D6mVACh+pe2M=
214
 github.com/prometheus/client_golang v1.11.0/go.mod h1:Z6t4BnS23TR94PD6BsDNk8yVqroYurpAkEiz0P2BEV0=
220
 github.com/prometheus/client_golang v1.11.0/go.mod h1:Z6t4BnS23TR94PD6BsDNk8yVqroYurpAkEiz0P2BEV0=
215
-github.com/prometheus/client_golang v1.12.1 h1:ZiaPsmm9uiBeaSMRznKsCDNtPCS0T3JVDGF+06gjBzk=
216
 github.com/prometheus/client_golang v1.12.1/go.mod h1:3Z9XVyYiZYEO+YQWt3RD2R3jrbd179Rt297l4aS6nDY=
221
 github.com/prometheus/client_golang v1.12.1/go.mod h1:3Z9XVyYiZYEO+YQWt3RD2R3jrbd179Rt297l4aS6nDY=
222
+github.com/prometheus/client_golang v1.13.0 h1:b71QUfeo5M8gq2+evJdTPfZhYMAU0uKPkyPJ7TPsloU=
223
+github.com/prometheus/client_golang v1.13.0/go.mod h1:vTeo+zgvILHsnnj/39Ou/1fPN5nJFOEMgftOUOmlvYQ=
217
 github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo=
224
 github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo=
218
 github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
225
 github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
219
 github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
226
 github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
222
 github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4=
229
 github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4=
223
 github.com/prometheus/common v0.10.0/go.mod h1:Tlit/dnDKsSWFlCLTWaA1cyBgKHSMdTB80sz/V91rCo=
230
 github.com/prometheus/common v0.10.0/go.mod h1:Tlit/dnDKsSWFlCLTWaA1cyBgKHSMdTB80sz/V91rCo=
224
 github.com/prometheus/common v0.26.0/go.mod h1:M7rCNAaPfAosfx8veZJCuw84e35h3Cfd9VFqTh1DIvc=
231
 github.com/prometheus/common v0.26.0/go.mod h1:M7rCNAaPfAosfx8veZJCuw84e35h3Cfd9VFqTh1DIvc=
225
-github.com/prometheus/common v0.32.1 h1:hWIdL3N2HoUx3B8j3YN9mWor0qhY/NlEKZEaXxuIRh4=
226
 github.com/prometheus/common v0.32.1/go.mod h1:vu+V0TpY+O6vW9J44gczi3Ap/oXXR10b+M/gUGO4Hls=
232
 github.com/prometheus/common v0.32.1/go.mod h1:vu+V0TpY+O6vW9J44gczi3Ap/oXXR10b+M/gUGO4Hls=
233
+github.com/prometheus/common v0.37.0 h1:ccBbHCgIiT9uSoFY0vX8H3zsNR5eLt17/RQLUvn8pXE=
234
+github.com/prometheus/common v0.37.0/go.mod h1:phzohg0JFMnBEFGxTDbfu3QyL5GI8gTQJFhYO5B3mfA=
227
 github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
235
 github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
228
 github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA=
236
 github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA=
229
 github.com/prometheus/procfs v0.1.3/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU=
237
 github.com/prometheus/procfs v0.1.3/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU=
230
 github.com/prometheus/procfs v0.6.0/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA=
238
 github.com/prometheus/procfs v0.6.0/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA=
231
-github.com/prometheus/procfs v0.7.3 h1:4jVXhlkAyzOScmCkXBTOLRLTz8EeU+eyjrwB/EPq0VU=
232
 github.com/prometheus/procfs v0.7.3/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA=
239
 github.com/prometheus/procfs v0.7.3/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA=
240
+github.com/prometheus/procfs v0.8.0 h1:ODq8ZFEaYeCaZOJlZZdJA2AbQR98dSHSM1KW/You5mo=
241
+github.com/prometheus/procfs v0.8.0/go.mod h1:z7EfXMXOkbkqb9IINtpCn86r/to3BnA0uaxHdg830/4=
233
 github.com/quasilyte/go-ruleguard/dsl v0.3.2/go.mod h1:KeCP03KrjuSO0H1kTuZQCWlQPulDV6YMIXmpQss17rU=
242
 github.com/quasilyte/go-ruleguard/dsl v0.3.2/go.mod h1:KeCP03KrjuSO0H1kTuZQCWlQPulDV6YMIXmpQss17rU=
234
 github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
243
 github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
235
 github.com/rogpeppe/go-internal v1.8.0/go.mod h1:WmiCO8CzOY8rg0OYDC4/i/2WRWAB6poM+XZ2dLUbcbE=
244
 github.com/rogpeppe/go-internal v1.8.0/go.mod h1:WmiCO8CzOY8rg0OYDC4/i/2WRWAB6poM+XZ2dLUbcbE=
236
 github.com/rs/xid v1.3.0/go.mod h1:trrq9SKmegXys3aeAKXMUTdJsYXVwGY3RLcfgqegfbg=
245
 github.com/rs/xid v1.3.0/go.mod h1:trrq9SKmegXys3aeAKXMUTdJsYXVwGY3RLcfgqegfbg=
237
-github.com/rs/zerolog v1.26.1 h1:/ihwxqH+4z8UxyI70wM1z9yCvkWcfz/a3mj48k/Zngc=
238
-github.com/rs/zerolog v1.26.1/go.mod h1:/wSSJWX7lVrsOwlbyTRSOJvqRlc+WjWlfes+CiJ+tmc=
246
+github.com/rs/zerolog v1.27.0 h1:1T7qCieN22GVc8S4Q2yuexzBb1EqjbgjSH9RohbMjKs=
247
+github.com/rs/zerolog v1.27.0/go.mod h1:7frBqO0oezxmnO7GF86FY++uy8I0Tk/If5ni1G9Qc0U=
239
 github.com/sebdah/goldie/v2 v2.5.3/go.mod h1:oZ9fp0+se1eapSRjfYbsV/0Hqhbuu3bJVvKI/NNtssI=
248
 github.com/sebdah/goldie/v2 v2.5.3/go.mod h1:oZ9fp0+se1eapSRjfYbsV/0Hqhbuu3bJVvKI/NNtssI=
240
 github.com/sergi/go-diff v1.0.0/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAmXWZgo=
249
 github.com/sergi/go-diff v1.0.0/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAmXWZgo=
241
 github.com/sergi/go-diff v1.1.0/go.mod h1:STckp+ISIX8hZLjrqAeVduY0gWCT9IjLuqbuNXdaHfM=
250
 github.com/sergi/go-diff v1.1.0/go.mod h1:STckp+ISIX8hZLjrqAeVduY0gWCT9IjLuqbuNXdaHfM=
252
 github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
261
 github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
253
 github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
262
 github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
254
 github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
263
 github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
255
-github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY=
256
 github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
264
 github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
265
+github.com/stretchr/testify v1.7.2 h1:4jaiDzPyXQvSd7D0EjG45355tLlV3VOECpq10pLC+8s=
266
+github.com/stretchr/testify v1.7.2/go.mod h1:R6va5+xMeoiuVRoj+gSkQ7d3FALtqAAGI1FQKckRals=
257
 github.com/txthinking/runnergroup v0.0.0-20210608031112-152c7c4432bf/go.mod h1:CLUSJbazqETbaR+i0YAhXBICV9TrKH93pziccMhmhpM=
267
 github.com/txthinking/runnergroup v0.0.0-20210608031112-152c7c4432bf/go.mod h1:CLUSJbazqETbaR+i0YAhXBICV9TrKH93pziccMhmhpM=
258
 github.com/txthinking/runnergroup v0.0.0-20220212043759-8da8edb7dae8 h1:iYc+JnXtzv6sdMx9Q7OTKkDAn7FhDPDogcjeSfEQcLY=
268
 github.com/txthinking/runnergroup v0.0.0-20220212043759-8da8edb7dae8 h1:iYc+JnXtzv6sdMx9Q7OTKkDAn7FhDPDogcjeSfEQcLY=
259
 github.com/txthinking/runnergroup v0.0.0-20220212043759-8da8edb7dae8/go.mod h1:CLUSJbazqETbaR+i0YAhXBICV9TrKH93pziccMhmhpM=
269
 github.com/txthinking/runnergroup v0.0.0-20220212043759-8da8edb7dae8/go.mod h1:CLUSJbazqETbaR+i0YAhXBICV9TrKH93pziccMhmhpM=
260
-github.com/txthinking/socks5 v0.0.0-20220212043548-414499347d4a h1:BOqgJ4jku0LHPDoR51RD8Mxmo0LHxCzJT/M9MemYdHo=
261
-github.com/txthinking/socks5 v0.0.0-20220212043548-414499347d4a/go.mod h1:7NloQcrxaZYKURWph5HLxVDlIwMHJXCPkeWPtpftsIg=
270
+github.com/txthinking/socks5 v0.0.0-20220615051428-39268faee3e6 h1:8DkPbOq/EPxbD5VJajKuvssiYZJSrlpeetcGfrBoBVE=
271
+github.com/txthinking/socks5 v0.0.0-20220615051428-39268faee3e6/go.mod h1:7NloQcrxaZYKURWph5HLxVDlIwMHJXCPkeWPtpftsIg=
262
 github.com/txthinking/x v0.0.0-20210326105829-476fab902fbe h1:gMWxZxBFRAXqoGkwkYlPX2zvyyKNWJpxOxCrjqJkm5A=
272
 github.com/txthinking/x v0.0.0-20210326105829-476fab902fbe h1:gMWxZxBFRAXqoGkwkYlPX2zvyyKNWJpxOxCrjqJkm5A=
263
 github.com/txthinking/x v0.0.0-20210326105829-476fab902fbe/go.mod h1:WgqbSEmUYSjEV3B1qmee/PpP2NYEz4bL9/+mF1ma+s4=
273
 github.com/txthinking/x v0.0.0-20210326105829-476fab902fbe/go.mod h1:WgqbSEmUYSjEV3B1qmee/PpP2NYEz4bL9/+mF1ma+s4=
264
 github.com/tylertreat/BoomFilters v0.0.0-20210315201527-1a82519a3e43 h1:QEePdg0ty2r0t1+qwfZmQ4OOl/MB2UXIeJSpIZv56lg=
274
 github.com/tylertreat/BoomFilters v0.0.0-20210315201527-1a82519a3e43 h1:QEePdg0ty2r0t1+qwfZmQ4OOl/MB2UXIeJSpIZv56lg=
268
 github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
278
 github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
269
 github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
279
 github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
270
 github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
280
 github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
271
-github.com/yuin/goldmark v1.4.0/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k=
272
 go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU=
281
 go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU=
273
 go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8=
282
 go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8=
274
 go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
283
 go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
290
 golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
299
 golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
291
 golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
300
 golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
292
 golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
301
 golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
293
-golang.org/x/crypto v0.0.0-20211215165025-cf75a172585e/go.mod h1:P+XmwS30IXTQdn5tA2iutPOUgjI07+tq3H3K9MVA1s8=
294
-golang.org/x/crypto v0.0.0-20220315160706-3147a52a75dd h1:XcWmESyNjXJMLahc3mqVQJcgSTDxFxhETVlfk9uGc38=
295
-golang.org/x/crypto v0.0.0-20220315160706-3147a52a75dd/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
302
+golang.org/x/crypto v0.0.0-20220722155217-630584e8d5aa h1:zuSxTR4o9y82ebqCUJYNGJbGPo6sKVl54f/TVDObg1c=
303
+golang.org/x/crypto v0.0.0-20220722155217-630584e8d5aa/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
296
 golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
304
 golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
297
 golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
305
 golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
298
 golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8=
306
 golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8=
323
 golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg=
331
 golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg=
324
 golang.org/x/mod v0.1.1-0.20191107180719-034126e5016b/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg=
332
 golang.org/x/mod v0.1.1-0.20191107180719-034126e5016b/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg=
325
 golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
333
 golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
334
+golang.org/x/mod v0.3.0 h1:RM4zey1++hCTbCVQfnWeKs9/IEsaBLA8vTkd0WVtmH4=
326
 golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
335
 golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
327
-golang.org/x/mod v0.4.2 h1:Gz96sIWK3OalVv/I/qNygP42zyoKp3xptRVCWRFEBvo=
328
-golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
329
 golang.org/x/net v0.0.0-20180218175443-cbe0f9307d01/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
336
 golang.org/x/net v0.0.0-20180218175443-cbe0f9307d01/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
330
 golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
337
 golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
331
 golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
338
 golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
356
 golang.org/x/net v0.0.0-20200707034311-ab3426394381/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
363
 golang.org/x/net v0.0.0-20200707034311-ab3426394381/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
357
 golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
364
 golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
358
 golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
365
 golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
359
-golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
360
 golang.org/x/net v0.0.0-20210525063256-abc453219eb5/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
366
 golang.org/x/net v0.0.0-20210525063256-abc453219eb5/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
361
-golang.org/x/net v0.0.0-20210805182204-aaa1db679c0d/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
362
-golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2 h1:CIJ76btIcR3eFI5EgSo6k1qKw9KJexJuRLI9G7Hp5wE=
363
-golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
367
+golang.org/x/net v0.0.0-20220127200216-cd36cc0744dd/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk=
368
+golang.org/x/net v0.0.0-20220225172249-27dd8689420f h1:oA4XRj0qtSt8Yo1Zms0CUlsT3KG69V2UGQWPBxujDmc=
369
+golang.org/x/net v0.0.0-20220225172249-27dd8689420f/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk=
364
 golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
370
 golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
365
 golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
371
 golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
366
 golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
372
 golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
367
 golang.org/x/oauth2 v0.0.0-20191202225959-858c2ad4c8b6/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
373
 golang.org/x/oauth2 v0.0.0-20191202225959-858c2ad4c8b6/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
368
 golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
374
 golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
369
 golang.org/x/oauth2 v0.0.0-20210514164344-f6687ab2804c/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
375
 golang.org/x/oauth2 v0.0.0-20210514164344-f6687ab2804c/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
376
+golang.org/x/oauth2 v0.0.0-20220223155221-ee480838109b/go.mod h1:DAh4E804XQdzx2j+YRIaUnCqCV2RuMz24cGBJ5QYIrc=
370
 golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
377
 golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
371
 golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
378
 golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
372
 golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
379
 golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
376
 golang.org/x/sync v0.0.0-20200317015054-43a5402ce75a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
383
 golang.org/x/sync v0.0.0-20200317015054-43a5402ce75a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
377
 golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
384
 golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
378
 golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
385
 golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
379
-golang.org/x/sync v0.0.0-20210220032951-036812b2e83c h1:5KslGYwFpkhGh+Q16bwMP3cOontH8FOep7tGV86Y7SQ=
380
-golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
386
+golang.org/x/sync v0.0.0-20220601150217-0de741cfad7f h1:Ax0t5p6N38Ga0dThY21weqDEyz2oklo4IvDkpigvkD8=
387
+golang.org/x/sync v0.0.0-20220601150217-0de741cfad7f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
381
 golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
388
 golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
382
 golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
389
 golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
383
 golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
390
 golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
416
 golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
423
 golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
417
 golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
424
 golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
418
 golang.org/x/sys v0.0.0-20210603081109-ebe580a85c40/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
425
 golang.org/x/sys v0.0.0-20210603081109-ebe580a85c40/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
419
-golang.org/x/sys v0.0.0-20210809222454-d867a43fc93e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
426
+golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
427
+golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
428
+golang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
429
+golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
420
 golang.org/x/sys v0.0.0-20220114195835-da31bd327af9/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
430
 golang.org/x/sys v0.0.0-20220114195835-da31bd327af9/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
421
-golang.org/x/sys v0.0.0-20220319134239-a9b59b0215f8 h1:OH54vjqzRWmbJ62fjuhxy7AxFFgoHN0/DPc/UrL8cAs=
422
-golang.org/x/sys v0.0.0-20220319134239-a9b59b0215f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
431
+golang.org/x/sys v0.0.0-20220804214406-8e32c043e418 h1:9vYwv7OjYaky/tlAeD7C4oC9EsPTlaFl1H2jS++V+ME=
432
+golang.org/x/sys v0.0.0-20220804214406-8e32c043e418/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
423
 golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
433
 golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
434
+golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
424
 golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
435
 golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
425
 golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
436
 golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
426
 golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
437
 golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
427
 golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
438
 golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
428
 golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
439
 golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
429
 golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
440
 golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
441
+golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
430
 golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
442
 golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
431
 golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
443
 golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
432
 golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
444
 golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
472
 golang.org/x/tools v0.0.0-20200729194436-6467de6f59a7/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA=
484
 golang.org/x/tools v0.0.0-20200729194436-6467de6f59a7/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA=
473
 golang.org/x/tools v0.0.0-20200804011535-6c149bb5ef0d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA=
485
 golang.org/x/tools v0.0.0-20200804011535-6c149bb5ef0d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA=
474
 golang.org/x/tools v0.0.0-20200820010801-b793a1359eac/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA=
486
 golang.org/x/tools v0.0.0-20200820010801-b793a1359eac/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA=
487
+golang.org/x/tools v0.0.0-20200825202427-b303f430e36d h1:W07d4xkoAUSNOkOzdzXCdFGxT7o2rW4q8M34tB2i//k=
475
 golang.org/x/tools v0.0.0-20200825202427-b303f430e36d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA=
488
 golang.org/x/tools v0.0.0-20200825202427-b303f430e36d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA=
476
-golang.org/x/tools v0.1.7 h1:6j8CgantCy3yc8JGBqkDLMKWqZ0RDU2g1HVgacojGWQ=
477
-golang.org/x/tools v0.1.7/go.mod h1:LGqMHiF4EqQNHR1JncWGqT5BVaXmza+X+BDGol+dOxo=
478
 golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
489
 golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
479
 golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
490
 golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
480
 golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
491
 golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
555
 google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c=
566
 google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c=
556
 google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw=
567
 google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw=
557
 google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
568
 google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
558
-google.golang.org/protobuf v1.27.1 h1:SnqbnDw1V7RiZcXPx5MEeqPv2s79L9i7BJUlG/+RurQ=
559
-google.golang.org/protobuf v1.27.1/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
569
+google.golang.org/protobuf v1.28.1 h1:d0NfwRgPtno5B1Wa6L2DAG+KivqkdutMf1UhdNx175w=
570
+google.golang.org/protobuf v1.28.1/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I=
560
 gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw=
571
 gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw=
561
 gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
572
 gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
562
 gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
573
 gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
567
 gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
578
 gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
568
 gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
579
 gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
569
 gopkg.in/yaml.v2 v2.2.5/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
580
 gopkg.in/yaml.v2 v2.2.5/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
570
-gopkg.in/yaml.v2 v2.2.7/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
571
 gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
581
 gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
572
 gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY=
582
 gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY=
573
 gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
583
 gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
574
 gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
584
 gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
575
-gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b h1:h8qDotaEPuJATrMmW04NCwg7v22aHH28wwpauUhK9Oo=
576
-gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
585
+gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
586
+gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
577
 honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
587
 honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
578
 honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
588
 honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
579
 honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
589
 honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=

+ 12
- 12
internal/cli/access.go Прегледај датотеку

31
 type accessResponseURLs struct {
31
 type accessResponseURLs struct {
32
 	IP        net.IP `json:"ip"`
32
 	IP        net.IP `json:"ip"`
33
 	Port      uint   `json:"port"`
33
 	Port      uint   `json:"port"`
34
-	TgURL     string `json:"tg_url"`     // nolint: tagliatelle
35
-	TgQrCode  string `json:"tg_qrcode"`  // nolint: tagliatelle
36
-	TmeURL    string `json:"tme_url"`    // nolint: tagliatelle
37
-	TmeQrCode string `json:"tme_qrcode"` // nolint: tagliatelle
34
+	TgURL     string `json:"tg_url"`     //nolint: tagliatelle
35
+	TgQrCode  string `json:"tg_qrcode"`  //nolint: tagliatelle
36
+	TmeURL    string `json:"tme_url"`    //nolint: tagliatelle
37
+	TmeQrCode string `json:"tme_qrcode"` //nolint: tagliatelle
38
 }
38
 }
39
 
39
 
40
 type Access struct {
40
 type Access struct {
41
-	ConfigPath string `kong:"arg,required,type='existingfile',help='Path to the configuration file.',name='config-path'"`                 // nolint: lll
42
-	PublicIPv4 net.IP `kong:"help='Public IPv4 address for proxy. By default it is resolved via remote website',name='ipv4',short='i'"`   // nolint: lll
43
-	PublicIPv6 net.IP `kong:"help='Public IPv6 address for proxy. By default it is resolved via remote website',name='ipv6',short='I'"`   // nolint: lll
44
-	Port       uint   `kong:"help='Port number. Default port is taken from configuration file, bind-to parameter',type:'uint',short='p'"` // nolint: lll
41
+	ConfigPath string `kong:"arg,required,type='existingfile',help='Path to the configuration file.',name='config-path'"`                 //nolint: lll
42
+	PublicIPv4 net.IP `kong:"help='Public IPv4 address for proxy. By default it is resolved via remote website',name='ipv4',short='i'"`   //nolint: lll
43
+	PublicIPv6 net.IP `kong:"help='Public IPv6 address for proxy. By default it is resolved via remote website',name='ipv6',short='I'"`   //nolint: lll
44
+	Port       uint   `kong:"help='Port number. Default port is taken from configuration file, bind-to parameter',type:'uint',short='p'"` //nolint: lll
45
 	Hex        bool   `kong:"help='Print secret in hex encoding.',short='x'"`
45
 	Hex        bool   `kong:"help='Print secret in hex encoding.',short='x'"`
46
 }
46
 }
47
 
47
 
61
 	}
61
 	}
62
 
62
 
63
 	wg := &sync.WaitGroup{}
63
 	wg := &sync.WaitGroup{}
64
-	wg.Add(2) // nolint: gomnd
64
+	wg.Add(2) //nolint: gomnd
65
 
65
 
66
 	go func() {
66
 	go func() {
67
 		defer wg.Done()
67
 		defer wg.Done()
108
 
108
 
109
 func (a *Access) getIP(ntw mtglib.Network, protocol string) net.IP {
109
 func (a *Access) getIP(ntw mtglib.Network, protocol string) net.IP {
110
 	client := ntw.MakeHTTPClient(func(ctx context.Context, network, address string) (essentials.Conn, error) {
110
 	client := ntw.MakeHTTPClient(func(ctx context.Context, network, address string) (essentials.Conn, error) {
111
-		return ntw.DialContext(ctx, protocol, address) // nolint: wrapcheck
111
+		return ntw.DialContext(ctx, protocol, address) //nolint: wrapcheck
112
 	})
112
 	})
113
 
113
 
114
-	req, err := http.NewRequest(http.MethodGet, "https://ifconfig.co", nil) // nolint: noctx
114
+	req, err := http.NewRequest(http.MethodGet, "https://ifconfig.co", nil) //nolint: noctx
115
 	if err != nil {
115
 	if err != nil {
116
 		panic(err)
116
 		panic(err)
117
 	}
117
 	}
128
 	}
128
 	}
129
 
129
 
130
 	defer func() {
130
 	defer func() {
131
-		io.Copy(io.Discard, resp.Body) // nolint: errcheck
131
+		io.Copy(io.Discard, resp.Body) //nolint: errcheck
132
 		resp.Body.Close()
132
 		resp.Body.Close()
133
 	}()
133
 	}()
134
 
134
 

+ 2
- 2
internal/cli/generate_secret.go Прегледај датотеку

15
 	secret := mtglib.GenerateSecret(cli.GenerateSecret.HostName)
15
 	secret := mtglib.GenerateSecret(cli.GenerateSecret.HostName)
16
 
16
 
17
 	if g.Hex {
17
 	if g.Hex {
18
-		fmt.Println(secret.Hex()) // nolint: forbidigo
18
+		fmt.Println(secret.Hex()) //nolint: forbidigo
19
 	} else {
19
 	} else {
20
-		fmt.Println(secret.Base64()) // nolint: forbidigo
20
+		fmt.Println(secret.Base64()) //nolint: forbidigo
21
 	}
21
 	}
22
 
22
 
23
 	return nil
23
 	return nil

+ 1
- 1
internal/cli/run.go Прегледај датотеку

7
 )
7
 )
8
 
8
 
9
 type Run struct {
9
 type Run struct {
10
-	ConfigPath string `kong:"arg,required,type='existingfile',help='Path to the configuration file.',name='config-path'"` // nolint: lll
10
+	ConfigPath string `kong:"arg,required,type='existingfile',help='Path to the configuration file.',name='config-path'"` //nolint: lll
11
 }
11
 }
12
 
12
 
13
 func (r *Run) Run(cli *CLI, version string) error {
13
 func (r *Run) Run(cli *CLI, version string) error {

+ 13
- 8
internal/cli/run_proxy.go Прегледај датотеку

49
 	}
49
 	}
50
 
50
 
51
 	if len(conf.Network.Proxies) == 0 {
51
 	if len(conf.Network.Proxies) == 0 {
52
-		return network.NewNetwork(baseDialer, userAgent, dohIP, httpTimeout) // nolint: wrapcheck
52
+		return network.NewNetwork(baseDialer, userAgent, dohIP, httpTimeout) //nolint: wrapcheck
53
 	}
53
 	}
54
 
54
 
55
 	proxyURLs := make([]*url.URL, 0, len(conf.Network.Proxies))
55
 	proxyURLs := make([]*url.URL, 0, len(conf.Network.Proxies))
66
 			return nil, fmt.Errorf("cannot build socks5 dialer: %w", err)
66
 			return nil, fmt.Errorf("cannot build socks5 dialer: %w", err)
67
 		}
67
 		}
68
 
68
 
69
-		return network.NewNetwork(socksDialer, userAgent, dohIP, httpTimeout) // nolint: wrapcheck
69
+		return network.NewNetwork(socksDialer, userAgent, dohIP, httpTimeout) //nolint: wrapcheck
70
 	}
70
 	}
71
 
71
 
72
 	socksDialer, err := network.NewLoadBalancedSocks5Dialer(baseDialer, proxyURLs)
72
 	socksDialer, err := network.NewLoadBalancedSocks5Dialer(baseDialer, proxyURLs)
74
 		return nil, fmt.Errorf("cannot build socks5 dialer: %w", err)
74
 		return nil, fmt.Errorf("cannot build socks5 dialer: %w", err)
75
 	}
75
 	}
76
 
76
 
77
-	return network.NewNetwork(socksDialer, userAgent, dohIP, httpTimeout) // nolint: wrapcheck
77
+	return network.NewNetwork(socksDialer, userAgent, dohIP, httpTimeout) //nolint: wrapcheck
78
 }
78
 }
79
 
79
 
80
 func makeAntiReplayCache(conf *config.Config) mtglib.AntiReplayCache {
80
 func makeAntiReplayCache(conf *config.Config) mtglib.AntiReplayCache {
127
 	logger mtglib.Logger,
127
 	logger mtglib.Logger,
128
 	ntw mtglib.Network,
128
 	ntw mtglib.Network,
129
 	updateCallback ipblocklist.FireholUpdateCallback,
129
 	updateCallback ipblocklist.FireholUpdateCallback,
130
-) (allowlist mtglib.IPBlocklist, err error) {
130
+) (mtglib.IPBlocklist, error) {
131
+	var (
132
+		allowlist mtglib.IPBlocklist
133
+		err       error
134
+	)
135
+
131
 	if !conf.Enabled.Get(false) {
136
 	if !conf.Enabled.Get(false) {
132
 		allowlist, err = ipblocklist.NewFireholFromFiles(
137
 		allowlist, err = ipblocklist.NewFireholFromFiles(
133
 			logger.Named("ipblocklist"),
138
 			logger.Named("ipblocklist"),
159
 }
164
 }
160
 
165
 
161
 func makeEventStream(conf *config.Config, logger mtglib.Logger) (mtglib.EventStream, error) {
166
 func makeEventStream(conf *config.Config, logger mtglib.Logger) (mtglib.EventStream, error) {
162
-	factories := make([]events.ObserverFactory, 0, 2) // nolint: gomnd
167
+	factories := make([]events.ObserverFactory, 0, 2) //nolint: gomnd
163
 
168
 
164
 	if conf.Stats.StatsD.Enabled.Get(false) {
169
 	if conf.Stats.StatsD.Enabled.Get(false) {
165
 		statsdFactory, err := stats.NewStatsd(
170
 		statsdFactory, err := stats.NewStatsd(
185
 			return nil, fmt.Errorf("cannot start a listener for prometheus: %w", err)
190
 			return nil, fmt.Errorf("cannot start a listener for prometheus: %w", err)
186
 		}
191
 		}
187
 
192
 
188
-		go prometheus.Serve(listener) // nolint: errcheck
193
+		go prometheus.Serve(listener) //nolint: errcheck
189
 
194
 
190
 		factories = append(factories, prometheus.Make)
195
 		factories = append(factories, prometheus.Make)
191
 	}
196
 	}
197
 	return events.NewNoopStream(), nil
202
 	return events.NewNoopStream(), nil
198
 }
203
 }
199
 
204
 
200
-func runProxy(conf *config.Config, version string) error { // nolint: funlen
205
+func runProxy(conf *config.Config, version string) error { //nolint: funlen
201
 	logger := makeLogger(conf)
206
 	logger := makeLogger(conf)
202
 
207
 
203
 	logger.BindJSON("configuration", conf.String()).Debug("configuration")
208
 	logger.BindJSON("configuration", conf.String()).Debug("configuration")
263
 
268
 
264
 	ctx := utils.RootContext()
269
 	ctx := utils.RootContext()
265
 
270
 
266
-	go proxy.Serve(listener) // nolint: errcheck
271
+	go proxy.Serve(listener) //nolint: errcheck
267
 
272
 
268
 	<-ctx.Done()
273
 	<-ctx.Done()
269
 	listener.Close()
274
 	listener.Close()

+ 11
- 11
internal/cli/simple_run.go Прегледај датотеку

13
 	BindTo string `kong:"arg,required,name='bind-to',help='A host:port to bind proxy to.'"`
13
 	BindTo string `kong:"arg,required,name='bind-to',help='A host:port to bind proxy to.'"`
14
 	Secret string `kong:"arg,required,name='secret',help='Proxy secret.'"`
14
 	Secret string `kong:"arg,required,name='secret',help='Proxy secret.'"`
15
 
15
 
16
-	Debug               bool          `kong:"name='debug',short='d',help='Run in debug mode.'"`                                                                        // nolint: lll
17
-	Concurrency         uint64        `kong:"name='concurrency',short='c',default='8192',help='Max number of concurrent connection to proxy.'"`                        // nolint: lll
18
-	TCPBuffer           string        `kong:"name='tcp-buffer',short='b',default='4KB',help='Deprecated and ignored'"`                                                 // nolint: lll
19
-	PreferIP            string        `kong:"name='prefer-ip',short='i',default='prefer-ipv6',help='IP preference. By default we prefer IPv6 with fallback to IPv4.'"` // nolint: lll
20
-	DomainFrontingPort  uint64        `kong:"name='domain-fronting-port',short='p',default='443',help='A port to access for domain fronting.'"`                        // nolint: lll
21
-	DOHIP               net.IP        `kong:"name='doh-ip',short='n',default='9.9.9.9',help='IP address of DNS-over-HTTP to use.'"`                                    // nolint: lll
22
-	Timeout             time.Duration `kong:"name='timeout',short='t',default='10s',help='Network timeout to use'"`                                                    // nolint: lll
23
-	AntiReplayCacheSize string        `kong:"name='antireplay-cache-size',short='a',default='1MB',help='A size of anti-replay cache to use.'"`                         // nolint: lll
16
+	Debug               bool          `kong:"name='debug',short='d',help='Run in debug mode.'"`                                                                        //nolint: lll
17
+	Concurrency         uint64        `kong:"name='concurrency',short='c',default='8192',help='Max number of concurrent connection to proxy.'"`                        //nolint: lll
18
+	TCPBuffer           string        `kong:"name='tcp-buffer',short='b',default='4KB',help='Deprecated and ignored'"`                                                 //nolint: lll
19
+	PreferIP            string        `kong:"name='prefer-ip',short='i',default='prefer-ipv6',help='IP preference. By default we prefer IPv6 with fallback to IPv4.'"` //nolint: lll
20
+	DomainFrontingPort  uint64        `kong:"name='domain-fronting-port',short='p',default='443',help='A port to access for domain fronting.'"`                        //nolint: lll
21
+	DOHIP               net.IP        `kong:"name='doh-ip',short='n',default='9.9.9.9',help='IP address of DNS-over-HTTP to use.'"`                                    //nolint: lll
22
+	Timeout             time.Duration `kong:"name='timeout',short='t',default='10s',help='Network timeout to use'"`                                                    //nolint: lll
23
+	AntiReplayCacheSize string        `kong:"name='antireplay-cache-size',short='a',default='1MB',help='A size of anti-replay cache to use.'"`                         //nolint: lll
24
 }
24
 }
25
 
25
 
26
-func (s *SimpleRun) Run(cli *CLI, version string) error { // nolint: cyclop
26
+func (s *SimpleRun) Run(cli *CLI, version string) error { //nolint: cyclop
27
 	conf := &config.Config{}
27
 	conf := &config.Config{}
28
 
28
 
29
 	if err := conf.BindTo.Set(s.BindTo); err != nil {
29
 	if err := conf.BindTo.Set(s.BindTo); err != nil {
34
 		return fmt.Errorf("incorrect secret: %w", err)
34
 		return fmt.Errorf("incorrect secret: %w", err)
35
 	}
35
 	}
36
 
36
 
37
-	if err := conf.Concurrency.Set(strconv.FormatUint(s.Concurrency, 10)); err != nil { // nolint: gomnd
37
+	if err := conf.Concurrency.Set(strconv.FormatUint(s.Concurrency, 10)); err != nil { //nolint: gomnd
38
 		return fmt.Errorf("incorrect concurrency: %w", err)
38
 		return fmt.Errorf("incorrect concurrency: %w", err)
39
 	}
39
 	}
40
 
40
 
42
 		return fmt.Errorf("incorrect prefer-ip: %w", err)
42
 		return fmt.Errorf("incorrect prefer-ip: %w", err)
43
 	}
43
 	}
44
 
44
 
45
-	if err := conf.DomainFrontingPort.Set(strconv.FormatUint(s.DomainFrontingPort, 10)); err != nil { // nolint: gomnd
45
+	if err := conf.DomainFrontingPort.Set(strconv.FormatUint(s.DomainFrontingPort, 10)); err != nil { //nolint: gomnd
46
 		return fmt.Errorf("incorrect domain-fronting-port: %w", err)
46
 		return fmt.Errorf("incorrect domain-fronting-port: %w", err)
47
 	}
47
 	}
48
 
48
 

+ 2
- 2
internal/config/type_concurrency.go Прегледај датотеку

10
 }
10
 }
11
 
11
 
12
 func (t *TypeConcurrency) Set(value string) error {
12
 func (t *TypeConcurrency) Set(value string) error {
13
-	concurrencyValue, err := strconv.ParseUint(value, 10, 16) // nolint: gomnd
13
+	concurrencyValue, err := strconv.ParseUint(value, 10, 16) //nolint: gomnd
14
 	if err != nil {
14
 	if err != nil {
15
 		return fmt.Errorf("value is not uint (%s): %w", value, err)
15
 		return fmt.Errorf("value is not uint (%s): %w", value, err)
16
 	}
16
 	}
41
 }
41
 }
42
 
42
 
43
 func (t TypeConcurrency) String() string {
43
 func (t TypeConcurrency) String() string {
44
-	return strconv.FormatUint(uint64(t.Value), 10) // nolint: gomnd
44
+	return strconv.FormatUint(uint64(t.Value), 10) //nolint: gomnd
45
 }
45
 }

+ 2
- 2
internal/config/type_error_rate.go Прегледај датотеку

12
 }
12
 }
13
 
13
 
14
 func (t *TypeErrorRate) Set(value string) error {
14
 func (t *TypeErrorRate) Set(value string) error {
15
-	parsedValue, err := strconv.ParseFloat(value, 64) // nolint: gomnd
15
+	parsedValue, err := strconv.ParseFloat(value, 64) //nolint: gomnd
16
 	if err != nil {
16
 	if err != nil {
17
 		return fmt.Errorf("value is not a float (%s): %w", value, err)
17
 		return fmt.Errorf("value is not a float (%s): %w", value, err)
18
 	}
18
 	}
43
 }
43
 }
44
 
44
 
45
 func (t TypeErrorRate) String() string {
45
 func (t TypeErrorRate) String() string {
46
-	return strconv.FormatFloat(t.Value, 'f', -1, 64) // nolint: gomnd
46
+	return strconv.FormatFloat(t.Value, 'f', -1, 64) //nolint: gomnd
47
 }
47
 }

+ 1
- 1
internal/config/type_hostport.go Прегледај датотеку

18
 		return fmt.Errorf("incorrect host:port value (%v): %w", value, err)
18
 		return fmt.Errorf("incorrect host:port value (%v): %w", value, err)
19
 	}
19
 	}
20
 
20
 
21
-	portValue, err := strconv.ParseUint(port, 10, 16) // nolint: gomnd
21
+	portValue, err := strconv.ParseUint(port, 10, 16) //nolint: gomnd
22
 	if err != nil {
22
 	if err != nil {
23
 		return fmt.Errorf("incorrect port number (%v): %w", value, err)
23
 		return fmt.Errorf("incorrect port number (%v): %w", value, err)
24
 	}
24
 	}

+ 1
- 1
internal/config/type_port.go Прегледај датотеку

10
 }
10
 }
11
 
11
 
12
 func (t *TypePort) Set(value string) error {
12
 func (t *TypePort) Set(value string) error {
13
-	portValue, err := strconv.ParseUint(value, 10, 16) // nolint: gomnd
13
+	portValue, err := strconv.ParseUint(value, 10, 16) //nolint: gomnd
14
 	if err != nil {
14
 	if err != nil {
15
 		return fmt.Errorf("incorrect port number (%v): %w", value, err)
15
 		return fmt.Errorf("incorrect port number (%v): %w", value, err)
16
 	}
16
 	}

+ 1
- 1
internal/testlib/capture_output.go Прегледај датотеку

27
 	closeChan := make(chan bool)
27
 	closeChan := make(chan bool)
28
 
28
 
29
 	go func() {
29
 	go func() {
30
-		io.Copy(buf, reader) // nolint: errcheck
30
+		io.Copy(buf, reader) //nolint: errcheck
31
 		close(closeChan)
31
 		close(closeChan)
32
 	}()
32
 	}()
33
 
33
 

+ 3
- 3
internal/testlib/mtglib_network_mock.go Прегледај датотеку

15
 func (m *MtglibNetworkMock) Dial(network, address string) (essentials.Conn, error) {
15
 func (m *MtglibNetworkMock) Dial(network, address string) (essentials.Conn, error) {
16
 	args := m.Called(network, address)
16
 	args := m.Called(network, address)
17
 
17
 
18
-	return args.Get(0).(essentials.Conn), args.Error(1) // nolint: wrapcheck, forcetypeassert
18
+	return args.Get(0).(essentials.Conn), args.Error(1) //nolint: wrapcheck, forcetypeassert
19
 }
19
 }
20
 
20
 
21
 func (m *MtglibNetworkMock) DialContext(ctx context.Context, network, address string) (essentials.Conn, error) {
21
 func (m *MtglibNetworkMock) DialContext(ctx context.Context, network, address string) (essentials.Conn, error) {
22
 	args := m.Called(ctx, network, address)
22
 	args := m.Called(ctx, network, address)
23
 
23
 
24
-	return args.Get(0).(essentials.Conn), args.Error(1) // nolint: wrapcheck, forcetypeassert
24
+	return args.Get(0).(essentials.Conn), args.Error(1) //nolint: wrapcheck, forcetypeassert
25
 }
25
 }
26
 
26
 
27
 func (m *MtglibNetworkMock) MakeHTTPClient(dialFunc func(ctx context.Context,
27
 func (m *MtglibNetworkMock) MakeHTTPClient(dialFunc func(ctx context.Context,
28
 	network, address string) (essentials.Conn, error),
28
 	network, address string) (essentials.Conn, error),
29
 ) *http.Client {
29
 ) *http.Client {
30
-	return m.Called(dialFunc).Get(0).(*http.Client) // nolint: forcetypeassert
30
+	return m.Called(dialFunc).Get(0).(*http.Client) //nolint: forcetypeassert
31
 }
31
 }

+ 8
- 8
internal/testlib/net_conn_mock.go Прегледај датотеку

24
 }
24
 }
25
 
25
 
26
 func (n *EssentialsConnMock) Close() error {
26
 func (n *EssentialsConnMock) Close() error {
27
-	return n.Called().Error(0) // nolint: wrapcheck
27
+	return n.Called().Error(0) //nolint: wrapcheck
28
 }
28
 }
29
 
29
 
30
 func (n *EssentialsConnMock) CloseRead() error {
30
 func (n *EssentialsConnMock) CloseRead() error {
31
-	return n.Called().Error(0) // nolint: wrapcheck
31
+	return n.Called().Error(0) //nolint: wrapcheck
32
 }
32
 }
33
 
33
 
34
 func (n *EssentialsConnMock) CloseWrite() error {
34
 func (n *EssentialsConnMock) CloseWrite() error {
35
-	return n.Called().Error(0) // nolint: wrapcheck
35
+	return n.Called().Error(0) //nolint: wrapcheck
36
 }
36
 }
37
 
37
 
38
 func (n *EssentialsConnMock) LocalAddr() net.Addr {
38
 func (n *EssentialsConnMock) LocalAddr() net.Addr {
39
-	return n.Called().Get(0).(net.Addr) // nolint: forcetypeassert
39
+	return n.Called().Get(0).(net.Addr) //nolint: forcetypeassert
40
 }
40
 }
41
 
41
 
42
 func (n *EssentialsConnMock) RemoteAddr() net.Addr {
42
 func (n *EssentialsConnMock) RemoteAddr() net.Addr {
43
-	return n.Called().Get(0).(net.Addr) // nolint: forcetypeassert
43
+	return n.Called().Get(0).(net.Addr) //nolint: forcetypeassert
44
 }
44
 }
45
 
45
 
46
 func (n *EssentialsConnMock) SetDeadline(t time.Time) error {
46
 func (n *EssentialsConnMock) SetDeadline(t time.Time) error {
47
-	return n.Called(t).Error(0) // nolint: wrapcheck
47
+	return n.Called(t).Error(0) //nolint: wrapcheck
48
 }
48
 }
49
 
49
 
50
 func (n *EssentialsConnMock) SetReadDeadline(t time.Time) error {
50
 func (n *EssentialsConnMock) SetReadDeadline(t time.Time) error {
51
-	return n.Called(t).Error(0) // nolint: wrapcheck
51
+	return n.Called(t).Error(0) //nolint: wrapcheck
52
 }
52
 }
53
 
53
 
54
 func (n *EssentialsConnMock) SetWriteDeadline(t time.Time) error {
54
 func (n *EssentialsConnMock) SetWriteDeadline(t time.Time) error {
55
-	return n.Called(t).Error(0) // nolint: wrapcheck
55
+	return n.Called(t).Error(0) //nolint: wrapcheck
56
 }
56
 }

+ 1
- 1
internal/utils/net_listener.go Прегледај датотеку

14
 func (l Listener) Accept() (net.Conn, error) {
14
 func (l Listener) Accept() (net.Conn, error) {
15
 	conn, err := l.Listener.Accept()
15
 	conn, err := l.Listener.Accept()
16
 	if err != nil {
16
 	if err != nil {
17
-		return nil, err // nolint: wrapcheck
17
+		return nil, err //nolint: wrapcheck
18
 	}
18
 	}
19
 
19
 
20
 	if err := network.SetClientSocketOptions(conn, 0); err != nil {
20
 	if err := network.SetClientSocketOptions(conn, 0); err != nil {

+ 0
- 25
internal/utils/rlimit.go Прегледај датотеку

1
-//go:build !windows
2
-// +build !windows
3
-
4
-package utils
5
-
6
-import (
7
-	"fmt"
8
-
9
-	"golang.org/x/sys/unix"
10
-)
11
-
12
-func SetLimits() error {
13
-	rLimit := unix.Rlimit{}
14
-	if err := unix.Getrlimit(unix.RLIMIT_NOFILE, &rLimit); err != nil {
15
-		return fmt.Errorf("cannot get rlimit: %w", err)
16
-	}
17
-
18
-	rLimit.Cur = rLimit.Max
19
-
20
-	if err := unix.Setrlimit(unix.RLIMIT_NOFILE, &rLimit); err != nil {
21
-		return fmt.Errorf("cannot set rlimit: %w", err)
22
-	}
23
-
24
-	return nil
25
-}

+ 0
- 8
internal/utils/rlimit_windows.go Прегледај датотеку

1
-//go:build windows
2
-// +build windows
3
-
4
-package utils
5
-
6
-func SetLimits() error {
7
-	return nil
8
-}

+ 8
- 0
ipblocklist/files/doc.go Прегледај датотеку

1
+// files defines a set of abstraction for 'files': an openable entities that
2
+// could be read after.
3
+//
4
+// This is not a file on a filesystem of your local machine, it also can
5
+// include "in memory" files or even remote ones, like HTTP endpoints. If you
6
+// make a GET request to HTTP endpoint, then a body is readable and you can
7
+// consider it as an openable file.
8
+package files

+ 3
- 1
ipblocklist/files/http.go Прегледај датотеку

22
 	response, err := h.http.Do(request)
22
 	response, err := h.http.Do(request)
23
 	if err != nil {
23
 	if err != nil {
24
 		if response != nil {
24
 		if response != nil {
25
-			io.Copy(io.Discard, response.Body) // nolint: errcheck
25
+			io.Copy(io.Discard, response.Body) //nolint: errcheck
26
 			response.Body.Close()
26
 			response.Body.Close()
27
 		}
27
 		}
28
 
28
 
40
 	return h.url
40
 	return h.url
41
 }
41
 }
42
 
42
 
43
+// NewHTTP returns a file abstraction for HTTP/HTTPS endpoint. You also need to
44
+// provide a valid instance of [http.Client] to access it.
43
 func NewHTTP(client *http.Client, endpoint string) (File, error) {
45
 func NewHTTP(client *http.Client, endpoint string) (File, error) {
44
 	if client == nil {
46
 	if client == nil {
45
 		return nil, ErrBadHTTPClient
47
 		return nil, ErrBadHTTPClient

+ 1
- 1
ipblocklist/files/http_test.go Прегледај датотеку

22
 }
22
 }
23
 
23
 
24
 func (suite *HTTPTestSuite) makeFile(path string) (files.File, error) {
24
 func (suite *HTTPTestSuite) makeFile(path string) (files.File, error) {
25
-	return files.NewHTTP(suite.httpClient, suite.httpServer.URL+"/"+path) // nolint: wrapcheck
25
+	return files.NewHTTP(suite.httpClient, suite.httpServer.URL+"/"+path) //nolint: wrapcheck
26
 }
26
 }
27
 
27
 
28
 func (suite *HTTPTestSuite) SetupSuite() {
28
 func (suite *HTTPTestSuite) SetupSuite() {

+ 7
- 0
ipblocklist/files/init.go Прегледај датотеку

6
 	"io"
6
 	"io"
7
 )
7
 )
8
 
8
 
9
+// ErrBadHTTPClient is returned if given HTTP client is initialized
10
+// incorrectly.
9
 var ErrBadHTTPClient = errors.New("incorrect http client")
11
 var ErrBadHTTPClient = errors.New("incorrect http client")
10
 
12
 
13
+// File is an abstraction for a entity that can be opened in some context.
11
 type File interface {
14
 type File interface {
15
+	// Open returns an readable entity for a file. It is important to not forget
16
+	// to close it after the usage.
12
 	Open(context.Context) (io.ReadCloser, error)
17
 	Open(context.Context) (io.ReadCloser, error)
18
+
19
+	// String returns a short text description for the file
13
 	String() string
20
 	String() string
14
 }
21
 }

+ 2
- 1
ipblocklist/files/local.go Прегледај датотеку

12
 }
12
 }
13
 
13
 
14
 func (l localFile) Open(ctx context.Context) (io.ReadCloser, error) {
14
 func (l localFile) Open(ctx context.Context) (io.ReadCloser, error) {
15
-	return os.Open(l.path) // nolint: wrapcheck
15
+	return os.Open(l.path) //nolint: wrapcheck
16
 }
16
 }
17
 
17
 
18
 func (l localFile) String() string {
18
 func (l localFile) String() string {
19
 	return l.path
19
 	return l.path
20
 }
20
 }
21
 
21
 
22
+// NewLocal returns an openable File for a path on a local file system.
22
 func NewLocal(path string) (File, error) {
23
 func NewLocal(path string) (File, error) {
23
 	if stat, err := os.Stat(path); os.IsNotExist(err) || stat.IsDir() || stat.Mode().Perm()&0o400 == 0 {
24
 	if stat, err := os.Stat(path); os.IsNotExist(err) || stat.IsDir() || stat.Mode().Perm()&0o400 == 0 {
24
 		return nil, fmt.Errorf("%s is not a readable file", path)
25
 		return nil, fmt.Errorf("%s is not a readable file", path)

+ 1
- 0
ipblocklist/files/mem.go Прегледај датотеку

19
 	return "mem"
19
 	return "mem"
20
 }
20
 }
21
 
21
 
22
+// NewMem returns an openable file that is kept in RAM.
22
 func NewMem(networks []*net.IPNet) File {
23
 func NewMem(networks []*net.IPNet) File {
23
 	builder := strings.Builder{}
24
 	builder := strings.Builder{}
24
 
25
 

+ 16
- 14
ipblocklist/firehol.go Прегледај датотеку

19
 var (
19
 var (
20
 	fireholRegexpComment = regexp.MustCompile(`\s*#.*?$`)
20
 	fireholRegexpComment = regexp.MustCompile(`\s*#.*?$`)
21
 
21
 
22
-	fireholIPv4DefaultCIDR = net.CIDRMask(32, 32)   // nolint: gomnd
23
-	fireholIPv6DefaultCIDR = net.CIDRMask(128, 128) // nolint: gomnd
22
+	fireholIPv4DefaultCIDR = net.CIDRMask(32, 32)   //nolint: gomnd
23
+	fireholIPv6DefaultCIDR = net.CIDRMask(128, 128) //nolint: gomnd
24
 )
24
 )
25
 
25
 
26
 // FireholUpdateCallback defines a signature of the callback that has to be
26
 // FireholUpdateCallback defines a signature of the callback that has to be
27
 // execute when ip list is updated.
27
 // execute when ip list is updated.
28
 type FireholUpdateCallback func(context.Context, int)
28
 type FireholUpdateCallback func(context.Context, int)
29
 
29
 
30
-// Firehol is IPBlocklist which uses lists from FireHOL:
30
+// Firehol is [mtglib.IPBlocklist] which uses lists from FireHOL:
31
 // https://iplists.firehol.org/
31
 // https://iplists.firehol.org/
32
 //
32
 //
33
-// It can use both local files and remote URLs. This is not necessary
34
-// that blocklists should be taken from this website, we expect only
35
-// compatible formats here.
33
+// It can use both local files and remote URLs. This is not necessary that
34
+// blocklists should be taken from this website, we expect only compatible
35
+// formats here.
36
 //
36
 //
37
 // Example of the format:
37
 // Example of the format:
38
 //
38
 //
39
-//     # this is a comment
40
-//     # to ignore
41
-//     127.0.0.1   # you can specify an IP
42
-//     10.0.0.0/8  # or cidr
39
+//	# this is a comment
40
+//	# to ignore
41
+//	127.0.0.1   # you can specify an IP
42
+//	10.0.0.0/8  # or cidr
43
 type Firehol struct {
43
 type Firehol struct {
44
 	ctx         context.Context
44
 	ctx         context.Context
45
 	ctxCancel   context.CancelFunc
45
 	ctxCancel   context.CancelFunc
78
 
78
 
79
 // Run starts a background update process.
79
 // Run starts a background update process.
80
 //
80
 //
81
-// This is a blocking method so you probably want to run it in a
82
-// goroutine.
81
+// This is a blocking method so you probably want to run it in a goroutine.
83
 func (f *Firehol) Run(updateEach time.Duration) {
82
 func (f *Firehol) Run(updateEach time.Duration) {
84
 	if updateEach == 0 {
83
 	if updateEach == 0 {
85
 		updateEach = DefaultFireholUpdateEach
84
 		updateEach = DefaultFireholUpdateEach
211
 
210
 
212
 // NewFirehol creates a new instance of FireHOL IP blocklist.
211
 // NewFirehol creates a new instance of FireHOL IP blocklist.
213
 //
212
 //
214
-// This method does not start an update process so please execute Run
215
-// when it is necessary.
213
+// This method does not start an update process so please execute Run when it
214
+// is necessary.
216
 func NewFirehol(logger mtglib.Logger, network mtglib.Network,
215
 func NewFirehol(logger mtglib.Logger, network mtglib.Network,
217
 	downloadConcurrency uint,
216
 	downloadConcurrency uint,
218
 	urls []string,
217
 	urls []string,
244
 	return NewFireholFromFiles(logger, downloadConcurrency, blocklists, updateCallback)
243
 	return NewFireholFromFiles(logger, downloadConcurrency, blocklists, updateCallback)
245
 }
244
 }
246
 
245
 
246
+// NewFirehol creates a new instance of FireHOL IP blocklist.
247
+//
248
+// This method creates this instances from a given list of files.
247
 func NewFireholFromFiles(logger mtglib.Logger,
249
 func NewFireholFromFiles(logger mtglib.Logger,
248
 	downloadConcurrency uint,
250
 	downloadConcurrency uint,
249
 	blocklists []files.File,
251
 	blocklists []files.File,

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

37
 
37
 
38
 		defer filefp.Close()
38
 		defer filefp.Close()
39
 
39
 
40
-		io.Copy(w, filefp) // nolint: errcheck
40
+		io.Copy(w, filefp) //nolint: errcheck
41
 	})
41
 	})
42
 
42
 
43
 	suite.httpServer = httptest.NewServer(mux)
43
 	suite.httpServer = httptest.NewServer(mux)

+ 5
- 5
ipblocklist/init.go Прегледај датотеку

1
 // Package ipblocklist contains default implementation of the
1
 // Package ipblocklist contains default implementation of the
2
-// IPBlocklist for mtg.
2
+// [mtglib.IPBlocklist] for mtg.
3
 //
3
 //
4
-// Please check documentation for mtglib.IPBlocklist interface to get an
5
-// idea of this abstraction.
4
+// Please check documentation for [mtglib.IPBlocklist] interface to get an idea
5
+// of this abstraction.
6
 package ipblocklist
6
 package ipblocklist
7
 
7
 
8
 import "time"
8
 import "time"
12
 	// concurrent downloads of ip blocklists for Firehol.
12
 	// concurrent downloads of ip blocklists for Firehol.
13
 	DefaultFireholDownloadConcurrency = 1
13
 	DefaultFireholDownloadConcurrency = 1
14
 
14
 
15
-	// DefaultFireholUpdateEach defines a default time period when
16
-	// Firehol requests updates of the blocklists.
15
+	// DefaultFireholUpdateEach defines a default time period when Firehol
16
+	// requests updates of the blocklists.
17
 	DefaultFireholUpdateEach = 6 * time.Hour
17
 	DefaultFireholUpdateEach = 6 * time.Hour
18
 )
18
 )

+ 1
- 2
ipblocklist/noop.go Прегледај датотеку

13
 func (n noop) Run(updateEach time.Duration) {}
13
 func (n noop) Run(updateEach time.Duration) {}
14
 func (n noop) Shutdown()                    {}
14
 func (n noop) Shutdown()                    {}
15
 
15
 
16
-// NewNoop returns a dummy ipblocklist which allows all incoming
17
-// connections.
16
+// NewNoop returns a dummy ipblocklist which allows all incoming connections.
18
 func NewNoop() mtglib.IPBlocklist {
17
 func NewNoop() mtglib.IPBlocklist {
19
 	return noop{}
18
 	return noop{}
20
 }
19
 }

+ 6
- 8
logger/init.go Прегледај датотеку

1
-// Package logger has implementation of loggers for mtglib.Logger
2
-// interface.
1
+// Package logger has implementation of loggers for [mtglib.Logger] interface.
3
 //
2
 //
4
-// Please see a description of that interface to get some agreements
5
-// which are used by mtglib.
3
+// Please see a description of that interface to get some agreements which are
4
+// used by mtglib.
6
 package logger
5
 package logger
7
 
6
 
8
-// StdLikeLogger is an interface which is close to log.Logger. This is
9
-// commonly used by many 3pp tools. While mtglib itself does not need
10
-// it, it is always a good idea to support it and have a transient end
11
-// to end logging.
7
+// StdLikeLogger is an interface which is close to [log.Logger]. This is
8
+// commonly used by many 3pp tools. While mtglib itself does not need it, it is
9
+// always a good idea to support it and have a transient end to end logging.
12
 type StdLikeLogger interface {
10
 type StdLikeLogger interface {
13
 	Printf(format string, args ...interface{})
11
 	Printf(format string, args ...interface{})
14
 }
12
 }

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

116
 	suite.NotContains("lalala", log12Output)
116
 	suite.NotContains("lalala", log12Output)
117
 }
117
 }
118
 
118
 
119
-func TestZeroLogger(t *testing.T) { // nolint: paralleltest
119
+func TestZeroLogger(t *testing.T) { //nolint: paralleltest
120
 	suite.Run(t, &ZeroLoggerTestSuite{})
120
 	suite.Run(t, &ZeroLoggerTestSuite{})
121
 }
121
 }

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

9
 package main
9
 package main
10
 
10
 
11
 import (
11
 import (
12
-	"fmt"
13
 	"math/rand"
12
 	"math/rand"
14
-	"runtime/debug"
15
-	"strconv"
16
 	"time"
13
 	"time"
17
 
14
 
18
 	"github.com/9seconds/mtg/v2/internal/cli"
15
 	"github.com/9seconds/mtg/v2/internal/cli"
19
-	"github.com/9seconds/mtg/v2/internal/utils"
20
 	"github.com/alecthomas/kong"
16
 	"github.com/alecthomas/kong"
21
 )
17
 )
22
 
18
 
23
-var version = "dev" // has to be set by ldflags
24
-
25
 func main() {
19
 func main() {
26
 	rand.Seed(time.Now().UTC().UnixNano())
20
 	rand.Seed(time.Now().UTC().UnixNano())
27
 
21
 
28
-	if err := utils.SetLimits(); err != nil {
29
-		panic(err)
30
-	}
31
-
32
-	if buildInfo, ok := debug.ReadBuildInfo(); ok {
33
-		vcsCommit := "<no-commit>"
34
-		vcsDate := time.Now()
35
-		vcsDirty := ""
36
-
37
-		for _, setting := range buildInfo.Settings {
38
-			switch setting.Key {
39
-			case "vcs.time":
40
-				vcsDate, _ = time.Parse(time.RFC3339, setting.Value)
41
-			case "vcs.revision":
42
-				vcsCommit = setting.Value
43
-			case "vcs.modified":
44
-				if isDirty, _ := strconv.ParseBool(setting.Value); isDirty {
45
-					vcsDirty = " [dirty]"
46
-				}
47
-			}
48
-		}
49
-
50
-		version = fmt.Sprintf("%s (%s: %s on %s%s)",
51
-			version,
52
-			buildInfo.GoVersion,
53
-			vcsDate.Format(time.RFC3339),
54
-			vcsCommit,
55
-			vcsDirty)
56
-	}
57
-
58
 	cli := &cli.CLI{}
22
 	cli := &cli.CLI{}
59
 	ctx := kong.Parse(cli, kong.Vars{
23
 	ctx := kong.Parse(cli, kong.Vars{
60
-		"version": version,
24
+		"version": getVersion(),
61
 	})
25
 	})
62
 
26
 
63
 	ctx.FatalIfErrorf(ctx.Run(cli, version))
27
 	ctx.FatalIfErrorf(ctx.Run(cli, version))

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

24
 		c.stream.Send(c.ctx, NewEventTraffic(c.streamID, uint(n), true))
24
 		c.stream.Send(c.ctx, NewEventTraffic(c.streamID, uint(n), true))
25
 	}
25
 	}
26
 
26
 
27
-	return n, err // nolint: wrapcheck
27
+	return n, err //nolint: wrapcheck
28
 }
28
 }
29
 
29
 
30
 func (c connTraffic) Write(b []byte) (int, error) {
30
 func (c connTraffic) Write(b []byte) (int, error) {
34
 		c.stream.Send(c.ctx, NewEventTraffic(c.streamID, uint(n), false))
34
 		c.stream.Send(c.ctx, NewEventTraffic(c.streamID, uint(n), false))
35
 	}
35
 	}
36
 
36
 
37
-	return n, err // nolint: wrapcheck
37
+	return n, err //nolint: wrapcheck
38
 }
38
 }
39
 
39
 
40
 type connRewind struct {
40
 type connRewind struct {
49
 	c.mutex.RLock()
49
 	c.mutex.RLock()
50
 	defer c.mutex.RUnlock()
50
 	defer c.mutex.RUnlock()
51
 
51
 
52
-	return c.active.Read(p) // nolint: wrapcheck
52
+	return c.active.Read(p) //nolint: wrapcheck
53
 }
53
 }
54
 
54
 
55
 func (c *connRewind) Rewind() {
55
 func (c *connRewind) Rewind() {

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

22
 func (c *ConnRewindBaseConn) Read(p []byte) (int, error) {
22
 func (c *ConnRewindBaseConn) Read(p []byte) (int, error) {
23
 	c.Called(p)
23
 	c.Called(p)
24
 
24
 
25
-	return c.readBuffer.Read(p) // nolint: wrapcheck
25
+	return c.readBuffer.Read(p) //nolint: wrapcheck
26
 }
26
 }
27
 
27
 
28
 type ConnTrafficTestSuite struct {
28
 type ConnTrafficTestSuite struct {
69
 	suite.Equal(10, n)
69
 	suite.Equal(10, n)
70
 }
70
 }
71
 
71
 
72
-func (suite *ConnTrafficTestSuite) TestReadErr() { // nolint: dupl
72
+func (suite *ConnTrafficTestSuite) TestReadErr() { //nolint: dupl
73
 	suite.eventStreamMock.
73
 	suite.eventStreamMock.
74
 		On("Send", mock.Anything, mock.Anything).
74
 		On("Send", mock.Anything, mock.Anything).
75
 		Once().
75
 		Once().
125
 	suite.Equal(10, n)
125
 	suite.Equal(10, n)
126
 }
126
 }
127
 
127
 
128
-func (suite *ConnTrafficTestSuite) TestWriteErr() { // nolint: dupl
128
+func (suite *ConnTrafficTestSuite) TestWriteErr() { //nolint: dupl
129
 	suite.eventStreamMock.
129
 	suite.eventStreamMock.
130
 		On("Send", mock.Anything, mock.Anything).
130
 		On("Send", mock.Anything, mock.Anything).
131
 		Once().
131
 		Once().

+ 17
- 17
mtglib/events.go Прегледај датотеку

29
 	RemoteIP net.IP
29
 	RemoteIP net.IP
30
 }
30
 }
31
 
31
 
32
-// EventConnectedToDC is emitted when mtg proxy has connected to a
33
-// Telegram server.
32
+// EventConnectedToDC is emitted when mtg proxy has connected to a Telegram
33
+// server.
34
 type EventConnectedToDC struct {
34
 type EventConnectedToDC struct {
35
 	eventBase
35
 	eventBase
36
 
36
 
37
-	// RemoteIP is an IP address of the Telegram server proxy has been
38
-	// connected to.
37
+	// RemoteIP is an IP address of the Telegram server proxy has been connected
38
+	// to.
39
 	RemoteIP net.IP
39
 	RemoteIP net.IP
40
 
40
 
41
 	// DC is an index of the datacenter proxy has been connected to.
41
 	// DC is an index of the datacenter proxy has been connected to.
49
 	// Traffic is a count of bytes which were transmitted.
49
 	// Traffic is a count of bytes which were transmitted.
50
 	Traffic uint
50
 	Traffic uint
51
 
51
 
52
-	// IsRead defines if we _read_ or _write_ to connection. A rule of
53
-	// thumb is simple: EventTraffic is bound to a remote connection. Not
54
-	// to a client one, but either to Telegram or front domain one.
52
+	// IsRead defines if we _read_ or _write_ to connection. A rule of thumb is
53
+	// simple: EventTraffic is bound to a remote connection. Not to a client one,
54
+	// but either to Telegram or front domain one.
55
 	//
55
 	//
56
-	// In the case of Telegram, isRead means that we've fetched some bytes
57
-	// from Telegram to send it to a client.
56
+	// In the case of Telegram, isRead means that we've fetched some bytes from
57
+	// Telegram to send it to a client.
58
 	//
58
 	//
59
-	// In the case of the front domain, it means that we've fetched some
60
-	// bytes from this domain to send it to a client.
59
+	// In the case of the front domain, it means that we've fetched some bytes
60
+	// from this domain to send it to a client.
61
 	IsRead bool
61
 	IsRead bool
62
 }
62
 }
63
 
63
 
66
 	eventBase
66
 	eventBase
67
 }
67
 }
68
 
68
 
69
-// EventDomainFronting is emitted when we connect to a front domain
70
-// instead of Telegram server.
69
+// EventDomainFronting is emitted when we connect to a front domain instead of
70
+// Telegram server.
71
 type EventDomainFronting struct {
71
 type EventDomainFronting struct {
72
 	eventBase
72
 	eventBase
73
 }
73
 }
74
 
74
 
75
-// EventConcurrencyLimited is emitted when connection was declined
76
-// because of the concurrency limit of the worker pool.
75
+// EventConcurrencyLimited is emitted when connection was declined because of
76
+// the concurrency limit of the worker pool.
77
 type EventConcurrencyLimited struct {
77
 type EventConcurrencyLimited struct {
78
 	eventBase
78
 	eventBase
79
 }
79
 }
80
 
80
 
81
-// EventIPBlocklisted is emitted when connection was declined because
82
-// IP address was found in IP blocklist.
81
+// EventIPBlocklisted is emitted when connection was declined because IP
82
+// address was found in IP blocklist.
83
 type EventIPBlocklisted struct {
83
 type EventIPBlocklisted struct {
84
 	eventBase
84
 	eventBase
85
 
85
 

+ 124
- 139
mtglib/init.go Прегледај датотеку

1
 // mtglib defines a package with MTPROTO proxy.
1
 // mtglib defines a package with MTPROTO proxy.
2
 //
2
 //
3
-// Since mtg itself is build as an example of how to work with mtglib,
4
-// it worth to telling a couple of words about a project organization.
3
+// Since mtg itself is build as an example of how to work with mtglib, it worth
4
+// to telling a couple of words about a project organization.
5
 //
5
 //
6
-// A core object of the project is mtglib.Proxy. This is a proxy you
7
-// expect: that one which you configure, set to serve on a listener
8
-// and/or shutdown on application termination.
6
+// A core object of the project is [mtglib.Proxy]. This is a proxy you expect:
7
+// that one which you configure, set to serve on a listener and/or shutdown on
8
+// application termination.
9
 //
9
 //
10
-// But it also has a core logic unrelated to Telegram per se: anti
11
-// replay cache, network connectivity (who knows, maybe you want to have
12
-// a native VMESS integration) and so on.
10
+// But it also has a core logic unrelated to Telegram per se: anti replay
11
+// cache, network connectivity (who knows, maybe you want to have a native
12
+// VMESS integration) and so on.
13
 //
13
 //
14
-// You can supply such parts to a proxy with interfaces. The rest of
15
-// the packages in mtg define some default implementations of these
16
-// interfaces. But if you want to integrate it with, let say, influxdb,
17
-// you can do it easily.
14
+// You can supply such parts to a proxy with interfaces. The rest of the
15
+// packages in mtg define some default implementations of these interfaces. But
16
+// if you want to integrate it with, let say, influxdb, you can do it easily.
18
 package mtglib
17
 package mtglib
19
 
18
 
20
 import (
19
 import (
28
 )
27
 )
29
 
28
 
30
 var (
29
 var (
31
-	// ErrSecretEmpty is returned if you are trying to create a proxy
32
-	// but do not provide a secret.
30
+	// ErrSecretEmpty is returned if you are trying to create a proxy but do not
31
+	// provide a secret.
33
 	ErrSecretEmpty = errors.New("secret is empty")
32
 	ErrSecretEmpty = errors.New("secret is empty")
34
 
33
 
35
-	// ErrSecretInvalid is returned if you are trying to create a proxy
36
-	// but secret value is invalid (no host or payload are zeroes).
34
+	// ErrSecretInvalid is returned if you are trying to create a proxy but secret
35
+	// value is invalid (no host or payload are zeroes).
37
 	ErrSecretInvalid = errors.New("secret is invalid")
36
 	ErrSecretInvalid = errors.New("secret is invalid")
38
 
37
 
39
-	// ErrNetworkIsNotDefined is returned if you are trying to create a
40
-	// proxy but network value is undefined.
38
+	// ErrNetworkIsNotDefined is returned if you are trying to create a proxy but
39
+	// network value is undefined.
41
 	ErrNetworkIsNotDefined = errors.New("network is not defined")
40
 	ErrNetworkIsNotDefined = errors.New("network is not defined")
42
 
41
 
43
-	// ErrAntiReplayCacheIsNotDefined is returned if you are trying to
44
-	// create a proxy but anti replay cache value is undefined.
42
+	// ErrAntiReplayCacheIsNotDefined is returned if you are trying to create a
43
+	// proxy but anti replay cache value is undefined.
45
 	ErrAntiReplayCacheIsNotDefined = errors.New("anti-replay cache is not defined")
44
 	ErrAntiReplayCacheIsNotDefined = errors.New("anti-replay cache is not defined")
46
 
45
 
47
-	// ErrIPBlocklistIsNotDefined is returned if you are trying to
48
-	// create a proxy but ip blocklist instance is not defined.
46
+	// ErrIPBlocklistIsNotDefined is returned if you are trying to create a proxy
47
+	// but ip blocklist instance is not defined.
49
 	ErrIPBlocklistIsNotDefined = errors.New("ip blocklist is not defined")
48
 	ErrIPBlocklistIsNotDefined = errors.New("ip blocklist is not defined")
50
 
49
 
51
-	// ErrIPAllowlistIsNotDefined is returned if you are trying to
52
-	// create a proxy but ip allowlist instance is not defined.
50
+	// ErrIPAllowlistIsNotDefined is returned if you are trying to create a proxy
51
+	// but ip allowlist instance is not defined.
53
 	ErrIPAllowlistIsNotDefined = errors.New("ip allowlist is not defined")
52
 	ErrIPAllowlistIsNotDefined = errors.New("ip allowlist is not defined")
54
 
53
 
55
-	// ErrEventStreamIsNotDefined is returned if you are trying to create a
56
-	// proxy but event stream instance is not defined.
54
+	// ErrEventStreamIsNotDefined is returned if you are trying to create a proxy
55
+	// but event stream instance is not defined.
57
 	ErrEventStreamIsNotDefined = errors.New("event stream is not defined")
56
 	ErrEventStreamIsNotDefined = errors.New("event stream is not defined")
58
 
57
 
59
-	// ErrLoggerIsNotDefined is returned if you are trying to
60
-	// create a proxy but logger is not defined.
58
+	// ErrLoggerIsNotDefined is returned if you are trying to create a proxy but
59
+	// logger is not defined.
61
 	ErrLoggerIsNotDefined = errors.New("logger is not defined")
60
 	ErrLoggerIsNotDefined = errors.New("logger is not defined")
62
 )
61
 )
63
 
62
 
64
 const (
63
 const (
65
-	// DefaultConcurrency is a default max count of simultaneously
66
-	// connected clients.
64
+	// DefaultConcurrency is a default max count of simultaneously connected
65
+	// clients.
67
 	DefaultConcurrency = 4096
66
 	DefaultConcurrency = 4096
68
 
67
 
69
 	// DefaultBufferSize is a default size of a copy buffer.
68
 	// DefaultBufferSize is a default size of a copy buffer.
71
 	// Deprecated: this setting no longer makes any effect.
70
 	// Deprecated: this setting no longer makes any effect.
72
 	DefaultBufferSize = 16 * 1024 // 16 kib
71
 	DefaultBufferSize = 16 * 1024 // 16 kib
73
 
72
 
74
-	// DefaultDomainFrontingPort is a default port (HTTPS) to connect to in
75
-	// case of probe-resistance activity.
73
+	// DefaultDomainFrontingPort is a default port (HTTPS) to connect to in case
74
+	// of probe-resistance activity.
76
 	DefaultDomainFrontingPort = 443
75
 	DefaultDomainFrontingPort = 443
77
 
76
 
78
-	// DefaultIdleTimeout is a default timeout for closing a connection
79
-	// in case of idling.
77
+	// DefaultIdleTimeout is a default timeout for closing a connection in case of
78
+	// idling.
80
 	//
79
 	//
81
-	// Deprecated: no longer in use because of changed TCP relay
82
-	// algorithm.
80
+	// Deprecated: no longer in use because of changed TCP relay algorithm.
83
 	DefaultIdleTimeout = time.Minute
81
 	DefaultIdleTimeout = time.Minute
84
 
82
 
85
-	// DefaultTolerateTimeSkewness is a default timeout for time
86
-	// skewness on a faketls timeout verification.
83
+	// DefaultTolerateTimeSkewness is a default timeout for time skewness on a
84
+	// faketls timeout verification.
87
 	DefaultTolerateTimeSkewness = 3 * time.Second
85
 	DefaultTolerateTimeSkewness = 3 * time.Second
88
 
86
 
89
-	// DefaultPreferIP is a default value for Telegram IP connectivity
90
-	// preference.
87
+	// DefaultPreferIP is a default value for Telegram IP connectivity preference.
91
 	DefaultPreferIP = "prefer-ipv6"
88
 	DefaultPreferIP = "prefer-ipv6"
92
 
89
 
93
-	// SecretKeyLength defines a length of the secret bytes used
94
-	// by Telegram and a proxy.
90
+	// SecretKeyLength defines a length of the secret bytes used by Telegram and a
91
+	// proxy.
95
 	SecretKeyLength = 16
92
 	SecretKeyLength = 16
96
 
93
 
97
-	// ConnectionIDBytesLength defines a count of random bytes used to generate
98
-	// a stream/connection ids.
94
+	// ConnectionIDBytesLength defines a count of random bytes used to generate a
95
+	// stream/connection ids.
99
 	ConnectionIDBytesLength = 16
96
 	ConnectionIDBytesLength = 16
100
 
97
 
101
 	// TCPRelayReadTimeout defines a max time period between two consecuitive
98
 	// TCPRelayReadTimeout defines a max time period between two consecuitive
104
 	TCPRelayReadTimeout = 20 * time.Second
101
 	TCPRelayReadTimeout = 20 * time.Second
105
 )
102
 )
106
 
103
 
107
-// Network defines a knowledge how to work with a network. It may sound
108
-// fun but it encapsulates all the knowledge how to properly establish
109
-// connections to remote hosts and configure HTTP clients.
104
+// Network defines a knowledge how to work with a network. It may sound fun but
105
+// it encapsulates all the knowledge how to properly establish connections to
106
+// remote hosts and configure HTTP clients.
110
 //
107
 //
111
-// For example, if you want to use SOCKS5 proxy, you probably want to
112
-// have all traffic routed to this proxy: telegram connections, http
113
-// requests and so on. This knowledge is encapsulated into instances of
114
-// such interface.
108
+// For example, if you want to use SOCKS5 proxy, you probably want to have all
109
+// traffic routed to this proxy: telegram connections, http requests and so on.
110
+// This knowledge is encapsulated into instances of such interface.
115
 //
111
 //
116
 // mtglib uses Network for:
112
 // mtglib uses Network for:
117
-//
118
-// 1. Dialing to Telegram
119
-//
120
-// 2. Dialing to front domain
121
-//
122
-// 3. Doing HTTP requests (for example, for FireHOL ipblocklist).
113
+//  1. Dialing to Telegram
114
+//  2. Dialing to front domain
115
+//  3. Doing HTTP requests (for example, for FireHOL ipblocklist).
123
 type Network interface {
116
 type Network interface {
124
 	// Dial establishes context-free TCP connections.
117
 	// Dial establishes context-free TCP connections.
125
 	Dial(network, address string) (essentials.Conn, error)
118
 	Dial(network, address string) (essentials.Conn, error)
126
 
119
 
127
-	// DialContext dials using a context. This is a preferrable
128
-	// way of establishing TCP connections.
120
+	// DialContext dials using a context. This is a preferrable way of
121
+	// establishing TCP connections.
129
 	DialContext(ctx context.Context, network, address string) (essentials.Conn, error)
122
 	DialContext(ctx context.Context, network, address string) (essentials.Conn, error)
130
 
123
 
131
-	// MakeHTTPClient build an HTTP client with given dial function. If
132
-	// nothing is provided, then DialContext of this interface is going
133
-	// to be used.
124
+	// MakeHTTPClient build an HTTP client with given dial function. If nothing is
125
+	// provided, then DialContext of this interface is going to be used.
134
 	MakeHTTPClient(func(ctx context.Context, network, address string) (essentials.Conn, error)) *http.Client
126
 	MakeHTTPClient(func(ctx context.Context, network, address string) (essentials.Conn, error)) *http.Client
135
 }
127
 }
136
 
128
 
137
-// AntiReplayCache is an interface that is used to detect replay attacks
138
-// based on some traffic fingerprints.
129
+// AntiReplayCache is an interface that is used to detect replay attacks based
130
+// on some traffic fingerprints.
139
 //
131
 //
140
-// Replay attacks are probe attacks whose main goal is to identify if
141
-// server software can be classified in some way. For example, if you
142
-// send some HTTP request to a web server, then you can expect that this
143
-// server will respond with HTTP response back.
132
+// Replay attacks are probe attacks whose main goal is to identify if server
133
+// software can be classified in some way. For example, if you send some HTTP
134
+// request to a web server, then you can expect that this server will respond
135
+// with HTTP response back.
144
 //
136
 //
145
-// There is a problem though. Let's imagine, that connection is
146
-// encrypted. Let's imagine, that it is encrypted with some static key
147
-// like ShadowSocks (https://shadowsocks.org/assets/whitepaper.pdf).
148
-// In that case, in theory, if you repeat the same bytes, you can get
149
-// the same responses. Let's imagine, that you've cracked the key. then
150
-// if you send the same bytes, you can decrypt a response and see its
151
-// structure. Based on its structure you can identify if this server is
152
-// SOCKS5, MTPROTO proxy etc.
137
+// There is a problem though. Let's imagine, that connection is encrypted.
138
+// Let's imagine, that it is encrypted with some static key like [ShadowSocks].
139
+// In that case, in theory, if you repeat the same bytes, you can get the same
140
+// responses. Let's imagine, that you've cracked the key. then if you send the
141
+// same bytes, you can decrypt a response and see its structure. Based on its
142
+// structure you can identify if this server is SOCKS5, MTPROTO proxy etc.
153
 //
143
 //
154
-// This is just one example, maybe not the best or not the most
155
-// relevant. In real life, different organizations use such replay
156
-// attacks to perform some reverse engineering of the proxy, do some
157
-// statical analysis to identify server software.
144
+// This is just one example, maybe not the best or not the most relevant. In
145
+// real life, different organizations use such replay attacks to perform some
146
+// reverse engineering of the proxy, do some statical analysis to identify
147
+// server software.
158
 //
148
 //
159
-// There are many ways how to protect your proxy against them. One
160
-// is domain fronting which is a core part of mtg. Another one is to
161
-// collect some 'handshake fingerprints' and forbid duplication.
149
+// There are many ways how to protect your proxy against them. One is domain
150
+// fronting which is a core part of mtg. Another one is to collect some
151
+// 'handshake fingerprints' and forbid duplication.
162
 //
152
 //
163
-// So, it one is sending the same byte flow right after you (or a couple
164
-// of hours after), mtg should detect that and reject this connection
165
-// (or redirect to fronting domain).
153
+// So, it one is sending the same byte flow right after you (or a couple of
154
+// hours after), mtg should detect that and reject this connection (or redirect
155
+// to fronting domain).
156
+//
157
+// [ShadowSocks]: https://shadowsocks.org/assets/whitepaper.pdf
166
 type AntiReplayCache interface {
158
 type AntiReplayCache interface {
167
-	// Seen before checks if this set of bytes was observed before or
168
-	// not. If it is required to store this information somewhere else,
169
-	// then it has to do that.
159
+	// Seen before checks if this set of bytes was observed before or not. If it
160
+	// is required to store this information somewhere else, then it has to do
161
+	// that.
170
 	SeenBefore(data []byte) bool
162
 	SeenBefore(data []byte) bool
171
 }
163
 }
172
 
164
 
173
 // IPBlocklist filters requests based on IP address.
165
 // IPBlocklist filters requests based on IP address.
174
 //
166
 //
175
-// If this filter has an IP address, then mtg closes a request without
176
-// reading anything from a socket. It also does not give such request to
177
-// a worker pool, so in worst cases you can expect that you invoke this
178
-// object more frequent than defined proxy concurrency.
167
+// If this filter has an IP address, then mtg closes a request without reading
168
+// anything from a socket. It also does not give such request to a worker pool,
169
+// so in worst cases you can expect that you invoke this object more frequent
170
+// than defined proxy concurrency.
179
 type IPBlocklist interface {
171
 type IPBlocklist interface {
180
-	// Contains checks if given IP address belongs to this blocklist If.
181
-	// it is, a connection is terminated                               .
172
+	// Contains checks if given IP address belongs to this blocklist If. it is, a
173
+	// connection is terminated .
182
 	Contains(net.IP) bool
174
 	Contains(net.IP) bool
183
 
175
 
184
 	// Run starts a background update procedure for a blocklist
176
 	// Run starts a background update procedure for a blocklist
188
 	Shutdown()
180
 	Shutdown()
189
 }
181
 }
190
 
182
 
191
-// Event is a data structure which is populated during mtg request
192
-// processing lifecycle. Each request popluates many events:
193
-//
194
-// 1. Client connected
183
+// Event is a data structure which is populated during mtg request processing
184
+// lifecycle. Each request popluates many events:
185
+//  1. Client connected
186
+//  2. Request is finished
187
+//  3. Connection to Telegram server is established
195
 //
188
 //
196
-// 2. Request is finished
197
-//
198
-// 3. Connection to Telegram server is established
199
-//
200
-// and so on. All these events are data structures but all of them
201
-// must conform the same interface.
189
+// and so on. All these events are data structures but all of them must conform
190
+// the same interface.
202
 type Event interface {
191
 type Event interface {
203
-	// StreamID returns an identifier of the stream, connection,
204
-	// request, you name it. All events within the same stream returns
205
-	// the same stream id.
192
+	// StreamID returns an identifier of the stream, connection, request, you name
193
+	// it. All events within the same stream returns the same stream id.
206
 	StreamID() string
194
 	StreamID() string
207
 
195
 
208
 	// Timestamp returns a timestamp when this event was generated.
196
 	// Timestamp returns a timestamp when this event was generated.
209
 	Timestamp() time.Time
197
 	Timestamp() time.Time
210
 }
198
 }
211
 
199
 
212
-// EventStream is an abstraction that accepts a set of events produced
213
-// by mtg. Its main goal is to inject your logging or monitoring system.
200
+// EventStream is an abstraction that accepts a set of events produced by mtg.
201
+// Its main goal is to inject your logging or monitoring system.
214
 //
202
 //
215
-// The idea is simple. When mtg works, it emits a set of events during
216
-// a lifecycle of the requestor: EventStart, EventFinish etc. mtg is a
217
-// producer which puts these events into a stream. Responsibility of
218
-// the stream is to deliver this event to consumers/observers. There
219
-// might be many different observers (for example, you want to have both
220
-// statsd and prometheus), mtg should know nothing about them.
203
+// The idea is simple. When mtg works, it emits a set of events during a
204
+// lifecycle of the requestor: EventStart, EventFinish etc. mtg is a producer
205
+// which puts these events into a stream. Responsibility of the stream is to
206
+// deliver this event to consumers/observers. There might be many different
207
+// observers (for example, you want to have both statsd and prometheus), mtg
208
+// should know nothing about them.
221
 type EventStream interface {
209
 type EventStream interface {
222
-	// Send delivers an event to observers. Given context has to be
223
-	// respected. If the context is closed, all blocking operations should
224
-	// be released ASAP.
210
+	// Send delivers an event to observers. Given context has to be respected. If
211
+	// the context is closed, all blocking operations should be released ASAP.
225
 	//
212
 	//
226
 	// It is possible that context is closed but the message is delivered.
213
 	// It is possible that context is closed but the message is delivered.
227
 	// EventStream implementations should solve this issue somehow.
214
 	// EventStream implementations should solve this issue somehow.
230
 
217
 
231
 // Logger defines an interface of the logger used by mtglib.
218
 // Logger defines an interface of the logger used by mtglib.
232
 //
219
 //
233
-// Each logger has a name. It is possible to stack names to organize
234
-// poor-man namespaces. Also, each logger must be able to bind
235
-// parameters to avoid pushing them all the time.
220
+// Each logger has a name. It is possible to stack names to organize poor-man
221
+// namespaces. Also, each logger must be able to bind parameters to avoid
222
+// pushing them all the time.
236
 //
223
 //
237
 // Example
224
 // Example
238
 //
225
 //
239
-//     logger := SomeLogger{}
240
-//     logger = logger.BindStr("ip", net.IP{127, 0, 0, 1})
241
-//     logger.Info("Hello")
226
+//	logger := SomeLogger{} logger = logger.BindStr("ip", net.IP{127, 0, 0, 1})
227
+//	logger.Info("Hello")
242
 //
228
 //
243
-// In that case, ip is bound as a parameter. It is a great idea to
244
-// put this parameter somewhere in a log message.
229
+// In that case, ip is bound as a parameter. It is a great idea to put this
230
+// parameter somewhere in a log message.
245
 //
231
 //
246
-//     logger1 = logger.BindStr("param1", "11")
247
-//     logger2 = logger.BindInt("param2", 11)
232
+//	logger1 = logger.BindStr("param1", "11") logger2 = logger.BindInt("param2",
233
+//	11)
248
 //
234
 //
249
 // logger1 should see no param2 and vice versa, logger2 should not see param1
235
 // logger1 should see no param2 and vice versa, logger2 should not see param1
250
 // If you attach a parameter to a logger, parents should not know about that.
236
 // If you attach a parameter to a logger, parents should not know about that.
251
 type Logger interface {
237
 type Logger interface {
252
-	// Named returns a new logger with a bound name. Name chaining is
253
-	// allowed and appreciated.
238
+	// Named returns a new logger with a bound name. Name chaining is allowed and
239
+	// appreciated.
254
 	Named(name string) Logger
240
 	Named(name string) Logger
255
 
241
 
256
 	// BindInt binds new integer parameter to a new logger instance.
242
 	// BindInt binds new integer parameter to a new logger instance.
268
 	// Info puts a message about some normal situation.
254
 	// Info puts a message about some normal situation.
269
 	Info(msg string)
255
 	Info(msg string)
270
 
256
 
271
-	// InfoError puts a message about some normal situation but this
272
-	// situation is related to a given error.
257
+	// InfoError puts a message about some normal situation but this situation is
258
+	// related to a given error.
273
 	InfoError(msg string, err error)
259
 	InfoError(msg string, err error)
274
 
260
 
275
-	// Warning puts a message about some extraordinary situation
276
-	// worth to look at.
261
+	// Warning puts a message about some extraordinary situation worth to look at.
277
 	Warning(msg string)
262
 	Warning(msg string)
278
 
263
 
279
-	// WarningError puts a message about some extraordinary situation
280
-	// worth to look at. This situation is related to a given error.
264
+	// WarningError puts a message about some extraordinary situation worth to
265
+	// look at. This situation is related to a given error.
281
 	WarningError(msg string, err error)
266
 	WarningError(msg string, err error)
282
 
267
 
283
 	// Debug puts a message useful for debugging only.
268
 	// Debug puts a message useful for debugging only.
284
 	Debug(msg string)
269
 	Debug(msg string)
285
 
270
 
286
-	// Debug puts a message useful for debugging only. This message is
287
-	// related to a given error.
271
+	// Debug puts a message useful for debugging only. This message is related to
272
+	// a given error.
288
 	DebugError(msg string, err error)
273
 	DebugError(msg string, err error)
289
 }
274
 }

+ 3
- 3
mtglib/internal/faketls/client_hello.go Прегледај датотеку

56
 	if len(handshake)-4 != int(handshakeLength) {
56
 	if len(handshake)-4 != int(handshakeLength) {
57
 		return hello,
57
 		return hello,
58
 			fmt.Errorf("incorrect handshake size. manifested=%d, real=%d",
58
 			fmt.Errorf("incorrect handshake size. manifested=%d, real=%d",
59
-				handshakeLength, len(handshake)-4) // nolint: gomnd
59
+				handshakeLength, len(handshake)-4) //nolint: gomnd
60
 	}
60
 	}
61
 
61
 
62
 	copy(hello.Random[:], handshake[ClientHelloRandomOffset:])
62
 	copy(hello.Random[:], handshake[ClientHelloRandomOffset:])
72
 	// mac is calculated for the whole record, not only
72
 	// mac is calculated for the whole record, not only
73
 	// for the payload part
73
 	// for the payload part
74
 	mac := hmac.New(sha256.New, secret)
74
 	mac := hmac.New(sha256.New, secret)
75
-	rec.Dump(mac) // nolint: errcheck
75
+	rec.Dump(mac) //nolint: errcheck
76
 
76
 
77
 	computedRandom := mac.Sum(nil)
77
 	computedRandom := mac.Sum(nil)
78
 
78
 
100
 }
100
 }
101
 
101
 
102
 func parseCipherSuite(hello *ClientHello, handshake []byte) {
102
 func parseCipherSuite(hello *ClientHello, handshake []byte) {
103
-	cipherSuiteOffset := ClientHelloSessionIDOffset + len(hello.SessionID) + 3 // nolint: gomnd
103
+	cipherSuiteOffset := ClientHelloSessionIDOffset + len(hello.SessionID) + 3 //nolint: gomnd
104
 	hello.CipherSuite = binary.BigEndian.Uint16(handshake[cipherSuiteOffset : cipherSuiteOffset+2])
104
 	hello.CipherSuite = binary.BigEndian.Uint16(handshake[cipherSuiteOffset : cipherSuiteOffset+2])
105
 }
105
 }
106
 
106
 

+ 6
- 6
mtglib/internal/faketls/conn.go Прегледај датотеку

25
 
25
 
26
 	for {
26
 	for {
27
 		if err := rec.Read(c.Conn); err != nil {
27
 		if err := rec.Read(c.Conn); err != nil {
28
-			return 0, err // nolint: wrapcheck
28
+			return 0, err //nolint: wrapcheck
29
 		}
29
 		}
30
 
30
 
31
-		switch rec.Type { // nolint: exhaustive
31
+		switch rec.Type { //nolint: exhaustive
32
 		case record.TypeApplicationData:
32
 		case record.TypeApplicationData:
33
-			rec.Payload.WriteTo(&c.readBuffer) // nolint: errcheck
33
+			rec.Payload.WriteTo(&c.readBuffer) //nolint: errcheck
34
 
34
 
35
-			return c.readBuffer.Read(p) // nolint: wrapcheck
35
+			return c.readBuffer.Read(p) //nolint: wrapcheck
36
 		case record.TypeChangeCipherSpec:
36
 		case record.TypeChangeCipherSpec:
37
 		default:
37
 		default:
38
 			return 0, fmt.Errorf("unsupported record type %v", rec.Type)
38
 			return 0, fmt.Errorf("unsupported record type %v", rec.Type)
60
 
60
 
61
 		rec.Payload.Reset()
61
 		rec.Payload.Reset()
62
 		rec.Payload.Write(p[:chunkSize])
62
 		rec.Payload.Write(p[:chunkSize])
63
-		rec.Dump(sendBuffer) // nolint: errcheck
63
+		rec.Dump(sendBuffer) //nolint: errcheck
64
 
64
 
65
 		p = p[chunkSize:]
65
 		p = p[chunkSize:]
66
 	}
66
 	}
67
 
67
 
68
 	if _, err := c.Conn.Write(sendBuffer.Bytes()); err != nil {
68
 	if _, err := c.Conn.Write(sendBuffer.Bytes()); err != nil {
69
-		return 0, err // nolint: wrapcheck
69
+		return 0, err //nolint: wrapcheck
70
 	}
70
 	}
71
 
71
 
72
 	return lenP, nil
72
 	return lenP, nil

+ 7
- 7
mtglib/internal/faketls/conn_test.go Прегледај датотеку

24
 func (m *ConnMock) Read(p []byte) (int, error) {
24
 func (m *ConnMock) Read(p []byte) (int, error) {
25
 	m.Called(p)
25
 	m.Called(p)
26
 
26
 
27
-	return m.readBuffer.Read(p) // nolint: wrapcheck
27
+	return m.readBuffer.Read(p) //nolint: wrapcheck
28
 }
28
 }
29
 
29
 
30
 func (m *ConnMock) Write(p []byte) (int, error) {
30
 func (m *ConnMock) Write(p []byte) (int, error) {
31
 	m.Called(p)
31
 	m.Called(p)
32
 
32
 
33
-	return m.writeBuffer.Write(p) // nolint: wrapcheck
33
+	return m.writeBuffer.Write(p) //nolint: wrapcheck
34
 }
34
 }
35
 
35
 
36
 type ConnTestSuite struct {
36
 type ConnTestSuite struct {
61
 	rec.Version = record.Version12
61
 	rec.Version = record.Version12
62
 
62
 
63
 	rec.Payload.WriteByte(0x01)
63
 	rec.Payload.WriteByte(0x01)
64
-	rec.Dump(&suite.connMock.readBuffer) // nolint: errcheck
64
+	rec.Dump(&suite.connMock.readBuffer) //nolint: errcheck
65
 	rec.Reset()
65
 	rec.Reset()
66
 
66
 
67
 	rec.Type = record.TypeApplicationData
67
 	rec.Type = record.TypeApplicationData
68
 	rec.Version = record.Version12
68
 	rec.Version = record.Version12
69
 
69
 
70
 	rec.Payload.Write([]byte{1, 2, 3, 4, 5, 6, 7, 8, 9, 10})
70
 	rec.Payload.Write([]byte{1, 2, 3, 4, 5, 6, 7, 8, 9, 10})
71
-	rec.Dump(&suite.connMock.readBuffer) // nolint: errcheck
71
+	rec.Dump(&suite.connMock.readBuffer) //nolint: errcheck
72
 
72
 
73
 	resultBuffer := &bytes.Buffer{}
73
 	resultBuffer := &bytes.Buffer{}
74
 	buf := make([]byte, 2)
74
 	buf := make([]byte, 2)
95
 	rec.Version = record.Version12
95
 	rec.Version = record.Version12
96
 
96
 
97
 	rec.Payload.WriteByte(0x01)
97
 	rec.Payload.WriteByte(0x01)
98
-	rec.Dump(&suite.connMock.readBuffer) // nolint: errcheck
98
+	rec.Dump(&suite.connMock.readBuffer) //nolint: errcheck
99
 	rec.Reset()
99
 	rec.Reset()
100
 
100
 
101
 	rec.Type = record.TypeHandshake
101
 	rec.Type = record.TypeHandshake
102
 	rec.Version = record.Version12
102
 	rec.Version = record.Version12
103
 
103
 
104
 	rec.Payload.Write([]byte{1, 2, 3, 4, 5, 6, 7, 8, 9, 10})
104
 	rec.Payload.Write([]byte{1, 2, 3, 4, 5, 6, 7, 8, 9, 10})
105
-	rec.Dump(&suite.connMock.readBuffer) // nolint: errcheck
105
+	rec.Dump(&suite.connMock.readBuffer) //nolint: errcheck
106
 
106
 
107
 	buf := make([]byte, 2)
107
 	buf := make([]byte, 2)
108
 
108
 
141
 
141
 
142
 		suite.Equal(record.TypeApplicationData, rec.Type)
142
 		suite.Equal(record.TypeApplicationData, rec.Type)
143
 		suite.Equal(record.Version12, rec.Version)
143
 		suite.Equal(record.Version12, rec.Version)
144
-		rec.Payload.WriteTo(buf) // nolint: errcheck
144
+		rec.Payload.WriteTo(buf) //nolint: errcheck
145
 	}
145
 	}
146
 
146
 
147
 	suite.Equal(dataToRec, buf.Bytes())
147
 	suite.Equal(dataToRec, buf.Bytes())

+ 1
- 1
mtglib/internal/faketls/pools.go Прегледај датотеку

12
 }
12
 }
13
 
13
 
14
 func acquireBytesBuffer() *bytes.Buffer {
14
 func acquireBytesBuffer() *bytes.Buffer {
15
-	return bytesBufferPool.Get().(*bytes.Buffer) // nolint: forcetypeassert
15
+	return bytesBufferPool.Get().(*bytes.Buffer) //nolint: forcetypeassert
16
 }
16
 }
17
 
17
 
18
 func releaseBytesBuffer(b *bytes.Buffer) {
18
 func releaseBytesBuffer(b *bytes.Buffer) {

+ 1
- 1
mtglib/internal/faketls/record/pools.go Прегледај датотеку

11
 }
11
 }
12
 
12
 
13
 func AcquireRecord() *Record {
13
 func AcquireRecord() *Record {
14
-	return recordPool.Get().(*Record) // nolint: forcetypeassert
14
+	return recordPool.Get().(*Record) //nolint: forcetypeassert
15
 }
15
 }
16
 
16
 
17
 func ReleaseRecord(r *Record) {
17
 func ReleaseRecord(r *Record) {

+ 7
- 7
mtglib/internal/faketls/welcome.go Прегледај датотеку

23
 	rec.Version = record.Version12
23
 	rec.Version = record.Version12
24
 
24
 
25
 	generateServerHello(&rec.Payload, clientHello)
25
 	generateServerHello(&rec.Payload, clientHello)
26
-	rec.Dump(buf) // nolint: errcheck
26
+	rec.Dump(buf) //nolint: errcheck
27
 	rec.Reset()
27
 	rec.Reset()
28
 
28
 
29
 	rec.Type = record.TypeChangeCipherSpec
29
 	rec.Type = record.TypeChangeCipherSpec
30
 	rec.Version = record.Version12
30
 	rec.Version = record.Version12
31
 	rec.Payload.WriteByte(ChangeCipherValue)
31
 	rec.Payload.WriteByte(ChangeCipherValue)
32
 
32
 
33
-	rec.Dump(buf) // nolint: errcheck
33
+	rec.Dump(buf) //nolint: errcheck
34
 	rec.Reset()
34
 	rec.Reset()
35
 
35
 
36
 	rec.Type = record.TypeApplicationData
36
 	rec.Type = record.TypeApplicationData
37
 	rec.Version = record.Version12
37
 	rec.Version = record.Version12
38
 
38
 
39
-	if _, err := io.CopyN(&rec.Payload, rand.Reader, int64(1024+mrand.Intn(3092))); err != nil { // nolint: gomnd
39
+	if _, err := io.CopyN(&rec.Payload, rand.Reader, int64(1024+mrand.Intn(3092))); err != nil { //nolint: gomnd
40
 		panic(err)
40
 		panic(err)
41
 	}
41
 	}
42
 
42
 
43
-	rec.Dump(buf) // nolint: errcheck
43
+	rec.Dump(buf) //nolint: errcheck
44
 
44
 
45
 	packet := buf.Bytes()
45
 	packet := buf.Bytes()
46
 	mac := hmac.New(sha256.New, secret)
46
 	mac := hmac.New(sha256.New, secret)
51
 	copy(packet[WelcomePacketRandomOffset:], mac.Sum(nil))
51
 	copy(packet[WelcomePacketRandomOffset:], mac.Sum(nil))
52
 
52
 
53
 	if _, err := writer.Write(packet); err != nil {
53
 	if _, err := writer.Write(packet); err != nil {
54
-		return err // nolint: wrapcheck
54
+		return err //nolint: wrapcheck
55
 	}
55
 	}
56
 
56
 
57
 	return nil
57
 	return nil
87
 	binary.BigEndian.PutUint32(header[:], uint32(bodyBuf.Len()))
87
 	binary.BigEndian.PutUint32(header[:], uint32(bodyBuf.Len()))
88
 	header[0] = HandshakeTypeServer
88
 	header[0] = HandshakeTypeServer
89
 
89
 
90
-	writer.Write(header[:]) // nolint: errcheck
91
-	bodyBuf.WriteTo(writer) // nolint: errcheck
90
+	writer.Write(header[:]) //nolint: errcheck
91
+	bodyBuf.WriteTo(writer) //nolint: errcheck
92
 }
92
 }

+ 1
- 1
mtglib/internal/obfuscated2/client_handshake_test.go Прегледај датотеку

22
 
22
 
23
 func (suite *ClientHandshakeTestSuite) TestCannotRead() {
23
 func (suite *ClientHandshakeTestSuite) TestCannotRead() {
24
 	buf := bytes.NewBuffer([]byte{1, 2, 3})
24
 	buf := bytes.NewBuffer([]byte{1, 2, 3})
25
-	_, _, _, err := obfuscated2.ClientHandshake([]byte{1, 2, 3}, buf) // nolint: dogsled
25
+	_, _, _, err := obfuscated2.ClientHandshake([]byte{1, 2, 3}, buf) //nolint: dogsled
26
 
26
 
27
 	suite.Error(err)
27
 	suite.Error(err)
28
 }
28
 }

+ 2
- 2
mtglib/internal/obfuscated2/conn.go Прегледај датотеку

16
 func (c Conn) Read(p []byte) (int, error) {
16
 func (c Conn) Read(p []byte) (int, error) {
17
 	n, err := c.Conn.Read(p)
17
 	n, err := c.Conn.Read(p)
18
 	if err != nil {
18
 	if err != nil {
19
-		return n, err // nolint: wrapcheck
19
+		return n, err //nolint: wrapcheck
20
 	}
20
 	}
21
 
21
 
22
 	c.Decryptor.XORKeyStream(p, p[:n])
22
 	c.Decryptor.XORKeyStream(p, p[:n])
33
 	payload := buf.Bytes()
33
 	payload := buf.Bytes()
34
 	c.Encryptor.XORKeyStream(payload, payload)
34
 	c.Encryptor.XORKeyStream(payload, payload)
35
 
35
 
36
-	return c.Conn.Write(payload) // nolint: wrapcheck
36
+	return c.Conn.Write(payload) //nolint: wrapcheck
37
 }
37
 }

+ 8
- 8
mtglib/internal/obfuscated2/handshake_frame.go Прегледај датотеку

23
 
23
 
24
 // A structure of obfuscated2 handshake frame is following:
24
 // A structure of obfuscated2 handshake frame is following:
25
 //
25
 //
26
-//    [frameOffsetFirst:frameOffsetKey:frameOffsetIV:frameOffsetMagic:frameOffsetDC:frameOffsetEnd].
26
+//	[frameOffsetFirst:frameOffsetKey:frameOffsetIV:frameOffsetMagic:frameOffsetDC:frameOffsetEnd].
27
 //
27
 //
28
-//    - 8 bytes of noise
29
-//    - 32 bytes of AES Key
30
-//    - 16 bytes of AES IV
31
-//    - 4 bytes of 'connection type' - this has some setting like a connection type
32
-//    - 2 bytes of 'DC'. DC is little endian int16
33
-//    - 2 bytes of noise
28
+//	- 8 bytes of noise
29
+//	- 32 bytes of AES Key
30
+//	- 16 bytes of AES IV
31
+//	- 4 bytes of 'connection type' - this has some setting like a connection type
32
+//	- 2 bytes of 'DC'. DC is little endian int16
33
+//	- 2 bytes of noise
34
 type handshakeFrame struct {
34
 type handshakeFrame struct {
35
 	data [handshakeFrameLen]byte
35
 	data [handshakeFrameLen]byte
36
 }
36
 }
37
 
37
 
38
 func (h *handshakeFrame) dc() int {
38
 func (h *handshakeFrame) dc() int {
39
-	idx := int16(h.data[handshakeFrameOffsetDC]) | int16(h.data[handshakeFrameOffsetDC+1])<<8 // nolint: gomnd, lll // little endian for int16 is here
39
+	idx := int16(h.data[handshakeFrameOffsetDC]) | int16(h.data[handshakeFrameOffsetDC+1])<<8 //nolint: gomnd, lll // little endian for int16 is here
40
 
40
 
41
 	switch {
41
 	switch {
42
 	case idx > 0:
42
 	case idx > 0:

+ 1
- 1
mtglib/internal/obfuscated2/handshake_frame_internal_test.go Прегледај датотеку

57
 		suite.T().Run(strconv.Itoa(int(incoming)), func(t *testing.T) {
57
 		suite.T().Run(strconv.Itoa(int(incoming)), func(t *testing.T) {
58
 			frame := handshakeFrame{}
58
 			frame := handshakeFrame{}
59
 
59
 
60
-			rand.Read(frame.data[:]) // nolint: errcheck
60
+			rand.Read(frame.data[:]) //nolint: errcheck
61
 
61
 
62
 			frame.data[handshakeFrameOffsetDC] = byte(incoming)
62
 			frame.data[handshakeFrameOffsetDC] = byte(incoming)
63
 			frame.data[handshakeFrameOffsetDC+1] = byte(incoming >> 8)
63
 			frame.data[handshakeFrameOffsetDC+1] = byte(incoming >> 8)

+ 2
- 2
mtglib/internal/obfuscated2/pools.go Прегледај датотеку

21
 )
21
 )
22
 
22
 
23
 func acquireSha256Hasher() hash.Hash {
23
 func acquireSha256Hasher() hash.Hash {
24
-	return sha256HasherPool.Get().(hash.Hash) // nolint: forcetypeassert
24
+	return sha256HasherPool.Get().(hash.Hash) //nolint: forcetypeassert
25
 }
25
 }
26
 
26
 
27
 func releaseSha256Hasher(h hash.Hash) {
27
 func releaseSha256Hasher(h hash.Hash) {
30
 }
30
 }
31
 
31
 
32
 func acquireBytesBuffer() *bytes.Buffer {
32
 func acquireBytesBuffer() *bytes.Buffer {
33
-	return bytesBufferPool.Get().(*bytes.Buffer) // nolint: forcetypeassert
33
+	return bytesBufferPool.Get().(*bytes.Buffer) //nolint: forcetypeassert
34
 }
34
 }
35
 
35
 
36
 func releaseBytesBuffer(buf *bytes.Buffer) {
36
 func releaseBytesBuffer(buf *bytes.Buffer) {

+ 2
- 2
mtglib/internal/obfuscated2/server_handshake.go Прегледај датотеку

47
 			panic(err)
47
 			panic(err)
48
 		}
48
 		}
49
 
49
 
50
-		if frame.data[0] == 0xef { // nolint: gomnd // taken from tg sources
50
+		if frame.data[0] == 0xef { //nolint: gomnd // taken from tg sources
51
 			continue
51
 			continue
52
 		}
52
 		}
53
 
53
 
54
 		switch binary.LittleEndian.Uint32(frame.data[:4]) {
54
 		switch binary.LittleEndian.Uint32(frame.data[:4]) {
55
-		case 0x44414548, 0x54534f50, 0x20544547, 0x4954504f, 0xeeeeeeee: // nolint: gomnd // taken from tg sources
55
+		case 0x44414548, 0x54534f50, 0x20544547, 0x4954504f, 0xeeeeeeee: //nolint: gomnd // taken from tg sources
56
 			continue
56
 			continue
57
 		}
57
 		}
58
 
58
 

+ 2
- 2
mtglib/internal/obfuscated2/server_handshake_fuzz_test.go Прегледај датотеку

19
 			Once().
19
 			Once().
20
 			Run(func(args mock.Arguments) {
20
 			Run(func(args mock.Arguments) {
21
 				message := make([]byte, len(data))
21
 				message := make([]byte, len(data))
22
-				handshakeData.decryptor.XORKeyStream(message, args.Get(0).([]byte)) // nolint: forcetypeassert
22
+				handshakeData.decryptor.XORKeyStream(message, args.Get(0).([]byte)) //nolint: forcetypeassert
23
 				assert.Equal(t, message, data)
23
 				assert.Equal(t, message, data)
24
 			})
24
 			})
25
 
25
 
45
 			Run(func(args mock.Arguments) {
45
 			Run(func(args mock.Arguments) {
46
 				message := make([]byte, len(data))
46
 				message := make([]byte, len(data))
47
 				handshakeData.encryptor.XORKeyStream(message, data)
47
 				handshakeData.encryptor.XORKeyStream(message, data)
48
-				copy(args.Get(0).([]byte), message) // nolint: forcetypeassert
48
+				copy(args.Get(0).([]byte), message) //nolint: forcetypeassert
49
 			})
49
 			})
50
 
50
 
51
 		n, err := handshakeData.proxyConn.Read(buffer)
51
 		n, err := handshakeData.proxyConn.Read(buffer)

+ 2
- 2
mtglib/internal/obfuscated2/server_handshake_test.go Прегледај датотеку

30
 		Once().
30
 		Once().
31
 		Run(func(args mock.Arguments) {
31
 		Run(func(args mock.Arguments) {
32
 			message := make([]byte, len(messageToTelegram))
32
 			message := make([]byte, len(messageToTelegram))
33
-			suite.data.decryptor.XORKeyStream(message, args.Get(0).([]byte)) // nolint: forcetypeassert
33
+			suite.data.decryptor.XORKeyStream(message, args.Get(0).([]byte)) //nolint: forcetypeassert
34
 			suite.Equal(messageToTelegram, message)
34
 			suite.Equal(messageToTelegram, message)
35
 		})
35
 		})
36
 
36
 
50
 		Run(func(args mock.Arguments) {
50
 		Run(func(args mock.Arguments) {
51
 			message := make([]byte, len(messageFromTelegram))
51
 			message := make([]byte, len(messageFromTelegram))
52
 			suite.data.encryptor.XORKeyStream(message, messageFromTelegram)
52
 			suite.data.encryptor.XORKeyStream(message, messageFromTelegram)
53
-			copy(args.Get(0).([]byte), message) // nolint: forcetypeassert
53
+			copy(args.Get(0).([]byte), message) //nolint: forcetypeassert
54
 		})
54
 		})
55
 
55
 
56
 	n, err := suite.data.proxyConn.Read(buffer)
56
 	n, err := suite.data.proxyConn.Read(buffer)

+ 1
- 1
mtglib/internal/relay/pools.go Прегледај датотеку

11
 }
11
 }
12
 
12
 
13
 func acquireCopyBuffer() *[]byte {
13
 func acquireCopyBuffer() *[]byte {
14
-	return copyBufferPool.Get().(*[]byte) // nolint: forcetypeassert
14
+	return copyBufferPool.Get().(*[]byte) //nolint: forcetypeassert
15
 }
15
 }
16
 
16
 
17
 func releaseCopyBuffer(buf *[]byte) {
17
 func releaseCopyBuffer(buf *[]byte) {

+ 2
- 2
mtglib/internal/relay/relay.go Прегледај датотеку

35
 }
35
 }
36
 
36
 
37
 func pump(log Logger, src, dst essentials.Conn, direction string) {
37
 func pump(log Logger, src, dst essentials.Conn, direction string) {
38
-	defer src.CloseRead()  // nolint: errcheck
39
-	defer dst.CloseWrite() // nolint: errcheck
38
+	defer src.CloseRead()  //nolint: errcheck
39
+	defer dst.CloseWrite() //nolint: errcheck
40
 
40
 
41
 	copyBuffer := acquireCopyBuffer()
41
 	copyBuffer := acquireCopyBuffer()
42
 	defer releaseCopyBuffer(copyBuffer)
42
 	defer releaseCopyBuffer(copyBuffer)

+ 7
- 7
mtglib/proxy.go Прегледај датотеку

44
 	return net.JoinHostPort(p.secret.Host, strconv.Itoa(p.domainFrontingPort))
44
 	return net.JoinHostPort(p.secret.Host, strconv.Itoa(p.domainFrontingPort))
45
 }
45
 }
46
 
46
 
47
-// ServeConn serves a connection. We do not check IP blocklist and
48
-// concurrency limit here.
47
+// ServeConn serves a connection. We do not check IP blocklist and concurrency
48
+// limit here.
49
 func (p *Proxy) ServeConn(conn essentials.Conn) {
49
 func (p *Proxy) ServeConn(conn essentials.Conn) {
50
 	p.streamWaitGroup.Add(1)
50
 	p.streamWaitGroup.Add(1)
51
 	defer p.streamWaitGroup.Done()
51
 	defer p.streamWaitGroup.Done()
106
 			}
106
 			}
107
 		}
107
 		}
108
 
108
 
109
-		ipAddr := conn.RemoteAddr().(*net.TCPAddr).IP // nolint: forcetypeassert
109
+		ipAddr := conn.RemoteAddr().(*net.TCPAddr).IP //nolint: forcetypeassert
110
 		logger := p.logger.BindStr("ip", ipAddr.String())
110
 		logger := p.logger.BindStr("ip", ipAddr.String())
111
 
111
 
112
 		if !p.allowlist.Contains(ipAddr) {
112
 		if !p.allowlist.Contains(ipAddr) {
138
 	}
138
 	}
139
 }
139
 }
140
 
140
 
141
-// Shutdown 'gracefully' shutdowns all connections. Please remember that
142
-// it does not close an underlying listener.
141
+// Shutdown 'gracefully' shutdowns all connections. Please remember that it
142
+// does not close an underlying listener.
143
 func (p *Proxy) Shutdown() {
143
 func (p *Proxy) Shutdown() {
144
 	p.ctxCancel()
144
 	p.ctxCancel()
145
 	p.streamWaitGroup.Wait()
145
 	p.streamWaitGroup.Wait()
253
 
253
 
254
 	p.eventStream.Send(ctx,
254
 	p.eventStream.Send(ctx,
255
 		NewEventConnectedToDC(ctx.streamID,
255
 		NewEventConnectedToDC(ctx.streamID,
256
-			conn.RemoteAddr().(*net.TCPAddr).IP, // nolint: forcetypeassert
256
+			conn.RemoteAddr().(*net.TCPAddr).IP, //nolint: forcetypeassert
257
 			ctx.dc),
257
 			ctx.dc),
258
 	)
258
 	)
259
 
259
 
316
 
316
 
317
 	pool, err := ants.NewPoolWithFunc(opts.getConcurrency(),
317
 	pool, err := ants.NewPoolWithFunc(opts.getConcurrency(),
318
 		func(arg interface{}) {
318
 		func(arg interface{}) {
319
-			proxy.ServeConn(arg.(essentials.Conn)) // nolint: forcetypeassert
319
+			proxy.ServeConn(arg.(essentials.Conn)) //nolint: forcetypeassert
320
 		},
320
 		},
321
 		ants.WithLogger(opts.getLogger("ants")),
321
 		ants.WithLogger(opts.getLogger("ants")),
322
 		ants.WithNonblocking(true))
322
 		ants.WithNonblocking(true))

+ 25
- 29
mtglib/proxy_opts.go Прегледај датотеку

4
 
4
 
5
 // ProxyOpts is a structure with settings to mtg proxy.
5
 // ProxyOpts is a structure with settings to mtg proxy.
6
 //
6
 //
7
-// This is not required per se, but this is to shorten function
8
-// signature and give an ability to conveniently provide default values.
7
+// This is not required per se, but this is to shorten function signature and
8
+// give an ability to conveniently provide default values.
9
 type ProxyOpts struct {
9
 type ProxyOpts struct {
10
 	// Secret defines a secret which should be used by a proxy.
10
 	// Secret defines a secret which should be used by a proxy.
11
 	//
11
 	//
12
 	// This is a mandatory setting.
12
 	// This is a mandatory setting.
13
 	Secret Secret
13
 	Secret Secret
14
 
14
 
15
-	// Network defines a network instance which should be used for all
16
-	// network communications made by proxies.
15
+	// Network defines a network instance which should be used for all network
16
+	// communications made by proxies.
17
 	//
17
 	//
18
 	// This is a mandatory setting.
18
 	// This is a mandatory setting.
19
 	Network Network
19
 	Network Network
45
 
45
 
46
 	// BufferSize is a size of the copy buffer in bytes.
46
 	// BufferSize is a size of the copy buffer in bytes.
47
 	//
47
 	//
48
-	// Please remember that we multiply this number in 2, because when
49
-	// we relay between proxies, we have to create 2 intermediate
50
-	// buffers: to and from.
48
+	// Please remember that we multiply this number in 2, because when we relay
49
+	// between proxies, we have to create 2 intermediate buffers: to and from.
51
 	//
50
 	//
52
 	// This is an optional setting.
51
 	// This is an optional setting.
53
 	//
52
 	//
62
 	// This is an optional setting.
61
 	// This is an optional setting.
63
 	Concurrency uint
62
 	Concurrency uint
64
 
63
 
65
-	// IdleTimeout is a timeout for relay when we have to break a
66
-	// stream.
64
+	// IdleTimeout is a timeout for relay when we have to break a stream.
67
 	//
65
 	//
68
-	// This is a timeout for any activity. So, if we have any message
69
-	// which will pass to either direction, a timer is reset. If we have
70
-	// no any reads or writes for this timeout, a connection will be
71
-	// aborted.
66
+	// This is a timeout for any activity. So, if we have any message which will
67
+	// pass to either direction, a timer is reset. If we have no any reads or
68
+	// writes for this timeout, a connection will be aborted.
72
 	//
69
 	//
73
 	// This is an optional setting.
70
 	// This is an optional setting.
74
 	IdleTimeout time.Duration
71
 	IdleTimeout time.Duration
75
 
72
 
76
-	// TolerateTimeSkewness is a time boundary that defines a time
77
-	// range where faketls timestamp is acceptable.
73
+	// TolerateTimeSkewness is a time boundary that defines a time range where
74
+	// faketls timestamp is acceptable.
78
 	//
75
 	//
79
-	// This means that if if you got a timestamp X, now is Y, then
80
-	// if |X-Y| < TolerateTimeSkewness, then you accept a packet.
76
+	// This means that if if you got a timestamp X, now is Y, then if |X-Y| <
77
+	// TolerateTimeSkewness, then you accept a packet.
81
 	//
78
 	//
82
 	// This is an optional setting.
79
 	// This is an optional setting.
83
 	TolerateTimeSkewness time.Duration
80
 	TolerateTimeSkewness time.Duration
88
 	// This is an optional setting.
85
 	// This is an optional setting.
89
 	PreferIP string
86
 	PreferIP string
90
 
87
 
91
-	// DomainFrontingPort is a port we use to connect to a fronting
92
-	// domain.
88
+	// DomainFrontingPort is a port we use to connect to a fronting domain.
93
 	//
89
 	//
94
-	// This is required because secret does not specify a port. It
95
-	// specifies a hostname only.
90
+	// This is required because secret does not specify a port. It specifies a
91
+	// hostname only.
96
 	//
92
 	//
97
 	// This is an optional setting.
93
 	// This is an optional setting.
98
 	DomainFrontingPort uint
94
 	DomainFrontingPort uint
99
 
95
 
100
 	// AllowFallbackOnUnknownDC defines how proxy behaves if unknown DC was
96
 	// AllowFallbackOnUnknownDC defines how proxy behaves if unknown DC was
101
-	// requested. If this setting is set to false, then such connection
102
-	// will be rejected. Otherwise, proxy will chose any DC.
97
+	// requested. If this setting is set to false, then such connection will be
98
+	// rejected. Otherwise, proxy will chose any DC.
103
 	//
99
 	//
104
-	// Telegram is designed in a way that any DC can serve any request,
105
-	// the problem is a latency.
100
+	// Telegram is designed in a way that any DC can serve any request, the
101
+	// problem is a latency.
106
 	//
102
 	//
107
 	// This is an optional setting.
103
 	// This is an optional setting.
108
 	AllowFallbackOnUnknownDC bool
104
 	AllowFallbackOnUnknownDC bool
109
 
105
 
110
-	// UseTestDCs defines if we have to connect to production or to staging
111
-	// DCs of Telegram.
106
+	// UseTestDCs defines if we have to connect to production or to staging DCs of
107
+	// Telegram.
112
 	//
108
 	//
113
-	// This is required if you use mtglib as an integration library for
114
-	// your Telegram-related projects.
109
+	// This is required if you use mtglib as an integration library for your
110
+	// Telegram-related projects.
115
 	//
111
 	//
116
 	// This is an optional setting.
112
 	// This is an optional setting.
117
 	UseTestDCs bool
113
 	UseTestDCs bool

+ 4
- 4
mtglib/proxy_test.go Прегледај датотеку

86
 
86
 
87
 	suite.listener = listener
87
 	suite.listener = listener
88
 
88
 
89
-	go suite.p.Serve(suite.listener) // nolint: errcheck
89
+	go suite.p.Serve(suite.listener) //nolint: errcheck
90
 }
90
 }
91
 
91
 
92
 func (suite *ProxyTestSuite) TearDownSuite() {
92
 func (suite *ProxyTestSuite) TearDownSuite() {
179
 
179
 
180
 	addr := fmt.Sprintf("https://%s/headers", suite.ProxyAddress())
180
 	addr := fmt.Sprintf("https://%s/headers", suite.ProxyAddress())
181
 
181
 
182
-	resp, err := client.Get(addr) // nolint: noctx
182
+	resp, err := client.Get(addr) //nolint: noctx
183
 	suite.NoError(err)
183
 	suite.NoError(err)
184
 
184
 
185
 	defer resp.Body.Close()
185
 	defer resp.Body.Close()
191
 
191
 
192
 	jsonStruct := struct {
192
 	jsonStruct := struct {
193
 		Headers struct {
193
 		Headers struct {
194
-			TraceID string `json:"X-Amzn-Trace-Id"` // nolint: tagliatelle
194
+			TraceID string `json:"X-Amzn-Trace-Id"` //nolint: tagliatelle
195
 		} `json:"headers"`
195
 		} `json:"headers"`
196
 	}{}
196
 	}{}
197
 
197
 
221
 		_, err := tg.NewClient(tgClient).HelpGetConfig(ctx)
221
 		_, err := tg.NewClient(tgClient).HelpGetConfig(ctx)
222
 		suite.NoError(err)
222
 		suite.NoError(err)
223
 
223
 
224
-		return err // nolint: wrapcheck
224
+		return err //nolint: wrapcheck
225
 	}))
225
 	}))
226
 }
226
 }
227
 
227
 

+ 18
- 19
mtglib/secret.go Прегледај датотеку

17
 // "ee367a189aee18fa31c190054efd4a8e9573746f726167652e676f6f676c65617069732e636f6d".
17
 // "ee367a189aee18fa31c190054efd4a8e9573746f726167652e676f6f676c65617069732e636f6d".
18
 // Actually, this is a serialized datastructure of 2 parts: key and host.
18
 // Actually, this is a serialized datastructure of 2 parts: key and host.
19
 //
19
 //
20
-//     ee367a189aee18fa31c190054efd4a8e9573746f726167652e676f6f676c65617069732e636f6d
21
-//     |-|-------------------------------|-------------------------------------------
22
-//     p key                             hostname
20
+//	ee367a189aee18fa31c190054efd4a8e9573746f726167652e676f6f676c65617069732e636f6d
21
+//	|-|-------------------------------|-------------------------------------------
22
+//	p key                             hostname
23
 //
23
 //
24
-// Serialized secret starts with 'ee'. Actually, in the past we also had
25
-// 'dd' secrets and prefixless ones. But this is history. Currently,
26
-// we do have only 'ee' secrets which mean faketls + protection from
27
-// statistical attacks on a length. 'ee' is a byte 238 (0xee).
24
+// Serialized secret starts with 'ee'. Actually, in the past we also had 'dd'
25
+// secrets and prefixless ones. But this is history. Currently, we do have only
26
+// 'ee' secrets which mean faketls + protection from statistical attacks on a
27
+// length. 'ee' is a byte 238 (0xee).
28
 //
28
 //
29
-// After that, we have 16 bytes of the key. This is a random generated
30
-// secret data of the proxy and this data is used to derive
31
-// authentication schemas. These secrets are mixed into hmacs and sha256
32
-// checksums which are used to build AEAD ciphers for obfuscated2
33
-// protocol and ensure faketls handshake.
29
+// After that, we have 16 bytes of the key. This is a random generated secret
30
+// data of the proxy and this data is used to derive authentication schemas.
31
+// These secrets are mixed into hmacs and sha256 checksums which are used to
32
+// build AEAD ciphers for obfuscated2 protocol and ensure faketls handshake.
34
 //
33
 //
35
-// Host is a domain fronting hostname in latin1 (ASCII) encoding. This
36
-// hostname should be used for SNI in faketls and MTG verifies it. Also,
37
-// this is when mtg gets about a domain fronting hostname.
34
+// Host is a domain fronting hostname in latin1 (ASCII) encoding. This hostname
35
+// should be used for SNI in faketls and MTG verifies it. Also, this is when
36
+// mtg gets about a domain fronting hostname.
38
 //
37
 //
39
-// Secrets can be serialized into 2 forms: hex and base64. If
40
-// you decode both forms into bytes, you'll get the same byte array.
41
-// Telegram clients nowadays accept all forms.
38
+// Secrets can be serialized into 2 forms: hex and base64. If you decode both
39
+// forms into bytes, you'll get the same byte array. Telegram clients nowadays
40
+// accept all forms.
42
 type Secret struct {
41
 type Secret struct {
43
 	// Key is a set of bytes used for traffic authentication.
42
 	// Key is a set of bytes used for traffic authentication.
44
 	Key [SecretKeyLength]byte
43
 	Key [SecretKeyLength]byte
75
 		return fmt.Errorf("incorrect secret format: %w", err)
74
 		return fmt.Errorf("incorrect secret format: %w", err)
76
 	}
75
 	}
77
 
76
 
78
-	if len(decoded) < 2 { // nolint: gomnd // we need at least 1 byte here
77
+	if len(decoded) < 2 { //nolint: gomnd // we need at least 1 byte here
79
 		return fmt.Errorf("secret is truncated, length=%d", len(decoded))
78
 		return fmt.Errorf("secret is truncated, length=%d", len(decoded))
80
 	}
79
 	}
81
 
80
 

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

29
 }
29
 }
30
 
30
 
31
 func (s *streamContext) Err() error {
31
 func (s *streamContext) Err() error {
32
-	return s.ctx.Err() // nolint: wrapcheck
32
+	return s.ctx.Err() //nolint: wrapcheck
33
 }
33
 }
34
 
34
 
35
 func (s *streamContext) Value(key interface{}) interface{} {
35
 func (s *streamContext) Value(key interface{}) interface{} {
49
 }
49
 }
50
 
50
 
51
 func (s *streamContext) ClientIP() net.IP {
51
 func (s *streamContext) ClientIP() net.IP {
52
-	return s.clientConn.RemoteAddr().(*net.TCPAddr).IP // nolint: forcetypeassert
52
+	return s.clientConn.RemoteAddr().(*net.TCPAddr).IP //nolint: forcetypeassert
53
 }
53
 }
54
 
54
 
55
 func newStreamContext(ctx context.Context, logger Logger, clientConn essentials.Conn) *streamContext {
55
 func newStreamContext(ctx context.Context, logger Logger, clientConn essentials.Conn) *streamContext {

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

24
 
24
 
25
 func (suite *StreamContextTestSuite) SetupTest() {
25
 func (suite *StreamContextTestSuite) SetupTest() {
26
 	ctx, cancel := context.WithCancel(context.Background())
26
 	ctx, cancel := context.WithCancel(context.Background())
27
-	ctx = context.WithValue(ctx, "key", "value") // nolint: golint, revive, staticcheck
27
+	ctx = context.WithValue(ctx, "key", "value") //nolint: golint, staticcheck
28
 
28
 
29
 	suite.ctxCancel = cancel
29
 	suite.ctxCancel = cancel
30
 	suite.connMock = &testlib.EssentialsConnMock{}
30
 	suite.connMock = &testlib.EssentialsConnMock{}

+ 5
- 5
network/circuit_breaker.go Прегледај датотеку

59
 			conn.Close()
59
 			conn.Close()
60
 		}
60
 		}
61
 
61
 
62
-		return nil, ctx.Err() // nolint: wrapcheck
62
+		return nil, ctx.Err() //nolint: wrapcheck
63
 	case c.stateMutexChan <- true:
63
 	case c.stateMutexChan <- true:
64
 		defer func() {
64
 		defer func() {
65
 			<-c.stateMutexChan
65
 			<-c.stateMutexChan
78
 		c.switchState(circuitBreakerStateOpened)
78
 		c.switchState(circuitBreakerStateOpened)
79
 	}
79
 	}
80
 
80
 
81
-	return conn, err // nolint: wrapcheck
81
+	return conn, err //nolint: wrapcheck
82
 }
82
 }
83
 
83
 
84
 func (c *circuitBreakerDialer) doHalfOpened(ctx context.Context,
84
 func (c *circuitBreakerDialer) doHalfOpened(ctx context.Context,
96
 			conn.Close()
96
 			conn.Close()
97
 		}
97
 		}
98
 
98
 
99
-		return nil, ctx.Err() // nolint: wrapcheck
99
+		return nil, ctx.Err() //nolint: wrapcheck
100
 	case c.stateMutexChan <- true:
100
 	case c.stateMutexChan <- true:
101
 		defer func() {
101
 		defer func() {
102
 			<-c.stateMutexChan
102
 			<-c.stateMutexChan
104
 	}
104
 	}
105
 
105
 
106
 	if c.state != circuitBreakerStateHalfOpened {
106
 	if c.state != circuitBreakerStateHalfOpened {
107
-		return conn, err // nolint: wrapcheck
107
+		return conn, err //nolint: wrapcheck
108
 	}
108
 	}
109
 
109
 
110
 	if err == nil {
110
 	if err == nil {
113
 		c.switchState(circuitBreakerStateOpened)
113
 		c.switchState(circuitBreakerStateOpened)
114
 	}
114
 	}
115
 
115
 
116
-	return conn, err // nolint: wrapcheck
116
+	return conn, err //nolint: wrapcheck
117
 }
117
 }
118
 
118
 
119
 func (c *circuitBreakerDialer) switchState(state uint32) {
119
 func (c *circuitBreakerDialer) switchState(state uint32) {

+ 4
- 4
network/circuit_breaker_internal_test.go Прегледај датотеку

110
 		Port: 80,
110
 		Port: 80,
111
 	})
111
 	})
112
 
112
 
113
-	suite.d.DialContext(suite.ctx, "tcp", "127.0.0.1") // nolint: errcheck
114
-	suite.d.DialContext(suite.ctx, "tcp", "127.0.0.1") // nolint: errcheck
115
-	suite.d.DialContext(suite.ctx, "tcp", "127.0.0.1") // nolint: errcheck
116
-	suite.d.DialContext(suite.ctx, "tcp", "127.0.0.1") // nolint: errcheck
113
+	suite.d.DialContext(suite.ctx, "tcp", "127.0.0.1") //nolint: errcheck
114
+	suite.d.DialContext(suite.ctx, "tcp", "127.0.0.1") //nolint: errcheck
115
+	suite.d.DialContext(suite.ctx, "tcp", "127.0.0.1") //nolint: errcheck
116
+	suite.d.DialContext(suite.ctx, "tcp", "127.0.0.1") //nolint: errcheck
117
 
117
 
118
 	time.Sleep(500 * time.Millisecond)
118
 	time.Sleep(500 * time.Millisecond)
119
 
119
 

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

19
 
19
 
20
 func (d *defaultDialer) DialContext(ctx context.Context, network, address string) (essentials.Conn, error) {
20
 func (d *defaultDialer) DialContext(ctx context.Context, network, address string) (essentials.Conn, error) {
21
 	switch network {
21
 	switch network {
22
-	case "tcp", "tcp4", "tcp6": // nolint: goconst
22
+	case "tcp", "tcp4", "tcp6": //nolint: goconst
23
 	default:
23
 	default:
24
 		return nil, fmt.Errorf("unsupported network %s", network)
24
 		return nil, fmt.Errorf("unsupported network %s", network)
25
 	}
25
 	}
36
 		return nil, fmt.Errorf("cannot set socket options: %w", err)
36
 		return nil, fmt.Errorf("cannot set socket options: %w", err)
37
 	}
37
 	}
38
 
38
 
39
-	return conn.(essentials.Conn), nil // nolint: forcetypeassert
39
+	return conn.(essentials.Conn), nil //nolint: forcetypeassert
40
 }
40
 }
41
 
41
 
42
 // NewDefaultDialer build a new dialer which dials bypassing proxies
42
 // NewDefaultDialer build a new dialer which dials bypassing proxies

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

57
 func (suite *DefaultDialerTestSuite) TestHTTPRequest() {
57
 func (suite *DefaultDialerTestSuite) TestHTTPRequest() {
58
 	httpClient := suite.MakeHTTPClient(suite.d)
58
 	httpClient := suite.MakeHTTPClient(suite.d)
59
 
59
 
60
-	resp, err := httpClient.Get(suite.MakeURL("/get")) // nolint: noctx
60
+	resp, err := httpClient.Get(suite.MakeURL("/get")) //nolint: noctx
61
 	if err == nil {
61
 	if err == nil {
62
 		defer resp.Body.Close()
62
 		defer resp.Body.Close()
63
 	}
63
 	}

+ 2
- 4
network/dns_resolver.go Прегледај датотеку

85
 	return ips
85
 	return ips
86
 }
86
 }
87
 
87
 
88
-func newDNSResolver(hostname string, httpClient *http.Client) (ret *dnsResolver) {
88
+func newDNSResolver(hostname string, httpClient *http.Client) *dnsResolver {
89
 	if net.ParseIP(hostname).To4() == nil {
89
 	if net.ParseIP(hostname).To4() == nil {
90
 		// the hostname is an IPv6 address
90
 		// the hostname is an IPv6 address
91
 		hostname = fmt.Sprintf("[%s]", hostname)
91
 		hostname = fmt.Sprintf("[%s]", hostname)
92
 	}
92
 	}
93
 
93
 
94
-	ret = &dnsResolver{
94
+	return &dnsResolver{
95
 		resolver: doh.Resolver{
95
 		resolver: doh.Resolver{
96
 			Host:       hostname,
96
 			Host:       hostname,
97
 			Class:      doh.IN,
97
 			Class:      doh.IN,
99
 		},
99
 		},
100
 		cache: map[string]dnsResolverCacheEntry{},
100
 		cache: map[string]dnsResolverCacheEntry{},
101
 	}
101
 	}
102
-
103
-	return
104
 }
102
 }

+ 32
- 42
network/init.go Прегледај датотеку

1
 // Network contains a default implementation of the network.
1
 // Network contains a default implementation of the network.
2
 //
2
 //
3
-// Please see mtglib.Network interface to get some basic idea behind
4
-// this abstraction.
3
+// Please see [mtglib.Network] interface to get some basic idea behind this
4
+// abstraction.
5
 //
5
 //
6
 // Some notable feature of this implementation:
6
 // Some notable feature of this implementation:
7
 //
7
 //
8
-// 1. It detaches dialer from a network. Dialer is something which
9
-// implements a real dialer and network completes it with more higher
10
-// level details.
11
-//
12
-// 2. It uses only TCP connections. Even for DNS it uses DNS-Over-HTTPS
13
-//
14
-// 3. It has some simple implementation of DNS cache which is good
15
-// enough for our purpose.
16
-//
17
-// 4. It sets uses SO_REUSEPORT port if applicable.
8
+//  1. It detaches dialer from a network. Dialer is something which implements a
9
+//     real dialer and network completes it with more higher level details.
10
+//  2. It uses only TCP connections. Even for DNS it uses DNS-Over-HTTPS
11
+//  3. It has some simple implementation of DNS cache which is good enough for
12
+//     our purpose.
13
+//  4. It sets uses SO_REUSEPORT port if applicable.
18
 package network
14
 package network
19
 
15
 
20
 import (
16
 import (
26
 )
22
 )
27
 
23
 
28
 const (
24
 const (
29
-	// DefaultTimeout is a default timeout for establishing TCP
30
-	// connection.
25
+	// DefaultTimeout is a default timeout for establishing TCP connection.
31
 	DefaultTimeout = 10 * time.Second
26
 	DefaultTimeout = 10 * time.Second
32
 
27
 
33
-	// DefaultHTTPTimeout defines a default timeout for making HTTP
34
-	// request.
28
+	// DefaultHTTPTimeout defines a default timeout for making HTTP request.
35
 	DefaultHTTPTimeout = 10 * time.Second
29
 	DefaultHTTPTimeout = 10 * time.Second
36
 
30
 
37
 	// Deprecated:
31
 	// Deprecated:
38
 	//
32
 	//
39
-	// DefaultBufferSize defines a TCP buffer size. Both read and write, so
40
-	// for real size, please multiply this number by 2.
33
+	// DefaultBufferSize defines a TCP buffer size. Both read and write, so for
34
+	// real size, please multiply this number by 2.
41
 	DefaultBufferSize = 16 * 1024 // 16 kib
35
 	DefaultBufferSize = 16 * 1024 // 16 kib
42
 
36
 
43
-	// DefaultTCPKeepAlivePeriod defines a time period between 2
44
-	// consequitive probes.
37
+	// DefaultTCPKeepAlivePeriod defines a time period between 2 consequitive
38
+	// probes.
45
 	DefaultTCPKeepAlivePeriod = 10 * time.Second
39
 	DefaultTCPKeepAlivePeriod = 10 * time.Second
46
 
40
 
47
-	// ProxyDialerOpenThreshold is used for load balancing SOCKS5 dialer
48
-	// only.
41
+	// ProxyDialerOpenThreshold is used for load balancing SOCKS5 dialer only.
49
 	//
42
 	//
50
-	// This dialer uses circuit breaker with of 3 stages: OPEN,
51
-	// HALF_OPEN and CLOSED. If state is CLOSED, all requests go in
52
-	// a normal mode. If you get more that ProxyDialerOpenThreshold
53
-	// errors, circuit breaker goes into OPEN mode.
43
+	// This dialer uses circuit breaker with of 3 stages: OPEN, HALF_OPEN and
44
+	// CLOSED. If state is CLOSED, all requests go in a normal mode. If you get
45
+	// more that ProxyDialerOpenThreshold errors, circuit breaker goes into OPEN
46
+	// mode.
54
 	//
47
 	//
55
-	// When circuit breaker is in OPEN mode, it forbids all request to
56
-	// a given proxy. But after ProxyDialerHalfOpenTimeout it gives a
57
-	// second chance and opens an access for a SINGLE request. If this
58
-	// request success, then circuit breaker closes, otherwise opens
59
-	// again.
48
+	// When circuit breaker is in OPEN mode, it forbids all request to a given
49
+	// proxy. But after ProxyDialerHalfOpenTimeout it gives a second chance and
50
+	// opens an access for a SINGLE request. If this request success, then circuit
51
+	// breaker closes, otherwise opens again.
60
 	//
52
 	//
61
 	// When circuit breaker is closed, it clears an error states each
53
 	// When circuit breaker is closed, it clears an error states each
62
 	// ProxyDialerResetFailuresTimeout.
54
 	// ProxyDialerResetFailuresTimeout.
63
 	ProxyDialerOpenThreshold = 5
55
 	ProxyDialerOpenThreshold = 5
64
 
56
 
65
-	// ProxyDialerHalfOpenTimeout defines a halfopen timeout for circuit
66
-	// breaker.
57
+	// ProxyDialerHalfOpenTimeout defines a halfopen timeout for circuit breaker.
67
 	ProxyDialerHalfOpenTimeout = time.Minute
58
 	ProxyDialerHalfOpenTimeout = time.Minute
68
 
59
 
69
-	// ProxyDialerResetFailuresTimeout defines a timeout for resetting a
70
-	// failure.
60
+	// ProxyDialerResetFailuresTimeout defines a timeout for resetting a failure.
71
 	ProxyDialerResetFailuresTimeout = 10 * time.Second
61
 	ProxyDialerResetFailuresTimeout = 10 * time.Second
72
 
62
 
73
-	// DefaultDOHHostname defines a default IP address for DOH host.
74
-	// Since mtg is simple, please pass IP address here. We do not
75
-	// have bootstrap servers here embedded.
63
+	// DefaultDOHHostname defines a default IP address for DOH host. Since mtg is
64
+	// simple, please pass IP address here. We do not have bootstrap servers here
65
+	// embedded.
76
 	DefaultDOHHostname = "9.9.9.9"
66
 	DefaultDOHHostname = "9.9.9.9"
77
 
67
 
78
 	// DNSTimeout defines a timeout for DNS queries.
68
 	// DNSTimeout defines a timeout for DNS queries.
84
 )
74
 )
85
 
75
 
86
 var (
76
 var (
87
-	// ErrCircuitBreakerOpened is returned when proxy is being accessed
88
-	// but circuit breaker is opened.
77
+	// ErrCircuitBreakerOpened is returned when proxy is being accessed but
78
+	// circuit breaker is opened.
89
 	ErrCircuitBreakerOpened = errors.New("circuit breaker is opened")
79
 	ErrCircuitBreakerOpened = errors.New("circuit breaker is opened")
90
 
80
 
91
-	// ErrCannotDialWithAllProxies is returned when load balancing
92
-	// client is trying to access proxies but all of them are failed.
81
+	// ErrCannotDialWithAllProxies is returned when load balancing client is
82
+	// trying to access proxies but all of them are failed.
93
 	ErrCannotDialWithAllProxies = errors.New("cannot dial with all proxies")
83
 	ErrCannotDialWithAllProxies = errors.New("cannot dial with all proxies")
94
 )
84
 )
95
 
85
 

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

14
 func (d *DialerMock) Dial(network, address string) (essentials.Conn, error) {
14
 func (d *DialerMock) Dial(network, address string) (essentials.Conn, error) {
15
 	args := d.Called(network, address)
15
 	args := d.Called(network, address)
16
 
16
 
17
-	return args.Get(0).(essentials.Conn), args.Error(1) // nolint: wrapcheck, forcetypeassert
17
+	return args.Get(0).(essentials.Conn), args.Error(1) //nolint: wrapcheck, forcetypeassert
18
 }
18
 }
19
 
19
 
20
 func (d *DialerMock) DialContext(ctx context.Context, network, address string) (essentials.Conn, error) {
20
 func (d *DialerMock) DialContext(ctx context.Context, network, address string) (essentials.Conn, error) {
21
 	args := d.Called(ctx, network, address)
21
 	args := d.Called(ctx, network, address)
22
 
22
 
23
-	return args.Get(0).(essentials.Conn), args.Error(1) // nolint: wrapcheck, forcetypeassert
23
+	return args.Get(0).(essentials.Conn), args.Error(1) //nolint: wrapcheck, forcetypeassert
24
 }
24
 }

+ 4
- 4
network/init_test.go Прегледај датотеку

22
 func (d *DialerMock) Dial(network, address string) (essentials.Conn, error) {
22
 func (d *DialerMock) Dial(network, address string) (essentials.Conn, error) {
23
 	args := d.Called(network, address)
23
 	args := d.Called(network, address)
24
 
24
 
25
-	return args.Get(0).(essentials.Conn), args.Error(1) // nolint: wrapcheck, forcetypeassert
25
+	return args.Get(0).(essentials.Conn), args.Error(1) //nolint: wrapcheck, forcetypeassert
26
 }
26
 }
27
 
27
 
28
 func (d *DialerMock) DialContext(ctx context.Context, network, address string) (essentials.Conn, error) {
28
 func (d *DialerMock) DialContext(ctx context.Context, network, address string) (essentials.Conn, error) {
29
 	args := d.Called(ctx, network, address)
29
 	args := d.Called(ctx, network, address)
30
 
30
 
31
-	return args.Get(0).(essentials.Conn), args.Error(1) // nolint: wrapcheck, forcetypeassert
31
+	return args.Get(0).(essentials.Conn), args.Error(1) //nolint: wrapcheck, forcetypeassert
32
 }
32
 }
33
 
33
 
34
 type HTTPServerTestSuite struct {
34
 type HTTPServerTestSuite struct {
55
 	return &http.Client{
55
 	return &http.Client{
56
 		Transport: &http.Transport{
56
 		Transport: &http.Transport{
57
 			DialContext: func(ctx context.Context, network, address string) (net.Conn, error) {
57
 			DialContext: func(ctx context.Context, network, address string) (net.Conn, error) {
58
-				return dialer.DialContext(ctx, network, address) // nolint: wrapcheck
58
+				return dialer.DialContext(ctx, network, address) //nolint: wrapcheck
59
 			},
59
 			},
60
 		},
60
 		},
61
 	}
61
 	}
74
 		},
74
 		},
75
 	})
75
 	})
76
 
76
 
77
-	go suite.socks5Server.Serve(suite.socks5Listener) // nolint: errcheck
77
+	go suite.socks5Server.Serve(suite.socks5Listener) //nolint: errcheck
78
 }
78
 }
79
 
79
 
80
 func (suite *Socks5ServerTestSuite) TearDownSuite() {
80
 func (suite *Socks5ServerTestSuite) TearDownSuite() {

+ 6
- 8
network/load_balanced_socks5.go Прегледај датотеку

33
 	return nil, ErrCannotDialWithAllProxies
33
 	return nil, ErrCannotDialWithAllProxies
34
 }
34
 }
35
 
35
 
36
-// NewLoadBalancedSocks5Dialer builds a new load balancing SOCKS5
37
-// dialer.
36
+// NewLoadBalancedSocks5Dialer builds a new load balancing SOCKS5 dialer.
38
 //
37
 //
39
-// The main difference from one which is made by NewSocks5Dialer is that
40
-// we actually have a list of these proxies. When dial is requested,
41
-// any proxy is picked and used. If proxy fails for some reason, we try
42
-// another one.
38
+// The main difference from one which is made by NewSocks5Dialer is that we
39
+// actually have a list of these proxies. When dial is requested, any proxy is
40
+// picked and used. If proxy fails for some reason, we try another one.
43
 //
41
 //
44
-// So, it is mostly useful if you have some routes with proxies which
45
-// are not always online or having buggy network.
42
+// So, it is mostly useful if you have some routes with proxies which are not
43
+// always online or having buggy network.
46
 func NewLoadBalancedSocks5Dialer(baseDialer Dialer, proxyURLs []*url.URL) (Dialer, error) {
44
 func NewLoadBalancedSocks5Dialer(baseDialer Dialer, proxyURLs []*url.URL) (Dialer, error) {
47
 	dialers := make([]Dialer, 0, len(proxyURLs))
45
 	dialers := make([]Dialer, 0, len(proxyURLs))
48
 
46
 

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

73
 }
73
 }
74
 
74
 
75
 func (suite *LoadBalancedSocks5TestSuite) TestDialOk() {
75
 func (suite *LoadBalancedSocks5TestSuite) TestDialOk() {
76
-	resp, err := suite.httpClient.Get(suite.MakeURL("/get")) // nolint: noctx
76
+	resp, err := suite.httpClient.Get(suite.MakeURL("/get")) //nolint: noctx
77
 	if err == nil {
77
 	if err == nil {
78
 		defer resp.Body.Close()
78
 		defer resp.Body.Close()
79
 	}
79
 	}

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

21
 func (n networkHTTPTransport) RoundTrip(req *http.Request) (*http.Response, error) {
21
 func (n networkHTTPTransport) RoundTrip(req *http.Request) (*http.Response, error) {
22
 	req.Header.Set("User-Agent", n.userAgent)
22
 	req.Header.Set("User-Agent", n.userAgent)
23
 
23
 
24
-	return n.next.RoundTrip(req) // nolint: wrapcheck
24
+	return n.next.RoundTrip(req) //nolint: wrapcheck
25
 }
25
 }
26
 
26
 
27
 type network struct {
27
 type network struct {
118
 	return ips, nil
118
 	return ips, nil
119
 }
119
 }
120
 
120
 
121
-// NewNetwork assembles an mtglib.Network compatible structure
122
-// based on a dialer and given params.
121
+// NewNetwork assembles an mtglib.Network compatible structure based on a
122
+// dialer and given params.
123
 //
123
 //
124
 // It brings simple DNS cache and DNS-Over-HTTPS when necessary.
124
 // It brings simple DNS cache and DNS-Over-HTTPS when necessary.
125
 func NewNetwork(dialer Dialer,
125
 func NewNetwork(dialer Dialer,

+ 4
- 4
network/network_test.go Прегледај датотеку

31
 
31
 
32
 	client := ntw.MakeHTTPClient(nil)
32
 	client := ntw.MakeHTTPClient(nil)
33
 
33
 
34
-	resp, err := client.Get(suite.httpServer.URL + "/headers") // nolint: noctx
34
+	resp, err := client.Get(suite.httpServer.URL + "/headers") //nolint: noctx
35
 	suite.NoError(err)
35
 	suite.NoError(err)
36
 
36
 
37
 	defer resp.Body.Close()
37
 	defer resp.Body.Close()
42
 
42
 
43
 	jsonStruct := struct {
43
 	jsonStruct := struct {
44
 		Headers struct {
44
 		Headers struct {
45
-			UserAgent []string `json:"User-Agent"` // nolint: tagliatelle
45
+			UserAgent []string `json:"User-Agent"` //nolint: tagliatelle
46
 		} `json:"headers"`
46
 		} `json:"headers"`
47
 	}{}
47
 	}{}
48
 
48
 
56
 
56
 
57
 	client := ntw.MakeHTTPClient(nil)
57
 	client := ntw.MakeHTTPClient(nil)
58
 
58
 
59
-	resp, err := client.Get("https://httpbin.org/headers") // nolint: noctx
59
+	resp, err := client.Get("https://httpbin.org/headers") //nolint: noctx
60
 	suite.NoError(err)
60
 	suite.NoError(err)
61
 
61
 
62
 	defer resp.Body.Close()
62
 	defer resp.Body.Close()
67
 
67
 
68
 	jsonStruct := struct {
68
 	jsonStruct := struct {
69
 		Headers struct {
69
 		Headers struct {
70
-			UserAgent string `json:"User-Agent"` // nolint: tagliatelle
70
+			UserAgent string `json:"User-Agent"` //nolint: tagliatelle
71
 		} `json:"headers"`
71
 		} `json:"headers"`
72
 	}{}
72
 	}{}
73
 
73
 

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

16
 	)
16
 	)
17
 
17
 
18
 	if param := params.Get("open_threshold"); param != "" {
18
 	if param := params.Get("open_threshold"); param != "" {
19
-		if intNum, err := strconv.ParseUint(param, 10, 32); err == nil { // nolint: gomnd
19
+		if intNum, err := strconv.ParseUint(param, 10, 32); err == nil { //nolint: gomnd
20
 			openThreshold = uint32(intNum)
20
 			openThreshold = uint32(intNum)
21
 		}
21
 		}
22
 	}
22
 	}

+ 5
- 5
network/proxy_dialer_internal_test.go Прегледај датотеку

21
 }
21
 }
22
 
22
 
23
 func (suite *ProxyDialerTestSuite) TestSetupDefaults() {
23
 func (suite *ProxyDialerTestSuite) TestSetupDefaults() {
24
-	d := newProxyDialer(&DialerMock{}, suite.u).(*circuitBreakerDialer) // nolint: forcetypeassert
24
+	d := newProxyDialer(&DialerMock{}, suite.u).(*circuitBreakerDialer) //nolint: forcetypeassert
25
 	suite.EqualValues(ProxyDialerOpenThreshold, d.openThreshold)
25
 	suite.EqualValues(ProxyDialerOpenThreshold, d.openThreshold)
26
 	suite.EqualValues(ProxyDialerHalfOpenTimeout, d.halfOpenTimeout)
26
 	suite.EqualValues(ProxyDialerHalfOpenTimeout, d.halfOpenTimeout)
27
 	suite.EqualValues(ProxyDialerResetFailuresTimeout, d.resetFailuresTimeout)
27
 	suite.EqualValues(ProxyDialerResetFailuresTimeout, d.resetFailuresTimeout)
34
 	query.Set("half_open_timeout", "2s")
34
 	query.Set("half_open_timeout", "2s")
35
 	suite.u.RawQuery = query.Encode()
35
 	suite.u.RawQuery = query.Encode()
36
 
36
 
37
-	d := newProxyDialer(&DialerMock{}, suite.u).(*circuitBreakerDialer) // nolint: forcetypeassert
37
+	d := newProxyDialer(&DialerMock{}, suite.u).(*circuitBreakerDialer) //nolint: forcetypeassert
38
 	suite.EqualValues(30, d.openThreshold)
38
 	suite.EqualValues(30, d.openThreshold)
39
 	suite.EqualValues(2*time.Second, d.halfOpenTimeout)
39
 	suite.EqualValues(2*time.Second, d.halfOpenTimeout)
40
 	suite.EqualValues(time.Second, d.resetFailuresTimeout)
40
 	suite.EqualValues(time.Second, d.resetFailuresTimeout)
50
 			query.Set("open_threshold", param)
50
 			query.Set("open_threshold", param)
51
 			suite.u.RawQuery = query.Encode()
51
 			suite.u.RawQuery = query.Encode()
52
 
52
 
53
-			d := newProxyDialer(&DialerMock{}, suite.u).(*circuitBreakerDialer) // nolint: forcetypeassert
53
+			d := newProxyDialer(&DialerMock{}, suite.u).(*circuitBreakerDialer) //nolint: forcetypeassert
54
 			assert.EqualValues(t, ProxyDialerOpenThreshold, d.openThreshold)
54
 			assert.EqualValues(t, ProxyDialerOpenThreshold, d.openThreshold)
55
 		})
55
 		})
56
 	}
56
 	}
66
 			query.Set("half_open_timeout", param)
66
 			query.Set("half_open_timeout", param)
67
 			suite.u.RawQuery = query.Encode()
67
 			suite.u.RawQuery = query.Encode()
68
 
68
 
69
-			d := newProxyDialer(&DialerMock{}, suite.u).(*circuitBreakerDialer) // nolint: forcetypeassert
69
+			d := newProxyDialer(&DialerMock{}, suite.u).(*circuitBreakerDialer) //nolint: forcetypeassert
70
 			assert.EqualValues(t, ProxyDialerHalfOpenTimeout, d.halfOpenTimeout)
70
 			assert.EqualValues(t, ProxyDialerHalfOpenTimeout, d.halfOpenTimeout)
71
 		})
71
 		})
72
 	}
72
 	}
82
 			query.Set("reset_failures_timeout", param)
82
 			query.Set("reset_failures_timeout", param)
83
 			suite.u.RawQuery = query.Encode()
83
 			suite.u.RawQuery = query.Encode()
84
 
84
 
85
-			d := newProxyDialer(&DialerMock{}, suite.u).(*circuitBreakerDialer) // nolint: forcetypeassert
85
+			d := newProxyDialer(&DialerMock{}, suite.u).(*circuitBreakerDialer) //nolint: forcetypeassert
86
 			assert.EqualValues(t, ProxyDialerHalfOpenTimeout, d.halfOpenTimeout)
86
 			assert.EqualValues(t, ProxyDialerHalfOpenTimeout, d.halfOpenTimeout)
87
 		})
87
 		})
88
 	}
88
 	}

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

10
 //
10
 //
11
 // bufferSize setting is deprecated and ignored.
11
 // bufferSize setting is deprecated and ignored.
12
 func SetClientSocketOptions(conn net.Conn, bufferSize int) error {
12
 func SetClientSocketOptions(conn net.Conn, bufferSize int) error {
13
-	return setCommonSocketOptions(conn.(*net.TCPConn)) // nolint: forcetypeassert
13
+	return setCommonSocketOptions(conn.(*net.TCPConn)) //nolint: forcetypeassert
14
 }
14
 }
15
 
15
 
16
 // SetServerSocketOptions tunes a TCP socket that represents a connection to
16
 // SetServerSocketOptions tunes a TCP socket that represents a connection to
17
 // remote server like Telegram or fronting domain (but not end user).
17
 // remote server like Telegram or fronting domain (but not end user).
18
 func SetServerSocketOptions(conn net.Conn, bufferSize int) error {
18
 func SetServerSocketOptions(conn net.Conn, bufferSize int) error {
19
-	return setCommonSocketOptions(conn.(*net.TCPConn)) // nolint: forcetypeassert
19
+	return setCommonSocketOptions(conn.(*net.TCPConn)) //nolint: forcetypeassert
20
 }
20
 }
21
 
21
 
22
 func setCommonSocketOptions(conn *net.TCPConn) error {
22
 func setCommonSocketOptions(conn *net.TCPConn) error {

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

13
 func setSocketReuseAddrPort(conn syscall.RawConn) error {
13
 func setSocketReuseAddrPort(conn syscall.RawConn) error {
14
 	var err error
14
 	var err error
15
 
15
 
16
-	conn.Control(func(fd uintptr) { // nolint: errcheck
17
-		err = unix.SetsockoptInt(int(fd), unix.SOL_SOCKET, unix.SO_REUSEADDR, 1)
16
+	conn.Control(func(fd uintptr) { //nolint: errcheck
17
+		err = unix.SetsockoptInt(int(fd), unix.SOL_SOCKET, unix.SO_REUSEADDR, 1) //nolint: nosnakecase
18
 		if err != nil {
18
 		if err != nil {
19
 			err = fmt.Errorf("cannot set SO_REUSEADDR: %w", err)
19
 			err = fmt.Errorf("cannot set SO_REUSEADDR: %w", err)
20
 
20
 
21
 			return
21
 			return
22
 		}
22
 		}
23
 
23
 
24
-		err = unix.SetsockoptInt(int(fd), unix.SOL_SOCKET, unix.SO_REUSEPORT, 1)
24
+		err = unix.SetsockoptInt(int(fd), unix.SOL_SOCKET, unix.SO_REUSEPORT, 1) //nolint: nosnakecase
25
 		if err != nil {
25
 		if err != nil {
26
 			err = fmt.Errorf("cannot set SO_REUSEPORT: %w", err)
26
 			err = fmt.Errorf("cannot set SO_REUSEPORT: %w", err)
27
 		}
27
 		}

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

136
 	return nil
136
 	return nil
137
 }
137
 }
138
 
138
 
139
-// NewSocks5Dialer build a new dialer from a given one (so, in theory
140
-// you can chain here). Proxy parameters are passed with URI in a form of:
139
+// NewSocks5Dialer build a new dialer from a given one (so, in theory you can
140
+// chain here). Proxy parameters are passed with URI in a form of:
141
 //
141
 //
142
-//     socks5://[user:[password]]@host:port
142
+//	socks5://[user:[password]]@host:port
143
 func NewSocks5Dialer(baseDialer Dialer, proxyURL *url.URL) (Dialer, error) {
143
 func NewSocks5Dialer(baseDialer Dialer, proxyURL *url.URL) (Dialer, error) {
144
 	if _, _, err := net.SplitHostPort(proxyURL.Host); err != nil {
144
 	if _, _, err := net.SplitHostPort(proxyURL.Host); err != nil {
145
 		return nil, fmt.Errorf("incorrect url %s", proxyURL.Redacted())
145
 		return nil, fmt.Errorf("incorrect url %s", proxyURL.Redacted())

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

33
 	dialer, _ := network.NewSocks5Dialer(suite.d, proxyURL)
33
 	dialer, _ := network.NewSocks5Dialer(suite.d, proxyURL)
34
 	httpClient := suite.MakeHTTPClient(dialer)
34
 	httpClient := suite.MakeHTTPClient(dialer)
35
 
35
 
36
-	resp, err := httpClient.Get(suite.MakeURL("/get")) // nolint: noctx
36
+	resp, err := httpClient.Get(suite.MakeURL("/get")) //nolint: noctx
37
 	if err == nil {
37
 	if err == nil {
38
 		defer resp.Body.Close()
38
 		defer resp.Body.Close()
39
 	}
39
 	}
46
 	dialer, _ := network.NewSocks5Dialer(suite.d, proxyURL)
46
 	dialer, _ := network.NewSocks5Dialer(suite.d, proxyURL)
47
 	httpClient := suite.MakeHTTPClient(dialer)
47
 	httpClient := suite.MakeHTTPClient(dialer)
48
 
48
 
49
-	resp, err := httpClient.Get(suite.MakeURL("/get")) // nolint: noctx
49
+	resp, err := httpClient.Get(suite.MakeURL("/get")) //nolint: noctx
50
 	if err == nil {
50
 	if err == nil {
51
 		defer resp.Body.Close()
51
 		defer resp.Body.Close()
52
 	}
52
 	}

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

1
-// Stats package has implementations of events.Observers for different
1
+// Stats package has implementations of [events.Observer] for different
2
 // monitoring systems.
2
 // monitoring systems.
3
 //
3
 //
4
 // Observer is a consumer of events produced by mtg. Consumers, defined
4
 // Observer is a consumer of events produced by mtg. Consumers, defined

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

11
 }
11
 }
12
 
12
 
13
 func acquireStreamInfo() *streamInfo {
13
 func acquireStreamInfo() *streamInfo {
14
-	return streamInfoPool.Get().(*streamInfo) // nolint: forcetypeassert
14
+	return streamInfoPool.Get().(*streamInfo) //nolint: forcetypeassert
15
 }
15
 }
16
 
16
 
17
 func releaseStreamInfo(info *streamInfo) {
17
 func releaseStreamInfo(info *streamInfo) {

+ 6
- 7
stats/prometheus.go Прегледај датотеку

139
 	}
139
 	}
140
 }
140
 }
141
 
141
 
142
-// PrometheusFactory is a factory of events.Observers which collect
142
+// PrometheusFactory is a factory of [events.Observer] which collect
143
 // information in a format suitable for Prometheus.
143
 // information in a format suitable for Prometheus.
144
 //
144
 //
145
-// This factory can also serve on a given listener. In that case it
146
-// starts HTTP server with a single endpoint - a Prometheus-compatible
147
-// scrape output.
145
+// This factory can also serve on a given listener. In that case it starts HTTP
146
+// server with a single endpoint - a Prometheus-compatible scrape output.
148
 type PrometheusFactory struct {
147
 type PrometheusFactory struct {
149
 	httpServer *http.Server
148
 	httpServer *http.Server
150
 
149
 
172
 
171
 
173
 // Serve starts an HTTP server on a given listener.
172
 // Serve starts an HTTP server on a given listener.
174
 func (p *PrometheusFactory) Serve(listener net.Listener) error {
173
 func (p *PrometheusFactory) Serve(listener net.Listener) error {
175
-	return p.httpServer.Serve(listener) // nolint: wrapcheck
174
+	return p.httpServer.Serve(listener) //nolint: wrapcheck
176
 }
175
 }
177
 
176
 
178
 // Close stops a factory. Please pay attention that underlying listener
177
 // Close stops a factory. Please pay attention that underlying listener
179
 // is not closed.
178
 // is not closed.
180
 func (p *PrometheusFactory) Close() error {
179
 func (p *PrometheusFactory) Close() error {
181
-	return p.httpServer.Shutdown(context.Background()) // nolint: wrapcheck
180
+	return p.httpServer.Shutdown(context.Background()) //nolint: wrapcheck
182
 }
181
 }
183
 
182
 
184
 // NewPrometheus builds an events.ObserverFactory which can serve HTTP
183
 // NewPrometheus builds an events.ObserverFactory which can serve HTTP
185
 // endpoint with Prometheus scrape data.
184
 // endpoint with Prometheus scrape data.
186
-func NewPrometheus(metricPrefix, httpPath string) *PrometheusFactory { // nolint: funlen
185
+func NewPrometheus(metricPrefix, httpPath string) *PrometheusFactory { //nolint: funlen
187
 	registry := prometheus.NewPedanticRegistry()
186
 	registry := prometheus.NewPedanticRegistry()
188
 	httpHandler := promhttp.HandlerFor(registry, promhttp.HandlerOpts{
187
 	httpHandler := promhttp.HandlerFor(registry, promhttp.HandlerOpts{
189
 		EnableOpenMetrics: true,
188
 		EnableOpenMetrics: true,

+ 4
- 4
stats/prometheus_test.go Прегледај датотеку

25
 func (suite *PrometheusTestSuite) Get() (string, error) {
25
 func (suite *PrometheusTestSuite) Get() (string, error) {
26
 	addr := fmt.Sprintf("http://%s/", suite.httpListener.Addr().String())
26
 	addr := fmt.Sprintf("http://%s/", suite.httpListener.Addr().String())
27
 
27
 
28
-	resp, err := http.Get(addr) // nolint: noctx
28
+	resp, err := http.Get(addr) //nolint: noctx
29
 	if err != nil {
29
 	if err != nil {
30
-		return "", err // nolint: wrapcheck
30
+		return "", err //nolint: wrapcheck
31
 	}
31
 	}
32
 
32
 
33
 	defer resp.Body.Close()
33
 	defer resp.Body.Close()
34
 
34
 
35
 	data, err := io.ReadAll(resp.Body)
35
 	data, err := io.ReadAll(resp.Body)
36
 	if err != nil {
36
 	if err != nil {
37
-		return "", err // nolint: wrapcheck
37
+		return "", err //nolint: wrapcheck
38
 	}
38
 	}
39
 
39
 
40
 	return string(data), nil
40
 	return string(data), nil
45
 	suite.factory = stats.NewPrometheus("mtg", "/")
45
 	suite.factory = stats.NewPrometheus("mtg", "/")
46
 	suite.prometheus = suite.factory.Make()
46
 	suite.prometheus = suite.factory.Make()
47
 
47
 
48
-	go suite.factory.Serve(suite.httpListener) // nolint: errcheck
48
+	go suite.factory.Serve(suite.httpListener) //nolint: errcheck
49
 }
49
 }
50
 
50
 
51
 func (suite *PrometheusTestSuite) TearDownTest() {
51
 func (suite *PrometheusTestSuite) TearDownTest() {

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

147
 	}
147
 	}
148
 }
148
 }
149
 
149
 
150
-// StatsdFactory is a factory of events.Observers which dumps
151
-// information to statsd.
150
+// StatsdFactory is a factory of [events.Observer] which dumps information to
151
+// statsd.
152
 //
152
 //
153
-// Please beware that we support ONLY UDP endpoints there. And this
154
-// factory won't use mtglib.Network so it won't use a proxy if you
155
-// provide any. If you need it, I would recommend starting a local
156
-// statsd and route metrics further by features of the chosen server.
153
+// Please beware that we support ONLY UDP endpoints there. And this factory
154
+// won't use [mtglib.Network] so it won't use a proxy if you provide any. If
155
+// you need it, I would recommend starting a local statsd and route metrics
156
+// further by features of the chosen server.
157
 type StatsdFactory struct {
157
 type StatsdFactory struct {
158
 	client *statsd.Client
158
 	client *statsd.Client
159
 }
159
 }
160
 
160
 
161
 // Close stops sending requests to statsd.
161
 // Close stops sending requests to statsd.
162
 func (s StatsdFactory) Close() error {
162
 func (s StatsdFactory) Close() error {
163
-	return s.client.Close() // nolint: wrapcheck
163
+	return s.client.Close() //nolint: wrapcheck
164
 }
164
 }
165
 
165
 
166
 // Make build a new observer.
166
 // Make build a new observer.
171
 	}
171
 	}
172
 }
172
 }
173
 
173
 
174
-// NewStatsd builds an events.ObserverFactory that sends events
175
-// to statsd.
174
+// NewStatsd builds an [events.ObserverFactory] that sends events to statsd.
176
 //
175
 //
177
 // Valid tagFormats are 'datadog', 'influxdb' and 'graphite'.
176
 // Valid tagFormats are 'datadog', 'influxdb' and 'graphite'.
178
 func NewStatsd(address string, log logger.StdLikeLogger,
177
 func NewStatsd(address string, log logger.StdLikeLogger,

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

30
 
30
 
31
 func (s *statsdFakeServer) Close() error {
31
 func (s *statsdFakeServer) Close() error {
32
 	if s.conn != nil {
32
 	if s.conn != nil {
33
-		return s.conn.Close() // nolint: wrapcheck
33
+		return s.conn.Close() //nolint: wrapcheck
34
 	}
34
 	}
35
 
35
 
36
 	return nil
36
 	return nil

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