REPOSITORY / ScuroNeko/mtg

Compare commits

DIFF REPOSITORY

Compare commits

...
32 Commits
Author SHA1 Message Date
9seconds 4814b0fcc1 Merge remote-tracking branch 'origin/master' into stable 2021-10-05 11:33:57 +03:00
9seconds 3ce549bb16 Update dependencies 2021-10-05 11:16:57 +03:00
Sergey ArkhipovandGitHub 5c636a68dc Merge pull request #217 from 9seconds/golangcilint-1.42.1
golangci-lint 1.42.1
2021-10-05 11:10:08 +03:00
9seconds 9f6f906786 Add go:build comments 2021-10-05 10:51:41 +03:00
9seconds eb32766c1f Update to golangci-lint 1.42.1 2021-10-05 10:51:15 +03:00
9seconds 787d72cf52 Use install, not go get 2021-10-05 10:50:58 +03:00
Sergey ArkhipovandGitHub ce8f1ebb6c Merge pull request #216 from 9seconds/configure-fallback-dc
Add configuration option allow-fallback-on-unknown-dc
2021-10-04 15:09:47 +03:00
9seconds cd29f3e20b Add configuration option allow-fallback-on-unknown-dc 2021-10-04 14:42:26 +03:00
Sergey ArkhipovandGitHub 3e105f2beb Merge pull request #215 from 9seconds/9seconds-patch-1
Update Actions permissions
2021-10-04 14:31:58 +03:00
Sergey ArkhipovandGitHub 6bbdd99e7f Update codeql-analysis.yml 2021-10-04 14:18:50 +03:00
Sergey Arkhipovand9seconds 894c68019e Update permissions in files 2021-10-04 14:16:29 +03:00
Sergey ArkhipovandGitHub 98f18fc22b Merge pull request #214 from 9seconds/log-json
Add new BindJSON method to a logger
2021-10-04 12:22:43 +03:00
Sergey ArkhipovandGitHub 01b739aa7c Merge pull request #213 from 9seconds/fix-windows-build
Fix windows build
2021-10-04 10:20:13 +03:00
9seconds dbaa743e03 Add new BindJSON method to a logger 2021-10-04 10:10:14 +03:00
9seconds d1e5f9d145 Fix windows build 2021-10-04 09:46:49 +03:00
9seconds 686f177ab9 Correct error for non-getting of underlying connection 2021-10-04 09:34:10 +03:00
Sergey ArkhipovandGitHub 706aef8ca1 Merge pull request #211 from 9seconds/docker-build-timelimit 2021-09-24 22:00:06 +03:00
9seconds 14dfb9506a Bump docker build timeout to 20 minutes 2021-09-24 16:59:11 +03:00
Sergey ArkhipovandGitHub f742066c54 Merge pull request #210 from 9seconds/fallback-to-random-dc
Fallback to another DC if given is unknown
2021-09-24 12:18:05 +03:00
9seconds fbe4d32590 Fallback to another DC if given is unknown 2021-09-24 11:47:35 +03:00
9seconds d0f18be91d Merge remote-tracking branch 'origin/stable' 2021-08-30 15:50:27 +03:00
9seconds 929b73e2eb Merge remote-tracking branch 'origin/master' into stable 2021-08-30 15:50:15 +03:00
9seconds 6b7364238a Update dependencies 2021-08-30 14:51:56 +03:00
Sergey ArkhipovandGitHub 866906e770 Merge pull request #206 from 9seconds/golang-1.17-v2
Upgrade to golang 1.17
2021-08-30 14:39:28 +03:00
9seconds b3c8c4a47d Upgrade to golang 1.17 2021-08-30 11:53:31 +03:00
Sergey ArkhipovandGitHub fbc7499cda Merge pull request #203 from 9seconds/simplify-time-randomization
Simplify TCP relay time randomization
2021-08-30 10:58:47 +03:00
9seconds ca5800cf60 Simplify tcp relay time randomization 2021-08-30 10:47:36 +03:00
Sergey ArkhipovandGitHub 00bb7be900 Merge pull request #202 from 9seconds/golangcilint-1.42 2021-08-28 04:33:21 +03:00
9seconds e8c70603f7 Upgrade golangci-lint for 1.42 2021-08-27 18:05:51 +03:00
Sergey ArkhipovandGitHub 9d72904508 Merge pull request #200 from 9seconds/aggressive-tcp-relay
Change algorithm of TCP relaying
2021-08-27 17:50:33 +03:00
9seconds 456ed5b051 Change algorithm of TCP relaying 2021-08-27 17:22:36 +03:00
9seconds 4b7be8c565 Merge remote-tracking branch 'origin/stable' 2021-07-31 21:05:56 +03:00
41 changed files with 553 additions and 539 deletions
+16 -3
View File
@@ -2,6 +2,18 @@
name: CI name: CI
permissions:
actions: read
checks: read
contents: read
deployments: read
issues: read
discussions: read
pull-requests: read
repository-projects: read
security-events: read
statuses: read
on: on:
push: push:
tags: tags:
@@ -30,7 +42,8 @@ jobs:
strategy: strategy:
matrix: matrix:
go_version: go_version:
- ^1.16 - ~1.16
- ^1.17
steps: steps:
- name: Checkout - name: Checkout
uses: actions/checkout@v2 uses: actions/checkout@v2
@@ -70,12 +83,12 @@ jobs:
- name: Run linter - name: Run linter
uses: golangci/golangci-lint-action@v2 uses: golangci/golangci-lint-action@v2
with: with:
version: v1.41.1 version: v1.42.1
docker: docker:
name: Docker name: Docker
runs-on: ubuntu-latest runs-on: ubuntu-latest
timeout-minutes: 15 timeout-minutes: 20
steps: steps:
- name: Checkout - name: Checkout
uses: actions/checkout@v2 uses: actions/checkout@v2
+8
View File
@@ -11,6 +11,14 @@
# #
name: "CodeQL" name: "CodeQL"
# https://docs.github.com/en/actions/reference/workflow-syntax-for-github-actions#permissions
# https://github.com/github/codeql-action/issues/572
permissions:
actions: read
contents: read
pull-requests: read
security-events: write
on: on:
push: push:
branches: branches:
+1 -1
View File
@@ -1,7 +1,7 @@
############################################################################### ###############################################################################
# BUILD STAGE # BUILD STAGE
FROM golang:1.16-alpine AS build FROM golang:1.17-alpine AS build
RUN set -x \ RUN set -x \
&& apk --no-cache --update add \ && apk --no-cache --update add \
+4 -4
View File
@@ -2,7 +2,7 @@ ROOT_DIR := $(shell dirname $(realpath $(lastword $(MAKEFILE_LIST))))
IMAGE_NAME := mtg IMAGE_NAME := mtg
APP_NAME := $(IMAGE_NAME) APP_NAME := $(IMAGE_NAME)
GOLANGCI_LINT_VERSION := v1.41.1 GOLANGCI_LINT_VERSION := v1.42.1
VERSION_GO := $(shell go version) VERSION_GO := $(shell go version)
VERSION_DATE := $(shell date -Ru) VERSION_DATE := $(shell date -Ru)
@@ -83,15 +83,15 @@ install-tools-lint: .bin
.PHONY: install-tools-godoc .PHONY: install-tools-godoc
install-tools-godoc: .bin install-tools-godoc: .bin
@$(GOTOOL) go get -u golang.org/x/tools/cmd/godoc @$(GOTOOL) go install golang.org/x/tools/cmd/godoc@latest
.PHONY: install-tools-gofumpt .PHONY: install-tools-gofumpt
install-tools-gofumpt: .bin install-tools-gofumpt: .bin
@$(GOTOOL) go get -u mvdan.cc/gofumpt @$(GOTOOL) go install mvdan.cc/gofumpt@latest
.PHONY: goreleaser .PHONY: goreleaser
install-tools-goreleaser: .bin install-tools-goreleaser: .bin
@$(GOTOOL) go get -u github.com/goreleaser/goreleaser @$(GOTOOL) go install github.com/goreleaser/goreleaser@latest
.PHONY: update-deps .PHONY: update-deps
update-deps: update-deps:
+13
View File
@@ -56,6 +56,19 @@ domain-fronting-port = 443
# time range of this parameter. # time range of this parameter.
tolerate-time-skewness = "5s" tolerate-time-skewness = "5s"
# Telegram has a concept of DC. You can think about DC as a number of a cluster
# with a certain purpose. Some clusters serve media, some - messages, some rule
# channels and so on. But sometimes unknown DC number is requested by client.
# It could be a bug or some global reconfiguration of the Telegram.
#
# By default, proxy rejects such requests. But it is also possible to fallback
# this request to any DC. Telegram works in a way that any DC is able to serve
# any request but sacrificing a latency.
#
# If this setting is disabled (default), mtg will reject a connection.
# Otherwise, chose a new DC.
allow-fallback-on-unknown-dc = false
# network defines different network-related settings # network defines different network-related settings
[network] [network]
# please be aware that mtg needs to do some external requests. For # please be aware that mtg needs to do some external requests. For
+29 -11
View File
@@ -1,32 +1,50 @@
module github.com/9seconds/mtg/v2 module github.com/9seconds/mtg/v2
go 1.16 go 1.17
require ( require (
github.com/OneOfOne/xxhash v1.2.8 github.com/OneOfOne/xxhash v1.2.8
github.com/alecthomas/kong v0.2.17 github.com/alecthomas/kong v0.2.17
github.com/alecthomas/units v0.0.0-20210208195552-ff826a37aa15 github.com/alecthomas/units v0.0.0-20210927113745-59d0afb8317a
github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5 github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5
github.com/babolivier/go-doh-client v0.0.0-20201028162107-a76cff4cb8b6 github.com/babolivier/go-doh-client v0.0.0-20201028162107-a76cff4cb8b6
github.com/d4l3k/messagediff v1.2.1 // indirect github.com/d4l3k/messagediff v1.2.1 // indirect
github.com/golang/protobuf v1.5.2 // indirect github.com/golang/protobuf v1.5.2 // indirect
github.com/gotd/td v0.34.0 github.com/gotd/td v0.34.0
github.com/jarcoal/httpmock v1.0.8 github.com/jarcoal/httpmock v1.0.8
github.com/kentik/patricia v0.0.0-20201202224819-f9447a6e25f1 github.com/kentik/patricia v0.0.0-20210909164817-21603333b70e
github.com/libp2p/go-reuseport v0.0.2
github.com/mccutchen/go-httpbin v1.1.1 github.com/mccutchen/go-httpbin v1.1.1
github.com/panjf2000/ants/v2 v2.4.6 github.com/panjf2000/ants/v2 v2.4.6
github.com/pelletier/go-toml v1.9.3 github.com/pelletier/go-toml v1.9.4
github.com/prometheus/client_golang v1.11.0 github.com/prometheus/client_golang v1.11.0
github.com/prometheus/common v0.30.0 // indirect github.com/prometheus/common v0.31.1 // indirect
github.com/prometheus/procfs v0.7.1 // indirect github.com/prometheus/procfs v0.7.3 // indirect
github.com/rs/zerolog v1.23.0 github.com/rs/zerolog v1.25.0
github.com/smira/go-statsd v1.3.2 github.com/smira/go-statsd v1.3.2
github.com/stretchr/objx v0.3.0 // indirect github.com/stretchr/objx v0.3.0 // indirect
github.com/stretchr/testify v1.7.0 github.com/stretchr/testify v1.7.0
github.com/tylertreat/BoomFilters v0.0.0-20210315201527-1a82519a3e43 github.com/tylertreat/BoomFilters v0.0.0-20210315201527-1a82519a3e43
golang.org/x/crypto v0.0.0-20210711020723-a769d52b0f97 golang.org/x/crypto v0.0.0-20210921155107-089bfa567519
golang.org/x/net v0.0.0-20210726213435-c6fcb2dbf985 golang.org/x/net v0.0.0-20211005001312-d4b1ae081e3b
golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c golang.org/x/sys v0.0.0-20211004093028-2c5d950f24ef
google.golang.org/protobuf v1.27.1 // indirect google.golang.org/protobuf v1.27.1 // indirect
) )
require (
github.com/beorn7/perks v1.0.1 // indirect
github.com/cenkalti/backoff/v4 v4.1.0 // indirect
github.com/cespare/xxhash/v2 v2.1.2 // indirect
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/matttproud/golang_protobuf_extensions v1.0.1 // 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
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/xerrors v0.0.0-20200804184101-5ec99f83aff1 // indirect
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b // indirect
)
+31 -31
View File
@@ -44,8 +44,8 @@ github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuy
github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=
github.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= github.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=
github.com/alecthomas/units v0.0.0-20190924025748-f65c72e2690d/go.mod h1:rBZYJk541a8SKzHPHnH3zbiI+7dagKZ0cgpgrD7Fyho= github.com/alecthomas/units v0.0.0-20190924025748-f65c72e2690d/go.mod h1:rBZYJk541a8SKzHPHnH3zbiI+7dagKZ0cgpgrD7Fyho=
github.com/alecthomas/units v0.0.0-20210208195552-ff826a37aa15 h1:AUNCr9CiJuwrRYS3XieqF+Z9B9gNxo/eANAJCF2eiN4= github.com/alecthomas/units v0.0.0-20210927113745-59d0afb8317a h1:E/8AP5dFtMhl5KPJz66Kt9G0n+7Sn41Fy1wv9/jHOrc=
github.com/alecthomas/units v0.0.0-20210208195552-ff826a37aa15/go.mod h1:OMCwj8VM1Kc9e19TLln2VL61YJF0x1XFtfdL4JdbSyE= github.com/alecthomas/units v0.0.0-20210927113745-59d0afb8317a/go.mod h1:OMCwj8VM1Kc9e19TLln2VL61YJF0x1XFtfdL4JdbSyE=
github.com/andres-erbsen/clock v0.0.0-20160526145045-9e14626cd129/go.mod h1:rFgpPQZYZ8vdbc+48xibu8ALc3yeyd64IhHS+PU6Yyg= github.com/andres-erbsen/clock v0.0.0-20160526145045-9e14626cd129/go.mod h1:rFgpPQZYZ8vdbc+48xibu8ALc3yeyd64IhHS+PU6Yyg=
github.com/andybalholm/cascadia v1.1.0/go.mod h1:GsXiBklL0woXo1j/WYWtSYYC4ouU9PqHO0sqidkEA4Y= github.com/andybalholm/cascadia v1.1.0/go.mod h1:GsXiBklL0woXo1j/WYWtSYYC4ouU9PqHO0sqidkEA4Y=
github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5 h1:0CwZNZbxp69SHPdPJAN/hZIm0C4OItdklCFmMRWYpio= github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5 h1:0CwZNZbxp69SHPdPJAN/hZIm0C4OItdklCFmMRWYpio=
@@ -59,8 +59,9 @@ github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6r
github.com/cenkalti/backoff/v4 v4.1.0 h1:c8LkOFQTzuO0WBM/ae5HdGQuZPfPxp7lqBRwQRm4fSc= github.com/cenkalti/backoff/v4 v4.1.0 h1:c8LkOFQTzuO0WBM/ae5HdGQuZPfPxp7lqBRwQRm4fSc=
github.com/cenkalti/backoff/v4 v4.1.0/go.mod h1:scbssz8iZGpm3xbr14ovlUdkxfGXNInqkPWOWmG2CLw= github.com/cenkalti/backoff/v4 v4.1.0/go.mod h1:scbssz8iZGpm3xbr14ovlUdkxfGXNInqkPWOWmG2CLw=
github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
github.com/cespare/xxhash/v2 v2.1.1 h1:6MnRN8NT7+YBpUIWxHtefFZOKTAPgGjpQSxqLNn0+qY=
github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
github.com/cespare/xxhash/v2 v2.1.2 h1:YRXhKfTDauu4ajMg1TPgFO5jnlC2HCbmLXMcTG5cbYE=
github.com/cespare/xxhash/v2 v2.1.2/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI= github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI=
github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI= github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI=
github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU= github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU=
@@ -168,8 +169,8 @@ github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7V
github.com/julienschmidt/httprouter v1.3.0/go.mod h1:JR6WtHb+2LUe8TCKY3cZOxFyyO8IZAc4RVcycCCAKdM= github.com/julienschmidt/httprouter v1.3.0/go.mod h1:JR6WtHb+2LUe8TCKY3cZOxFyyO8IZAc4RVcycCCAKdM=
github.com/k0kubun/colorstring v0.0.0-20150214042306-9440f1994b88/go.mod h1:3w7q1U84EfirKl04SVQ/s7nPm1ZPhiXd34z40TNz36k= github.com/k0kubun/colorstring v0.0.0-20150214042306-9440f1994b88/go.mod h1:3w7q1U84EfirKl04SVQ/s7nPm1ZPhiXd34z40TNz36k=
github.com/k0kubun/pp v2.4.0+incompatible/go.mod h1:GWse8YhT0p8pT4ir3ZgBbfZild3tgzSScAn6HmfYukg= github.com/k0kubun/pp v2.4.0+incompatible/go.mod h1:GWse8YhT0p8pT4ir3ZgBbfZild3tgzSScAn6HmfYukg=
github.com/kentik/patricia v0.0.0-20201202224819-f9447a6e25f1 h1:D7qhJP3R49ZjUzpzKQ6B2H3lgejPs6DTO5gRomhhOpE= github.com/kentik/patricia v0.0.0-20210909164817-21603333b70e h1:1wAVuGu1c+lsdaOPQN+9xoP9+gaIMJV6H0ehGc+K5iA=
github.com/kentik/patricia v0.0.0-20201202224819-f9447a6e25f1/go.mod h1:2OfLA+0esiUJpwMjrH39pEk79cb8MvGTBS9YlZpejJ4= github.com/kentik/patricia v0.0.0-20210909164817-21603333b70e/go.mod h1:2OfLA+0esiUJpwMjrH39pEk79cb8MvGTBS9YlZpejJ4=
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
github.com/konsorten/go-windows-terminal-sequences v1.0.3/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/konsorten/go-windows-terminal-sequences v1.0.3/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
@@ -179,8 +180,6 @@ github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORN
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= 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 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE=
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
github.com/libp2p/go-reuseport v0.0.2 h1:XSG94b1FJfGA01BUrT82imejHQyTxO4jEWqheyCXYvU=
github.com/libp2p/go-reuseport v0.0.2/go.mod h1:SPD+5RwGC7rcnzngoYC86GjPzjSywuQyMVAheVBD9nQ=
github.com/mattn/go-colorable v0.1.2/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE= github.com/mattn/go-colorable v0.1.2/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE=
github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= 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.9/go.mod h1:YNRxwqDuOph6SZLI9vUUz6OYw3QyUt7WiY2yME+cCiQ=
@@ -196,8 +195,8 @@ github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRW
github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f/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.6 h1:drmj9mcygn2gawZ155dRbo+NfXEfAssjZNU1qoIb4gQ= github.com/panjf2000/ants/v2 v2.4.6 h1:drmj9mcygn2gawZ155dRbo+NfXEfAssjZNU1qoIb4gQ=
github.com/panjf2000/ants/v2 v2.4.6/go.mod h1:f6F0NZVFsGCp5A7QW/Zj/m92atWwOkY0OIhFxRNFr4A= github.com/panjf2000/ants/v2 v2.4.6/go.mod h1:f6F0NZVFsGCp5A7QW/Zj/m92atWwOkY0OIhFxRNFr4A=
github.com/pelletier/go-toml v1.9.3 h1:zeC5b1GviRUyKYd6OJPvBU/mcVDVoL1OhT17FCt5dSQ= github.com/pelletier/go-toml v1.9.4 h1:tjENF6MfZAg8e4ZmZTeWaWiT2vXtsoO6+iuOjFhECwM=
github.com/pelletier/go-toml v1.9.3/go.mod h1:u1nR/EPcESfeI/szUZKdtJ0xRNbUoANCkoOuaOx1Y+c= github.com/pelletier/go-toml v1.9.4/go.mod h1:u1nR/EPcESfeI/szUZKdtJ0xRNbUoANCkoOuaOx1Y+c=
github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e/go.mod h1:pJLUxLENpZxwdsKMEsNbx1VGcRFpLqf3715MtcvvzbA= 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.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
@@ -218,20 +217,20 @@ 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.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.10.0/go.mod h1:Tlit/dnDKsSWFlCLTWaA1cyBgKHSMdTB80sz/V91rCo=
github.com/prometheus/common v0.26.0/go.mod h1:M7rCNAaPfAosfx8veZJCuw84e35h3Cfd9VFqTh1DIvc= github.com/prometheus/common v0.26.0/go.mod h1:M7rCNAaPfAosfx8veZJCuw84e35h3Cfd9VFqTh1DIvc=
github.com/prometheus/common v0.30.0 h1:JEkYlQnpzrzQFxi6gnukFPdQ+ac82oRhzMcIduJu/Ug= github.com/prometheus/common v0.31.1 h1:d18hG4PkHnNAKNMOmFuXFaiY8Us0nird/2m60uS1AMs=
github.com/prometheus/common v0.30.0/go.mod h1:vu+V0TpY+O6vW9J44gczi3Ap/oXXR10b+M/gUGO4Hls= github.com/prometheus/common v0.31.1/go.mod h1:vu+V0TpY+O6vW9J44gczi3Ap/oXXR10b+M/gUGO4Hls=
github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= 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.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.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.6.0/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA=
github.com/prometheus/procfs v0.7.1 h1:TlEtJq5GvGqMykEwWzbZWjjztF86swFhsPix1i0bkgA= github.com/prometheus/procfs v0.7.3 h1:4jVXhlkAyzOScmCkXBTOLRLTz8EeU+eyjrwB/EPq0VU=
github.com/prometheus/procfs v0.7.1/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA= github.com/prometheus/procfs v0.7.3/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA=
github.com/quasilyte/go-ruleguard/dsl v0.3.2/go.mod h1:KeCP03KrjuSO0H1kTuZQCWlQPulDV6YMIXmpQss17rU= 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.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
github.com/rogpeppe/go-internal v1.8.0/go.mod h1:WmiCO8CzOY8rg0OYDC4/i/2WRWAB6poM+XZ2dLUbcbE= github.com/rogpeppe/go-internal v1.8.0/go.mod h1:WmiCO8CzOY8rg0OYDC4/i/2WRWAB6poM+XZ2dLUbcbE=
github.com/rs/xid v1.2.1/go.mod h1:+uKXf+4Djp6Md1KODXJxgGQPKngRmWyn10oCKFzNHOQ= github.com/rs/xid v1.3.0/go.mod h1:trrq9SKmegXys3aeAKXMUTdJsYXVwGY3RLcfgqegfbg=
github.com/rs/zerolog v1.23.0 h1:UskrK+saS9P9Y789yNNulYKdARjPZuS35B8gJF2x60g= github.com/rs/zerolog v1.25.0 h1:Rj7XygbUHKUlDPcVdoLyR91fJBsduXj5fRxyqIQj/II=
github.com/rs/zerolog v1.23.0/go.mod h1:6c7hFfxPOy7TacJc4Fcdi24/J0NKYGzjG8FWRI916Qo= github.com/rs/zerolog v1.25.0/go.mod h1:7KHcEGe0QZPOm2IE4Kpb5rTh6n1h2hIgS5OOnu1rUaI=
github.com/sebdah/goldie/v2 v2.5.3/go.mod h1:oZ9fp0+se1eapSRjfYbsV/0Hqhbuu3bJVvKI/NNtssI= 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.0.0/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAmXWZgo=
github.com/sergi/go-diff v1.1.0/go.mod h1:STckp+ISIX8hZLjrqAeVduY0gWCT9IjLuqbuNXdaHfM= github.com/sergi/go-diff v1.1.0/go.mod h1:STckp+ISIX8hZLjrqAeVduY0gWCT9IjLuqbuNXdaHfM=
@@ -248,7 +247,6 @@ github.com/stretchr/testify v1.1.5-0.20170809224252-890a5c3458b4/go.mod h1:a8OnR
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= 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.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA=
github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= 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 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY=
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
@@ -257,7 +255,7 @@ github.com/tylertreat/BoomFilters v0.0.0-20210315201527-1a82519a3e43/go.mod h1:O
github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= 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.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k=
go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU= 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.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8=
go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
@@ -279,8 +277,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-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-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-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/crypto v0.0.0-20210711020723-a769d52b0f97 h1:/UOmuWzQfxxo9UtlXMwuQU8CMgg1eZXqTRwkSQJWKOI= golang.org/x/crypto v0.0.0-20210921155107-089bfa567519 h1:7I4JAnoQBe7ZtJcBaYHi5UtiO8tQHbUSXxL+pnGRANg=
golang.org/x/crypto v0.0.0-20210711020723-a769d52b0f97/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= 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-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8=
@@ -311,8 +309,9 @@ 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.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.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.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.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-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-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
@@ -344,9 +343,10 @@ golang.org/x/net v0.0.0-20200707034311-ab3426394381/go.mod h1:/O7V0waA8r7cgGh81R
golang.org/x/net v0.0.0-20200822124328-c89045814202/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-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-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM=
golang.org/x/net v0.0.0-20210525063256-abc453219eb5/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20210525063256-abc453219eb5/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
golang.org/x/net v0.0.0-20210726213435-c6fcb2dbf985 h1:4CSI6oo7cOjJKajidEljs9h+uP0rRZBPPPhcCbj5mw8= golang.org/x/net v0.0.0-20211005001312-d4b1ae081e3b h1:SXy8Ld8oKlcogOvUAh0J5Pm5RKzgYBMMxLxt6n5XW50=
golang.org/x/net v0.0.0-20210726213435-c6fcb2dbf985/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20211005001312-d4b1ae081e3b/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= 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-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-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
@@ -361,15 +361,14 @@ golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJ
golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20200317015054-43a5402ce75a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= 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-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20201207232520-09787c993a3a h1:DcqTD9SDLc+1P/r1EmRBwnVsrOwW+kk2vWf9n+1sGhs=
golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/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/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= 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-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190228124157-a34e9553db1e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
@@ -400,13 +399,14 @@ golang.org/x/sys v0.0.0-20200625212154-ddb9806d33ae/go.mod h1:h1NjWce9XRLGQEsW7w
golang.org/x/sys v0.0.0-20200803210538-64077c9b5642/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200803210538-64077c9b5642/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20210603081109-ebe580a85c40/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210603081109-ebe580a85c40/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-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c h1:F1jZWGFhYfh0Ci55sIpILtKKK8p3i2/krTr0H1rg74I= golang.org/x/sys v0.0.0-20211004093028-2c5d950f24ef h1:fPxZ3Umkct3LZ8gK9nbk+DWDJ9fstZa2grBn+lWVKPs=
golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20211004093028-2c5d950f24ef/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-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= 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.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
@@ -460,8 +460,8 @@ golang.org/x/tools v0.0.0-20200729194436-6467de6f59a7/go.mod h1:njjCfa9FT2d7l9Bc
golang.org/x/tools v0.0.0-20200804011535-6c149bb5ef0d/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-20200820010801-b793a1359eac/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA=
golang.org/x/tools v0.0.0-20200825202427-b303f430e36d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= golang.org/x/tools v0.0.0-20200825202427-b303f430e36d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA=
golang.org/x/tools v0.1.0 h1:po9/4sTYwZU9lPhi1tOrb4hCv3qrhiQ77LZfGa2OjwY= golang.org/x/tools v0.1.5 h1:ouewzE6p+/VEB31YYnTbEJdi8pFqKp4P4n85vwo3DHA=
golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0= golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= 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-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
+4 -3
View File
@@ -156,7 +156,7 @@ func makeEventStream(conf *config.Config, logger mtglib.Logger) (mtglib.EventStr
func runProxy(conf *config.Config, version string) error { func runProxy(conf *config.Config, version string) error {
logger := makeLogger(conf) logger := makeLogger(conf)
logger.BindStr("configuration", conf.String()).Debug("configuration") logger.BindJSON("configuration", conf.String()).Debug("configuration")
ntw, err := makeNetwork(conf, version) ntw, err := makeNetwork(conf, version)
if err != nil { if err != nil {
@@ -183,8 +183,9 @@ func runProxy(conf *config.Config, version string) error {
Secret: conf.Secret, Secret: conf.Secret,
BufferSize: conf.TCPBuffer.Get(mtglib.DefaultBufferSize), BufferSize: conf.TCPBuffer.Get(mtglib.DefaultBufferSize),
DomainFrontingPort: conf.DomainFrontingPort.Get(mtglib.DefaultDomainFrontingPort), DomainFrontingPort: conf.DomainFrontingPort.Get(mtglib.DefaultDomainFrontingPort),
IdleTimeout: conf.Network.Timeout.Idle.Get(mtglib.DefaultIdleTimeout),
PreferIP: conf.PreferIP.Get(mtglib.DefaultPreferIP), PreferIP: conf.PreferIP.Get(mtglib.DefaultPreferIP),
AllowFallbackOnUnknownDC: conf.AllowFallbackOnUnknownDC.Get(false),
} }
proxy, err := mtglib.NewProxy(opts) proxy, err := mtglib.NewProxy(opts)
@@ -192,7 +193,7 @@ func runProxy(conf *config.Config, version string) error {
return fmt.Errorf("cannot create a proxy: %w", err) return fmt.Errorf("cannot create a proxy: %w", err)
} }
listener, err := net.Listen("tcp", conf.BindTo.Get("")) listener, err := utils.NewListener(conf.BindTo.Get(""), int(opts.BufferSize))
if err != nil { if err != nil {
return fmt.Errorf("cannot start proxy: %w", err) return fmt.Errorf("cannot start proxy: %w", err)
} }
+1
View File
@@ -71,6 +71,7 @@ func (s *SimpleRun) Run(cli *CLI, version string) error { // nolint: cyclop
} }
conf.Debug.Value = s.Debug conf.Debug.Value = s.Debug
conf.AllowFallbackOnUnknownDC.Value = true
conf.Defense.AntiReplay.Enabled.Value = true conf.Defense.AntiReplay.Enabled.Value = true
if err := conf.Validate(); err != nil { if err := conf.Validate(); err != nil {
+1
View File
@@ -10,6 +10,7 @@ import (
type Config struct { type Config struct {
Debug TypeBool `json:"debug"` Debug TypeBool `json:"debug"`
AllowFallbackOnUnknownDC TypeBool `json:"allowFallbackOnUnknownDc"`
Secret mtglib.Secret `json:"secret"` Secret mtglib.Secret `json:"secret"`
BindTo TypeHostPort `json:"bindTo"` BindTo TypeHostPort `json:"bindTo"`
TCPBuffer TypeBytes `json:"tcpBuffer"` TCPBuffer TypeBytes `json:"tcpBuffer"`
+1
View File
@@ -10,6 +10,7 @@ import (
type tomlConfig struct { type tomlConfig struct {
Debug bool `toml:"debug" json:"debug,omitempty"` Debug bool `toml:"debug" json:"debug,omitempty"`
AllowFallbackOnUnknownDC bool `toml:"allow-fallback-on-unknown-dc" json:"allowFallbackOnUnknownDc,omitempty"`
Secret string `toml:"secret" json:"secret"` Secret string `toml:"secret" json:"secret"`
BindTo string `toml:"bind-to" json:"bindTo"` BindTo string `toml:"bind-to" json:"bindTo"`
TCPBuffer string `toml:"tcp-buffer" json:"tcpBuffer,omitempty"` TCPBuffer string `toml:"tcp-buffer" json:"tcpBuffer,omitempty"`
+41
View File
@@ -0,0 +1,41 @@
package utils
import (
"fmt"
"net"
"github.com/9seconds/mtg/v2/network"
)
type Listener struct {
net.Listener
bufferSize int
}
func (l Listener) Accept() (net.Conn, error) {
conn, err := l.Listener.Accept()
if err != nil {
return nil, err // nolint: wrapcheck
}
if err := network.SetClientSocketOptions(conn, l.bufferSize); err != nil {
conn.Close()
return nil, fmt.Errorf("cannot set TCP options: %w", err)
}
return conn, nil
}
func NewListener(bindTo string, bufferSize int) (net.Listener, error) {
base, err := net.Listen("tcp", bindTo)
if err != nil {
return nil, fmt.Errorf("cannot build a base listener: %w", err)
}
return Listener{
Listener: base,
bufferSize: bufferSize,
}, nil
}
+1
View File
@@ -1,3 +1,4 @@
//go:build !windows
// +build !windows // +build !windows
package utils package utils
+1
View File
@@ -1,3 +1,4 @@
//go:build windows
// +build windows // +build windows
package utils package utils
+1
View File
@@ -1,3 +1,4 @@
//go:build !windows
// +build !windows // +build !windows
package utils package utils
+1
View File
@@ -1,3 +1,4 @@
//go:build windows
// +build windows // +build windows
package utils package utils
+6 -18
View File
@@ -121,7 +121,7 @@ func (f *Firehol) Run(updateEach time.Duration) {
func (f *Firehol) containsIPv4(addr net.IP) bool { func (f *Firehol) containsIPv4(addr net.IP) bool {
ip := patricia.NewIPv4AddressFromBytes(addr, 32) // nolint: gomnd ip := patricia.NewIPv4AddressFromBytes(addr, 32) // nolint: gomnd
if ok, _, err := f.treeV4.FindDeepestTag(ip); ok && err == nil { if ok, _ := f.treeV4.FindDeepestTag(ip); ok {
return true return true
} }
@@ -131,7 +131,7 @@ func (f *Firehol) containsIPv4(addr net.IP) bool {
func (f *Firehol) containsIPv6(addr net.IP) bool { func (f *Firehol) containsIPv6(addr net.IP) bool {
ip := patricia.NewIPv6Address(addr, 128) // nolint: gomnd ip := patricia.NewIPv6Address(addr, 128) // nolint: gomnd
if ok, _, err := f.treeV6.FindDeepestTag(ip); ok && err == nil { if ok, _ := f.treeV6.FindDeepestTag(ip); ok {
return true return true
} }
@@ -267,9 +267,7 @@ func (f *Firehol) updateTrees(mutex sync.Locker,
return fmt.Errorf("cannot parse a line: %w", err) return fmt.Errorf("cannot parse a line: %w", err)
} }
if err := f.updateAddToTrees(ip, cidr, mutex, v4tree, v6tree); err != nil { f.updateAddToTrees(ip, cidr, mutex, v4tree, v6tree)
return fmt.Errorf("cannot add a node to the tree: %w", err)
}
} }
if scanner.Err() != nil { if scanner.Err() != nil {
@@ -302,27 +300,17 @@ func (f *Firehol) updateParseLine(text string) (net.IP, uint, error) {
func (f *Firehol) updateAddToTrees(ip net.IP, cidr uint, func (f *Firehol) updateAddToTrees(ip net.IP, cidr uint,
mutex sync.Locker, mutex sync.Locker,
v4tree *bool_tree.TreeV4, v6tree *bool_tree.TreeV6) error { v4tree *bool_tree.TreeV4, v6tree *bool_tree.TreeV6) {
mutex.Lock() mutex.Lock()
defer mutex.Unlock() defer mutex.Unlock()
if ip.To4() != nil { if ip.To4() != nil {
addr := patricia.NewIPv4AddressFromBytes(ip, cidr) v4tree.Set(patricia.NewIPv4AddressFromBytes(ip, cidr), true)
if _, _, err := v4tree.Set(addr, true); err != nil {
return err // nolint: wrapcheck
}
} else { } else {
addr := patricia.NewIPv6Address(ip, cidr) v6tree.Set(patricia.NewIPv6Address(ip, cidr), true)
if _, _, err := v6tree.Set(addr, true); err != nil {
return err // nolint: wrapcheck
} }
} }
return nil
}
// NewFirehol creates a new instance of FireHOL IP blocklist. // NewFirehol creates a new instance of FireHOL IP blocklist.
// //
// This method does not start an update process so please execute Run // This method does not start an update process so please execute Run
+1
View File
@@ -7,6 +7,7 @@ type noopLogger struct{}
func (n noopLogger) Named(_ string) mtglib.Logger { return n } func (n noopLogger) Named(_ string) mtglib.Logger { return n }
func (n noopLogger) BindInt(_ string, _ int) mtglib.Logger { return n } func (n noopLogger) BindInt(_ string, _ int) mtglib.Logger { return n }
func (n noopLogger) BindStr(_, _ string) mtglib.Logger { return n } func (n noopLogger) BindStr(_, _ string) mtglib.Logger { return n }
func (n noopLogger) BindJSON(_, _ string) mtglib.Logger { return n }
func (n noopLogger) Printf(_ string, _ ...interface{}) {} func (n noopLogger) Printf(_ string, _ ...interface{}) {}
func (n noopLogger) Info(_ string) {} func (n noopLogger) Info(_ string) {}
func (n noopLogger) Warning(_ string) {} func (n noopLogger) Warning(_ string) {}
+14
View File
@@ -15,6 +15,7 @@ const (
zeroLogContextVarTypeUnknown zeroLogContextVarType = iota zeroLogContextVarTypeUnknown zeroLogContextVarType = iota
zeroLogContextVarTypeStr zeroLogContextVarTypeStr
zeroLogContextVarTypeInt zeroLogContextVarTypeInt
zeroLogContextVarTypeJSON
) )
type zeroLogContext struct { type zeroLogContext struct {
@@ -66,6 +67,17 @@ func (z *zeroLogContext) BindStr(name, value string) mtglib.Logger {
} }
} }
func (z *zeroLogContext) BindJSON(name, value string) mtglib.Logger {
return &zeroLogContext{
name: z.name,
log: z.log,
ctxVarType: zeroLogContextVarTypeJSON,
ctxVarName: name,
ctxVarStr: value,
parent: z,
}
}
func (z *zeroLogContext) Printf(format string, args ...interface{}) { func (z *zeroLogContext) Printf(format string, args ...interface{}) {
z.Debug(fmt.Sprintf(format, args...)) z.Debug(fmt.Sprintf(format, args...))
} }
@@ -110,6 +122,8 @@ func (z *zeroLogContext) attachCtx(evt *zerolog.Event) {
evt.Str(z.ctxVarName, z.ctxVarStr) evt.Str(z.ctxVarName, z.ctxVarStr)
case zeroLogContextVarTypeInt: case zeroLogContextVarTypeInt:
evt.Int(z.ctxVarName, z.ctxVarInt) evt.Int(z.ctxVarName, z.ctxVarInt)
case zeroLogContextVarTypeJSON:
evt.RawJSON(z.ctxVarName, []byte(z.ctxVarStr))
case zeroLogContextVarTypeUnknown: case zeroLogContextVarTypeUnknown:
} }
} }
+13 -2
View File
@@ -69,6 +69,9 @@ const (
// DefaultIdleTimeout is a default timeout for closing a connection // DefaultIdleTimeout is a default timeout for closing a connection
// in case of idling. // in case of idling.
//
// Deprecated: no longer in use because of changed TCP relay
// algorithm.
DefaultIdleTimeout = time.Minute DefaultIdleTimeout = time.Minute
// DefaultTolerateTimeSkewness is a default timeout for time // DefaultTolerateTimeSkewness is a default timeout for time
@@ -83,9 +86,14 @@ const (
// by Telegram and a proxy. // by Telegram and a proxy.
SecretKeyLength = 16 SecretKeyLength = 16
// ConnectionIDBytesLength defines a count of random bytes // ConnectionIDBytesLength defines a count of random bytes used to generate
// used to generate a stream/connection ids. // a stream/connection ids.
ConnectionIDBytesLength = 16 ConnectionIDBytesLength = 16
// TCPRelayReadTimeout defines a max time period between two consecuitive
// reads from Telegram after which connection will be terminated. This is
// required to abort stale connections.
TCPRelayReadTimeout = 20 * time.Second
) )
// Network defines a knowledge how to work with a network. It may sound // Network defines a knowledge how to work with a network. It may sound
@@ -237,6 +245,9 @@ type Logger interface {
// BindStr binds new string parameter to a new logger instance. // BindStr binds new string parameter to a new logger instance.
BindStr(name, value string) Logger BindStr(name, value string) Logger
// BindJSON binds a new JSON-encoded string to a new logger instance.
BindJSON(name, value string) Logger
// Printf is to support log.Logger behavior. // Printf is to support log.Logger behavior.
Printf(format string, args ...interface{}) Printf(format string, args ...interface{})
+1
View File
@@ -11,6 +11,7 @@ type NoopLogger struct{}
func (n NoopLogger) Named(_ string) Logger { return n } func (n NoopLogger) Named(_ string) Logger { return n }
func (n NoopLogger) BindInt(_ string, _ int) Logger { return n } func (n NoopLogger) BindInt(_ string, _ int) Logger { return n }
func (n NoopLogger) BindStr(_, _ string) Logger { return n } func (n NoopLogger) BindStr(_, _ string) Logger { return n }
func (n NoopLogger) BindJSON(_, _ string) Logger { return n }
func (n NoopLogger) Printf(_ string, _ ...interface{}) {} func (n NoopLogger) Printf(_ string, _ ...interface{}) {}
func (n NoopLogger) Info(_ string) {} func (n NoopLogger) Info(_ string) {}
func (n NoopLogger) Warning(_ string) {} func (n NoopLogger) Warning(_ string) {}
+11 -7
View File
@@ -46,7 +46,11 @@ func (c *Conn) Write(p []byte) (int, error) {
rec.Type = record.TypeApplicationData rec.Type = record.TypeApplicationData
rec.Version = record.Version12 rec.Version = record.Version12
written := 0
sendBuffer := acquireBytesBuffer()
defer releaseBytesBuffer(sendBuffer)
lenP := len(p)
for len(p) > 0 { for len(p) > 0 {
chunkSize := rand.Intn(record.TLSMaxRecordSize) chunkSize := rand.Intn(record.TLSMaxRecordSize)
@@ -56,14 +60,14 @@ func (c *Conn) Write(p []byte) (int, error) {
rec.Payload.Reset() rec.Payload.Reset()
rec.Payload.Write(p[:chunkSize]) rec.Payload.Write(p[:chunkSize])
rec.Dump(sendBuffer) // nolint: errcheck
if err := rec.Dump(c.Conn); err != nil {
return written, err // nolint: wrapcheck
}
written += chunkSize
p = p[chunkSize:] p = p[chunkSize:]
} }
return written, nil if _, err := c.Conn.Write(sendBuffer.Bytes()); err != nil {
return 0, err // nolint: wrapcheck
}
return lenP, nil
} }
+7 -23
View File
@@ -1,35 +1,19 @@
package relay package relay
import ( import (
"context" "fmt"
"io" "net"
"time"
) )
type conn struct { type conn struct {
io.ReadWriteCloser net.Conn
ctx context.Context
tickChannel chan struct{}
} }
func (c conn) Read(p []byte) (int, error) { func (c conn) Read(p []byte) (int, error) {
n, err := c.ReadWriteCloser.Read(p) if err := c.SetReadDeadline(time.Now().Add(getTimeout())); err != nil {
return 0, fmt.Errorf("cannot set read deadline: %w", err)
select {
case <-c.ctx.Done():
case c.tickChannel <- struct{}{}:
} }
return n, err // nolint: wrapcheck return c.Conn.Read(p) // nolint: wrapcheck
}
func (c conn) Write(p []byte) (int, error) {
n, err := c.ReadWriteCloser.Write(p)
select {
case <-c.ctx.Done():
case c.tickChannel <- struct{}{}:
}
return n, err // nolint: wrapcheck
} }
-125
View File
@@ -1,125 +0,0 @@
package relay
import (
"context"
"errors"
"io"
"testing"
"github.com/9seconds/mtg/v2/internal/testlib"
"github.com/stretchr/testify/mock"
"github.com/stretchr/testify/suite"
)
type ConnTestSuite struct {
suite.Suite
ctxCancel context.CancelFunc
connMock *testlib.NetConnMock
tickChannel chan struct{}
buf []byte
c conn
}
func (suite *ConnTestSuite) SetupTest() {
ctx, cancel := context.WithCancel(context.Background())
suite.tickChannel = make(chan struct{}, 1)
suite.connMock = &testlib.NetConnMock{}
suite.ctxCancel = cancel
suite.buf = make([]byte, 5)
suite.c = conn{
ReadWriteCloser: suite.connMock,
ctx: ctx,
tickChannel: suite.tickChannel,
}
}
func (suite *ConnTestSuite) TestReadOk() {
suite.connMock.On("Read", mock.Anything).Once().Return(len(suite.buf), nil)
n, err := suite.c.Read(suite.buf)
suite.NoError(err)
suite.Equal(len(suite.buf), n)
select {
case <-suite.tickChannel:
default:
suite.FailNow("cannot find a tick event")
}
}
func (suite *ConnTestSuite) TestReadErr() {
suite.connMock.On("Read", mock.Anything).Once().Return(0, io.EOF)
_, err := suite.c.Read(suite.buf)
suite.True(errors.Is(err, io.EOF))
select {
case <-suite.tickChannel:
default:
suite.FailNow("cannot find a tick event")
}
}
func (suite *ConnTestSuite) TestReadContextDone() {
suite.connMock.On("Read", mock.Anything).Once().Return(len(suite.buf), nil)
suite.ctxCancel()
suite.tickChannel <- struct{}{}
suite.c.Read(suite.buf) // nolint: errcheck
}
func (suite *ConnTestSuite) TestWriteOk() {
suite.connMock.On("Write", mock.Anything).Once().Return(len(suite.buf), nil)
n, err := suite.c.Write(suite.buf)
suite.NoError(err)
suite.Equal(len(suite.buf), n)
select {
case <-suite.tickChannel:
default:
suite.FailNow("cannot find a tick event")
}
}
func (suite *ConnTestSuite) TestWriteErr() {
suite.connMock.On("Write", mock.Anything).Once().Return(0, io.EOF)
_, err := suite.c.Write(suite.buf)
suite.True(errors.Is(err, io.EOF))
select {
case <-suite.tickChannel:
default:
suite.FailNow("cannot find a tick event")
}
}
func (suite *ConnTestSuite) TestWriteContextDone() {
suite.connMock.On("Write", mock.Anything).Once().Return(len(suite.buf), nil)
suite.ctxCancel()
suite.tickChannel <- struct{}{}
suite.c.Write(suite.buf) // nolint: errcheck
}
func (suite *ConnTestSuite) TearDownTest() {
select {
case <-suite.tickChannel:
default:
}
close(suite.tickChannel)
suite.connMock.AssertExpectations(suite.T())
}
func TestConn(t *testing.T) {
t.Parallel()
suite.Run(t, &ConnTestSuite{})
}
+9
View File
@@ -1,5 +1,14 @@
package relay package relay
import "time"
const (
ConnectionTimeToLiveMin = 2 * time.Minute
ConnectionTimeToLiveMax = 10 * time.Minute
TimeoutMin = 20 * time.Second
TimeoutMax = time.Minute
)
type Logger interface { type Logger interface {
Printf(msg string, args ...interface{}) Printf(msg string, args ...interface{})
} }
-44
View File
@@ -1,49 +1,5 @@
package relay_test package relay_test
import (
"bytes"
"io"
"sync"
)
type loggerMock struct{} type loggerMock struct{}
func (l loggerMock) Printf(format string, args ...interface{}) {} func (l loggerMock) Printf(format string, args ...interface{}) {}
type rwcMock struct {
bytes.Buffer
closed bool
mutex sync.Mutex
}
func (r *rwcMock) Read(p []byte) (int, error) {
r.mutex.Lock()
defer r.mutex.Unlock()
if r.closed {
return 0, io.EOF
}
return r.Buffer.Read(p) // nolint: wrapcheck
}
func (r *rwcMock) Write(p []byte) (int, error) {
r.mutex.Lock()
defer r.mutex.Unlock()
if r.closed {
return 0, io.EOF
}
return r.Buffer.Write(p) // nolint: wrapcheck
}
func (r *rwcMock) Close() error {
r.mutex.Lock()
defer r.mutex.Unlock()
r.closed = true
return nil
}
+17 -30
View File
@@ -1,45 +1,32 @@
package relay package relay
import ( import "sync"
"context"
"sync"
"time"
)
var relayPool = sync.Pool{ type eastWest struct {
New: func() interface{} { east []byte
return &Relay{ west []byte
tickChannel: make(chan struct{}),
errorChannel: make(chan error, 1),
} }
var eastWestPool = sync.Pool{
New: func() interface{} {
return &eastWest{}
}, },
} }
func AcquireRelay(ctx context.Context, logger Logger, bufferSize int, idleTimeout time.Duration) *Relay { func acquireEastWest(bufferSize int) *eastWest {
ctx, cancel := context.WithCancel(ctx) wanted := eastWestPool.Get().(*eastWest) // nolint: forcetypeassert
r, ok := relayPool.Get().(*Relay) if len(wanted.east) != bufferSize {
if !ok { wanted.east = make([]byte, bufferSize)
panic("Relay pool has no relay!")
} }
r.ctx = ctx if len(wanted.west) != bufferSize {
r.ctxCancel = cancel wanted.west = make([]byte, bufferSize)
r.logger = logger
r.tickTimeout = idleTimeout
if len(r.eastBuffer) != bufferSize {
r.eastBuffer = make([]byte, bufferSize)
} }
if len(r.westBuffer) != bufferSize { return wanted
r.westBuffer = make([]byte, bufferSize)
} }
return r func releaseEastWest(ew *eastWest) {
} eastWestPool.Put(ew)
func ReleaseRelay(r *Relay) {
r.Reset()
relayPool.Put(r)
} }
+25 -104
View File
@@ -3,127 +3,48 @@ package relay
import ( import (
"context" "context"
"io" "io"
"net"
"sync" "sync"
"time"
) )
type Relay struct { func Relay(ctx context.Context, log Logger, bufferSize int,
ctx context.Context telegramConn net.Conn, clientConn io.ReadWriteCloser) {
ctxCancel context.CancelFunc defer telegramConn.Close()
logger Logger defer clientConn.Close()
processMutex sync.Mutex
eastBuffer []byte
westBuffer []byte
tickChannel chan struct{}
errorChannel chan error
tickTimeout time.Duration
}
func (r *Relay) Reset() { ctx, cancel := context.WithTimeout(ctx, getConnectionTimeToLive())
r.processMutex.Lock() defer cancel()
defer r.processMutex.Unlock()
if r.ctxCancel != nil { go func() {
r.ctxCancel() <-ctx.Done()
} telegramConn.Close()
clientConn.Close()
}()
r.ctx = nil buffers := acquireEastWest(bufferSize)
r.ctxCancel = nil defer releaseEastWest(buffers)
r.logger = nil
}
func (r *Relay) Process(eastConn, westConn io.ReadWriteCloser) error { telegramConn = conn{
r.processMutex.Lock() Conn: telegramConn,
defer r.processMutex.Unlock()
eastConn = conn{
ReadWriteCloser: eastConn,
ctx: r.ctx,
tickChannel: r.tickChannel,
}
westConn = conn{
ReadWriteCloser: westConn,
ctx: r.ctx,
tickChannel: r.tickChannel,
} }
wg := &sync.WaitGroup{} wg := &sync.WaitGroup{}
wg.Add(3) // nolint: gomnd wg.Add(2) // nolint: gomnd
go r.runObserver(eastConn, westConn, wg) go pump(log, telegramConn, clientConn, wg, buffers.east, "east -> west")
go r.transmit(eastConn, westConn, r.westBuffer, "west", wg) pump(log, clientConn, telegramConn, wg, buffers.west, "west -> east")
r.transmit(westConn, eastConn, r.eastBuffer, "east", wg)
wg.Wait() wg.Wait()
select {
case err := <-r.errorChannel:
return err
default:
return nil
}
} }
func (r *Relay) transmit(src io.ReadCloser, dst io.WriteCloser, func pump(log Logger, src io.ReadCloser, dst io.WriteCloser, wg *sync.WaitGroup,
buffer []byte, direction string, wg *sync.WaitGroup) { buf []byte, direction string) {
defer wg.Done() defer wg.Done()
defer src.Close()
defer dst.Close()
defer func() { if n, err := io.CopyBuffer(dst, src, buf); err != nil {
r.ctxCancel() log.Printf("cannot pump %s (written %d bytes): %w", direction, n, err)
src.Close()
dst.Close()
}()
if _, err := io.CopyBuffer(dst, src, buffer); err != nil {
r.logger.Printf("error '%v' happened on direction %s", err, direction)
select {
case <-r.ctx.Done():
err = r.ctx.Err()
default:
}
select {
case r.errorChannel <- err:
default:
}
}
}
func (r *Relay) runObserver(one, another io.Closer, wg *sync.WaitGroup) {
defer wg.Done()
ticker := time.NewTicker(time.Second)
defer func() {
one.Close()
another.Close()
ticker.Stop()
select {
case <-ticker.C:
default:
}
}()
lastTickAt := time.Now()
for {
select {
case <-r.ctx.Done():
return
case <-r.tickChannel:
lastTickAt = time.Now()
case <-ticker.C:
if time.Since(lastTickAt) > r.tickTimeout {
r.logger.Printf("exit due to a timeout")
r.ctxCancel()
return
}
}
} }
} }
+21 -42
View File
@@ -4,7 +4,6 @@ import (
"context" "context"
"io" "io"
"testing" "testing"
"time"
"github.com/9seconds/mtg/v2/internal/testlib" "github.com/9seconds/mtg/v2/internal/testlib"
"github.com/9seconds/mtg/v2/mtglib/internal/relay" "github.com/9seconds/mtg/v2/mtglib/internal/relay"
@@ -15,60 +14,40 @@ import (
type RelayTestSuite struct { type RelayTestSuite struct {
suite.Suite suite.Suite
loggerMock relay.Logger
ctx context.Context ctx context.Context
ctxCancel context.CancelFunc ctxCancel context.CancelFunc
r *relay.Relay telegramConnMock *testlib.NetConnMock
clientConnMock *testlib.NetConnMock
} }
func (suite *RelayTestSuite) SetupTest() { func (suite *RelayTestSuite) SetupTest() {
suite.ctx, suite.ctxCancel = context.WithCancel(context.Background()) ctx, cancel := context.WithCancel(context.Background())
suite.r = relay.AcquireRelay(suite.ctx, loggerMock{}, 4096, time.Second) suite.ctx = ctx
suite.ctxCancel = cancel
suite.loggerMock = &loggerMock{}
suite.telegramConnMock = &testlib.NetConnMock{}
suite.clientConnMock = &testlib.NetConnMock{}
} }
func (suite *RelayTestSuite) TearDownTest() { func (suite *RelayTestSuite) TearDownTest() {
suite.ctxCancel() suite.ctxCancel()
relay.ReleaseRelay(suite.r) suite.telegramConnMock.AssertExpectations(suite.T())
suite.r = nil suite.clientConnMock.AssertExpectations(suite.T())
} }
func (suite *RelayTestSuite) TestCancelled() { func (suite *RelayTestSuite) TestExit() {
suite.ctxCancel() suite.telegramConnMock.On("SetReadDeadline", mock.Anything).Return(nil)
suite.telegramConnMock.On("Close").Return(nil)
suite.telegramConnMock.On("Read", mock.Anything).Return(10, io.EOF).Once()
suite.telegramConnMock.On("Write", mock.Anything).Return(10, io.EOF).Maybe()
eastConn := &rwcMock{} suite.clientConnMock.On("Read", mock.Anything).Return(0, io.EOF).Once()
eastConn.Write([]byte{1, 2, 3, 4, 5}) // nolint: errcheck suite.clientConnMock.On("Write", mock.Anything).Return(10, io.EOF).Maybe()
suite.clientConnMock.On("Close").Return(nil)
westConn := &rwcMock{} relay.Relay(suite.ctx, suite.loggerMock, 1024,
westConn.Write([]byte{100, 101, 102}) // nolint: errcheck suite.telegramConnMock, suite.clientConnMock)
suite.Nil(suite.r.Process(eastConn, westConn))
}
func (suite *RelayTestSuite) TestCopyFine() {
eastConn := &rwcMock{}
eastConn.Write([]byte{1, 2, 3, 4, 5}) // nolint: errcheck
westConn := &rwcMock{}
westConn.Write([]byte{100, 101, 102}) // nolint: errcheck
// yes, this test is not good enough. but apparently, if it hangs,
// we can debug most of possible issues.
_ = suite.r.Process(eastConn, westConn)
}
func (suite *RelayTestSuite) TestTimeout() {
eastConn := &rwcMock{}
eastConn.Write([]byte{1, 2, 3, 4, 5}) // nolint: errcheck
westConn := &testlib.NetConnMock{}
westConn.On("Close").Return(nil)
westConn.On("Read", mock.Anything).Return(0, io.EOF).Run(func(_ mock.Arguments) {
time.Sleep(2 * time.Second)
})
westConn.On("Write", mock.Anything).Return(0, io.EOF).Run(func(_ mock.Arguments) {
time.Sleep(2 * time.Second)
})
suite.Error(suite.r.Process(eastConn, westConn))
} }
func TestRelay(t *testing.T) { func TestRelay(t *testing.T) {
+22
View File
@@ -0,0 +1,22 @@
package relay
import (
"math/rand"
"time"
)
func getConnectionTimeToLive() time.Duration {
return getTime(ConnectionTimeToLiveMin, ConnectionTimeToLiveMax)
}
func getTimeout() time.Duration {
return getTime(TimeoutMin, TimeoutMax)
}
func getTime(minDuration, maxDuration time.Duration) time.Duration {
minDurationInSeconds := int(minDuration.Seconds())
maxDurationInSeconds := int(maxDuration.Seconds())
number := minDurationInSeconds + rand.Intn(maxDurationInSeconds-minDurationInSeconds)
return time.Duration(number) * time.Second
}
@@ -0,0 +1,37 @@
package relay
import (
"fmt"
"testing"
"github.com/stretchr/testify/suite"
)
type TimeoutsTestSuite struct {
suite.Suite
}
func (suite *TimeoutsTestSuite) TestGetConnectionTimeToLive() {
for i := 0; i < 100; i++ {
value := getConnectionTimeToLive()
message := fmt.Sprintf("generated value is %v", value)
suite.GreaterOrEqual(value, ConnectionTimeToLiveMin, message)
suite.LessOrEqual(value, ConnectionTimeToLiveMax, message)
}
}
func (suite *TimeoutsTestSuite) TestGetTimeout() {
for i := 0; i < 100; i++ {
value := getTimeout()
message := fmt.Sprintf("generated value is %v", value)
suite.GreaterOrEqual(value, TimeoutMin, message)
suite.LessOrEqual(value, TimeoutMax, message)
}
}
func TestTimeouts(t *testing.T) {
t.Parallel()
suite.Run(t, &TimeoutsTestSuite{})
}
+8
View File
@@ -7,6 +7,14 @@ type addressPool struct {
v6 [][]tgAddr v6 [][]tgAddr
} }
func (a addressPool) isValidDC(dc int) bool {
return dc > 0 && dc <= len(a.v4) && dc <= len(a.v6)
}
func (a addressPool) getRandomDC() int {
return 1 + rand.Intn(len(a.v4))
}
func (a addressPool) getV4(dc int) []tgAddr { func (a addressPool) getV4(dc int) []tgAddr {
return a.get(a.v4, dc-1) return a.get(a.v4, dc-1)
} }
+8
View File
@@ -42,6 +42,14 @@ func (t Telegram) Dial(ctx context.Context, dc int) (net.Conn, error) {
return nil, fmt.Errorf("cannot dial to %d dc: %w", dc, err) return nil, fmt.Errorf("cannot dial to %d dc: %w", dc, err)
} }
func (t Telegram) IsKnownDC(dc int) bool {
return t.pool.isValidDC(dc)
}
func (t Telegram) GetFallbackDC() int {
return t.pool.getRandomDC()
}
func New(dialer Dialer, ipPreference string, useTestDCs bool) (*Telegram, error) { func New(dialer Dialer, ipPreference string, useTestDCs bool) (*Telegram, error) {
var pref preferIP var pref preferIP
@@ -44,6 +44,7 @@ func (suite *TelegramTestSuite) TestUnknownDC() {
suite.T().Run(strconv.Itoa(value), func(t *testing.T) { suite.T().Run(strconv.Itoa(value), func(t *testing.T) {
_, err := suite.t.Dial(context.Background(), value) _, err := suite.t.Dial(context.Background(), value)
assert.Error(t, err) assert.Error(t, err)
assert.False(t, suite.t.IsKnownDC(value))
}) })
} }
} }
@@ -71,6 +72,7 @@ func (suite *TelegramTestSuite) TestDialToCorrectIPs() {
_, err := suite.t.Dial(context.Background(), idx) _, err := suite.t.Dial(context.Background(), idx)
assert.True(t, errors.Is(err, io.EOF)) assert.True(t, errors.Is(err, io.EOF))
assert.True(t, suite.t.IsKnownDC(idx))
}) })
} }
} }
@@ -135,6 +137,22 @@ func (suite *TelegramTestSuite) TestUnknownPreferIP() {
suite.Error(err) suite.Error(err)
} }
func (suite *TelegramTestSuite) TestFallbackDC() {
dcs := make([]int, 10)
for i := 0; i < len(dcs); i++ {
dcs[i] = suite.t.GetFallbackDC()
}
for _, v := range dcs {
value := v
suite.T().Run(strconv.Itoa(value), func(t *testing.T) {
assert.True(t, suite.t.IsKnownDC(value))
})
}
}
func TestTelegram(t *testing.T) { func TestTelegram(t *testing.T) {
t.Parallel() t.Parallel()
suite.Run(t, &TelegramTestSuite{}) suite.Run(t, &TelegramTestSuite{})
+26 -17
View File
@@ -23,7 +23,7 @@ type Proxy struct {
ctxCancel context.CancelFunc ctxCancel context.CancelFunc
streamWaitGroup sync.WaitGroup streamWaitGroup sync.WaitGroup
idleTimeout time.Duration allowFallbackOnUnknownDC bool
tolerateTimeSkewness time.Duration tolerateTimeSkewness time.Duration
bufferSize int bufferSize int
domainFrontingPort int domainFrontingPort int
@@ -81,13 +81,13 @@ func (p *Proxy) ServeConn(conn net.Conn) {
return return
} }
rel := relay.AcquireRelay(ctx, relay.Relay(
p.logger.Named("relay"), p.bufferSize, p.idleTimeout) ctx,
defer relay.ReleaseRelay(rel) ctx.logger.Named("relay"),
p.bufferSize,
if err := rel.Process(ctx.clientConn, ctx.telegramConn); err != nil { ctx.telegramConn,
p.logger.DebugError("relay has been finished", err) ctx.clientConn,
} )
} }
// Serve starts a proxy on a given listener. // Serve starts a proxy on a given listener.
@@ -208,7 +208,16 @@ func (p *Proxy) doObfuscated2Handshake(ctx *streamContext) error {
} }
func (p *Proxy) doTelegramCall(ctx *streamContext) error { func (p *Proxy) doTelegramCall(ctx *streamContext) error {
conn, err := p.telegram.Dial(ctx, ctx.dc) dc := ctx.dc
if p.allowFallbackOnUnknownDC && !p.telegram.IsKnownDC(dc) {
dc = p.telegram.GetFallbackDC()
ctx.logger = ctx.logger.BindInt("fallback_dc", dc)
ctx.logger.Warning("unknown DC, fallbacks")
}
conn, err := p.telegram.Dial(ctx, dc)
if err != nil { if err != nil {
return fmt.Errorf("cannot dial to Telegram: %w", err) return fmt.Errorf("cannot dial to Telegram: %w", err)
} }
@@ -255,13 +264,13 @@ func (p *Proxy) doDomainFronting(ctx *streamContext, conn *connRewind) {
stream: p.eventStream, stream: p.eventStream,
} }
rel := relay.AcquireRelay(ctx, relay.Relay(
p.logger.Named("domain-fronting"), p.bufferSize, p.idleTimeout) ctx,
defer relay.ReleaseRelay(rel) ctx.logger.Named("domain-fronting"),
p.bufferSize,
if err := rel.Process(conn, frontConn); err != nil { frontConn,
p.logger.DebugError("domain fronting relay has been finished", err) conn,
} )
} }
// NewProxy makes a new proxy instance. // NewProxy makes a new proxy instance.
@@ -287,8 +296,8 @@ func NewProxy(opts ProxyOpts) (*Proxy, error) {
logger: opts.getLogger("proxy"), logger: opts.getLogger("proxy"),
domainFrontingPort: opts.getDomainFrontingPort(), domainFrontingPort: opts.getDomainFrontingPort(),
tolerateTimeSkewness: opts.getTolerateTimeSkewness(), tolerateTimeSkewness: opts.getTolerateTimeSkewness(),
idleTimeout: opts.getIdleTimeout(),
bufferSize: opts.getBufferSize(), bufferSize: opts.getBufferSize(),
allowFallbackOnUnknownDC: opts.AllowFallbackOnUnknownDC,
telegram: tg, telegram: tg,
} }
+10 -8
View File
@@ -90,6 +90,16 @@ type ProxyOpts struct {
// This is an optional setting. // This is an optional setting.
DomainFrontingPort uint 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.
//
// 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 // UseTestDCs defines if we have to connect to production or to staging
// DCs of Telegram. // DCs of Telegram.
// //
@@ -143,14 +153,6 @@ func (p ProxyOpts) getDomainFrontingPort() int {
return int(p.DomainFrontingPort) return int(p.DomainFrontingPort)
} }
func (p ProxyOpts) getIdleTimeout() time.Duration {
if p.IdleTimeout == 0 {
return DefaultIdleTimeout
}
return p.IdleTimeout
}
func (p ProxyOpts) getTolerateTimeSkewness() time.Duration { func (p ProxyOpts) getTolerateTimeSkewness() time.Duration {
if p.TolerateTimeSkewness == 0 { if p.TolerateTimeSkewness == 0 {
return DefaultTolerateTimeSkewness return DefaultTolerateTimeSkewness
+4 -29
View File
@@ -5,8 +5,6 @@ import (
"fmt" "fmt"
"net" "net"
"time" "time"
"github.com/libp2p/go-reuseport"
) )
type defaultDialer struct { type defaultDialer struct {
@@ -31,36 +29,14 @@ func (d *defaultDialer) DialContext(ctx context.Context, network, address string
return nil, fmt.Errorf("cannot dial to %s: %w", address, err) return nil, fmt.Errorf("cannot dial to %s: %w", address, err)
} }
tcpConn, ok := conn.(*net.TCPConn) // we do not need to call to end user. End users call us.
if !ok { if err := SetServerSocketOptions(conn, d.bufferSize); err != nil {
panic("conn type is not tcp")
}
if err := tcpConn.SetNoDelay(true); err != nil {
conn.Close() conn.Close()
return nil, fmt.Errorf("cannot set TCP_NO_DELAY: %w", err) return nil, fmt.Errorf("cannot set socket options: %w", err)
} }
if err := tcpConn.SetReadBuffer(d.bufferSize); err != nil { return conn, nil
tcpConn.Close()
return nil, fmt.Errorf("cannot set read buffer size: %w", err)
}
if err := tcpConn.SetWriteBuffer(d.bufferSize); err != nil {
tcpConn.Close()
return nil, fmt.Errorf("cannot set write buffer size: %w", err)
}
if err := tcpConn.SetKeepAlive(true); err != nil {
tcpConn.Close()
return nil, fmt.Errorf("cannot enable keep-alive: %w", err)
}
return tcpConn, nil
} }
// NewDefaultDialer build a new dialer which dials bypassing proxies // NewDefaultDialer build a new dialer which dials bypassing proxies
@@ -87,7 +63,6 @@ func NewDefaultDialer(timeout time.Duration, bufferSize int) (Dialer, error) {
return &defaultDialer{ return &defaultDialer{
Dialer: net.Dialer{ Dialer: net.Dialer{
Timeout: timeout, Timeout: timeout,
Control: reuseport.Control,
}, },
bufferSize: bufferSize, bufferSize: bufferSize,
}, nil }, nil
+4
View File
@@ -70,6 +70,10 @@ const (
// DNSTimeout defines a timeout for DNS queries. // DNSTimeout defines a timeout for DNS queries.
DNSTimeout = 5 * time.Second DNSTimeout = 5 * time.Second
// tcpLingerTimeout defines a number of seconds to wait for sending
// unacknowledged data.
tcpLingerTimeout = 1
) )
var ( var (
+59
View File
@@ -0,0 +1,59 @@
package network
import (
"fmt"
"net"
)
// SetClientSocketOptions tunes a TCP socket that represents a connection to
// end user (not Telegram service or fronting domain).
func SetClientSocketOptions(conn net.Conn, bufferSize int) error {
tcpConn := conn.(*net.TCPConn) // nolint: forcetypeassert
if err := tcpConn.SetNoDelay(false); err != nil {
return fmt.Errorf("cannot disable TCP_NO_DELAY: %w", err)
}
return setCommonSocketOptions(tcpConn, bufferSize)
}
// 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 {
tcpConn := conn.(*net.TCPConn) // nolint: forcetypeassert
if err := tcpConn.SetNoDelay(true); err != nil {
return fmt.Errorf("cannot enable TCP_NO_DELAY: %w", err)
}
return setCommonSocketOptions(tcpConn, bufferSize)
}
func setCommonSocketOptions(conn *net.TCPConn, bufferSize int) error {
if err := conn.SetReadBuffer(bufferSize); err != nil {
return fmt.Errorf("cannot set read buffer size: %w", err)
}
if err := conn.SetWriteBuffer(bufferSize); err != nil {
return fmt.Errorf("cannot set write buffer size: %w", err)
}
if err := conn.SetKeepAlive(false); err != nil {
return fmt.Errorf("cannot disable TCP keepalive probes: %w", err)
}
if err := conn.SetLinger(tcpLingerTimeout); err != nil {
return fmt.Errorf("cannot set TCP linger timeout: %w", err)
}
rawConn, err := conn.SyscallConn()
if err != nil {
return fmt.Errorf("cannot get underlying raw connection: %w", err)
}
if err := setSocketReuseAddrPort(rawConn, bufferSize); err != nil {
return fmt.Errorf("cannot setup SO_REUSEADDR/PORT: %w", err)
}
return nil
}
+31
View File
@@ -0,0 +1,31 @@
//go:build !windows
// +build !windows
package network
import (
"fmt"
"syscall"
"golang.org/x/sys/unix"
)
func setSocketReuseAddrPort(conn syscall.RawConn, bufferSize int) error {
var err error
conn.Control(func(fd uintptr) { // nolint: errcheck
err = unix.SetsockoptInt(int(fd), unix.SOL_SOCKET, unix.SO_REUSEADDR, 1)
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)
if err != nil {
err = fmt.Errorf("cannot set SO_REUSEPORT: %w", err)
}
})
return err
}
+10
View File
@@ -0,0 +1,10 @@
//go:build windows
// +build windows
package network
import "syscall"
func setSocketReuseAddrPort(conn syscall.RawConn, bufferSize int) error {
return nil
}