diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index ba56441af..a09fc52f0 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -42,7 +42,7 @@ jobs: strategy: matrix: go_version: - - ^1.18 + - ^1.19 steps: - name: Checkout uses: actions/checkout@v2 @@ -114,12 +114,12 @@ jobs: - name: Setup Go uses: actions/setup-go@v2 with: - go-version: ^1.18 + go-version: ^1.19 - name: Run linter uses: golangci/golangci-lint-action@v3 with: - version: v1.45.0 + version: v1.48.0 docker: name: Docker diff --git a/.golangci.toml b/.golangci.toml index a595c75e2..e10d80f55 100644 --- a/.golangci.toml +++ b/.golangci.toml @@ -9,4 +9,14 @@ format = "colored-line-number" [linters] enable-all = true -disable = ["thelper", "ireturn", "varnamelen", "gochecknoglobals", "gas", "goerr113", "exhaustivestruct", "containedctx"] +disable = [ + "containedctx", + "exhaustivestruct", + "exhaustruct", + "gas", + "gochecknoglobals", + "goerr113", + "ireturn", + "thelper", + "varnamelen", +] diff --git a/Dockerfile b/Dockerfile index b700b9d79..86c5b4994 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,7 +1,7 @@ ############################################################################### # BUILD STAGE -FROM golang:1.18-alpine AS build +FROM golang:1.19-alpine AS build RUN set -x \ && apk --no-cache --update add \ diff --git a/Makefile b/Makefile index 9a4c7a00d..76a89d03e 100644 --- a/Makefile +++ b/Makefile @@ -2,7 +2,7 @@ ROOT_DIR := $(shell dirname $(realpath $(lastword $(MAKEFILE_LIST)))) IMAGE_NAME := mtg APP_NAME := $(IMAGE_NAME) -GOLANGCI_LINT_VERSION := v1.45.0 +GOLANGCI_LINT_VERSION := v1.48.0 VERSION := $(shell git describe --exact-match HEAD 2>/dev/null || git describe --tags --always) COMMON_BUILD_FLAGS := -trimpath -mod=readonly -ldflags="-extldflags '-static' -s -w -X 'main.version=$(VERSION)'" diff --git a/README.md b/README.md index 15c738fbf..0d5e55d48 100644 --- a/README.md +++ b/README.md @@ -190,7 +190,7 @@ surprises. Always choose some version tag. Also, if you have `go` installed, you can always download this tool with `go get`: ```console -go get github.com/9seconds/mtg/v2 +go install github.com/9seconds/mtg/v2@latest ``` #### Build from sources @@ -338,7 +338,7 @@ $ sudo systemctl start mtg or you can run a docker image ```console -docker run -d -v /etc/mtg.toml:/config.toml -p 443:3128 --name mtg-proxy --restart=unless-stopped nineseconds/mtg:2 +docker run -d -v $PWD/config.toml:config.toml -p 443:3128 --name mtg-proxy --restart=unless-stopped nineseconds/mtg:2 ``` where _443_ is a host port (a port you want to connect to from a diff --git a/antireplay/init.go b/antireplay/init.go index eb4eeb187..1005916f5 100644 --- a/antireplay/init.go +++ b/antireplay/init.go @@ -1,17 +1,17 @@ -// Antireplay package has cache implementations that are effective -// against replay attacks. +// Antireplay package has cache implementations that are effective against +// replay attacks. // -// To understand more about replay attacks, please read documentation -// for mtglib.AntiReplayCache interface. This package has a list of some +// To understand more about replay attacks, please read documentation for +// [mtglib.AntiReplayCache] interface. This package has a list of some // implementations of this interface. package antireplay const ( - // DefaultStableBloomFilterMaxSize is a recommended byte size for a - // stable bloom filter. + // DefaultStableBloomFilterMaxSize is a recommended byte size for a stable + // bloom filter. DefaultStableBloomFilterMaxSize = 1024 * 1024 // 1MiB - // DefaultStableBloomFilterErrorRate is a recommended default error - // rate for a stable bloom filter. + // DefaultStableBloomFilterErrorRate is a recommended default error rate for a + // stable bloom filter. DefaultStableBloomFilterErrorRate = 0.001 ) diff --git a/antireplay/noop.go b/antireplay/noop.go index e4e7cf442..6ca2450cd 100644 --- a/antireplay/noop.go +++ b/antireplay/noop.go @@ -6,9 +6,8 @@ type noop struct{} func (n noop) SeenBefore(_ []byte) bool { return false } -// NewNoop returns an implementation that does nothing. A corresponding -// method always returns false, so this cache accepts everything you -// pass to it. +// NewNoop returns an implementation that does nothing. A corresponding method +// always returns false, so this cache accepts everything you pass to it. func NewNoop() mtglib.AntiReplayCache { return noop{} } diff --git a/antireplay/stable_bloom_filter.go b/antireplay/stable_bloom_filter.go index 61f993421..01c64c8dd 100644 --- a/antireplay/stable_bloom_filter.go +++ b/antireplay/stable_bloom_filter.go @@ -20,19 +20,19 @@ func (s *stableBloomFilter) SeenBefore(digest []byte) bool { return s.filter.TestAndAdd(digest) } -// NewStableBloomFilter returns an implementation of AntiReplayCache -// based on stable bloom filter. +// NewStableBloomFilter returns an implementation of AntiReplayCache based on +// stable bloom filter. // // http://webdocs.cs.ualberta.ca/~drafiei/papers/DupDet06Sigmod.pdf // -// The basic idea of a stable bloom filter is quite simple: each time -// when you set a new element, you randomly reset P elements. There is a -// hardcore math which proves that if you choose this P correctly, you -// can maintain the same error rate for a stream of elements. +// The basic idea of a stable bloom filter is quite simple: each time when you +// set a new element, you randomly reset P elements. There is a hardcore math +// which proves that if you choose this P correctly, you can maintain the same +// error rate for a stream of elements. // // byteSize is the number of bytes you want to give to a bloom filter. -// errorRate is desired false-positive error rate. If you want to use -// default values, please pass 0 for byteSize and <0 for errorRate. +// errorRate is desired false-positive error rate. If you want to use default +// values, please pass 0 for byteSize and <0 for errorRate. func NewStableBloomFilter(byteSize uint, errorRate float64) mtglib.AntiReplayCache { if byteSize == 0 { byteSize = DefaultStableBloomFilterMaxSize @@ -42,7 +42,7 @@ func NewStableBloomFilter(byteSize uint, errorRate float64) mtglib.AntiReplayCac errorRate = DefaultStableBloomFilterErrorRate } - sf := boom.NewDefaultStableBloomFilter(byteSize*8, errorRate) // nolint: gomnd + sf := boom.NewDefaultStableBloomFilter(byteSize*8, errorRate) //nolint: gomnd sf.SetHash(xxhash.New64()) return &stableBloomFilter{ diff --git a/buildinfo.go b/buildinfo.go new file mode 100644 index 000000000..74e6782dd --- /dev/null +++ b/buildinfo.go @@ -0,0 +1,84 @@ +package main + +import ( + "crypto/sha256" + "encoding/base64" + "encoding/binary" + "fmt" + "io" + "runtime/debug" + "sort" + "strconv" + "time" +) + +var version = "dev" // has to be set by ldflags + +const ( + buildInfoModuleStart byte = iota + buildInfoModuleFinish + buildInfoModuleDelimeter +) + +func getVersion() string { + buildInfo, ok := debug.ReadBuildInfo() + if !ok { + return version + } + + date := time.Now() + commit := "" + goVersion := buildInfo.GoVersion + dirtySuffix := "" + + for _, setting := range buildInfo.Settings { + switch setting.Key { + case "vcs.time": + date, _ = time.Parse(time.RFC3339, setting.Value) + case "vcs.revision": + commit = setting.Value + case "vcs.modified": + if dirty, _ := strconv.ParseBool(setting.Value); dirty { + dirtySuffix = " [dirty]" + } + } + } + + hasher := sha256.New() + + checksumModule := func(mod *debug.Module) { + hasher.Write([]byte{buildInfoModuleStart}) + + io.WriteString(hasher, mod.Path) //nolint: errcheck + hasher.Write([]byte{buildInfoModuleDelimeter}) + + io.WriteString(hasher, mod.Version) //nolint: errcheck + hasher.Write([]byte{buildInfoModuleDelimeter}) + + io.WriteString(hasher, mod.Sum) //nolint: errcheck + + hasher.Write([]byte{buildInfoModuleFinish}) + } + + io.WriteString(hasher, buildInfo.Path) //nolint: errcheck + + binary.Write(hasher, binary.LittleEndian, uint64(1+len(buildInfo.Deps))) //nolint: errcheck + + sort.Slice(buildInfo.Deps, func(i, j int) bool { + return buildInfo.Deps[i].Path > buildInfo.Deps[j].Path + }) + + checksumModule(&buildInfo.Main) + + for _, module := range buildInfo.Deps { + checksumModule(module) + } + + return fmt.Sprintf("%s (%s: %s on %s%s, modules checksum %s)", + version, + goVersion, + date.Format(time.RFC3339), + commit, + dirtySuffix, + base64.StdEncoding.EncodeToString(hasher.Sum(nil))) +} diff --git a/essentials/conns.go b/essentials/conns.go index 1b3cbf052..5b42efe3d 100644 --- a/essentials/conns.go +++ b/essentials/conns.go @@ -5,19 +5,19 @@ import ( "net" ) -// CloseableReader is a reader interface that can close its reading end. +// CloseableReader is an [io.Reader] interface that can close its reading end. type CloseableReader interface { io.Reader CloseRead() error } -// CloseableWriter is a writer that can close its writing end. +// CloseableWriter is an [io.Writer] that can close its writing end. type CloseableWriter interface { io.Writer CloseWrite() error } -// Conn is an extension of net.Conn that can close its ends. This mostly +// Conn is an extension of [net.Conn] that can close its ends. This mostly // implies TCP connections. type Conn interface { net.Conn diff --git a/events/event_stream.go b/events/event_stream.go index c847bf29c..7552d2e01 100644 --- a/events/event_stream.go +++ b/events/event_stream.go @@ -9,7 +9,7 @@ import ( "github.com/OneOfOne/xxhash" ) -// EventStream is a default implementation of the mtglib.EventStream +// EventStream is a default implementation of the [mtglib.EventStream] // interface. // // EventStream manages a set of goroutines, observers. Main @@ -77,7 +77,7 @@ func NewEventStream(observerFactories []ObserverFactory) EventStream { return rv } -func eventStreamProcessor(ctx context.Context, eventChan <-chan mtglib.Event, observer Observer) { // nolint: cyclop +func eventStreamProcessor(ctx context.Context, eventChan <-chan mtglib.Event, observer Observer) { //nolint: cyclop defer observer.Shutdown() for { diff --git a/events/init.go b/events/init.go index 94804dcc4..6d541161c 100644 --- a/events/init.go +++ b/events/init.go @@ -1,19 +1,19 @@ // Events has a default implementations of EventStream for mtglib. // -// Please see documentation for mtglib.EventStream interface to get an -// idea of such an abstraction. This package has implementations for the -// default event stream. +// Please see documentation for [mtglib.EventStream] interface to get an idea +// of such an abstraction. This package has implementations for the default +// event stream. // -// Default event stream has a list of its own concepts. First, all it -// does is a routing of messages to known observers. It takes an event, -// defines its type and pass this message to a method of the observer. +// Default event stream has a list of its own concepts. First, all it does is a +// routing of messages to known observers. It takes an event, defines its type +// and pass this message to a method of the observer. // -// There might be many observers, but default event stream has a -// guarantee though. It uses StreamID as a sharding key and guarantees -// that a message with the same StreamID will be devlivered to the same -// observer instance. So, each producer is guarateed to get all relevant -// messages related to the same session. It is not possible that it will -// get EventFinish if it has not seen EventStart for that session yet. +// There might be many observers, but default event stream has a guarantee +// though. It uses StreamID as a sharding key and guarantees that a message +// with the same StreamID will be devlivered to the same observer instance. So, +// each producer is guarateed to get all relevant messages related to the same +// session. It is not possible that it will get EventFinish if it has not seen +// EventStart for that session yet. package events import "github.com/9seconds/mtg/v2/mtglib" @@ -21,10 +21,10 @@ import "github.com/9seconds/mtg/v2/mtglib" // Observer is an instance that listens for the incoming events. // // As it is said in the package description, the default event stream -// guarantees that all events with the same StreamID are going to be -// routed to the same instance of the observer. So, there is no need -// to synchronize information about streams between many observers -// instances, they can have their local storage. +// guarantees that all events with the same StreamID are going to be routed to +// the same instance of the observer. So, there is no need to synchronize +// information about streams between many observers instances, they can have +// their local storage. type Observer interface { // EventStart reacts on incoming mtglib.EventStart event. EventStart(mtglib.EventStart) @@ -65,8 +65,8 @@ type Observer interface { // ObserverFactory creates a new instance of the observer. // -// Default event stream creates a small set of goroutines to manage -// incoming messages. Each message is routed to an appropriate observer -// based on a sharding key, stream id. So, it is possible that an -// instance of mtg will have many observer instances, not a single one. +// Default event stream creates a small set of goroutines to manage incoming +// messages. Each message is routed to an appropriate observer based on a +// sharding key, stream id. So, it is possible that an instance of mtg will +// have many observer instances, not a single one. type ObserverFactory func() Observer diff --git a/go.mod b/go.mod index 5d27ae8bb..afd1bfbe4 100644 --- a/go.mod +++ b/go.mod @@ -4,7 +4,7 @@ go 1.18 require ( github.com/OneOfOne/xxhash v1.2.8 - github.com/alecthomas/kong v0.5.0 + github.com/alecthomas/kong v0.6.1 github.com/alecthomas/units v0.0.0-20211218093645-b94a6e3cc137 github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5 github.com/babolivier/go-doh-client v0.0.0-20201028162107-a76cff4cb8b6 @@ -13,24 +13,24 @@ require ( github.com/gotd/td v0.34.0 github.com/jarcoal/httpmock v1.0.8 github.com/mccutchen/go-httpbin v1.1.1 - github.com/panjf2000/ants/v2 v2.4.8 - github.com/pelletier/go-toml v1.9.4 - github.com/prometheus/client_golang v1.12.1 - github.com/prometheus/common v0.32.1 // indirect - github.com/prometheus/procfs v0.7.3 // indirect - github.com/rs/zerolog v1.26.1 + github.com/panjf2000/ants/v2 v2.5.0 + github.com/pelletier/go-toml v1.9.5 + github.com/prometheus/client_golang v1.13.0 + github.com/prometheus/common v0.37.0 // indirect + github.com/prometheus/procfs v0.8.0 // indirect + github.com/rs/zerolog v1.27.0 github.com/smira/go-statsd v1.3.2 github.com/stretchr/objx v0.3.0 // indirect - github.com/stretchr/testify v1.7.0 + github.com/stretchr/testify v1.7.2 github.com/tylertreat/BoomFilters v0.0.0-20210315201527-1a82519a3e43 - golang.org/x/crypto v0.0.0-20220315160706-3147a52a75dd - golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2 // indirect - golang.org/x/sys v0.0.0-20220319134239-a9b59b0215f8 - google.golang.org/protobuf v1.27.1 // indirect + golang.org/x/crypto v0.0.0-20220722155217-630584e8d5aa + golang.org/x/net v0.0.0-20220225172249-27dd8689420f // indirect + golang.org/x/sys v0.0.0-20220804214406-8e32c043e418 + google.golang.org/protobuf v1.28.1 // indirect ) require ( - github.com/txthinking/socks5 v0.0.0-20220212043548-414499347d4a + github.com/txthinking/socks5 v0.0.0-20220615051428-39268faee3e6 github.com/yl2chen/cidranger v1.0.2 ) @@ -41,9 +41,10 @@ require ( github.com/davecgh/go-spew v1.1.1 // indirect github.com/gotd/ige v0.1.5 // indirect github.com/gotd/xor v0.1.1 // indirect + github.com/mattn/go-colorable v0.1.12 // indirect + github.com/mattn/go-isatty v0.0.14 // indirect github.com/matttproud/golang_protobuf_extensions v1.0.1 // indirect github.com/patrickmn/go-cache v2.1.0+incompatible // indirect - github.com/pkg/errors v0.9.1 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect github.com/prometheus/client_model v0.2.0 // indirect github.com/txthinking/runnergroup v0.0.0-20220212043759-8da8edb7dae8 // indirect @@ -51,7 +52,7 @@ require ( go.uber.org/atomic v1.7.0 // indirect go.uber.org/multierr v1.6.0 // indirect go.uber.org/zap v1.16.0 // indirect - golang.org/x/sync v0.0.0-20210220032951-036812b2e83c // indirect + golang.org/x/sync v0.0.0-20220601150217-0de741cfad7f // indirect golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 // indirect - gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b // indirect + gopkg.in/yaml.v3 v3.0.1 // indirect ) diff --git a/go.sum b/go.sum index 756401553..1642ac3e3 100644 --- a/go.sum +++ b/go.sum @@ -37,8 +37,8 @@ github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym github.com/OneOfOne/xxhash v1.2.8 h1:31czK/TI9sNkxIKfaUfGlU47BAxQ0ztGgd9vPyqimf8= github.com/OneOfOne/xxhash v1.2.8/go.mod h1:eZbhyaAYD41SGSSsnmcpxVoRiQ/MPUTjUdIIOT9Um7Q= github.com/PuerkitoBio/goquery v1.6.1/go.mod h1:GsLWisAFVj4WgDibEWF4pvYnkVQBpKBKeU+7zCJoLcc= -github.com/alecthomas/kong v0.5.0 h1:u8Kdw+eeml93qtMZ04iei0CFYve/WPcA5IFh+9wSskE= -github.com/alecthomas/kong v0.5.0/go.mod h1:uzxf/HUh0tj43x1AyJROl3JT7SgsZ5m+icOv1csRhc0= +github.com/alecthomas/kong v0.6.1 h1:1kNhcFepkR+HmasQpbiKDLylIL8yh5B5y1zPp5bJimA= +github.com/alecthomas/kong v0.6.1/go.mod h1:JfHWDzLmbh/puW6I3V7uWenoh56YNVONW+w8eKeUr9I= github.com/alecthomas/repr v0.0.0-20210801044451-80ca428c5142 h1:8Uy0oSf5co/NZXje7U1z8Mpep++QJOldL2hs/sBQf48= github.com/alecthomas/repr v0.0.0-20210801044451-80ca428c5142/go.mod h1:2kn6fqh/zIyPLmm3ugklbEi5hg5wS435eygvNfaDQL8= github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= @@ -69,7 +69,7 @@ github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5P github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU= github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc= -github.com/coreos/go-systemd/v22 v22.3.2/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc= +github.com/coreos/go-systemd/v22 v22.3.3-0.20220203105225-a9a7ef127534/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc= github.com/d4l3k/messagediff v1.2.1 h1:ZcAIMYsUg0EAp9X+tt8/enBE/Q8Yd5kzPynLyKptt9U= github.com/d4l3k/messagediff v1.2.1/go.mod h1:Oozbb1TVXFac9FtSIxHBMnBCq2qeH/2KkEQxENCrlLo= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= @@ -85,9 +85,11 @@ github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2 github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= github.com/go-kit/kit v0.9.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= github.com/go-kit/log v0.1.0/go.mod h1:zbhenjAZHb184qTLMA9ZjW7ThYL0H2mk7Q6pNt4vbaY= +github.com/go-kit/log v0.2.0/go.mod h1:NwTd00d/i8cPZ3xOwwiv2PO5MOcx78fFErGNcVmBjv0= github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE= github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk= github.com/go-logfmt/logfmt v0.5.0/go.mod h1:wCYkCAKZfumFQihp8CzCvQ3paCTfi41vtzG1KdI/P7A= +github.com/go-logfmt/logfmt v0.5.1/go.mod h1:WYhtIu8zTZfxdn5+rREduYbwxfcBr/Vr6KEVveWlfTs= github.com/go-openapi/inflect v0.19.0/go.mod h1:lHpZVlpIQqLyKwJ4N+YSc9hchQy/i12fJykb83CRBH4= github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= @@ -130,8 +132,8 @@ github.com/google/go-cmp v0.4.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/ github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.5 h1:Khx7svrCpmxxtHBq5j2mp/xVjsi8hQMfNLvJFAlrGgU= github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.8 h1:e6P7q2lk1O+qJJb4BtCQXlK8vWEO8V1ZeuEdJNOqZyg= github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs= github.com/google/martian/v3 v3.0.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0= @@ -182,8 +184,12 @@ github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= github.com/mattn/go-colorable v0.1.2/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE= +github.com/mattn/go-colorable v0.1.12 h1:jF+Du6AlPIjs2BiUiQlKOX0rt3SujHxPnksPKZbaA40= +github.com/mattn/go-colorable v0.1.12/go.mod h1:u5H1YNBxpqRaxsYJYSkiCWKzEfiAb1Gb520KVy5xxl4= github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= github.com/mattn/go-isatty v0.0.9/go.mod h1:YNRxwqDuOph6SZLI9vUUz6OYw3QyUt7WiY2yME+cCiQ= +github.com/mattn/go-isatty v0.0.14 h1:yVuAays6BHfxijgZPzw+3Zlu5yQgKGP2/hcQbHb7S9Y= +github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94= github.com/matttproud/golang_protobuf_extensions v1.0.1 h1:4hp9jkHxhMHkqkrB3Ix0jegS5sx/RkqARlsWZ6pIwiU= github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= github.com/mccutchen/go-httpbin v1.1.1 h1:aEws49HEJEyXHLDnshQVswfUlCVoS8g6h9YaDyaW7RE= @@ -195,12 +201,12 @@ github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3Rllmb github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk= github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= -github.com/panjf2000/ants/v2 v2.4.8 h1:JgTbolX6K6RreZ4+bfctI0Ifs+3mrE5BIHudQxUDQ9k= -github.com/panjf2000/ants/v2 v2.4.8/go.mod h1:f6F0NZVFsGCp5A7QW/Zj/m92atWwOkY0OIhFxRNFr4A= +github.com/panjf2000/ants/v2 v2.5.0 h1:1rWGWSnxCsQBga+nQbA4/iY6VMeNoOIAM0ZWh9u3q2Q= +github.com/panjf2000/ants/v2 v2.5.0/go.mod h1:cU93usDlihJZ5CfRGNDYsiBYvoilLvBF5Qp/BT2GNRE= github.com/patrickmn/go-cache v2.1.0+incompatible h1:HRMgzkcYKYpi3C8ajMPV8OFXaaRUnok+kx1WdO15EQc= github.com/patrickmn/go-cache v2.1.0+incompatible/go.mod h1:3Qf8kWWT7OJRJbdiICTKqZju1ZixQ/KpMGzzAfe6+WQ= -github.com/pelletier/go-toml v1.9.4 h1:tjENF6MfZAg8e4ZmZTeWaWiT2vXtsoO6+iuOjFhECwM= -github.com/pelletier/go-toml v1.9.4/go.mod h1:u1nR/EPcESfeI/szUZKdtJ0xRNbUoANCkoOuaOx1Y+c= +github.com/pelletier/go-toml v1.9.5 h1:4yBQzkHv+7BHq2PQUZF3Mx0IYxG7LsP222s7Agd3ve8= +github.com/pelletier/go-toml v1.9.5/go.mod h1:u1nR/EPcESfeI/szUZKdtJ0xRNbUoANCkoOuaOx1Y+c= github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e/go.mod h1:pJLUxLENpZxwdsKMEsNbx1VGcRFpLqf3715MtcvvzbA= github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= @@ -212,8 +218,9 @@ github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXP github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5FsnadC4Ky3P0J6CfImo= github.com/prometheus/client_golang v1.7.1/go.mod h1:PY5Wy2awLA44sXw4AOSfFBetzPP4j5+D6mVACh+pe2M= github.com/prometheus/client_golang v1.11.0/go.mod h1:Z6t4BnS23TR94PD6BsDNk8yVqroYurpAkEiz0P2BEV0= -github.com/prometheus/client_golang v1.12.1 h1:ZiaPsmm9uiBeaSMRznKsCDNtPCS0T3JVDGF+06gjBzk= github.com/prometheus/client_golang v1.12.1/go.mod h1:3Z9XVyYiZYEO+YQWt3RD2R3jrbd179Rt297l4aS6nDY= +github.com/prometheus/client_golang v1.13.0 h1:b71QUfeo5M8gq2+evJdTPfZhYMAU0uKPkyPJ7TPsloU= +github.com/prometheus/client_golang v1.13.0/go.mod h1:vTeo+zgvILHsnnj/39Ou/1fPN5nJFOEMgftOUOmlvYQ= github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= @@ -222,20 +229,22 @@ github.com/prometheus/client_model v0.2.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6T github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= github.com/prometheus/common v0.10.0/go.mod h1:Tlit/dnDKsSWFlCLTWaA1cyBgKHSMdTB80sz/V91rCo= github.com/prometheus/common v0.26.0/go.mod h1:M7rCNAaPfAosfx8veZJCuw84e35h3Cfd9VFqTh1DIvc= -github.com/prometheus/common v0.32.1 h1:hWIdL3N2HoUx3B8j3YN9mWor0qhY/NlEKZEaXxuIRh4= github.com/prometheus/common v0.32.1/go.mod h1:vu+V0TpY+O6vW9J44gczi3Ap/oXXR10b+M/gUGO4Hls= +github.com/prometheus/common v0.37.0 h1:ccBbHCgIiT9uSoFY0vX8H3zsNR5eLt17/RQLUvn8pXE= +github.com/prometheus/common v0.37.0/go.mod h1:phzohg0JFMnBEFGxTDbfu3QyL5GI8gTQJFhYO5B3mfA= github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= github.com/prometheus/procfs v0.1.3/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU= github.com/prometheus/procfs v0.6.0/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA= -github.com/prometheus/procfs v0.7.3 h1:4jVXhlkAyzOScmCkXBTOLRLTz8EeU+eyjrwB/EPq0VU= github.com/prometheus/procfs v0.7.3/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA= +github.com/prometheus/procfs v0.8.0 h1:ODq8ZFEaYeCaZOJlZZdJA2AbQR98dSHSM1KW/You5mo= +github.com/prometheus/procfs v0.8.0/go.mod h1:z7EfXMXOkbkqb9IINtpCn86r/to3BnA0uaxHdg830/4= github.com/quasilyte/go-ruleguard/dsl v0.3.2/go.mod h1:KeCP03KrjuSO0H1kTuZQCWlQPulDV6YMIXmpQss17rU= github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= github.com/rogpeppe/go-internal v1.8.0/go.mod h1:WmiCO8CzOY8rg0OYDC4/i/2WRWAB6poM+XZ2dLUbcbE= github.com/rs/xid v1.3.0/go.mod h1:trrq9SKmegXys3aeAKXMUTdJsYXVwGY3RLcfgqegfbg= -github.com/rs/zerolog v1.26.1 h1:/ihwxqH+4z8UxyI70wM1z9yCvkWcfz/a3mj48k/Zngc= -github.com/rs/zerolog v1.26.1/go.mod h1:/wSSJWX7lVrsOwlbyTRSOJvqRlc+WjWlfes+CiJ+tmc= +github.com/rs/zerolog v1.27.0 h1:1T7qCieN22GVc8S4Q2yuexzBb1EqjbgjSH9RohbMjKs= +github.com/rs/zerolog v1.27.0/go.mod h1:7frBqO0oezxmnO7GF86FY++uy8I0Tk/If5ni1G9Qc0U= github.com/sebdah/goldie/v2 v2.5.3/go.mod h1:oZ9fp0+se1eapSRjfYbsV/0Hqhbuu3bJVvKI/NNtssI= github.com/sergi/go-diff v1.0.0/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAmXWZgo= github.com/sergi/go-diff v1.1.0/go.mod h1:STckp+ISIX8hZLjrqAeVduY0gWCT9IjLuqbuNXdaHfM= @@ -252,13 +261,14 @@ github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXf github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= -github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY= github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.7.2 h1:4jaiDzPyXQvSd7D0EjG45355tLlV3VOECpq10pLC+8s= +github.com/stretchr/testify v1.7.2/go.mod h1:R6va5+xMeoiuVRoj+gSkQ7d3FALtqAAGI1FQKckRals= github.com/txthinking/runnergroup v0.0.0-20210608031112-152c7c4432bf/go.mod h1:CLUSJbazqETbaR+i0YAhXBICV9TrKH93pziccMhmhpM= github.com/txthinking/runnergroup v0.0.0-20220212043759-8da8edb7dae8 h1:iYc+JnXtzv6sdMx9Q7OTKkDAn7FhDPDogcjeSfEQcLY= github.com/txthinking/runnergroup v0.0.0-20220212043759-8da8edb7dae8/go.mod h1:CLUSJbazqETbaR+i0YAhXBICV9TrKH93pziccMhmhpM= -github.com/txthinking/socks5 v0.0.0-20220212043548-414499347d4a h1:BOqgJ4jku0LHPDoR51RD8Mxmo0LHxCzJT/M9MemYdHo= -github.com/txthinking/socks5 v0.0.0-20220212043548-414499347d4a/go.mod h1:7NloQcrxaZYKURWph5HLxVDlIwMHJXCPkeWPtpftsIg= +github.com/txthinking/socks5 v0.0.0-20220615051428-39268faee3e6 h1:8DkPbOq/EPxbD5VJajKuvssiYZJSrlpeetcGfrBoBVE= +github.com/txthinking/socks5 v0.0.0-20220615051428-39268faee3e6/go.mod h1:7NloQcrxaZYKURWph5HLxVDlIwMHJXCPkeWPtpftsIg= github.com/txthinking/x v0.0.0-20210326105829-476fab902fbe h1:gMWxZxBFRAXqoGkwkYlPX2zvyyKNWJpxOxCrjqJkm5A= github.com/txthinking/x v0.0.0-20210326105829-476fab902fbe/go.mod h1:WgqbSEmUYSjEV3B1qmee/PpP2NYEz4bL9/+mF1ma+s4= github.com/tylertreat/BoomFilters v0.0.0-20210315201527-1a82519a3e43 h1:QEePdg0ty2r0t1+qwfZmQ4OOl/MB2UXIeJSpIZv56lg= @@ -268,7 +278,6 @@ github.com/yl2chen/cidranger v1.0.2/go.mod h1:9U1yz7WPYDwf0vpNWFaeRh0bjwz5RVgRy/ github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= -github.com/yuin/goldmark v1.4.0/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU= go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8= go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= @@ -290,9 +299,8 @@ golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8U golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= -golang.org/x/crypto v0.0.0-20211215165025-cf75a172585e/go.mod h1:P+XmwS30IXTQdn5tA2iutPOUgjI07+tq3H3K9MVA1s8= -golang.org/x/crypto v0.0.0-20220315160706-3147a52a75dd h1:XcWmESyNjXJMLahc3mqVQJcgSTDxFxhETVlfk9uGc38= -golang.org/x/crypto v0.0.0-20220315160706-3147a52a75dd/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= +golang.org/x/crypto v0.0.0-20220722155217-630584e8d5aa h1:zuSxTR4o9y82ebqCUJYNGJbGPo6sKVl54f/TVDObg1c= +golang.org/x/crypto v0.0.0-20220722155217-630584e8d5aa/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= @@ -323,9 +331,8 @@ golang.org/x/mod v0.1.0/go.mod h1:0QHyrYULN0/3qlju5TqG8bIK38QM8yzMo5ekMj3DlcY= golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= golang.org/x/mod v0.1.1-0.20191107180719-034126e5016b/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/mod v0.3.0 h1:RM4zey1++hCTbCVQfnWeKs9/IEsaBLA8vTkd0WVtmH4= golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= -golang.org/x/mod v0.4.2 h1:Gz96sIWK3OalVv/I/qNygP42zyoKp3xptRVCWRFEBvo= -golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/net v0.0.0-20180218175443-cbe0f9307d01/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= @@ -356,17 +363,17 @@ golang.org/x/net v0.0.0-20200625001655-4c5254603344/go.mod h1:/O7V0waA8r7cgGh81R golang.org/x/net v0.0.0-20200707034311-ab3426394381/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= -golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20210525063256-abc453219eb5/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= -golang.org/x/net v0.0.0-20210805182204-aaa1db679c0d/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= -golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2 h1:CIJ76btIcR3eFI5EgSo6k1qKw9KJexJuRLI9G7Hp5wE= -golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= +golang.org/x/net v0.0.0-20220127200216-cd36cc0744dd/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= +golang.org/x/net v0.0.0-20220225172249-27dd8689420f h1:oA4XRj0qtSt8Yo1Zms0CUlsT3KG69V2UGQWPBxujDmc= +golang.org/x/net v0.0.0-20220225172249-27dd8689420f/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20191202225959-858c2ad4c8b6/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20210514164344-f6687ab2804c/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.0.0-20220223155221-ee480838109b/go.mod h1:DAh4E804XQdzx2j+YRIaUnCqCV2RuMz24cGBJ5QYIrc= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= @@ -376,8 +383,8 @@ golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sync v0.0.0-20200317015054-43a5402ce75a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20210220032951-036812b2e83c h1:5KslGYwFpkhGh+Q16bwMP3cOontH8FOep7tGV86Y7SQ= -golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20220601150217-0de741cfad7f h1:Ax0t5p6N38Ga0dThY21weqDEyz2oklo4IvDkpigvkD8= +golang.org/x/sync v0.0.0-20220601150217-0de741cfad7f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= @@ -416,17 +423,22 @@ golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210603081109-ebe580a85c40/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20210809222454-d867a43fc93e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220114195835-da31bd327af9/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220319134239-a9b59b0215f8 h1:OH54vjqzRWmbJ62fjuhxy7AxFFgoHN0/DPc/UrL8cAs= -golang.org/x/sys v0.0.0-20220319134239-a9b59b0215f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220804214406-8e32c043e418 h1:9vYwv7OjYaky/tlAeD7C4oC9EsPTlaFl1H2jS++V+ME= +golang.org/x/sys v0.0.0-20220804214406-8e32c043e418/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= +golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= @@ -472,9 +484,8 @@ golang.org/x/tools v0.0.0-20200618134242-20370b0cb4b2/go.mod h1:EkVYQZoAsY45+roY golang.org/x/tools v0.0.0-20200729194436-6467de6f59a7/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= golang.org/x/tools v0.0.0-20200804011535-6c149bb5ef0d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= golang.org/x/tools v0.0.0-20200820010801-b793a1359eac/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= +golang.org/x/tools v0.0.0-20200825202427-b303f430e36d h1:W07d4xkoAUSNOkOzdzXCdFGxT7o2rW4q8M34tB2i//k= golang.org/x/tools v0.0.0-20200825202427-b303f430e36d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= -golang.org/x/tools v0.1.7 h1:6j8CgantCy3yc8JGBqkDLMKWqZ0RDU2g1HVgacojGWQ= -golang.org/x/tools v0.1.7/go.mod h1:LGqMHiF4EqQNHR1JncWGqT5BVaXmza+X+BDGol+dOxo= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= @@ -555,8 +566,8 @@ google.golang.org/protobuf v1.24.0/go.mod h1:r/3tXBNzIEhYS9I1OUVjXDlt8tc493IdKGj google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c= google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= -google.golang.org/protobuf v1.27.1 h1:SnqbnDw1V7RiZcXPx5MEeqPv2s79L9i7BJUlG/+RurQ= -google.golang.org/protobuf v1.27.1/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= +google.golang.org/protobuf v1.28.1 h1:d0NfwRgPtno5B1Wa6L2DAG+KivqkdutMf1UhdNx175w= +google.golang.org/protobuf v1.28.1/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= @@ -567,13 +578,12 @@ gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.5/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v2 v2.2.7/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= -gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b h1:h8qDotaEPuJATrMmW04NCwg7v22aHH28wwpauUhK9Oo= -gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= +gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= diff --git a/internal/cli/access.go b/internal/cli/access.go index 2c9a0318f..5dfa10b6e 100644 --- a/internal/cli/access.go +++ b/internal/cli/access.go @@ -31,17 +31,17 @@ type accessResponse struct { type accessResponseURLs struct { IP net.IP `json:"ip"` Port uint `json:"port"` - TgURL string `json:"tg_url"` // nolint: tagliatelle - TgQrCode string `json:"tg_qrcode"` // nolint: tagliatelle - TmeURL string `json:"tme_url"` // nolint: tagliatelle - TmeQrCode string `json:"tme_qrcode"` // nolint: tagliatelle + TgURL string `json:"tg_url"` //nolint: tagliatelle + TgQrCode string `json:"tg_qrcode"` //nolint: tagliatelle + TmeURL string `json:"tme_url"` //nolint: tagliatelle + TmeQrCode string `json:"tme_qrcode"` //nolint: tagliatelle } type Access struct { - ConfigPath string `kong:"arg,required,type='existingfile',help='Path to the configuration file.',name='config-path'"` // nolint: lll - PublicIPv4 net.IP `kong:"help='Public IPv4 address for proxy. By default it is resolved via remote website',name='ipv4',short='i'"` // nolint: lll - PublicIPv6 net.IP `kong:"help='Public IPv6 address for proxy. By default it is resolved via remote website',name='ipv6',short='I'"` // nolint: lll - Port uint `kong:"help='Port number. Default port is taken from configuration file, bind-to parameter',type:'uint',short='p'"` // nolint: lll + ConfigPath string `kong:"arg,required,type='existingfile',help='Path to the configuration file.',name='config-path'"` //nolint: lll + PublicIPv4 net.IP `kong:"help='Public IPv4 address for proxy. By default it is resolved via remote website',name='ipv4',short='i'"` //nolint: lll + PublicIPv6 net.IP `kong:"help='Public IPv6 address for proxy. By default it is resolved via remote website',name='ipv6',short='I'"` //nolint: lll + Port uint `kong:"help='Port number. Default port is taken from configuration file, bind-to parameter',type:'uint',short='p'"` //nolint: lll Hex bool `kong:"help='Print secret in hex encoding.',short='x'"` } @@ -61,7 +61,7 @@ func (a *Access) Run(cli *CLI, version string) error { } wg := &sync.WaitGroup{} - wg.Add(2) // nolint: gomnd + wg.Add(2) //nolint: gomnd go func() { defer wg.Done() @@ -108,10 +108,10 @@ func (a *Access) Run(cli *CLI, version string) error { func (a *Access) getIP(ntw mtglib.Network, protocol string) net.IP { client := ntw.MakeHTTPClient(func(ctx context.Context, network, address string) (essentials.Conn, error) { - return ntw.DialContext(ctx, protocol, address) // nolint: wrapcheck + return ntw.DialContext(ctx, protocol, address) //nolint: wrapcheck }) - req, err := http.NewRequest(http.MethodGet, "https://ifconfig.co", nil) // nolint: noctx + req, err := http.NewRequest(http.MethodGet, "https://ifconfig.co", nil) //nolint: noctx if err != nil { panic(err) } @@ -128,7 +128,7 @@ func (a *Access) getIP(ntw mtglib.Network, protocol string) net.IP { } defer func() { - io.Copy(io.Discard, resp.Body) // nolint: errcheck + io.Copy(io.Discard, resp.Body) //nolint: errcheck resp.Body.Close() }() diff --git a/internal/cli/generate_secret.go b/internal/cli/generate_secret.go index 17b3b0985..8d6a681d9 100644 --- a/internal/cli/generate_secret.go +++ b/internal/cli/generate_secret.go @@ -15,9 +15,9 @@ func (g *GenerateSecret) Run(cli *CLI, _ string) error { secret := mtglib.GenerateSecret(cli.GenerateSecret.HostName) if g.Hex { - fmt.Println(secret.Hex()) // nolint: forbidigo + fmt.Println(secret.Hex()) //nolint: forbidigo } else { - fmt.Println(secret.Base64()) // nolint: forbidigo + fmt.Println(secret.Base64()) //nolint: forbidigo } return nil diff --git a/internal/cli/run.go b/internal/cli/run.go index 390f30ab8..1fbee7329 100644 --- a/internal/cli/run.go +++ b/internal/cli/run.go @@ -7,7 +7,7 @@ import ( ) type Run struct { - ConfigPath string `kong:"arg,required,type='existingfile',help='Path to the configuration file.',name='config-path'"` // nolint: lll + ConfigPath string `kong:"arg,required,type='existingfile',help='Path to the configuration file.',name='config-path'"` //nolint: lll } func (r *Run) Run(cli *CLI, version string) error { diff --git a/internal/cli/run_proxy.go b/internal/cli/run_proxy.go index 01c6240b0..c3ec94a66 100644 --- a/internal/cli/run_proxy.go +++ b/internal/cli/run_proxy.go @@ -49,7 +49,7 @@ func makeNetwork(conf *config.Config, version string) (mtglib.Network, error) { } if len(conf.Network.Proxies) == 0 { - return network.NewNetwork(baseDialer, userAgent, dohIP, httpTimeout) // nolint: wrapcheck + return network.NewNetwork(baseDialer, userAgent, dohIP, httpTimeout) //nolint: wrapcheck } proxyURLs := make([]*url.URL, 0, len(conf.Network.Proxies)) @@ -66,7 +66,7 @@ func makeNetwork(conf *config.Config, version string) (mtglib.Network, error) { return nil, fmt.Errorf("cannot build socks5 dialer: %w", err) } - return network.NewNetwork(socksDialer, userAgent, dohIP, httpTimeout) // nolint: wrapcheck + return network.NewNetwork(socksDialer, userAgent, dohIP, httpTimeout) //nolint: wrapcheck } socksDialer, err := network.NewLoadBalancedSocks5Dialer(baseDialer, proxyURLs) @@ -74,7 +74,7 @@ func makeNetwork(conf *config.Config, version string) (mtglib.Network, error) { return nil, fmt.Errorf("cannot build socks5 dialer: %w", err) } - return network.NewNetwork(socksDialer, userAgent, dohIP, httpTimeout) // nolint: wrapcheck + return network.NewNetwork(socksDialer, userAgent, dohIP, httpTimeout) //nolint: wrapcheck } func makeAntiReplayCache(conf *config.Config) mtglib.AntiReplayCache { @@ -127,7 +127,12 @@ func makeIPAllowlist(conf config.ListConfig, logger mtglib.Logger, ntw mtglib.Network, updateCallback ipblocklist.FireholUpdateCallback, -) (allowlist mtglib.IPBlocklist, err error) { +) (mtglib.IPBlocklist, error) { + var ( + allowlist mtglib.IPBlocklist + err error + ) + if !conf.Enabled.Get(false) { allowlist, err = ipblocklist.NewFireholFromFiles( logger.Named("ipblocklist"), @@ -159,7 +164,7 @@ func makeIPAllowlist(conf config.ListConfig, } func makeEventStream(conf *config.Config, logger mtglib.Logger) (mtglib.EventStream, error) { - factories := make([]events.ObserverFactory, 0, 2) // nolint: gomnd + factories := make([]events.ObserverFactory, 0, 2) //nolint: gomnd if conf.Stats.StatsD.Enabled.Get(false) { statsdFactory, err := stats.NewStatsd( @@ -185,7 +190,7 @@ func makeEventStream(conf *config.Config, logger mtglib.Logger) (mtglib.EventStr return nil, fmt.Errorf("cannot start a listener for prometheus: %w", err) } - go prometheus.Serve(listener) // nolint: errcheck + go prometheus.Serve(listener) //nolint: errcheck factories = append(factories, prometheus.Make) } @@ -197,7 +202,7 @@ func makeEventStream(conf *config.Config, logger mtglib.Logger) (mtglib.EventStr return events.NewNoopStream(), nil } -func runProxy(conf *config.Config, version string) error { // nolint: funlen +func runProxy(conf *config.Config, version string) error { //nolint: funlen logger := makeLogger(conf) logger.BindJSON("configuration", conf.String()).Debug("configuration") @@ -263,7 +268,7 @@ func runProxy(conf *config.Config, version string) error { // nolint: funlen ctx := utils.RootContext() - go proxy.Serve(listener) // nolint: errcheck + go proxy.Serve(listener) //nolint: errcheck <-ctx.Done() listener.Close() diff --git a/internal/cli/simple_run.go b/internal/cli/simple_run.go index 80edec36f..e633aba6a 100644 --- a/internal/cli/simple_run.go +++ b/internal/cli/simple_run.go @@ -13,17 +13,18 @@ type SimpleRun struct { BindTo string `kong:"arg,required,name='bind-to',help='A host:port to bind proxy to.'"` Secret string `kong:"arg,required,name='secret',help='Proxy secret.'"` - Debug bool `kong:"name='debug',short='d',help='Run in debug mode.'"` // nolint: lll - Concurrency uint64 `kong:"name='concurrency',short='c',default='8192',help='Max number of concurrent connection to proxy.'"` // nolint: lll - TCPBuffer string `kong:"name='tcp-buffer',short='b',default='4KB',help='Deprecated and ignored'"` // nolint: lll - 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 - DomainFrontingPort uint64 `kong:"name='domain-fronting-port',short='p',default='443',help='A port to access for domain fronting.'"` // nolint: lll - 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 - Timeout time.Duration `kong:"name='timeout',short='t',default='10s',help='Network timeout to use'"` // nolint: lll - AntiReplayCacheSize string `kong:"name='antireplay-cache-size',short='a',default='1MB',help='A size of anti-replay cache to use.'"` // nolint: lll + Debug bool `kong:"name='debug',short='d',help='Run in debug mode.'"` //nolint: lll + Concurrency uint64 `kong:"name='concurrency',short='c',default='8192',help='Max number of concurrent connection to proxy.'"` //nolint: lll + TCPBuffer string `kong:"name='tcp-buffer',short='b',default='4KB',help='Deprecated and ignored'"` //nolint: lll + 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 + DomainFrontingPort uint64 `kong:"name='domain-fronting-port',short='p',default='443',help='A port to access for domain fronting.'"` //nolint: lll + 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 + Timeout time.Duration `kong:"name='timeout',short='t',default='10s',help='Network timeout to use'"` //nolint: lll + Socks5Proxies []string `kong:"name='socks5-proxy',short='s',help='Socks5 proxies to use for network access.'"` //nolint: lll + AntiReplayCacheSize string `kong:"name='antireplay-cache-size',short='a',default='1MB',help='A size of anti-replay cache to use.'"` //nolint: lll } -func (s *SimpleRun) Run(cli *CLI, version string) error { // nolint: cyclop +func (s *SimpleRun) Run(cli *CLI, version string) error { //nolint: cyclop,funlen conf := &config.Config{} if err := conf.BindTo.Set(s.BindTo); err != nil { @@ -34,7 +35,7 @@ func (s *SimpleRun) Run(cli *CLI, version string) error { // nolint: cyclop return fmt.Errorf("incorrect secret: %w", err) } - if err := conf.Concurrency.Set(strconv.FormatUint(s.Concurrency, 10)); err != nil { // nolint: gomnd + if err := conf.Concurrency.Set(strconv.FormatUint(s.Concurrency, 10)); err != nil { //nolint: gomnd return fmt.Errorf("incorrect concurrency: %w", err) } @@ -42,7 +43,7 @@ func (s *SimpleRun) Run(cli *CLI, version string) error { // nolint: cyclop return fmt.Errorf("incorrect prefer-ip: %w", err) } - if err := conf.DomainFrontingPort.Set(strconv.FormatUint(s.DomainFrontingPort, 10)); err != nil { // nolint: gomnd + if err := conf.DomainFrontingPort.Set(strconv.FormatUint(s.DomainFrontingPort, 10)); err != nil { //nolint: gomnd return fmt.Errorf("incorrect domain-fronting-port: %w", err) } @@ -66,6 +67,16 @@ func (s *SimpleRun) Run(cli *CLI, version string) error { // nolint: cyclop return fmt.Errorf("incorrect antireplay-cache-size: %w", err) } + for _, v := range s.Socks5Proxies { + proxyURL := config.TypeProxyURL{} + + if err := proxyURL.Set(v); err != nil { + return fmt.Errorf("incorrect socks5 proxy URL: %w", err) + } + + conf.Network.Proxies = append(conf.Network.Proxies, proxyURL) + } + conf.Debug.Value = s.Debug conf.AllowFallbackOnUnknownDC.Value = true conf.Defense.AntiReplay.Enabled.Value = true diff --git a/internal/config/type_concurrency.go b/internal/config/type_concurrency.go index e2ccd6734..699d03c63 100644 --- a/internal/config/type_concurrency.go +++ b/internal/config/type_concurrency.go @@ -10,7 +10,7 @@ type TypeConcurrency struct { } func (t *TypeConcurrency) Set(value string) error { - concurrencyValue, err := strconv.ParseUint(value, 10, 16) // nolint: gomnd + concurrencyValue, err := strconv.ParseUint(value, 10, 16) //nolint: gomnd if err != nil { return fmt.Errorf("value is not uint (%s): %w", value, err) } @@ -41,5 +41,5 @@ func (t TypeConcurrency) MarshalJSON() ([]byte, error) { } func (t TypeConcurrency) String() string { - return strconv.FormatUint(uint64(t.Value), 10) // nolint: gomnd + return strconv.FormatUint(uint64(t.Value), 10) //nolint: gomnd } diff --git a/internal/config/type_error_rate.go b/internal/config/type_error_rate.go index 92465ded1..c094b4584 100644 --- a/internal/config/type_error_rate.go +++ b/internal/config/type_error_rate.go @@ -12,7 +12,7 @@ type TypeErrorRate struct { } func (t *TypeErrorRate) Set(value string) error { - parsedValue, err := strconv.ParseFloat(value, 64) // nolint: gomnd + parsedValue, err := strconv.ParseFloat(value, 64) //nolint: gomnd if err != nil { return fmt.Errorf("value is not a float (%s): %w", value, err) } @@ -43,5 +43,5 @@ func (t TypeErrorRate) MarshalJSON() ([]byte, error) { } func (t TypeErrorRate) String() string { - return strconv.FormatFloat(t.Value, 'f', -1, 64) // nolint: gomnd + return strconv.FormatFloat(t.Value, 'f', -1, 64) //nolint: gomnd } diff --git a/internal/config/type_hostport.go b/internal/config/type_hostport.go index 8dcb254a8..b95d7dc2c 100644 --- a/internal/config/type_hostport.go +++ b/internal/config/type_hostport.go @@ -18,7 +18,7 @@ func (t *TypeHostPort) Set(value string) error { return fmt.Errorf("incorrect host:port value (%v): %w", value, err) } - portValue, err := strconv.ParseUint(port, 10, 16) // nolint: gomnd + portValue, err := strconv.ParseUint(port, 10, 16) //nolint: gomnd if err != nil { return fmt.Errorf("incorrect port number (%v): %w", value, err) } diff --git a/internal/config/type_port.go b/internal/config/type_port.go index 3965fb7a9..67b521588 100644 --- a/internal/config/type_port.go +++ b/internal/config/type_port.go @@ -10,7 +10,7 @@ type TypePort struct { } func (t *TypePort) Set(value string) error { - portValue, err := strconv.ParseUint(value, 10, 16) // nolint: gomnd + portValue, err := strconv.ParseUint(value, 10, 16) //nolint: gomnd if err != nil { return fmt.Errorf("incorrect port number (%v): %w", value, err) } diff --git a/internal/testlib/capture_output.go b/internal/testlib/capture_output.go index aa538c233..3e059628e 100644 --- a/internal/testlib/capture_output.go +++ b/internal/testlib/capture_output.go @@ -27,7 +27,7 @@ func captureOutput(filefp **os.File, callback func()) string { closeChan := make(chan bool) go func() { - io.Copy(buf, reader) // nolint: errcheck + io.Copy(buf, reader) //nolint: errcheck close(closeChan) }() diff --git a/internal/testlib/mtglib_network_mock.go b/internal/testlib/mtglib_network_mock.go index 7eb21a4d3..21ae79c89 100644 --- a/internal/testlib/mtglib_network_mock.go +++ b/internal/testlib/mtglib_network_mock.go @@ -15,17 +15,17 @@ type MtglibNetworkMock struct { func (m *MtglibNetworkMock) Dial(network, address string) (essentials.Conn, error) { args := m.Called(network, address) - return args.Get(0).(essentials.Conn), args.Error(1) // nolint: wrapcheck, forcetypeassert + return args.Get(0).(essentials.Conn), args.Error(1) //nolint: wrapcheck, forcetypeassert } func (m *MtglibNetworkMock) DialContext(ctx context.Context, network, address string) (essentials.Conn, error) { args := m.Called(ctx, network, address) - return args.Get(0).(essentials.Conn), args.Error(1) // nolint: wrapcheck, forcetypeassert + return args.Get(0).(essentials.Conn), args.Error(1) //nolint: wrapcheck, forcetypeassert } func (m *MtglibNetworkMock) MakeHTTPClient(dialFunc func(ctx context.Context, network, address string) (essentials.Conn, error), ) *http.Client { - return m.Called(dialFunc).Get(0).(*http.Client) // nolint: forcetypeassert + return m.Called(dialFunc).Get(0).(*http.Client) //nolint: forcetypeassert } diff --git a/internal/testlib/net_conn_mock.go b/internal/testlib/net_conn_mock.go index f4c455b9f..2d9ce30ea 100644 --- a/internal/testlib/net_conn_mock.go +++ b/internal/testlib/net_conn_mock.go @@ -24,33 +24,33 @@ func (n *EssentialsConnMock) Write(b []byte) (int, error) { } func (n *EssentialsConnMock) Close() error { - return n.Called().Error(0) // nolint: wrapcheck + return n.Called().Error(0) //nolint: wrapcheck } func (n *EssentialsConnMock) CloseRead() error { - return n.Called().Error(0) // nolint: wrapcheck + return n.Called().Error(0) //nolint: wrapcheck } func (n *EssentialsConnMock) CloseWrite() error { - return n.Called().Error(0) // nolint: wrapcheck + return n.Called().Error(0) //nolint: wrapcheck } func (n *EssentialsConnMock) LocalAddr() net.Addr { - return n.Called().Get(0).(net.Addr) // nolint: forcetypeassert + return n.Called().Get(0).(net.Addr) //nolint: forcetypeassert } func (n *EssentialsConnMock) RemoteAddr() net.Addr { - return n.Called().Get(0).(net.Addr) // nolint: forcetypeassert + return n.Called().Get(0).(net.Addr) //nolint: forcetypeassert } func (n *EssentialsConnMock) SetDeadline(t time.Time) error { - return n.Called(t).Error(0) // nolint: wrapcheck + return n.Called(t).Error(0) //nolint: wrapcheck } func (n *EssentialsConnMock) SetReadDeadline(t time.Time) error { - return n.Called(t).Error(0) // nolint: wrapcheck + return n.Called(t).Error(0) //nolint: wrapcheck } func (n *EssentialsConnMock) SetWriteDeadline(t time.Time) error { - return n.Called(t).Error(0) // nolint: wrapcheck + return n.Called(t).Error(0) //nolint: wrapcheck } diff --git a/internal/utils/net_listener.go b/internal/utils/net_listener.go index 496f51b38..8879a30bd 100644 --- a/internal/utils/net_listener.go +++ b/internal/utils/net_listener.go @@ -14,7 +14,7 @@ type Listener struct { func (l Listener) Accept() (net.Conn, error) { conn, err := l.Listener.Accept() if err != nil { - return nil, err // nolint: wrapcheck + return nil, err //nolint: wrapcheck } if err := network.SetClientSocketOptions(conn, 0); err != nil { diff --git a/internal/utils/rlimit.go b/internal/utils/rlimit.go deleted file mode 100644 index 82fbb1ecc..000000000 --- a/internal/utils/rlimit.go +++ /dev/null @@ -1,25 +0,0 @@ -//go:build !windows -// +build !windows - -package utils - -import ( - "fmt" - - "golang.org/x/sys/unix" -) - -func SetLimits() error { - rLimit := unix.Rlimit{} - if err := unix.Getrlimit(unix.RLIMIT_NOFILE, &rLimit); err != nil { - return fmt.Errorf("cannot get rlimit: %w", err) - } - - rLimit.Cur = rLimit.Max - - if err := unix.Setrlimit(unix.RLIMIT_NOFILE, &rLimit); err != nil { - return fmt.Errorf("cannot set rlimit: %w", err) - } - - return nil -} diff --git a/internal/utils/rlimit_windows.go b/internal/utils/rlimit_windows.go deleted file mode 100644 index 06229a3f1..000000000 --- a/internal/utils/rlimit_windows.go +++ /dev/null @@ -1,8 +0,0 @@ -//go:build windows -// +build windows - -package utils - -func SetLimits() error { - return nil -} diff --git a/ipblocklist/files/doc.go b/ipblocklist/files/doc.go new file mode 100644 index 000000000..e4df08740 --- /dev/null +++ b/ipblocklist/files/doc.go @@ -0,0 +1,8 @@ +// files defines a set of abstraction for 'files': an openable entities that +// could be read after. +// +// This is not a file on a filesystem of your local machine, it also can +// include "in memory" files or even remote ones, like HTTP endpoints. If you +// make a GET request to HTTP endpoint, then a body is readable and you can +// consider it as an openable file. +package files diff --git a/ipblocklist/files/http.go b/ipblocklist/files/http.go index 6a60edeb9..6092193a1 100644 --- a/ipblocklist/files/http.go +++ b/ipblocklist/files/http.go @@ -22,7 +22,7 @@ func (h httpFile) Open(ctx context.Context) (io.ReadCloser, error) { response, err := h.http.Do(request) if err != nil { if response != nil { - io.Copy(io.Discard, response.Body) // nolint: errcheck + io.Copy(io.Discard, response.Body) //nolint: errcheck response.Body.Close() } @@ -40,6 +40,8 @@ func (h httpFile) String() string { return h.url } +// NewHTTP returns a file abstraction for HTTP/HTTPS endpoint. You also need to +// provide a valid instance of [http.Client] to access it. func NewHTTP(client *http.Client, endpoint string) (File, error) { if client == nil { return nil, ErrBadHTTPClient diff --git a/ipblocklist/files/http_test.go b/ipblocklist/files/http_test.go index 6559969b2..a08c6935f 100644 --- a/ipblocklist/files/http_test.go +++ b/ipblocklist/files/http_test.go @@ -22,7 +22,7 @@ type HTTPTestSuite struct { } func (suite *HTTPTestSuite) makeFile(path string) (files.File, error) { - return files.NewHTTP(suite.httpClient, suite.httpServer.URL+"/"+path) // nolint: wrapcheck + return files.NewHTTP(suite.httpClient, suite.httpServer.URL+"/"+path) //nolint: wrapcheck } func (suite *HTTPTestSuite) SetupSuite() { diff --git a/ipblocklist/files/init.go b/ipblocklist/files/init.go index 97570afd9..5876eccbf 100644 --- a/ipblocklist/files/init.go +++ b/ipblocklist/files/init.go @@ -6,9 +6,16 @@ import ( "io" ) +// ErrBadHTTPClient is returned if given HTTP client is initialized +// incorrectly. var ErrBadHTTPClient = errors.New("incorrect http client") +// File is an abstraction for a entity that can be opened in some context. type File interface { + // Open returns an readable entity for a file. It is important to not forget + // to close it after the usage. Open(context.Context) (io.ReadCloser, error) + + // String returns a short text description for the file String() string } diff --git a/ipblocklist/files/local.go b/ipblocklist/files/local.go index 3cd08c709..0823e4f98 100644 --- a/ipblocklist/files/local.go +++ b/ipblocklist/files/local.go @@ -12,13 +12,14 @@ type localFile struct { } func (l localFile) Open(ctx context.Context) (io.ReadCloser, error) { - return os.Open(l.path) // nolint: wrapcheck + return os.Open(l.path) //nolint: wrapcheck } func (l localFile) String() string { return l.path } +// NewLocal returns an openable File for a path on a local file system. func NewLocal(path string) (File, error) { if stat, err := os.Stat(path); os.IsNotExist(err) || stat.IsDir() || stat.Mode().Perm()&0o400 == 0 { return nil, fmt.Errorf("%s is not a readable file", path) diff --git a/ipblocklist/files/mem.go b/ipblocklist/files/mem.go index db23bef7b..ff62edf5a 100644 --- a/ipblocklist/files/mem.go +++ b/ipblocklist/files/mem.go @@ -19,6 +19,7 @@ func (m memFile) String() string { return "mem" } +// NewMem returns an openable file that is kept in RAM. func NewMem(networks []*net.IPNet) File { builder := strings.Builder{} diff --git a/ipblocklist/firehol.go b/ipblocklist/firehol.go index efe57f067..c253b4e0e 100644 --- a/ipblocklist/firehol.go +++ b/ipblocklist/firehol.go @@ -19,27 +19,27 @@ import ( var ( fireholRegexpComment = regexp.MustCompile(`\s*#.*?$`) - fireholIPv4DefaultCIDR = net.CIDRMask(32, 32) // nolint: gomnd - fireholIPv6DefaultCIDR = net.CIDRMask(128, 128) // nolint: gomnd + fireholIPv4DefaultCIDR = net.CIDRMask(32, 32) //nolint: gomnd + fireholIPv6DefaultCIDR = net.CIDRMask(128, 128) //nolint: gomnd ) // FireholUpdateCallback defines a signature of the callback that has to be // execute when ip list is updated. type FireholUpdateCallback func(context.Context, int) -// Firehol is IPBlocklist which uses lists from FireHOL: +// Firehol is [mtglib.IPBlocklist] which uses lists from FireHOL: // https://iplists.firehol.org/ // -// It can use both local files and remote URLs. This is not necessary -// that blocklists should be taken from this website, we expect only -// compatible formats here. +// It can use both local files and remote URLs. This is not necessary that +// blocklists should be taken from this website, we expect only compatible +// formats here. // // Example of the format: // -// # this is a comment -// # to ignore -// 127.0.0.1 # you can specify an IP -// 10.0.0.0/8 # or cidr +// # this is a comment +// # to ignore +// 127.0.0.1 # you can specify an IP +// 10.0.0.0/8 # or cidr type Firehol struct { ctx context.Context ctxCancel context.CancelFunc @@ -78,8 +78,7 @@ func (f *Firehol) Contains(ip net.IP) bool { // Run starts a background update process. // -// This is a blocking method so you probably want to run it in a -// goroutine. +// This is a blocking method so you probably want to run it in a goroutine. func (f *Firehol) Run(updateEach time.Duration) { if updateEach == 0 { updateEach = DefaultFireholUpdateEach @@ -211,8 +210,8 @@ func (f *Firehol) updateParseLine(text string) (*net.IPNet, error) { // NewFirehol creates a new instance of FireHOL IP blocklist. // -// This method does not start an update process so please execute Run -// when it is necessary. +// This method does not start an update process so please execute Run when it +// is necessary. func NewFirehol(logger mtglib.Logger, network mtglib.Network, downloadConcurrency uint, urls []string, @@ -244,6 +243,9 @@ func NewFirehol(logger mtglib.Logger, network mtglib.Network, return NewFireholFromFiles(logger, downloadConcurrency, blocklists, updateCallback) } +// NewFirehol creates a new instance of FireHOL IP blocklist. +// +// This method creates this instances from a given list of files. func NewFireholFromFiles(logger mtglib.Logger, downloadConcurrency uint, blocklists []files.File, diff --git a/ipblocklist/firehol_test.go b/ipblocklist/firehol_test.go index 416d43e82..b03ac9aaf 100644 --- a/ipblocklist/firehol_test.go +++ b/ipblocklist/firehol_test.go @@ -37,7 +37,7 @@ func (suite *FireholTestSuite) SetupSuite() { defer filefp.Close() - io.Copy(w, filefp) // nolint: errcheck + io.Copy(w, filefp) //nolint: errcheck }) suite.httpServer = httptest.NewServer(mux) diff --git a/ipblocklist/init.go b/ipblocklist/init.go index f5a06d3fd..b1b3cea40 100644 --- a/ipblocklist/init.go +++ b/ipblocklist/init.go @@ -1,8 +1,8 @@ // Package ipblocklist contains default implementation of the -// IPBlocklist for mtg. +// [mtglib.IPBlocklist] for mtg. // -// Please check documentation for mtglib.IPBlocklist interface to get an -// idea of this abstraction. +// Please check documentation for [mtglib.IPBlocklist] interface to get an idea +// of this abstraction. package ipblocklist import "time" @@ -12,7 +12,7 @@ const ( // concurrent downloads of ip blocklists for Firehol. DefaultFireholDownloadConcurrency = 1 - // DefaultFireholUpdateEach defines a default time period when - // Firehol requests updates of the blocklists. + // DefaultFireholUpdateEach defines a default time period when Firehol + // requests updates of the blocklists. DefaultFireholUpdateEach = 6 * time.Hour ) diff --git a/ipblocklist/noop.go b/ipblocklist/noop.go index 40da20fc6..2d3631744 100644 --- a/ipblocklist/noop.go +++ b/ipblocklist/noop.go @@ -13,8 +13,7 @@ func (n noop) Contains(ip net.IP) bool { return false } func (n noop) Run(updateEach time.Duration) {} func (n noop) Shutdown() {} -// NewNoop returns a dummy ipblocklist which allows all incoming -// connections. +// NewNoop returns a dummy ipblocklist which allows all incoming connections. func NewNoop() mtglib.IPBlocklist { return noop{} } diff --git a/logger/init.go b/logger/init.go index 8ff8ddc2f..da4ff400c 100644 --- a/logger/init.go +++ b/logger/init.go @@ -1,14 +1,12 @@ -// Package logger has implementation of loggers for mtglib.Logger -// interface. +// Package logger has implementation of loggers for [mtglib.Logger] interface. // -// Please see a description of that interface to get some agreements -// which are used by mtglib. +// Please see a description of that interface to get some agreements which are +// used by mtglib. package logger -// StdLikeLogger is an interface which is close to log.Logger. This is -// commonly used by many 3pp tools. While mtglib itself does not need -// it, it is always a good idea to support it and have a transient end -// to end logging. +// StdLikeLogger is an interface which is close to [log.Logger]. This is +// commonly used by many 3pp tools. While mtglib itself does not need it, it is +// always a good idea to support it and have a transient end to end logging. type StdLikeLogger interface { Printf(format string, args ...interface{}) } diff --git a/logger/zerolog_test.go b/logger/zerolog_test.go index a3e9ae20c..a1f8d1f64 100644 --- a/logger/zerolog_test.go +++ b/logger/zerolog_test.go @@ -116,6 +116,6 @@ func (suite *ZeroLoggerTestSuite) TestIndependence() { suite.NotContains("lalala", log12Output) } -func TestZeroLogger(t *testing.T) { // nolint: paralleltest +func TestZeroLogger(t *testing.T) { //nolint: paralleltest suite.Run(t, &ZeroLoggerTestSuite{}) } diff --git a/main.go b/main.go index dd795c75f..52b32f598 100644 --- a/main.go +++ b/main.go @@ -9,55 +9,19 @@ package main import ( - "fmt" "math/rand" - "runtime/debug" - "strconv" "time" "github.com/9seconds/mtg/v2/internal/cli" - "github.com/9seconds/mtg/v2/internal/utils" "github.com/alecthomas/kong" ) -var version = "dev" // has to be set by ldflags - func main() { rand.Seed(time.Now().UTC().UnixNano()) - if err := utils.SetLimits(); err != nil { - panic(err) - } - - if buildInfo, ok := debug.ReadBuildInfo(); ok { - vcsCommit := "" - vcsDate := time.Now() - vcsDirty := "" - - for _, setting := range buildInfo.Settings { - switch setting.Key { - case "vcs.time": - vcsDate, _ = time.Parse(time.RFC3339, setting.Value) - case "vcs.revision": - vcsCommit = setting.Value - case "vcs.modified": - if isDirty, _ := strconv.ParseBool(setting.Value); isDirty { - vcsDirty = " [dirty]" - } - } - } - - version = fmt.Sprintf("%s (%s: %s on %s%s)", - version, - buildInfo.GoVersion, - vcsDate.Format(time.RFC3339), - vcsCommit, - vcsDirty) - } - cli := &cli.CLI{} ctx := kong.Parse(cli, kong.Vars{ - "version": version, + "version": getVersion(), }) ctx.FatalIfErrorf(ctx.Run(cli, version)) diff --git a/mtglib/conns.go b/mtglib/conns.go index 129ef52a2..9c3fa67c9 100644 --- a/mtglib/conns.go +++ b/mtglib/conns.go @@ -24,7 +24,7 @@ func (c connTraffic) Read(b []byte) (int, error) { c.stream.Send(c.ctx, NewEventTraffic(c.streamID, uint(n), true)) } - return n, err // nolint: wrapcheck + return n, err //nolint: wrapcheck } func (c connTraffic) Write(b []byte) (int, error) { @@ -34,7 +34,7 @@ func (c connTraffic) Write(b []byte) (int, error) { c.stream.Send(c.ctx, NewEventTraffic(c.streamID, uint(n), false)) } - return n, err // nolint: wrapcheck + return n, err //nolint: wrapcheck } type connRewind struct { @@ -49,7 +49,7 @@ func (c *connRewind) Read(p []byte) (int, error) { c.mutex.RLock() defer c.mutex.RUnlock() - return c.active.Read(p) // nolint: wrapcheck + return c.active.Read(p) //nolint: wrapcheck } func (c *connRewind) Rewind() { diff --git a/mtglib/conns_internal_test.go b/mtglib/conns_internal_test.go index ea46d7352..2797d0503 100644 --- a/mtglib/conns_internal_test.go +++ b/mtglib/conns_internal_test.go @@ -22,7 +22,7 @@ type ConnRewindBaseConn struct { func (c *ConnRewindBaseConn) Read(p []byte) (int, error) { c.Called(p) - return c.readBuffer.Read(p) // nolint: wrapcheck + return c.readBuffer.Read(p) //nolint: wrapcheck } type ConnTrafficTestSuite struct { @@ -69,7 +69,7 @@ func (suite *ConnTrafficTestSuite) TestReadOk() { suite.Equal(10, n) } -func (suite *ConnTrafficTestSuite) TestReadErr() { // nolint: dupl +func (suite *ConnTrafficTestSuite) TestReadErr() { //nolint: dupl suite.eventStreamMock. On("Send", mock.Anything, mock.Anything). Once(). @@ -125,7 +125,7 @@ func (suite *ConnTrafficTestSuite) TestWriteOk() { suite.Equal(10, n) } -func (suite *ConnTrafficTestSuite) TestWriteErr() { // nolint: dupl +func (suite *ConnTrafficTestSuite) TestWriteErr() { //nolint: dupl suite.eventStreamMock. On("Send", mock.Anything, mock.Anything). Once(). diff --git a/mtglib/events.go b/mtglib/events.go index f1c515252..0a1aefd19 100644 --- a/mtglib/events.go +++ b/mtglib/events.go @@ -29,13 +29,13 @@ type EventStart struct { RemoteIP net.IP } -// EventConnectedToDC is emitted when mtg proxy has connected to a -// Telegram server. +// EventConnectedToDC is emitted when mtg proxy has connected to a Telegram +// server. type EventConnectedToDC struct { eventBase - // RemoteIP is an IP address of the Telegram server proxy has been - // connected to. + // RemoteIP is an IP address of the Telegram server proxy has been connected + // to. RemoteIP net.IP // DC is an index of the datacenter proxy has been connected to. @@ -49,15 +49,15 @@ type EventTraffic struct { // Traffic is a count of bytes which were transmitted. Traffic uint - // IsRead defines if we _read_ or _write_ to connection. A rule of - // thumb is simple: EventTraffic is bound to a remote connection. Not - // to a client one, but either to Telegram or front domain one. + // IsRead defines if we _read_ or _write_ to connection. A rule of thumb is + // simple: EventTraffic is bound to a remote connection. Not to a client one, + // but either to Telegram or front domain one. // - // In the case of Telegram, isRead means that we've fetched some bytes - // from Telegram to send it to a client. + // In the case of Telegram, isRead means that we've fetched some bytes from + // Telegram to send it to a client. // - // In the case of the front domain, it means that we've fetched some - // bytes from this domain to send it to a client. + // In the case of the front domain, it means that we've fetched some bytes + // from this domain to send it to a client. IsRead bool } @@ -66,20 +66,20 @@ type EventFinish struct { eventBase } -// EventDomainFronting is emitted when we connect to a front domain -// instead of Telegram server. +// EventDomainFronting is emitted when we connect to a front domain instead of +// Telegram server. type EventDomainFronting struct { eventBase } -// EventConcurrencyLimited is emitted when connection was declined -// because of the concurrency limit of the worker pool. +// EventConcurrencyLimited is emitted when connection was declined because of +// the concurrency limit of the worker pool. type EventConcurrencyLimited struct { eventBase } -// EventIPBlocklisted is emitted when connection was declined because -// IP address was found in IP blocklist. +// EventIPBlocklisted is emitted when connection was declined because IP +// address was found in IP blocklist. type EventIPBlocklisted struct { eventBase diff --git a/mtglib/init.go b/mtglib/init.go index 0e00db66e..40e3f4126 100644 --- a/mtglib/init.go +++ b/mtglib/init.go @@ -1,20 +1,19 @@ // mtglib defines a package with MTPROTO proxy. // -// Since mtg itself is build as an example of how to work with mtglib, -// it worth to telling a couple of words about a project organization. +// Since mtg itself is build as an example of how to work with mtglib, it worth +// to telling a couple of words about a project organization. // -// A core object of the project is mtglib.Proxy. This is a proxy you -// expect: that one which you configure, set to serve on a listener -// and/or shutdown on application termination. +// A core object of the project is [mtglib.Proxy]. This is a proxy you expect: +// that one which you configure, set to serve on a listener and/or shutdown on +// application termination. // -// But it also has a core logic unrelated to Telegram per se: anti -// replay cache, network connectivity (who knows, maybe you want to have -// a native VMESS integration) and so on. +// But it also has a core logic unrelated to Telegram per se: anti replay +// cache, network connectivity (who knows, maybe you want to have a native +// VMESS integration) and so on. // -// You can supply such parts to a proxy with interfaces. The rest of -// the packages in mtg define some default implementations of these -// interfaces. But if you want to integrate it with, let say, influxdb, -// you can do it easily. +// You can supply such parts to a proxy with interfaces. The rest of the +// packages in mtg define some default implementations of these interfaces. But +// if you want to integrate it with, let say, influxdb, you can do it easily. package mtglib import ( @@ -28,42 +27,42 @@ import ( ) var ( - // ErrSecretEmpty is returned if you are trying to create a proxy - // but do not provide a secret. + // ErrSecretEmpty is returned if you are trying to create a proxy but do not + // provide a secret. ErrSecretEmpty = errors.New("secret is empty") - // ErrSecretInvalid is returned if you are trying to create a proxy - // but secret value is invalid (no host or payload are zeroes). + // ErrSecretInvalid is returned if you are trying to create a proxy but secret + // value is invalid (no host or payload are zeroes). ErrSecretInvalid = errors.New("secret is invalid") - // ErrNetworkIsNotDefined is returned if you are trying to create a - // proxy but network value is undefined. + // ErrNetworkIsNotDefined is returned if you are trying to create a proxy but + // network value is undefined. ErrNetworkIsNotDefined = errors.New("network is not defined") - // ErrAntiReplayCacheIsNotDefined is returned if you are trying to - // create a proxy but anti replay cache value is undefined. + // ErrAntiReplayCacheIsNotDefined is returned if you are trying to create a + // proxy but anti replay cache value is undefined. ErrAntiReplayCacheIsNotDefined = errors.New("anti-replay cache is not defined") - // ErrIPBlocklistIsNotDefined is returned if you are trying to - // create a proxy but ip blocklist instance is not defined. + // ErrIPBlocklistIsNotDefined is returned if you are trying to create a proxy + // but ip blocklist instance is not defined. ErrIPBlocklistIsNotDefined = errors.New("ip blocklist is not defined") - // ErrIPAllowlistIsNotDefined is returned if you are trying to - // create a proxy but ip allowlist instance is not defined. + // ErrIPAllowlistIsNotDefined is returned if you are trying to create a proxy + // but ip allowlist instance is not defined. ErrIPAllowlistIsNotDefined = errors.New("ip allowlist is not defined") - // ErrEventStreamIsNotDefined is returned if you are trying to create a - // proxy but event stream instance is not defined. + // ErrEventStreamIsNotDefined is returned if you are trying to create a proxy + // but event stream instance is not defined. ErrEventStreamIsNotDefined = errors.New("event stream is not defined") - // ErrLoggerIsNotDefined is returned if you are trying to - // create a proxy but logger is not defined. + // ErrLoggerIsNotDefined is returned if you are trying to create a proxy but + // logger is not defined. ErrLoggerIsNotDefined = errors.New("logger is not defined") ) const ( - // DefaultConcurrency is a default max count of simultaneously - // connected clients. + // DefaultConcurrency is a default max count of simultaneously connected + // clients. DefaultConcurrency = 4096 // DefaultBufferSize is a default size of a copy buffer. @@ -71,31 +70,29 @@ const ( // Deprecated: this setting no longer makes any effect. DefaultBufferSize = 16 * 1024 // 16 kib - // DefaultDomainFrontingPort is a default port (HTTPS) to connect to in - // case of probe-resistance activity. + // DefaultDomainFrontingPort is a default port (HTTPS) to connect to in case + // of probe-resistance activity. DefaultDomainFrontingPort = 443 - // DefaultIdleTimeout is a default timeout for closing a connection - // in case of idling. + // DefaultIdleTimeout is a default timeout for closing a connection in case of + // idling. // - // Deprecated: no longer in use because of changed TCP relay - // algorithm. + // Deprecated: no longer in use because of changed TCP relay algorithm. DefaultIdleTimeout = time.Minute - // DefaultTolerateTimeSkewness is a default timeout for time - // skewness on a faketls timeout verification. + // DefaultTolerateTimeSkewness is a default timeout for time skewness on a + // faketls timeout verification. DefaultTolerateTimeSkewness = 3 * time.Second - // DefaultPreferIP is a default value for Telegram IP connectivity - // preference. + // DefaultPreferIP is a default value for Telegram IP connectivity preference. DefaultPreferIP = "prefer-ipv6" - // SecretKeyLength defines a length of the secret bytes used - // by Telegram and a proxy. + // SecretKeyLength defines a length of the secret bytes used by Telegram and a + // proxy. SecretKeyLength = 16 - // ConnectionIDBytesLength defines a count of random bytes used to generate - // a stream/connection ids. + // ConnectionIDBytesLength defines a count of random bytes used to generate a + // stream/connection ids. ConnectionIDBytesLength = 16 // TCPRelayReadTimeout defines a max time period between two consecuitive @@ -104,81 +101,76 @@ const ( TCPRelayReadTimeout = 20 * time.Second ) -// Network defines a knowledge how to work with a network. It may sound -// fun but it encapsulates all the knowledge how to properly establish -// connections to remote hosts and configure HTTP clients. +// Network defines a knowledge how to work with a network. It may sound fun but +// it encapsulates all the knowledge how to properly establish connections to +// remote hosts and configure HTTP clients. // -// For example, if you want to use SOCKS5 proxy, you probably want to -// have all traffic routed to this proxy: telegram connections, http -// requests and so on. This knowledge is encapsulated into instances of -// such interface. +// For example, if you want to use SOCKS5 proxy, you probably want to have all +// traffic routed to this proxy: telegram connections, http requests and so on. +// This knowledge is encapsulated into instances of such interface. // // mtglib uses Network for: -// -// 1. Dialing to Telegram -// -// 2. Dialing to front domain -// -// 3. Doing HTTP requests (for example, for FireHOL ipblocklist). +// 1. Dialing to Telegram +// 2. Dialing to front domain +// 3. Doing HTTP requests (for example, for FireHOL ipblocklist). type Network interface { // Dial establishes context-free TCP connections. Dial(network, address string) (essentials.Conn, error) - // DialContext dials using a context. This is a preferrable - // way of establishing TCP connections. + // DialContext dials using a context. This is a preferrable way of + // establishing TCP connections. DialContext(ctx context.Context, network, address string) (essentials.Conn, error) - // MakeHTTPClient build an HTTP client with given dial function. If - // nothing is provided, then DialContext of this interface is going - // to be used. + // MakeHTTPClient build an HTTP client with given dial function. If nothing is + // provided, then DialContext of this interface is going to be used. MakeHTTPClient(func(ctx context.Context, network, address string) (essentials.Conn, error)) *http.Client } -// AntiReplayCache is an interface that is used to detect replay attacks -// based on some traffic fingerprints. +// AntiReplayCache is an interface that is used to detect replay attacks based +// on some traffic fingerprints. // -// Replay attacks are probe attacks whose main goal is to identify if -// server software can be classified in some way. For example, if you -// send some HTTP request to a web server, then you can expect that this -// server will respond with HTTP response back. +// Replay attacks are probe attacks whose main goal is to identify if server +// software can be classified in some way. For example, if you send some HTTP +// request to a web server, then you can expect that this server will respond +// with HTTP response back. // -// There is a problem though. Let's imagine, that connection is -// encrypted. Let's imagine, that it is encrypted with some static key -// like ShadowSocks (https://shadowsocks.org/assets/whitepaper.pdf). -// In that case, in theory, if you repeat the same bytes, you can get -// the same responses. Let's imagine, that you've cracked the key. then -// if you send the same bytes, you can decrypt a response and see its -// structure. Based on its structure you can identify if this server is -// SOCKS5, MTPROTO proxy etc. +// There is a problem though. Let's imagine, that connection is encrypted. +// Let's imagine, that it is encrypted with some static key like [ShadowSocks]. +// In that case, in theory, if you repeat the same bytes, you can get the same +// responses. Let's imagine, that you've cracked the key. then if you send the +// same bytes, you can decrypt a response and see its structure. Based on its +// structure you can identify if this server is SOCKS5, MTPROTO proxy etc. // -// This is just one example, maybe not the best or not the most -// relevant. In real life, different organizations use such replay -// attacks to perform some reverse engineering of the proxy, do some -// statical analysis to identify server software. +// This is just one example, maybe not the best or not the most relevant. In +// real life, different organizations use such replay attacks to perform some +// reverse engineering of the proxy, do some statical analysis to identify +// server software. // -// There are many ways how to protect your proxy against them. One -// is domain fronting which is a core part of mtg. Another one is to -// collect some 'handshake fingerprints' and forbid duplication. +// There are many ways how to protect your proxy against them. One is domain +// fronting which is a core part of mtg. Another one is to collect some +// 'handshake fingerprints' and forbid duplication. // -// So, it one is sending the same byte flow right after you (or a couple -// of hours after), mtg should detect that and reject this connection -// (or redirect to fronting domain). +// So, it one is sending the same byte flow right after you (or a couple of +// hours after), mtg should detect that and reject this connection (or redirect +// to fronting domain). +// +// [ShadowSocks]: https://shadowsocks.org/assets/whitepaper.pdf type AntiReplayCache interface { - // Seen before checks if this set of bytes was observed before or - // not. If it is required to store this information somewhere else, - // then it has to do that. + // Seen before checks if this set of bytes was observed before or not. If it + // is required to store this information somewhere else, then it has to do + // that. SeenBefore(data []byte) bool } // IPBlocklist filters requests based on IP address. // -// If this filter has an IP address, then mtg closes a request without -// reading anything from a socket. It also does not give such request to -// a worker pool, so in worst cases you can expect that you invoke this -// object more frequent than defined proxy concurrency. +// If this filter has an IP address, then mtg closes a request without reading +// anything from a socket. It also does not give such request to a worker pool, +// so in worst cases you can expect that you invoke this object more frequent +// than defined proxy concurrency. type IPBlocklist interface { - // Contains checks if given IP address belongs to this blocklist If. - // it is, a connection is terminated . + // Contains checks if given IP address belongs to this blocklist If. it is, a + // connection is terminated . Contains(net.IP) bool // Run starts a background update procedure for a blocklist @@ -188,40 +180,35 @@ type IPBlocklist interface { Shutdown() } -// Event is a data structure which is populated during mtg request -// processing lifecycle. Each request popluates many events: -// -// 1. Client connected +// Event is a data structure which is populated during mtg request processing +// lifecycle. Each request popluates many events: +// 1. Client connected +// 2. Request is finished +// 3. Connection to Telegram server is established // -// 2. Request is finished -// -// 3. Connection to Telegram server is established -// -// and so on. All these events are data structures but all of them -// must conform the same interface. +// and so on. All these events are data structures but all of them must conform +// the same interface. type Event interface { - // StreamID returns an identifier of the stream, connection, - // request, you name it. All events within the same stream returns - // the same stream id. + // StreamID returns an identifier of the stream, connection, request, you name + // it. All events within the same stream returns the same stream id. StreamID() string // Timestamp returns a timestamp when this event was generated. Timestamp() time.Time } -// EventStream is an abstraction that accepts a set of events produced -// by mtg. Its main goal is to inject your logging or monitoring system. +// EventStream is an abstraction that accepts a set of events produced by mtg. +// Its main goal is to inject your logging or monitoring system. // -// The idea is simple. When mtg works, it emits a set of events during -// a lifecycle of the requestor: EventStart, EventFinish etc. mtg is a -// producer which puts these events into a stream. Responsibility of -// the stream is to deliver this event to consumers/observers. There -// might be many different observers (for example, you want to have both -// statsd and prometheus), mtg should know nothing about them. +// The idea is simple. When mtg works, it emits a set of events during a +// lifecycle of the requestor: EventStart, EventFinish etc. mtg is a producer +// which puts these events into a stream. Responsibility of the stream is to +// deliver this event to consumers/observers. There might be many different +// observers (for example, you want to have both statsd and prometheus), mtg +// should know nothing about them. type EventStream interface { - // Send delivers an event to observers. Given context has to be - // respected. If the context is closed, all blocking operations should - // be released ASAP. + // Send delivers an event to observers. Given context has to be respected. If + // the context is closed, all blocking operations should be released ASAP. // // It is possible that context is closed but the message is delivered. // EventStream implementations should solve this issue somehow. @@ -230,27 +217,26 @@ type EventStream interface { // Logger defines an interface of the logger used by mtglib. // -// Each logger has a name. It is possible to stack names to organize -// poor-man namespaces. Also, each logger must be able to bind -// parameters to avoid pushing them all the time. +// Each logger has a name. It is possible to stack names to organize poor-man +// namespaces. Also, each logger must be able to bind parameters to avoid +// pushing them all the time. // // Example // -// logger := SomeLogger{} -// logger = logger.BindStr("ip", net.IP{127, 0, 0, 1}) -// logger.Info("Hello") +// logger := SomeLogger{} logger = logger.BindStr("ip", net.IP{127, 0, 0, 1}) +// logger.Info("Hello") // -// In that case, ip is bound as a parameter. It is a great idea to -// put this parameter somewhere in a log message. +// In that case, ip is bound as a parameter. It is a great idea to put this +// parameter somewhere in a log message. // -// logger1 = logger.BindStr("param1", "11") -// logger2 = logger.BindInt("param2", 11) +// logger1 = logger.BindStr("param1", "11") logger2 = logger.BindInt("param2", +// 11) // // logger1 should see no param2 and vice versa, logger2 should not see param1 // If you attach a parameter to a logger, parents should not know about that. type Logger interface { - // Named returns a new logger with a bound name. Name chaining is - // allowed and appreciated. + // Named returns a new logger with a bound name. Name chaining is allowed and + // appreciated. Named(name string) Logger // BindInt binds new integer parameter to a new logger instance. @@ -268,22 +254,21 @@ type Logger interface { // Info puts a message about some normal situation. Info(msg string) - // InfoError puts a message about some normal situation but this - // situation is related to a given error. + // InfoError puts a message about some normal situation but this situation is + // related to a given error. InfoError(msg string, err error) - // Warning puts a message about some extraordinary situation - // worth to look at. + // Warning puts a message about some extraordinary situation worth to look at. Warning(msg string) - // WarningError puts a message about some extraordinary situation - // worth to look at. This situation is related to a given error. + // WarningError puts a message about some extraordinary situation worth to + // look at. This situation is related to a given error. WarningError(msg string, err error) // Debug puts a message useful for debugging only. Debug(msg string) - // Debug puts a message useful for debugging only. This message is - // related to a given error. + // Debug puts a message useful for debugging only. This message is related to + // a given error. DebugError(msg string, err error) } diff --git a/mtglib/internal/faketls/client_hello.go b/mtglib/internal/faketls/client_hello.go index 2062a8a29..1017a5eaa 100644 --- a/mtglib/internal/faketls/client_hello.go +++ b/mtglib/internal/faketls/client_hello.go @@ -56,7 +56,7 @@ func ParseClientHello(secret, handshake []byte) (ClientHello, error) { if len(handshake)-4 != int(handshakeLength) { return hello, fmt.Errorf("incorrect handshake size. manifested=%d, real=%d", - handshakeLength, len(handshake)-4) // nolint: gomnd + handshakeLength, len(handshake)-4) //nolint: gomnd } copy(hello.Random[:], handshake[ClientHelloRandomOffset:]) @@ -72,7 +72,7 @@ func ParseClientHello(secret, handshake []byte) (ClientHello, error) { // mac is calculated for the whole record, not only // for the payload part mac := hmac.New(sha256.New, secret) - rec.Dump(mac) // nolint: errcheck + rec.Dump(mac) //nolint: errcheck computedRandom := mac.Sum(nil) @@ -100,7 +100,7 @@ func parseSessionID(hello *ClientHello, handshake []byte) { } func parseCipherSuite(hello *ClientHello, handshake []byte) { - cipherSuiteOffset := ClientHelloSessionIDOffset + len(hello.SessionID) + 3 // nolint: gomnd + cipherSuiteOffset := ClientHelloSessionIDOffset + len(hello.SessionID) + 3 //nolint: gomnd hello.CipherSuite = binary.BigEndian.Uint16(handshake[cipherSuiteOffset : cipherSuiteOffset+2]) } diff --git a/mtglib/internal/faketls/conn.go b/mtglib/internal/faketls/conn.go index 74c802083..f88771c15 100644 --- a/mtglib/internal/faketls/conn.go +++ b/mtglib/internal/faketls/conn.go @@ -25,14 +25,14 @@ func (c *Conn) Read(p []byte) (int, error) { for { if err := rec.Read(c.Conn); err != nil { - return 0, err // nolint: wrapcheck + return 0, err //nolint: wrapcheck } - switch rec.Type { // nolint: exhaustive + switch rec.Type { //nolint: exhaustive case record.TypeApplicationData: - rec.Payload.WriteTo(&c.readBuffer) // nolint: errcheck + rec.Payload.WriteTo(&c.readBuffer) //nolint: errcheck - return c.readBuffer.Read(p) // nolint: wrapcheck + return c.readBuffer.Read(p) //nolint: wrapcheck case record.TypeChangeCipherSpec: default: return 0, fmt.Errorf("unsupported record type %v", rec.Type) @@ -60,13 +60,13 @@ func (c *Conn) Write(p []byte) (int, error) { rec.Payload.Reset() rec.Payload.Write(p[:chunkSize]) - rec.Dump(sendBuffer) // nolint: errcheck + rec.Dump(sendBuffer) //nolint: errcheck p = p[chunkSize:] } if _, err := c.Conn.Write(sendBuffer.Bytes()); err != nil { - return 0, err // nolint: wrapcheck + return 0, err //nolint: wrapcheck } return lenP, nil diff --git a/mtglib/internal/faketls/conn_test.go b/mtglib/internal/faketls/conn_test.go index e7f311aa8..142874f0c 100644 --- a/mtglib/internal/faketls/conn_test.go +++ b/mtglib/internal/faketls/conn_test.go @@ -24,13 +24,13 @@ type ConnMock struct { func (m *ConnMock) Read(p []byte) (int, error) { m.Called(p) - return m.readBuffer.Read(p) // nolint: wrapcheck + return m.readBuffer.Read(p) //nolint: wrapcheck } func (m *ConnMock) Write(p []byte) (int, error) { m.Called(p) - return m.writeBuffer.Write(p) // nolint: wrapcheck + return m.writeBuffer.Write(p) //nolint: wrapcheck } type ConnTestSuite struct { @@ -61,14 +61,14 @@ func (suite *ConnTestSuite) TestRead() { rec.Version = record.Version12 rec.Payload.WriteByte(0x01) - rec.Dump(&suite.connMock.readBuffer) // nolint: errcheck + rec.Dump(&suite.connMock.readBuffer) //nolint: errcheck rec.Reset() rec.Type = record.TypeApplicationData rec.Version = record.Version12 rec.Payload.Write([]byte{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}) - rec.Dump(&suite.connMock.readBuffer) // nolint: errcheck + rec.Dump(&suite.connMock.readBuffer) //nolint: errcheck resultBuffer := &bytes.Buffer{} buf := make([]byte, 2) @@ -95,14 +95,14 @@ func (suite *ConnTestSuite) TestReadUnexpected() { rec.Version = record.Version12 rec.Payload.WriteByte(0x01) - rec.Dump(&suite.connMock.readBuffer) // nolint: errcheck + rec.Dump(&suite.connMock.readBuffer) //nolint: errcheck rec.Reset() rec.Type = record.TypeHandshake rec.Version = record.Version12 rec.Payload.Write([]byte{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}) - rec.Dump(&suite.connMock.readBuffer) // nolint: errcheck + rec.Dump(&suite.connMock.readBuffer) //nolint: errcheck buf := make([]byte, 2) @@ -141,7 +141,7 @@ func (suite *ConnTestSuite) TestWrite() { suite.Equal(record.TypeApplicationData, rec.Type) suite.Equal(record.Version12, rec.Version) - rec.Payload.WriteTo(buf) // nolint: errcheck + rec.Payload.WriteTo(buf) //nolint: errcheck } suite.Equal(dataToRec, buf.Bytes()) diff --git a/mtglib/internal/faketls/pools.go b/mtglib/internal/faketls/pools.go index e8dbcd27d..54183a087 100644 --- a/mtglib/internal/faketls/pools.go +++ b/mtglib/internal/faketls/pools.go @@ -12,7 +12,7 @@ var bytesBufferPool = sync.Pool{ } func acquireBytesBuffer() *bytes.Buffer { - return bytesBufferPool.Get().(*bytes.Buffer) // nolint: forcetypeassert + return bytesBufferPool.Get().(*bytes.Buffer) //nolint: forcetypeassert } func releaseBytesBuffer(b *bytes.Buffer) { diff --git a/mtglib/internal/faketls/record/pools.go b/mtglib/internal/faketls/record/pools.go index e51c10cad..cc4739a5e 100644 --- a/mtglib/internal/faketls/record/pools.go +++ b/mtglib/internal/faketls/record/pools.go @@ -11,7 +11,7 @@ var recordPool = sync.Pool{ } func AcquireRecord() *Record { - return recordPool.Get().(*Record) // nolint: forcetypeassert + return recordPool.Get().(*Record) //nolint: forcetypeassert } func ReleaseRecord(r *Record) { diff --git a/mtglib/internal/faketls/welcome.go b/mtglib/internal/faketls/welcome.go index 0b5e5c024..b4dcd30b7 100644 --- a/mtglib/internal/faketls/welcome.go +++ b/mtglib/internal/faketls/welcome.go @@ -23,24 +23,24 @@ func SendWelcomePacket(writer io.Writer, secret []byte, clientHello ClientHello) rec.Version = record.Version12 generateServerHello(&rec.Payload, clientHello) - rec.Dump(buf) // nolint: errcheck + rec.Dump(buf) //nolint: errcheck rec.Reset() rec.Type = record.TypeChangeCipherSpec rec.Version = record.Version12 rec.Payload.WriteByte(ChangeCipherValue) - rec.Dump(buf) // nolint: errcheck + rec.Dump(buf) //nolint: errcheck rec.Reset() rec.Type = record.TypeApplicationData rec.Version = record.Version12 - if _, err := io.CopyN(&rec.Payload, rand.Reader, int64(1024+mrand.Intn(3092))); err != nil { // nolint: gomnd + if _, err := io.CopyN(&rec.Payload, rand.Reader, int64(1024+mrand.Intn(3092))); err != nil { //nolint: gomnd panic(err) } - rec.Dump(buf) // nolint: errcheck + rec.Dump(buf) //nolint: errcheck packet := buf.Bytes() mac := hmac.New(sha256.New, secret) @@ -51,7 +51,7 @@ func SendWelcomePacket(writer io.Writer, secret []byte, clientHello ClientHello) copy(packet[WelcomePacketRandomOffset:], mac.Sum(nil)) if _, err := writer.Write(packet); err != nil { - return err // nolint: wrapcheck + return err //nolint: wrapcheck } return nil @@ -87,6 +87,6 @@ func generateServerHello(writer io.Writer, clientHello ClientHello) { binary.BigEndian.PutUint32(header[:], uint32(bodyBuf.Len())) header[0] = HandshakeTypeServer - writer.Write(header[:]) // nolint: errcheck - bodyBuf.WriteTo(writer) // nolint: errcheck + writer.Write(header[:]) //nolint: errcheck + bodyBuf.WriteTo(writer) //nolint: errcheck } diff --git a/mtglib/internal/obfuscated2/client_handshake_test.go b/mtglib/internal/obfuscated2/client_handshake_test.go index c310e96dd..59996fc3a 100644 --- a/mtglib/internal/obfuscated2/client_handshake_test.go +++ b/mtglib/internal/obfuscated2/client_handshake_test.go @@ -22,7 +22,7 @@ func (suite *ClientHandshakeTestSuite) SetupSuite() { func (suite *ClientHandshakeTestSuite) TestCannotRead() { buf := bytes.NewBuffer([]byte{1, 2, 3}) - _, _, _, err := obfuscated2.ClientHandshake([]byte{1, 2, 3}, buf) // nolint: dogsled + _, _, _, err := obfuscated2.ClientHandshake([]byte{1, 2, 3}, buf) //nolint: dogsled suite.Error(err) } diff --git a/mtglib/internal/obfuscated2/conn.go b/mtglib/internal/obfuscated2/conn.go index b6ecbf489..29e323ecc 100644 --- a/mtglib/internal/obfuscated2/conn.go +++ b/mtglib/internal/obfuscated2/conn.go @@ -16,7 +16,7 @@ type Conn struct { func (c Conn) Read(p []byte) (int, error) { n, err := c.Conn.Read(p) if err != nil { - return n, err // nolint: wrapcheck + return n, err //nolint: wrapcheck } c.Decryptor.XORKeyStream(p, p[:n]) @@ -33,5 +33,5 @@ func (c Conn) Write(p []byte) (int, error) { payload := buf.Bytes() c.Encryptor.XORKeyStream(payload, payload) - return c.Conn.Write(payload) // nolint: wrapcheck + return c.Conn.Write(payload) //nolint: wrapcheck } diff --git a/mtglib/internal/obfuscated2/handshake_frame.go b/mtglib/internal/obfuscated2/handshake_frame.go index 4a8e15659..83e0c0d54 100644 --- a/mtglib/internal/obfuscated2/handshake_frame.go +++ b/mtglib/internal/obfuscated2/handshake_frame.go @@ -23,20 +23,20 @@ var handshakeConnectionType = []byte{0xdd, 0xdd, 0xdd, 0xdd} // A structure of obfuscated2 handshake frame is following: // -// [frameOffsetFirst:frameOffsetKey:frameOffsetIV:frameOffsetMagic:frameOffsetDC:frameOffsetEnd]. +// [frameOffsetFirst:frameOffsetKey:frameOffsetIV:frameOffsetMagic:frameOffsetDC:frameOffsetEnd]. // -// - 8 bytes of noise -// - 32 bytes of AES Key -// - 16 bytes of AES IV -// - 4 bytes of 'connection type' - this has some setting like a connection type -// - 2 bytes of 'DC'. DC is little endian int16 -// - 2 bytes of noise +// - 8 bytes of noise +// - 32 bytes of AES Key +// - 16 bytes of AES IV +// - 4 bytes of 'connection type' - this has some setting like a connection type +// - 2 bytes of 'DC'. DC is little endian int16 +// - 2 bytes of noise type handshakeFrame struct { data [handshakeFrameLen]byte } func (h *handshakeFrame) dc() int { - idx := int16(h.data[handshakeFrameOffsetDC]) | int16(h.data[handshakeFrameOffsetDC+1])<<8 // nolint: gomnd, lll // little endian for int16 is here + idx := int16(h.data[handshakeFrameOffsetDC]) | int16(h.data[handshakeFrameOffsetDC+1])<<8 //nolint: gomnd, lll // little endian for int16 is here switch { case idx > 0: diff --git a/mtglib/internal/obfuscated2/handshake_frame_internal_test.go b/mtglib/internal/obfuscated2/handshake_frame_internal_test.go index 7b197dbac..011c60163 100644 --- a/mtglib/internal/obfuscated2/handshake_frame_internal_test.go +++ b/mtglib/internal/obfuscated2/handshake_frame_internal_test.go @@ -57,7 +57,7 @@ func (suite *HandshakeFrameTestSuite) TestDC() { suite.T().Run(strconv.Itoa(int(incoming)), func(t *testing.T) { frame := handshakeFrame{} - rand.Read(frame.data[:]) // nolint: errcheck + rand.Read(frame.data[:]) //nolint: errcheck frame.data[handshakeFrameOffsetDC] = byte(incoming) frame.data[handshakeFrameOffsetDC+1] = byte(incoming >> 8) diff --git a/mtglib/internal/obfuscated2/pools.go b/mtglib/internal/obfuscated2/pools.go index fd4a3da1d..f714262d1 100644 --- a/mtglib/internal/obfuscated2/pools.go +++ b/mtglib/internal/obfuscated2/pools.go @@ -21,7 +21,7 @@ var ( ) func acquireSha256Hasher() hash.Hash { - return sha256HasherPool.Get().(hash.Hash) // nolint: forcetypeassert + return sha256HasherPool.Get().(hash.Hash) //nolint: forcetypeassert } func releaseSha256Hasher(h hash.Hash) { @@ -30,7 +30,7 @@ func releaseSha256Hasher(h hash.Hash) { } func acquireBytesBuffer() *bytes.Buffer { - return bytesBufferPool.Get().(*bytes.Buffer) // nolint: forcetypeassert + return bytesBufferPool.Get().(*bytes.Buffer) //nolint: forcetypeassert } func releaseBytesBuffer(buf *bytes.Buffer) { diff --git a/mtglib/internal/obfuscated2/server_handshake.go b/mtglib/internal/obfuscated2/server_handshake.go index 9712fde5d..5433dae82 100644 --- a/mtglib/internal/obfuscated2/server_handshake.go +++ b/mtglib/internal/obfuscated2/server_handshake.go @@ -47,12 +47,12 @@ func generateServerHanshakeFrame() serverHandshakeFrame { panic(err) } - if frame.data[0] == 0xef { // nolint: gomnd // taken from tg sources + if frame.data[0] == 0xef { //nolint: gomnd // taken from tg sources continue } switch binary.LittleEndian.Uint32(frame.data[:4]) { - case 0x44414548, 0x54534f50, 0x20544547, 0x4954504f, 0xeeeeeeee: // nolint: gomnd // taken from tg sources + case 0x44414548, 0x54534f50, 0x20544547, 0x4954504f, 0xeeeeeeee: //nolint: gomnd // taken from tg sources continue } diff --git a/mtglib/internal/obfuscated2/server_handshake_fuzz_test.go b/mtglib/internal/obfuscated2/server_handshake_fuzz_test.go index d129f3779..33e0e0d8d 100644 --- a/mtglib/internal/obfuscated2/server_handshake_fuzz_test.go +++ b/mtglib/internal/obfuscated2/server_handshake_fuzz_test.go @@ -19,7 +19,7 @@ func FuzzServerSend(f *testing.F) { Once(). Run(func(args mock.Arguments) { message := make([]byte, len(data)) - handshakeData.decryptor.XORKeyStream(message, args.Get(0).([]byte)) // nolint: forcetypeassert + handshakeData.decryptor.XORKeyStream(message, args.Get(0).([]byte)) //nolint: forcetypeassert assert.Equal(t, message, data) }) @@ -45,7 +45,7 @@ func FuzzServerReceive(f *testing.F) { Run(func(args mock.Arguments) { message := make([]byte, len(data)) handshakeData.encryptor.XORKeyStream(message, data) - copy(args.Get(0).([]byte), message) // nolint: forcetypeassert + copy(args.Get(0).([]byte), message) //nolint: forcetypeassert }) n, err := handshakeData.proxyConn.Read(buffer) diff --git a/mtglib/internal/obfuscated2/server_handshake_test.go b/mtglib/internal/obfuscated2/server_handshake_test.go index 09943ae0b..b46f06c0f 100644 --- a/mtglib/internal/obfuscated2/server_handshake_test.go +++ b/mtglib/internal/obfuscated2/server_handshake_test.go @@ -30,7 +30,7 @@ func (suite *ServerHandshakeTestSuite) TestSendToTelegram() { Once(). Run(func(args mock.Arguments) { message := make([]byte, len(messageToTelegram)) - suite.data.decryptor.XORKeyStream(message, args.Get(0).([]byte)) // nolint: forcetypeassert + suite.data.decryptor.XORKeyStream(message, args.Get(0).([]byte)) //nolint: forcetypeassert suite.Equal(messageToTelegram, message) }) @@ -50,7 +50,7 @@ func (suite *ServerHandshakeTestSuite) TestRecieveFromTelegram() { Run(func(args mock.Arguments) { message := make([]byte, len(messageFromTelegram)) suite.data.encryptor.XORKeyStream(message, messageFromTelegram) - copy(args.Get(0).([]byte), message) // nolint: forcetypeassert + copy(args.Get(0).([]byte), message) //nolint: forcetypeassert }) n, err := suite.data.proxyConn.Read(buffer) diff --git a/mtglib/internal/relay/pools.go b/mtglib/internal/relay/pools.go index b8536811c..49ac7acad 100644 --- a/mtglib/internal/relay/pools.go +++ b/mtglib/internal/relay/pools.go @@ -11,7 +11,7 @@ var copyBufferPool = sync.Pool{ } func acquireCopyBuffer() *[]byte { - return copyBufferPool.Get().(*[]byte) // nolint: forcetypeassert + return copyBufferPool.Get().(*[]byte) //nolint: forcetypeassert } func releaseCopyBuffer(buf *[]byte) { diff --git a/mtglib/internal/relay/relay.go b/mtglib/internal/relay/relay.go index 0350373f5..79af09cc9 100644 --- a/mtglib/internal/relay/relay.go +++ b/mtglib/internal/relay/relay.go @@ -35,8 +35,8 @@ func Relay(ctx context.Context, log Logger, telegramConn, clientConn essentials. } func pump(log Logger, src, dst essentials.Conn, direction string) { - defer src.CloseRead() // nolint: errcheck - defer dst.CloseWrite() // nolint: errcheck + defer src.CloseRead() //nolint: errcheck + defer dst.CloseWrite() //nolint: errcheck copyBuffer := acquireCopyBuffer() defer releaseCopyBuffer(copyBuffer) diff --git a/mtglib/proxy.go b/mtglib/proxy.go index e8d3b4421..f6eee5348 100644 --- a/mtglib/proxy.go +++ b/mtglib/proxy.go @@ -44,8 +44,8 @@ func (p *Proxy) DomainFrontingAddress() string { return net.JoinHostPort(p.secret.Host, strconv.Itoa(p.domainFrontingPort)) } -// ServeConn serves a connection. We do not check IP blocklist and -// concurrency limit here. +// ServeConn serves a connection. We do not check IP blocklist and concurrency +// limit here. func (p *Proxy) ServeConn(conn essentials.Conn) { p.streamWaitGroup.Add(1) defer p.streamWaitGroup.Done() @@ -106,7 +106,7 @@ func (p *Proxy) Serve(listener net.Listener) error { } } - ipAddr := conn.RemoteAddr().(*net.TCPAddr).IP // nolint: forcetypeassert + ipAddr := conn.RemoteAddr().(*net.TCPAddr).IP //nolint: forcetypeassert logger := p.logger.BindStr("ip", ipAddr.String()) if !p.allowlist.Contains(ipAddr) { @@ -138,8 +138,8 @@ func (p *Proxy) Serve(listener net.Listener) error { } } -// Shutdown 'gracefully' shutdowns all connections. Please remember that -// it does not close an underlying listener. +// Shutdown 'gracefully' shutdowns all connections. Please remember that it +// does not close an underlying listener. func (p *Proxy) Shutdown() { p.ctxCancel() p.streamWaitGroup.Wait() @@ -253,7 +253,7 @@ func (p *Proxy) doTelegramCall(ctx *streamContext) error { p.eventStream.Send(ctx, NewEventConnectedToDC(ctx.streamID, - conn.RemoteAddr().(*net.TCPAddr).IP, // nolint: forcetypeassert + conn.RemoteAddr().(*net.TCPAddr).IP, //nolint: forcetypeassert ctx.dc), ) @@ -316,7 +316,7 @@ func NewProxy(opts ProxyOpts) (*Proxy, error) { pool, err := ants.NewPoolWithFunc(opts.getConcurrency(), func(arg interface{}) { - proxy.ServeConn(arg.(essentials.Conn)) // nolint: forcetypeassert + proxy.ServeConn(arg.(essentials.Conn)) //nolint: forcetypeassert }, ants.WithLogger(opts.getLogger("ants")), ants.WithNonblocking(true)) diff --git a/mtglib/proxy_opts.go b/mtglib/proxy_opts.go index c10463c23..deb3fb0bb 100644 --- a/mtglib/proxy_opts.go +++ b/mtglib/proxy_opts.go @@ -4,16 +4,16 @@ import "time" // ProxyOpts is a structure with settings to mtg proxy. // -// This is not required per se, but this is to shorten function -// signature and give an ability to conveniently provide default values. +// This is not required per se, but this is to shorten function signature and +// give an ability to conveniently provide default values. type ProxyOpts struct { // Secret defines a secret which should be used by a proxy. // // This is a mandatory setting. Secret Secret - // Network defines a network instance which should be used for all - // network communications made by proxies. + // Network defines a network instance which should be used for all network + // communications made by proxies. // // This is a mandatory setting. Network Network @@ -45,9 +45,8 @@ type ProxyOpts struct { // BufferSize is a size of the copy buffer in bytes. // - // Please remember that we multiply this number in 2, because when - // we relay between proxies, we have to create 2 intermediate - // buffers: to and from. + // Please remember that we multiply this number in 2, because when we relay + // between proxies, we have to create 2 intermediate buffers: to and from. // // This is an optional setting. // @@ -62,22 +61,20 @@ type ProxyOpts struct { // This is an optional setting. Concurrency uint - // IdleTimeout is a timeout for relay when we have to break a - // stream. + // IdleTimeout is a timeout for relay when we have to break a stream. // - // This is a timeout for any activity. So, if we have any message - // which will pass to either direction, a timer is reset. If we have - // no any reads or writes for this timeout, a connection will be - // aborted. + // This is a timeout for any activity. So, if we have any message which will + // pass to either direction, a timer is reset. If we have no any reads or + // writes for this timeout, a connection will be aborted. // // This is an optional setting. IdleTimeout time.Duration - // TolerateTimeSkewness is a time boundary that defines a time - // range where faketls timestamp is acceptable. + // TolerateTimeSkewness is a time boundary that defines a time range where + // faketls timestamp is acceptable. // - // This means that if if you got a timestamp X, now is Y, then - // if |X-Y| < TolerateTimeSkewness, then you accept a packet. + // This means that if if you got a timestamp X, now is Y, then if |X-Y| < + // TolerateTimeSkewness, then you accept a packet. // // This is an optional setting. TolerateTimeSkewness time.Duration @@ -88,30 +85,29 @@ type ProxyOpts struct { // This is an optional setting. PreferIP string - // DomainFrontingPort is a port we use to connect to a fronting - // domain. + // DomainFrontingPort is a port we use to connect to a fronting domain. // - // This is required because secret does not specify a port. It - // specifies a hostname only. + // This is required because secret does not specify a port. It specifies a + // hostname only. // // This is an optional setting. DomainFrontingPort uint // AllowFallbackOnUnknownDC defines how proxy behaves if unknown DC was - // requested. If this setting is set to false, then such connection - // will be rejected. Otherwise, proxy will chose any DC. + // requested. If this setting is set to false, then such connection will be + // rejected. Otherwise, proxy will chose any DC. // - // Telegram is designed in a way that any DC can serve any request, - // the problem is a latency. + // Telegram is designed in a way that any DC can serve any request, the + // problem is a latency. // // This is an optional setting. AllowFallbackOnUnknownDC bool - // UseTestDCs defines if we have to connect to production or to staging - // DCs of Telegram. + // UseTestDCs defines if we have to connect to production or to staging DCs of + // Telegram. // - // This is required if you use mtglib as an integration library for - // your Telegram-related projects. + // This is required if you use mtglib as an integration library for your + // Telegram-related projects. // // This is an optional setting. UseTestDCs bool diff --git a/mtglib/proxy_test.go b/mtglib/proxy_test.go index 480b0b38a..697b0d694 100644 --- a/mtglib/proxy_test.go +++ b/mtglib/proxy_test.go @@ -86,7 +86,7 @@ func (suite *ProxyTestSuite) SetupSuite() { suite.listener = listener - go suite.p.Serve(suite.listener) // nolint: errcheck + go suite.p.Serve(suite.listener) //nolint: errcheck } func (suite *ProxyTestSuite) TearDownSuite() { @@ -179,7 +179,7 @@ func (suite *ProxyTestSuite) TestHTTPSRequest() { addr := fmt.Sprintf("https://%s/headers", suite.ProxyAddress()) - resp, err := client.Get(addr) // nolint: noctx + resp, err := client.Get(addr) //nolint: noctx suite.NoError(err) defer resp.Body.Close() @@ -191,7 +191,7 @@ func (suite *ProxyTestSuite) TestHTTPSRequest() { jsonStruct := struct { Headers struct { - TraceID string `json:"X-Amzn-Trace-Id"` // nolint: tagliatelle + TraceID string `json:"X-Amzn-Trace-Id"` //nolint: tagliatelle } `json:"headers"` }{} @@ -221,7 +221,7 @@ func (suite *ProxyTestSuite) TestMakeRealRequest() { _, err := tg.NewClient(tgClient).HelpGetConfig(ctx) suite.NoError(err) - return err // nolint: wrapcheck + return err //nolint: wrapcheck })) } diff --git a/mtglib/secret.go b/mtglib/secret.go index eced18146..90d9e3819 100644 --- a/mtglib/secret.go +++ b/mtglib/secret.go @@ -17,28 +17,27 @@ var secretEmptyKey [SecretKeyLength]byte // "ee367a189aee18fa31c190054efd4a8e9573746f726167652e676f6f676c65617069732e636f6d". // Actually, this is a serialized datastructure of 2 parts: key and host. // -// ee367a189aee18fa31c190054efd4a8e9573746f726167652e676f6f676c65617069732e636f6d -// |-|-------------------------------|------------------------------------------- -// p key hostname +// ee367a189aee18fa31c190054efd4a8e9573746f726167652e676f6f676c65617069732e636f6d +// |-|-------------------------------|------------------------------------------- +// p key hostname // -// Serialized secret starts with 'ee'. Actually, in the past we also had -// 'dd' secrets and prefixless ones. But this is history. Currently, -// we do have only 'ee' secrets which mean faketls + protection from -// statistical attacks on a length. 'ee' is a byte 238 (0xee). +// Serialized secret starts with 'ee'. Actually, in the past we also had 'dd' +// secrets and prefixless ones. But this is history. Currently, we do have only +// 'ee' secrets which mean faketls + protection from statistical attacks on a +// length. 'ee' is a byte 238 (0xee). // -// After that, we have 16 bytes of the key. This is a random generated -// secret data of the proxy and this data is used to derive -// authentication schemas. These secrets are mixed into hmacs and sha256 -// checksums which are used to build AEAD ciphers for obfuscated2 -// protocol and ensure faketls handshake. +// After that, we have 16 bytes of the key. This is a random generated secret +// data of the proxy and this data is used to derive authentication schemas. +// These secrets are mixed into hmacs and sha256 checksums which are used to +// build AEAD ciphers for obfuscated2 protocol and ensure faketls handshake. // -// Host is a domain fronting hostname in latin1 (ASCII) encoding. This -// hostname should be used for SNI in faketls and MTG verifies it. Also, -// this is when mtg gets about a domain fronting hostname. +// Host is a domain fronting hostname in latin1 (ASCII) encoding. This hostname +// should be used for SNI in faketls and MTG verifies it. Also, this is when +// mtg gets about a domain fronting hostname. // -// Secrets can be serialized into 2 forms: hex and base64. If -// you decode both forms into bytes, you'll get the same byte array. -// Telegram clients nowadays accept all forms. +// Secrets can be serialized into 2 forms: hex and base64. If you decode both +// forms into bytes, you'll get the same byte array. Telegram clients nowadays +// accept all forms. type Secret struct { // Key is a set of bytes used for traffic authentication. Key [SecretKeyLength]byte @@ -75,7 +74,7 @@ func (s *Secret) Set(text string) error { return fmt.Errorf("incorrect secret format: %w", err) } - if len(decoded) < 2 { // nolint: gomnd // we need at least 1 byte here + if len(decoded) < 2 { //nolint: gomnd // we need at least 1 byte here return fmt.Errorf("secret is truncated, length=%d", len(decoded)) } diff --git a/mtglib/stream_context.go b/mtglib/stream_context.go index 81752f239..2031bd43f 100644 --- a/mtglib/stream_context.go +++ b/mtglib/stream_context.go @@ -29,7 +29,7 @@ func (s *streamContext) Done() <-chan struct{} { } func (s *streamContext) Err() error { - return s.ctx.Err() // nolint: wrapcheck + return s.ctx.Err() //nolint: wrapcheck } func (s *streamContext) Value(key interface{}) interface{} { @@ -49,7 +49,7 @@ func (s *streamContext) Close() { } func (s *streamContext) ClientIP() net.IP { - return s.clientConn.RemoteAddr().(*net.TCPAddr).IP // nolint: forcetypeassert + return s.clientConn.RemoteAddr().(*net.TCPAddr).IP //nolint: forcetypeassert } func newStreamContext(ctx context.Context, logger Logger, clientConn essentials.Conn) *streamContext { diff --git a/mtglib/stream_context_internal_test.go b/mtglib/stream_context_internal_test.go index 52b5d4a08..f9d5f4b79 100644 --- a/mtglib/stream_context_internal_test.go +++ b/mtglib/stream_context_internal_test.go @@ -24,7 +24,7 @@ func (suite *StreamContextTestSuite) SetupSuite() { func (suite *StreamContextTestSuite) SetupTest() { ctx, cancel := context.WithCancel(context.Background()) - ctx = context.WithValue(ctx, "key", "value") // nolint: golint, revive, staticcheck + ctx = context.WithValue(ctx, "key", "value") //nolint: golint, staticcheck suite.ctxCancel = cancel suite.connMock = &testlib.EssentialsConnMock{} diff --git a/network/circuit_breaker.go b/network/circuit_breaker.go index e5f2702c5..745b86f76 100644 --- a/network/circuit_breaker.go +++ b/network/circuit_breaker.go @@ -59,7 +59,7 @@ func (c *circuitBreakerDialer) doClosed(ctx context.Context, conn.Close() } - return nil, ctx.Err() // nolint: wrapcheck + return nil, ctx.Err() //nolint: wrapcheck case c.stateMutexChan <- true: defer func() { <-c.stateMutexChan @@ -78,7 +78,7 @@ func (c *circuitBreakerDialer) doClosed(ctx context.Context, c.switchState(circuitBreakerStateOpened) } - return conn, err // nolint: wrapcheck + return conn, err //nolint: wrapcheck } func (c *circuitBreakerDialer) doHalfOpened(ctx context.Context, @@ -96,7 +96,7 @@ func (c *circuitBreakerDialer) doHalfOpened(ctx context.Context, conn.Close() } - return nil, ctx.Err() // nolint: wrapcheck + return nil, ctx.Err() //nolint: wrapcheck case c.stateMutexChan <- true: defer func() { <-c.stateMutexChan @@ -104,7 +104,7 @@ func (c *circuitBreakerDialer) doHalfOpened(ctx context.Context, } if c.state != circuitBreakerStateHalfOpened { - return conn, err // nolint: wrapcheck + return conn, err //nolint: wrapcheck } if err == nil { @@ -113,7 +113,7 @@ func (c *circuitBreakerDialer) doHalfOpened(ctx context.Context, c.switchState(circuitBreakerStateOpened) } - return conn, err // nolint: wrapcheck + return conn, err //nolint: wrapcheck } func (c *circuitBreakerDialer) switchState(state uint32) { diff --git a/network/circuit_breaker_internal_test.go b/network/circuit_breaker_internal_test.go index d300d684a..16a844337 100644 --- a/network/circuit_breaker_internal_test.go +++ b/network/circuit_breaker_internal_test.go @@ -110,10 +110,10 @@ func (suite *CircuitBreakerTestSuite) TestHalfOpen() { Port: 80, }) - suite.d.DialContext(suite.ctx, "tcp", "127.0.0.1") // nolint: errcheck - suite.d.DialContext(suite.ctx, "tcp", "127.0.0.1") // nolint: errcheck - suite.d.DialContext(suite.ctx, "tcp", "127.0.0.1") // nolint: errcheck - suite.d.DialContext(suite.ctx, "tcp", "127.0.0.1") // nolint: errcheck + suite.d.DialContext(suite.ctx, "tcp", "127.0.0.1") //nolint: errcheck + suite.d.DialContext(suite.ctx, "tcp", "127.0.0.1") //nolint: errcheck + suite.d.DialContext(suite.ctx, "tcp", "127.0.0.1") //nolint: errcheck + suite.d.DialContext(suite.ctx, "tcp", "127.0.0.1") //nolint: errcheck time.Sleep(500 * time.Millisecond) diff --git a/network/default.go b/network/default.go index e2a5ff0ab..16c39697d 100644 --- a/network/default.go +++ b/network/default.go @@ -19,7 +19,7 @@ func (d *defaultDialer) Dial(network, address string) (essentials.Conn, error) { func (d *defaultDialer) DialContext(ctx context.Context, network, address string) (essentials.Conn, error) { switch network { - case "tcp", "tcp4", "tcp6": // nolint: goconst + case "tcp", "tcp4", "tcp6": //nolint: goconst default: return nil, fmt.Errorf("unsupported network %s", network) } @@ -36,7 +36,7 @@ func (d *defaultDialer) DialContext(ctx context.Context, network, address string return nil, fmt.Errorf("cannot set socket options: %w", err) } - return conn.(essentials.Conn), nil // nolint: forcetypeassert + return conn.(essentials.Conn), nil //nolint: forcetypeassert } // NewDefaultDialer build a new dialer which dials bypassing proxies diff --git a/network/default_test.go b/network/default_test.go index 5a3802647..7151a5652 100644 --- a/network/default_test.go +++ b/network/default_test.go @@ -57,7 +57,7 @@ func (suite *DefaultDialerTestSuite) TestConnectOk() { func (suite *DefaultDialerTestSuite) TestHTTPRequest() { httpClient := suite.MakeHTTPClient(suite.d) - resp, err := httpClient.Get(suite.MakeURL("/get")) // nolint: noctx + resp, err := httpClient.Get(suite.MakeURL("/get")) //nolint: noctx if err == nil { defer resp.Body.Close() } diff --git a/network/dns_resolver.go b/network/dns_resolver.go index 424c7ae70..a731e4ab9 100644 --- a/network/dns_resolver.go +++ b/network/dns_resolver.go @@ -85,13 +85,13 @@ func (d *dnsResolver) LookupAAAA(hostname string) []string { return ips } -func newDNSResolver(hostname string, httpClient *http.Client) (ret *dnsResolver) { +func newDNSResolver(hostname string, httpClient *http.Client) *dnsResolver { if net.ParseIP(hostname).To4() == nil { // the hostname is an IPv6 address hostname = fmt.Sprintf("[%s]", hostname) } - ret = &dnsResolver{ + return &dnsResolver{ resolver: doh.Resolver{ Host: hostname, Class: doh.IN, @@ -99,6 +99,4 @@ func newDNSResolver(hostname string, httpClient *http.Client) (ret *dnsResolver) }, cache: map[string]dnsResolverCacheEntry{}, } - - return } diff --git a/network/init.go b/network/init.go index a1426b3ad..52831c25e 100644 --- a/network/init.go +++ b/network/init.go @@ -1,20 +1,16 @@ // Network contains a default implementation of the network. // -// Please see mtglib.Network interface to get some basic idea behind -// this abstraction. +// Please see [mtglib.Network] interface to get some basic idea behind this +// abstraction. // // Some notable feature of this implementation: // -// 1. It detaches dialer from a network. Dialer is something which -// implements a real dialer and network completes it with more higher -// level details. -// -// 2. It uses only TCP connections. Even for DNS it uses DNS-Over-HTTPS -// -// 3. It has some simple implementation of DNS cache which is good -// enough for our purpose. -// -// 4. It sets uses SO_REUSEPORT port if applicable. +// 1. It detaches dialer from a network. Dialer is something which implements a +// real dialer and network completes it with more higher level details. +// 2. It uses only TCP connections. Even for DNS it uses DNS-Over-HTTPS +// 3. It has some simple implementation of DNS cache which is good enough for +// our purpose. +// 4. It sets uses SO_REUSEPORT port if applicable. package network import ( @@ -26,53 +22,47 @@ import ( ) const ( - // DefaultTimeout is a default timeout for establishing TCP - // connection. + // DefaultTimeout is a default timeout for establishing TCP connection. DefaultTimeout = 10 * time.Second - // DefaultHTTPTimeout defines a default timeout for making HTTP - // request. + // DefaultHTTPTimeout defines a default timeout for making HTTP request. DefaultHTTPTimeout = 10 * time.Second // Deprecated: // - // DefaultBufferSize defines a TCP buffer size. Both read and write, so - // for real size, please multiply this number by 2. + // DefaultBufferSize defines a TCP buffer size. Both read and write, so for + // real size, please multiply this number by 2. DefaultBufferSize = 16 * 1024 // 16 kib - // DefaultTCPKeepAlivePeriod defines a time period between 2 - // consequitive probes. + // DefaultTCPKeepAlivePeriod defines a time period between 2 consequitive + // probes. DefaultTCPKeepAlivePeriod = 10 * time.Second - // ProxyDialerOpenThreshold is used for load balancing SOCKS5 dialer - // only. + // ProxyDialerOpenThreshold is used for load balancing SOCKS5 dialer only. // - // This dialer uses circuit breaker with of 3 stages: OPEN, - // HALF_OPEN and CLOSED. If state is CLOSED, all requests go in - // a normal mode. If you get more that ProxyDialerOpenThreshold - // errors, circuit breaker goes into OPEN mode. + // This dialer uses circuit breaker with of 3 stages: OPEN, HALF_OPEN and + // CLOSED. If state is CLOSED, all requests go in a normal mode. If you get + // more that ProxyDialerOpenThreshold errors, circuit breaker goes into OPEN + // mode. // - // When circuit breaker is in OPEN mode, it forbids all request to - // a given proxy. But after ProxyDialerHalfOpenTimeout it gives a - // second chance and opens an access for a SINGLE request. If this - // request success, then circuit breaker closes, otherwise opens - // again. + // When circuit breaker is in OPEN mode, it forbids all request to a given + // proxy. But after ProxyDialerHalfOpenTimeout it gives a second chance and + // opens an access for a SINGLE request. If this request success, then circuit + // breaker closes, otherwise opens again. // // When circuit breaker is closed, it clears an error states each // ProxyDialerResetFailuresTimeout. ProxyDialerOpenThreshold = 5 - // ProxyDialerHalfOpenTimeout defines a halfopen timeout for circuit - // breaker. + // ProxyDialerHalfOpenTimeout defines a halfopen timeout for circuit breaker. ProxyDialerHalfOpenTimeout = time.Minute - // ProxyDialerResetFailuresTimeout defines a timeout for resetting a - // failure. + // ProxyDialerResetFailuresTimeout defines a timeout for resetting a failure. ProxyDialerResetFailuresTimeout = 10 * time.Second - // DefaultDOHHostname defines a default IP address for DOH host. - // Since mtg is simple, please pass IP address here. We do not - // have bootstrap servers here embedded. + // DefaultDOHHostname defines a default IP address for DOH host. Since mtg is + // simple, please pass IP address here. We do not have bootstrap servers here + // embedded. DefaultDOHHostname = "9.9.9.9" // DNSTimeout defines a timeout for DNS queries. @@ -84,12 +74,12 @@ const ( ) var ( - // ErrCircuitBreakerOpened is returned when proxy is being accessed - // but circuit breaker is opened. + // ErrCircuitBreakerOpened is returned when proxy is being accessed but + // circuit breaker is opened. ErrCircuitBreakerOpened = errors.New("circuit breaker is opened") - // ErrCannotDialWithAllProxies is returned when load balancing - // client is trying to access proxies but all of them are failed. + // ErrCannotDialWithAllProxies is returned when load balancing client is + // trying to access proxies but all of them are failed. ErrCannotDialWithAllProxies = errors.New("cannot dial with all proxies") ) diff --git a/network/init_internal_test.go b/network/init_internal_test.go index 0b6e4a9df..2a6e595d0 100644 --- a/network/init_internal_test.go +++ b/network/init_internal_test.go @@ -14,11 +14,11 @@ type DialerMock struct { func (d *DialerMock) Dial(network, address string) (essentials.Conn, error) { args := d.Called(network, address) - return args.Get(0).(essentials.Conn), args.Error(1) // nolint: wrapcheck, forcetypeassert + return args.Get(0).(essentials.Conn), args.Error(1) //nolint: wrapcheck, forcetypeassert } func (d *DialerMock) DialContext(ctx context.Context, network, address string) (essentials.Conn, error) { args := d.Called(ctx, network, address) - return args.Get(0).(essentials.Conn), args.Error(1) // nolint: wrapcheck, forcetypeassert + return args.Get(0).(essentials.Conn), args.Error(1) //nolint: wrapcheck, forcetypeassert } diff --git a/network/init_test.go b/network/init_test.go index c5e265129..5cd57d7d6 100644 --- a/network/init_test.go +++ b/network/init_test.go @@ -22,13 +22,13 @@ type DialerMock struct { func (d *DialerMock) Dial(network, address string) (essentials.Conn, error) { args := d.Called(network, address) - return args.Get(0).(essentials.Conn), args.Error(1) // nolint: wrapcheck, forcetypeassert + return args.Get(0).(essentials.Conn), args.Error(1) //nolint: wrapcheck, forcetypeassert } func (d *DialerMock) DialContext(ctx context.Context, network, address string) (essentials.Conn, error) { args := d.Called(ctx, network, address) - return args.Get(0).(essentials.Conn), args.Error(1) // nolint: wrapcheck, forcetypeassert + return args.Get(0).(essentials.Conn), args.Error(1) //nolint: wrapcheck, forcetypeassert } type HTTPServerTestSuite struct { @@ -55,7 +55,7 @@ func (suite *HTTPServerTestSuite) MakeHTTPClient(dialer network.Dialer) *http.Cl return &http.Client{ Transport: &http.Transport{ DialContext: func(ctx context.Context, network, address string) (net.Conn, error) { - return dialer.DialContext(ctx, network, address) // nolint: wrapcheck + return dialer.DialContext(ctx, network, address) //nolint: wrapcheck }, }, } @@ -74,7 +74,7 @@ func (suite *Socks5ServerTestSuite) SetupSuite() { }, }) - go suite.socks5Server.Serve(suite.socks5Listener) // nolint: errcheck + go suite.socks5Server.Serve(suite.socks5Listener) //nolint: errcheck } func (suite *Socks5ServerTestSuite) TearDownSuite() { diff --git a/network/load_balanced_socks5.go b/network/load_balanced_socks5.go index 37cbf28e8..f6d0a82bd 100644 --- a/network/load_balanced_socks5.go +++ b/network/load_balanced_socks5.go @@ -33,16 +33,14 @@ func (l loadBalancedSocks5Dialer) DialContext(ctx context.Context, network, addr return nil, ErrCannotDialWithAllProxies } -// NewLoadBalancedSocks5Dialer builds a new load balancing SOCKS5 -// dialer. +// NewLoadBalancedSocks5Dialer builds a new load balancing SOCKS5 dialer. // -// The main difference from one which is made by NewSocks5Dialer is that -// we actually have a list of these proxies. When dial is requested, -// any proxy is picked and used. If proxy fails for some reason, we try -// another one. +// The main difference from one which is made by NewSocks5Dialer is that we +// actually have a list of these proxies. When dial is requested, any proxy is +// picked and used. If proxy fails for some reason, we try another one. // -// So, it is mostly useful if you have some routes with proxies which -// are not always online or having buggy network. +// So, it is mostly useful if you have some routes with proxies which are not +// always online or having buggy network. func NewLoadBalancedSocks5Dialer(baseDialer Dialer, proxyURLs []*url.URL) (Dialer, error) { dialers := make([]Dialer, 0, len(proxyURLs)) diff --git a/network/load_balanced_socks5_test.go b/network/load_balanced_socks5_test.go index b6983c8b9..6000cba26 100644 --- a/network/load_balanced_socks5_test.go +++ b/network/load_balanced_socks5_test.go @@ -73,7 +73,7 @@ func (suite *LoadBalancedSocks5TestSuite) TestCannotDial() { } func (suite *LoadBalancedSocks5TestSuite) TestDialOk() { - resp, err := suite.httpClient.Get(suite.MakeURL("/get")) // nolint: noctx + resp, err := suite.httpClient.Get(suite.MakeURL("/get")) //nolint: noctx if err == nil { defer resp.Body.Close() } diff --git a/network/network.go b/network/network.go index 6aecd6ac9..3f68b112e 100644 --- a/network/network.go +++ b/network/network.go @@ -21,7 +21,7 @@ type networkHTTPTransport struct { func (n networkHTTPTransport) RoundTrip(req *http.Request) (*http.Response, error) { req.Header.Set("User-Agent", n.userAgent) - return n.next.RoundTrip(req) // nolint: wrapcheck + return n.next.RoundTrip(req) //nolint: wrapcheck } type network struct { @@ -118,8 +118,8 @@ func (n *network) dnsResolve(protocol, address string) ([]string, error) { return ips, nil } -// NewNetwork assembles an mtglib.Network compatible structure -// based on a dialer and given params. +// NewNetwork assembles an mtglib.Network compatible structure based on a +// dialer and given params. // // It brings simple DNS cache and DNS-Over-HTTPS when necessary. func NewNetwork(dialer Dialer, diff --git a/network/network_test.go b/network/network_test.go index 891c614f6..f099abaaa 100644 --- a/network/network_test.go +++ b/network/network_test.go @@ -31,7 +31,7 @@ func (suite *NetworkTestSuite) TestLocalHTTPRequest() { client := ntw.MakeHTTPClient(nil) - resp, err := client.Get(suite.httpServer.URL + "/headers") // nolint: noctx + resp, err := client.Get(suite.httpServer.URL + "/headers") //nolint: noctx suite.NoError(err) defer resp.Body.Close() @@ -42,7 +42,7 @@ func (suite *NetworkTestSuite) TestLocalHTTPRequest() { jsonStruct := struct { Headers struct { - UserAgent []string `json:"User-Agent"` // nolint: tagliatelle + UserAgent []string `json:"User-Agent"` //nolint: tagliatelle } `json:"headers"` }{} @@ -56,7 +56,7 @@ func (suite *NetworkTestSuite) TestRealHTTPRequest() { client := ntw.MakeHTTPClient(nil) - resp, err := client.Get("https://httpbin.org/headers") // nolint: noctx + resp, err := client.Get("https://httpbin.org/headers") //nolint: noctx suite.NoError(err) defer resp.Body.Close() @@ -67,7 +67,7 @@ func (suite *NetworkTestSuite) TestRealHTTPRequest() { jsonStruct := struct { Headers struct { - UserAgent string `json:"User-Agent"` // nolint: tagliatelle + UserAgent string `json:"User-Agent"` //nolint: tagliatelle } `json:"headers"` }{} diff --git a/network/proxy_dialer.go b/network/proxy_dialer.go index 941949979..9756677be 100644 --- a/network/proxy_dialer.go +++ b/network/proxy_dialer.go @@ -16,7 +16,7 @@ func newProxyDialer(baseDialer Dialer, proxyURL *url.URL) Dialer { ) if param := params.Get("open_threshold"); param != "" { - if intNum, err := strconv.ParseUint(param, 10, 32); err == nil { // nolint: gomnd + if intNum, err := strconv.ParseUint(param, 10, 32); err == nil { //nolint: gomnd openThreshold = uint32(intNum) } } diff --git a/network/proxy_dialer_internal_test.go b/network/proxy_dialer_internal_test.go index 8a3e3bbdf..07a6f7c3f 100644 --- a/network/proxy_dialer_internal_test.go +++ b/network/proxy_dialer_internal_test.go @@ -21,7 +21,7 @@ func (suite *ProxyDialerTestSuite) SetupSuite() { } func (suite *ProxyDialerTestSuite) TestSetupDefaults() { - d := newProxyDialer(&DialerMock{}, suite.u).(*circuitBreakerDialer) // nolint: forcetypeassert + d := newProxyDialer(&DialerMock{}, suite.u).(*circuitBreakerDialer) //nolint: forcetypeassert suite.EqualValues(ProxyDialerOpenThreshold, d.openThreshold) suite.EqualValues(ProxyDialerHalfOpenTimeout, d.halfOpenTimeout) suite.EqualValues(ProxyDialerResetFailuresTimeout, d.resetFailuresTimeout) @@ -34,7 +34,7 @@ func (suite *ProxyDialerTestSuite) TestSetupValuesAllOk() { query.Set("half_open_timeout", "2s") suite.u.RawQuery = query.Encode() - d := newProxyDialer(&DialerMock{}, suite.u).(*circuitBreakerDialer) // nolint: forcetypeassert + d := newProxyDialer(&DialerMock{}, suite.u).(*circuitBreakerDialer) //nolint: forcetypeassert suite.EqualValues(30, d.openThreshold) suite.EqualValues(2*time.Second, d.halfOpenTimeout) suite.EqualValues(time.Second, d.resetFailuresTimeout) @@ -50,7 +50,7 @@ func (suite *ProxyDialerTestSuite) TestOpenThreshold() { query.Set("open_threshold", param) suite.u.RawQuery = query.Encode() - d := newProxyDialer(&DialerMock{}, suite.u).(*circuitBreakerDialer) // nolint: forcetypeassert + d := newProxyDialer(&DialerMock{}, suite.u).(*circuitBreakerDialer) //nolint: forcetypeassert assert.EqualValues(t, ProxyDialerOpenThreshold, d.openThreshold) }) } @@ -66,7 +66,7 @@ func (suite *ProxyDialerTestSuite) TestHalfOpenTimeout() { query.Set("half_open_timeout", param) suite.u.RawQuery = query.Encode() - d := newProxyDialer(&DialerMock{}, suite.u).(*circuitBreakerDialer) // nolint: forcetypeassert + d := newProxyDialer(&DialerMock{}, suite.u).(*circuitBreakerDialer) //nolint: forcetypeassert assert.EqualValues(t, ProxyDialerHalfOpenTimeout, d.halfOpenTimeout) }) } @@ -82,7 +82,7 @@ func (suite *ProxyDialerTestSuite) TestResetFailuresTimeout() { query.Set("reset_failures_timeout", param) suite.u.RawQuery = query.Encode() - d := newProxyDialer(&DialerMock{}, suite.u).(*circuitBreakerDialer) // nolint: forcetypeassert + d := newProxyDialer(&DialerMock{}, suite.u).(*circuitBreakerDialer) //nolint: forcetypeassert assert.EqualValues(t, ProxyDialerHalfOpenTimeout, d.halfOpenTimeout) }) } diff --git a/network/sockopts.go b/network/sockopts.go index 938155b5d..22ec16b35 100644 --- a/network/sockopts.go +++ b/network/sockopts.go @@ -10,13 +10,13 @@ import ( // // bufferSize setting is deprecated and ignored. func SetClientSocketOptions(conn net.Conn, bufferSize int) error { - return setCommonSocketOptions(conn.(*net.TCPConn)) // nolint: forcetypeassert + return setCommonSocketOptions(conn.(*net.TCPConn)) //nolint: forcetypeassert } // SetServerSocketOptions tunes a TCP socket that represents a connection to // remote server like Telegram or fronting domain (but not end user). func SetServerSocketOptions(conn net.Conn, bufferSize int) error { - return setCommonSocketOptions(conn.(*net.TCPConn)) // nolint: forcetypeassert + return setCommonSocketOptions(conn.(*net.TCPConn)) //nolint: forcetypeassert } func setCommonSocketOptions(conn *net.TCPConn) error { diff --git a/network/sockopts_unix.go b/network/sockopts_unix.go index b7c5f10f0..65a692da0 100644 --- a/network/sockopts_unix.go +++ b/network/sockopts_unix.go @@ -13,15 +13,15 @@ import ( func setSocketReuseAddrPort(conn syscall.RawConn) error { var err error - conn.Control(func(fd uintptr) { // nolint: errcheck - err = unix.SetsockoptInt(int(fd), unix.SOL_SOCKET, unix.SO_REUSEADDR, 1) + conn.Control(func(fd uintptr) { //nolint: errcheck + err = unix.SetsockoptInt(int(fd), unix.SOL_SOCKET, unix.SO_REUSEADDR, 1) //nolint: nosnakecase if err != nil { err = fmt.Errorf("cannot set SO_REUSEADDR: %w", err) return } - err = unix.SetsockoptInt(int(fd), unix.SOL_SOCKET, unix.SO_REUSEPORT, 1) + err = unix.SetsockoptInt(int(fd), unix.SOL_SOCKET, unix.SO_REUSEPORT, 1) //nolint: nosnakecase if err != nil { err = fmt.Errorf("cannot set SO_REUSEPORT: %w", err) } diff --git a/network/socks5.go b/network/socks5.go index 459f64bc0..9d6ae2ca3 100644 --- a/network/socks5.go +++ b/network/socks5.go @@ -136,10 +136,10 @@ func (s socks5Dialer) connect(conn io.ReadWriter, address string) error { return nil } -// NewSocks5Dialer build a new dialer from a given one (so, in theory -// you can chain here). Proxy parameters are passed with URI in a form of: +// NewSocks5Dialer build a new dialer from a given one (so, in theory you can +// chain here). Proxy parameters are passed with URI in a form of: // -// socks5://[user:[password]]@host:port +// socks5://[user:[password]]@host:port func NewSocks5Dialer(baseDialer Dialer, proxyURL *url.URL) (Dialer, error) { if _, _, err := net.SplitHostPort(proxyURL.Host); err != nil { return nil, fmt.Errorf("incorrect url %s", proxyURL.Redacted()) diff --git a/network/socks5_test.go b/network/socks5_test.go index 5cb56c384..0c4ed0729 100644 --- a/network/socks5_test.go +++ b/network/socks5_test.go @@ -33,7 +33,7 @@ func (suite *Socks5TestSuite) TestRequestFailed() { dialer, _ := network.NewSocks5Dialer(suite.d, proxyURL) httpClient := suite.MakeHTTPClient(dialer) - resp, err := httpClient.Get(suite.MakeURL("/get")) // nolint: noctx + resp, err := httpClient.Get(suite.MakeURL("/get")) //nolint: noctx if err == nil { defer resp.Body.Close() } @@ -46,7 +46,7 @@ func (suite *Socks5TestSuite) TestRequestOk() { dialer, _ := network.NewSocks5Dialer(suite.d, proxyURL) httpClient := suite.MakeHTTPClient(dialer) - resp, err := httpClient.Get(suite.MakeURL("/get")) // nolint: noctx + resp, err := httpClient.Get(suite.MakeURL("/get")) //nolint: noctx if err == nil { defer resp.Body.Close() } diff --git a/stats/init.go b/stats/init.go index 1bf33dfb6..a2236e77f 100644 --- a/stats/init.go +++ b/stats/init.go @@ -1,4 +1,4 @@ -// Stats package has implementations of events.Observers for different +// Stats package has implementations of [events.Observer] for different // monitoring systems. // // Observer is a consumer of events produced by mtg. Consumers, defined diff --git a/stats/pools.go b/stats/pools.go index 6c81d20b8..a8c962197 100644 --- a/stats/pools.go +++ b/stats/pools.go @@ -11,7 +11,7 @@ var streamInfoPool = sync.Pool{ } func acquireStreamInfo() *streamInfo { - return streamInfoPool.Get().(*streamInfo) // nolint: forcetypeassert + return streamInfoPool.Get().(*streamInfo) //nolint: forcetypeassert } func releaseStreamInfo(info *streamInfo) { diff --git a/stats/prometheus.go b/stats/prometheus.go index eec64b5ca..920332c4d 100644 --- a/stats/prometheus.go +++ b/stats/prometheus.go @@ -139,12 +139,11 @@ func (p prometheusProcessor) Shutdown() { } } -// PrometheusFactory is a factory of events.Observers which collect +// PrometheusFactory is a factory of [events.Observer] which collect // information in a format suitable for Prometheus. // -// This factory can also serve on a given listener. In that case it -// starts HTTP server with a single endpoint - a Prometheus-compatible -// scrape output. +// This factory can also serve on a given listener. In that case it starts HTTP +// server with a single endpoint - a Prometheus-compatible scrape output. type PrometheusFactory struct { httpServer *http.Server @@ -172,18 +171,18 @@ func (p *PrometheusFactory) Make() events.Observer { // Serve starts an HTTP server on a given listener. func (p *PrometheusFactory) Serve(listener net.Listener) error { - return p.httpServer.Serve(listener) // nolint: wrapcheck + return p.httpServer.Serve(listener) //nolint: wrapcheck } // Close stops a factory. Please pay attention that underlying listener // is not closed. func (p *PrometheusFactory) Close() error { - return p.httpServer.Shutdown(context.Background()) // nolint: wrapcheck + return p.httpServer.Shutdown(context.Background()) //nolint: wrapcheck } // NewPrometheus builds an events.ObserverFactory which can serve HTTP // endpoint with Prometheus scrape data. -func NewPrometheus(metricPrefix, httpPath string) *PrometheusFactory { // nolint: funlen +func NewPrometheus(metricPrefix, httpPath string) *PrometheusFactory { //nolint: funlen registry := prometheus.NewPedanticRegistry() httpHandler := promhttp.HandlerFor(registry, promhttp.HandlerOpts{ EnableOpenMetrics: true, diff --git a/stats/prometheus_test.go b/stats/prometheus_test.go index 9adcb1b10..66de6f0b3 100644 --- a/stats/prometheus_test.go +++ b/stats/prometheus_test.go @@ -25,16 +25,16 @@ type PrometheusTestSuite struct { func (suite *PrometheusTestSuite) Get() (string, error) { addr := fmt.Sprintf("http://%s/", suite.httpListener.Addr().String()) - resp, err := http.Get(addr) // nolint: noctx + resp, err := http.Get(addr) //nolint: noctx if err != nil { - return "", err // nolint: wrapcheck + return "", err //nolint: wrapcheck } defer resp.Body.Close() data, err := io.ReadAll(resp.Body) if err != nil { - return "", err // nolint: wrapcheck + return "", err //nolint: wrapcheck } return string(data), nil @@ -45,7 +45,7 @@ func (suite *PrometheusTestSuite) SetupTest() { suite.factory = stats.NewPrometheus("mtg", "/") suite.prometheus = suite.factory.Make() - go suite.factory.Serve(suite.httpListener) // nolint: errcheck + go suite.factory.Serve(suite.httpListener) //nolint: errcheck } func (suite *PrometheusTestSuite) TearDownTest() { diff --git a/stats/statsd.go b/stats/statsd.go index 1c6a99f97..64b51172b 100644 --- a/stats/statsd.go +++ b/stats/statsd.go @@ -147,20 +147,20 @@ func (s statsdProcessor) Shutdown() { } } -// StatsdFactory is a factory of events.Observers which dumps -// information to statsd. +// StatsdFactory is a factory of [events.Observer] which dumps information to +// statsd. // -// Please beware that we support ONLY UDP endpoints there. And this -// factory won't use mtglib.Network so it won't use a proxy if you -// provide any. If you need it, I would recommend starting a local -// statsd and route metrics further by features of the chosen server. +// Please beware that we support ONLY UDP endpoints there. And this factory +// won't use [mtglib.Network] so it won't use a proxy if you provide any. If +// you need it, I would recommend starting a local statsd and route metrics +// further by features of the chosen server. type StatsdFactory struct { client *statsd.Client } // Close stops sending requests to statsd. func (s StatsdFactory) Close() error { - return s.client.Close() // nolint: wrapcheck + return s.client.Close() //nolint: wrapcheck } // Make build a new observer. @@ -171,8 +171,7 @@ func (s StatsdFactory) Make() events.Observer { } } -// NewStatsd builds an events.ObserverFactory that sends events -// to statsd. +// NewStatsd builds an [events.ObserverFactory] that sends events to statsd. // // Valid tagFormats are 'datadog', 'influxdb' and 'graphite'. func NewStatsd(address string, log logger.StdLikeLogger, diff --git a/stats/statsd_test.go b/stats/statsd_test.go index 6107f3c61..51c2613d0 100644 --- a/stats/statsd_test.go +++ b/stats/statsd_test.go @@ -30,7 +30,7 @@ func (s *statsdFakeServer) Addr() string { func (s *statsdFakeServer) Close() error { if s.conn != nil { - return s.conn.Close() // nolint: wrapcheck + return s.conn.Close() //nolint: wrapcheck } return nil