mirror of
https://github.com/ScuroNeko/mtg.git
synced 2026-09-01 01:24:02 +03:00
REPOSITORY / ScuroNeko/mtg
Compare commits
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
8ccf61c23e | ||
|
|
35f0fca3c5 | ||
|
|
cd46a734ea | ||
|
|
cd92a343aa | ||
|
|
289e8f5945 | ||
|
|
850bed0dfc | ||
|
|
8977d77a13 | ||
|
|
91726d461f | ||
|
|
be1a47287a | ||
|
|
426483d27b | ||
|
|
bc72717582 | ||
|
|
391d901402 | ||
|
|
837d96dc43 | ||
|
|
9125a29e79 | ||
|
|
6449109b2b | ||
|
|
829669eefd | ||
|
|
2d9f2345dc | ||
|
|
6a9069ca72 | ||
|
|
d72ed03a43 | ||
|
|
f0d2cd494a | ||
|
|
b5810c955d | ||
|
|
4ebae693e0 | ||
|
|
0e033b59b3 | ||
|
|
1a619e3090 | ||
|
|
8e29ff78ba | ||
|
|
efdac2c0d8 | ||
|
|
e559388802 | ||
|
|
cb691453f0 | ||
|
|
020065f389 | ||
|
|
cf5197cee0 | ||
|
|
720158f15c | ||
|
|
07f00a363e | ||
|
|
d32ab34e60 |
@@ -17,3 +17,4 @@ script:
|
|||||||
matrix:
|
matrix:
|
||||||
allow_failures:
|
allow_failures:
|
||||||
- go: master
|
- go: master
|
||||||
|
- go: 1.14.x # because of golangci-lint
|
||||||
|
|||||||
+1
-1
@@ -1,7 +1,7 @@
|
|||||||
###############################################################################
|
###############################################################################
|
||||||
# BUILD STAGE
|
# BUILD STAGE
|
||||||
|
|
||||||
FROM golang:1.13-alpine
|
FROM golang:1.14-alpine
|
||||||
|
|
||||||
RUN set -x \
|
RUN set -x \
|
||||||
&& apk --no-cache --update add \
|
&& apk --no-cache --update add \
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ APP_NAME := $(IMAGE_NAME)
|
|||||||
|
|
||||||
CC_BINARIES := $(shell bash -c "echo -n $(APP_NAME)-{linux,freebsd,openbsd}-{386,amd64} $(APP_NAME)-linux-{arm,arm64}")
|
CC_BINARIES := $(shell bash -c "echo -n $(APP_NAME)-{linux,freebsd,openbsd}-{386,amd64} $(APP_NAME)-linux-{arm,arm64}")
|
||||||
|
|
||||||
GOLANGCI_LINT_VERSION := v1.23.3
|
GOLANGCI_LINT_VERSION := v1.24.0
|
||||||
|
|
||||||
VERSION_GO := $(shell go version)
|
VERSION_GO := $(shell go version)
|
||||||
VERSION_DATE := $(shell date -Ru)
|
VERSION_DATE := $(shell date -Ru)
|
||||||
|
|||||||
@@ -194,11 +194,14 @@ supported environment variables:
|
|||||||
| `MTG_STATSD_PREFIX` | `--statsd-prefix` | `mtg` | Which bucket prefix we should use. For example, if you set `mtg`, then metric `traffic.ingress` would be send as `mtg.traffic.ingress`. |
|
| `MTG_STATSD_PREFIX` | `--statsd-prefix` | `mtg` | Which bucket prefix we should use. For example, if you set `mtg`, then metric `traffic.ingress` would be send as `mtg.traffic.ingress`. |
|
||||||
| `MTG_STATSD_TAGS_FORMAT` | `--statsd-tags-format` | | Which tags format we should use. By default, we are using default vanilla statsd tags format but if you want to send directly to InfluxDB or Datadog, please specify it there. Possible options are `influxdb` and `datadog`. |
|
| `MTG_STATSD_TAGS_FORMAT` | `--statsd-tags-format` | | Which tags format we should use. By default, we are using default vanilla statsd tags format but if you want to send directly to InfluxDB or Datadog, please specify it there. Possible options are `influxdb` and `datadog`. |
|
||||||
| `MTG_STATSD_TAGS` | `--statsd-tags` | | Which tags should we send to statsd with our metrics. Please specify them as `key=value` pairs. |
|
| `MTG_STATSD_TAGS` | `--statsd-tags` | | Which tags should we send to statsd with our metrics. Please specify them as `key=value` pairs. |
|
||||||
| `MTG_BUFFER_WRITE` | `-w`, `--write-buffer` | `64KB` | The size of TCP write buffer in bytes. Write buffer is the buffer for messages which are going from client to Telegram. |
|
| `MTG_BUFFER_WRITE` | `-w`, `--write-buffer` | `32KB` | The size of TCP write buffer in bytes. Write buffer is the buffer for messages which are going from client to Telegram. |
|
||||||
| `MTG_BUFFER_READ` | `-r`, `--read-buffer` | `128KB` | The size of TCP read buffer in bytes. Read buffer is the buffer for messages from Telegram to client. |
|
| `MTG_BUFFER_READ` | `-r`, `--read-buffer` | `32KB` | The size of TCP read buffer in bytes. Read buffer is the buffer for messages from Telegram to client. |
|
||||||
| `MTG_ANTIREPLAY_MAXSIZE` | `--anti-replay-max-size` | `128MB` | Max size of antireplay cache. |
|
| `MTG_ANTIREPLAY_MAXSIZE` | `--anti-replay-max-size` | `128MB` | Max size of antireplay cache. |
|
||||||
| `MTG_CLOAK_PORT` | `--cloak-port` | `443` | Which port we should use to connect to cloaked host in FakeTLS mode. |
|
| `MTG_CLOAK_PORT` | `--cloak-port` | `443` | Which port we should use to connect to cloaked host in FakeTLS mode. |
|
||||||
| `MTG_MULTIPLEX_PERCONNECTION` | `--multiplex-per-connection` | `50` | How many client connections can share a single Telegram connection in adtag mode |
|
| `MTG_MULTIPLEX_PERCONNECTION` | `--multiplex-per-connection` | `50` | How many client connections can share a single Telegram connection in adtag mode |
|
||||||
|
| `MTG_NTP_SERVERS` | `--ntp-server` | default pool | A list of NTP servers to use. |
|
||||||
|
| `MTG_PREFER_DIRECT_IP` | `--prefer-ip` | `ipv6` | Which IP protocol to prefer if possible. Works mostly in direct mode. |
|
||||||
|
|
||||||
|
|
||||||
Usually you want to modify only read/write buffer sizes. If you feel
|
Usually you want to modify only read/write buffer sizes. If you feel
|
||||||
that proxy is slow, try to increase both sizes giving more priority to
|
that proxy is slow, try to increase both sizes giving more priority to
|
||||||
|
|||||||
@@ -32,6 +32,13 @@ const (
|
|||||||
SecretModeTLS
|
SecretModeTLS
|
||||||
)
|
)
|
||||||
|
|
||||||
|
type PreferIP uint8
|
||||||
|
|
||||||
|
const (
|
||||||
|
PreferIPv4 PreferIP = iota
|
||||||
|
PreferIPv6
|
||||||
|
)
|
||||||
|
|
||||||
const SimpleSecretLength = 16
|
const SimpleSecretLength = 16
|
||||||
|
|
||||||
type OptionType uint8
|
type OptionType uint8
|
||||||
@@ -40,6 +47,8 @@ const (
|
|||||||
OptionTypeDebug OptionType = iota
|
OptionTypeDebug OptionType = iota
|
||||||
OptionTypeVerbose
|
OptionTypeVerbose
|
||||||
|
|
||||||
|
OptionTypePreferIP
|
||||||
|
|
||||||
OptionTypeBind
|
OptionTypeBind
|
||||||
OptionTypePublicIPv4
|
OptionTypePublicIPv4
|
||||||
OptionTypePublicIPv6
|
OptionTypePublicIPv6
|
||||||
@@ -59,6 +68,8 @@ const (
|
|||||||
|
|
||||||
OptionTypeMultiplexPerConnection
|
OptionTypeMultiplexPerConnection
|
||||||
|
|
||||||
|
OptionTypeNTPServers
|
||||||
|
|
||||||
OptionTypeSecret
|
OptionTypeSecret
|
||||||
OptionTypeAdtag
|
OptionTypeAdtag
|
||||||
)
|
)
|
||||||
@@ -86,6 +97,8 @@ type Config struct {
|
|||||||
Debug bool `json:"debug"`
|
Debug bool `json:"debug"`
|
||||||
Verbose bool `json:"verbose"`
|
Verbose bool `json:"verbose"`
|
||||||
SecretMode SecretMode `json:"secret_mode"`
|
SecretMode SecretMode `json:"secret_mode"`
|
||||||
|
PreferIP PreferIP `json:"prefer_ip"`
|
||||||
|
NTPServers []string `json:"ntp_servers"`
|
||||||
|
|
||||||
Secret []byte `json:"secret"`
|
Secret []byte `json:"secret"`
|
||||||
AdTag []byte `json:"adtag"`
|
AdTag []byte `json:"adtag"`
|
||||||
@@ -105,6 +118,16 @@ func Init(options ...Opt) error { // nolint: gocyclo, funlen
|
|||||||
C.Debug = opt.Value.(bool)
|
C.Debug = opt.Value.(bool)
|
||||||
case OptionTypeVerbose:
|
case OptionTypeVerbose:
|
||||||
C.Verbose = opt.Value.(bool)
|
C.Verbose = opt.Value.(bool)
|
||||||
|
case OptionTypePreferIP:
|
||||||
|
value := opt.Value.(string)
|
||||||
|
switch value {
|
||||||
|
case "ipv4":
|
||||||
|
C.PreferIP = PreferIPv4
|
||||||
|
case "ipv6":
|
||||||
|
C.PreferIP = PreferIPv6
|
||||||
|
default:
|
||||||
|
return fmt.Errorf("incorrect direct IP mode %s", value)
|
||||||
|
}
|
||||||
case OptionTypeBind:
|
case OptionTypeBind:
|
||||||
C.Bind = opt.Value.(*net.TCPAddr)
|
C.Bind = opt.Value.(*net.TCPAddr)
|
||||||
case OptionTypePublicIPv4:
|
case OptionTypePublicIPv4:
|
||||||
@@ -145,6 +168,11 @@ func Init(options ...Opt) error { // nolint: gocyclo, funlen
|
|||||||
C.AntiReplayMaxSize = int(opt.Value.(units.Base2Bytes))
|
C.AntiReplayMaxSize = int(opt.Value.(units.Base2Bytes))
|
||||||
case OptionTypeMultiplexPerConnection:
|
case OptionTypeMultiplexPerConnection:
|
||||||
C.MultiplexPerConnection = int(opt.Value.(uint))
|
C.MultiplexPerConnection = int(opt.Value.(uint))
|
||||||
|
case OptionTypeNTPServers:
|
||||||
|
C.NTPServers = opt.Value.([]string)
|
||||||
|
if len(C.NTPServers) == 0 {
|
||||||
|
return errors.New("ntp server list is empty")
|
||||||
|
}
|
||||||
case OptionTypeSecret:
|
case OptionTypeSecret:
|
||||||
C.Secret = opt.Value.([]byte)
|
C.Secret = opt.Value.([]byte)
|
||||||
case OptionTypeAdtag:
|
case OptionTypeAdtag:
|
||||||
|
|||||||
@@ -63,7 +63,12 @@ func (c *ClientProtocol) tlsHandshake(conn io.ReadWriter) error {
|
|||||||
return fmt.Errorf("cannot read initial record: %w", err)
|
return fmt.Errorf("cannot read initial record: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
clientHello, err := tlstypes.ParseClientHello(helloRecord.Data.Bytes())
|
buf := acquireBytesBuffer()
|
||||||
|
defer releaseBytesBuffer(buf)
|
||||||
|
|
||||||
|
helloRecord.Data.WriteBytes(buf)
|
||||||
|
|
||||||
|
clientHello, err := tlstypes.ParseClientHello(buf.Bytes())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("cannot parse client hello: %w", err)
|
return fmt.Errorf("cannot parse client hello: %w", err)
|
||||||
}
|
}
|
||||||
|
|||||||
+11
-8
@@ -28,15 +28,9 @@ func cloak(one, another io.ReadWriteCloser) {
|
|||||||
|
|
||||||
wg.Add(2)
|
wg.Add(2)
|
||||||
|
|
||||||
go func() {
|
go cloakPipe(one, another, wg)
|
||||||
defer wg.Done()
|
|
||||||
io.Copy(one, another) // nolint: errcheck
|
|
||||||
}()
|
|
||||||
|
|
||||||
go func() {
|
go cloakPipe(another, one, wg)
|
||||||
defer wg.Done()
|
|
||||||
io.Copy(another, one) // nolint: errcheck
|
|
||||||
}()
|
|
||||||
|
|
||||||
go func() {
|
go func() {
|
||||||
wg.Wait()
|
wg.Wait()
|
||||||
@@ -69,3 +63,12 @@ func cloak(one, another io.ReadWriteCloser) {
|
|||||||
|
|
||||||
<-ctx.Done()
|
<-ctx.Done()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func cloakPipe(one io.Writer, another io.Reader, wg *sync.WaitGroup) {
|
||||||
|
defer wg.Done()
|
||||||
|
|
||||||
|
buf := acquireCloakBuffer()
|
||||||
|
defer releaseCloakBuffer(buf)
|
||||||
|
|
||||||
|
io.CopyBuffer(one, another, *buf) // nolint: errcheck
|
||||||
|
}
|
||||||
|
|||||||
@@ -0,0 +1,39 @@
|
|||||||
|
package faketls
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
"sync"
|
||||||
|
)
|
||||||
|
|
||||||
|
const cloakBufferSize = 1024
|
||||||
|
|
||||||
|
var (
|
||||||
|
poolBytesBuffer = sync.Pool{
|
||||||
|
New: func() interface{} {
|
||||||
|
return &bytes.Buffer{}
|
||||||
|
},
|
||||||
|
}
|
||||||
|
poolCloakBuffer = sync.Pool{
|
||||||
|
New: func() interface{} {
|
||||||
|
rv := make([]byte, cloakBufferSize)
|
||||||
|
return &rv
|
||||||
|
},
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
func acquireBytesBuffer() *bytes.Buffer {
|
||||||
|
return poolBytesBuffer.Get().(*bytes.Buffer)
|
||||||
|
}
|
||||||
|
|
||||||
|
func acquireCloakBuffer() *[]byte {
|
||||||
|
return poolCloakBuffer.Get().(*[]byte)
|
||||||
|
}
|
||||||
|
|
||||||
|
func releaseBytesBuffer(buf *bytes.Buffer) {
|
||||||
|
buf.Reset()
|
||||||
|
poolBytesBuffer.Put(buf)
|
||||||
|
}
|
||||||
|
|
||||||
|
func releaseCloakBuffer(buf *[]byte) {
|
||||||
|
poolCloakBuffer.Put(buf)
|
||||||
|
}
|
||||||
@@ -5,17 +5,17 @@ go 1.13
|
|||||||
require (
|
require (
|
||||||
github.com/VictoriaMetrics/fastcache v1.5.7
|
github.com/VictoriaMetrics/fastcache v1.5.7
|
||||||
github.com/alecthomas/units v0.0.0-20190924025748-f65c72e2690d
|
github.com/alecthomas/units v0.0.0-20190924025748-f65c72e2690d
|
||||||
github.com/beevik/ntp v0.2.0
|
github.com/beevik/ntp v0.3.0
|
||||||
github.com/golang/protobuf v1.3.3 // indirect
|
github.com/golang/protobuf v1.3.5 // indirect
|
||||||
github.com/prometheus/client_golang v1.4.0
|
github.com/prometheus/client_golang v1.5.1
|
||||||
|
github.com/prometheus/procfs v0.0.11 // indirect
|
||||||
github.com/smira/go-statsd v1.3.1
|
github.com/smira/go-statsd v1.3.1
|
||||||
go.uber.org/atomic v1.5.1 // indirect
|
go.uber.org/zap v1.14.1
|
||||||
go.uber.org/multierr v1.4.0 // indirect
|
golang.org/x/crypto v0.0.0-20200323165209-0ec3e9974c59
|
||||||
go.uber.org/zap v1.13.0
|
golang.org/x/lint v0.0.0-20200302205851-738671d3881b // indirect
|
||||||
golang.org/x/crypto v0.0.0-20200128174031-69ecbb4d6d5d
|
golang.org/x/net v0.0.0-20200324143707-d3edc9973b7e // indirect
|
||||||
golang.org/x/lint v0.0.0-20200130185559-910be7a94367 // indirect
|
golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd
|
||||||
golang.org/x/net v0.0.0-20200202094626-16171245cfb2 // indirect
|
golang.org/x/tools v0.0.0-20200319210407-521f4a0cd458 // indirect
|
||||||
golang.org/x/sys v0.0.0-20200202164722-d101bd2416d5
|
|
||||||
golang.org/x/tools v0.0.0-20200204074204-1cc6d1ef6c74 // indirect
|
|
||||||
gopkg.in/alecthomas/kingpin.v2 v2.2.6
|
gopkg.in/alecthomas/kingpin.v2 v2.2.6
|
||||||
|
honnef.co/go/tools v0.0.1-2020.1.3 // indirect
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -14,8 +14,8 @@ github.com/alecthomas/units v0.0.0-20190924025748-f65c72e2690d h1:UQZhZ2O0vMHr2c
|
|||||||
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/allegro/bigcache v1.2.1-0.20190218064605-e24eb225f156 h1:eMwmnE/GDgah4HI848JfFxHt+iPb26b4zyfspmqY0/8=
|
github.com/allegro/bigcache v1.2.1-0.20190218064605-e24eb225f156 h1:eMwmnE/GDgah4HI848JfFxHt+iPb26b4zyfspmqY0/8=
|
||||||
github.com/allegro/bigcache v1.2.1-0.20190218064605-e24eb225f156/go.mod h1:Cb/ax3seSYIx7SuZdm2G2xzfwmv3TPSk2ucNfQESPXM=
|
github.com/allegro/bigcache v1.2.1-0.20190218064605-e24eb225f156/go.mod h1:Cb/ax3seSYIx7SuZdm2G2xzfwmv3TPSk2ucNfQESPXM=
|
||||||
github.com/beevik/ntp v0.2.0 h1:sGsd+kAXzT0bfVfzJfce04g+dSRfrs+tbQW8lweuYgw=
|
github.com/beevik/ntp v0.3.0 h1:xzVrPrE4ziasFXgBVBZJDP0Wg/KpMwk2KHJ4Ba8GrDw=
|
||||||
github.com/beevik/ntp v0.2.0/go.mod h1:hIHWr+l3+/clUnF44zdK+CWW7fO8dR5cIylAQ76NRpg=
|
github.com/beevik/ntp v0.3.0/go.mod h1:hIHWr+l3+/clUnF44zdK+CWW7fO8dR5cIylAQ76NRpg=
|
||||||
github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973 h1:xJ4a3vCFaGF/jqvzLMYoU8P317H5OQ+Via4RmuPwCS0=
|
github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973 h1:xJ4a3vCFaGF/jqvzLMYoU8P317H5OQ+Via4RmuPwCS0=
|
||||||
github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q=
|
github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q=
|
||||||
github.com/beorn7/perks v1.0.0 h1:HWo1m869IqiPhD389kmkxeTalrjNbbJTC8LXupb+sl0=
|
github.com/beorn7/perks v1.0.0 h1:HWo1m869IqiPhD389kmkxeTalrjNbbJTC8LXupb+sl0=
|
||||||
@@ -40,8 +40,8 @@ github.com/golang/protobuf v1.3.1 h1:YF8+flBXS5eO826T4nzqPrxfhQThhXl0YzfuUPu4SBg
|
|||||||
github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
||||||
github.com/golang/protobuf v1.3.2 h1:6nsPYzhq5kReh6QImI3k5qWzO4PEbvbIW2cwSfR/6xs=
|
github.com/golang/protobuf v1.3.2 h1:6nsPYzhq5kReh6QImI3k5qWzO4PEbvbIW2cwSfR/6xs=
|
||||||
github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
||||||
github.com/golang/protobuf v1.3.3 h1:gyjaxf+svBWX08ZjK86iN9geUJF0H6gp2IRKX6Nf6/I=
|
github.com/golang/protobuf v1.3.5 h1:F768QJ1E9tib+q5Sc8MkdJi1RxLTbRcTf8LJV56aRls=
|
||||||
github.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw=
|
github.com/golang/protobuf v1.3.5/go.mod h1:6O5/vntMXwX2lRkT1hjjk0nAC1IDOTvTlVgjlRvqsdk=
|
||||||
github.com/golang/snappy v0.0.1 h1:Qgr9rKW7uDUkrbSmQeiDsGa8SjGyCOGtuasMWwvp2P4=
|
github.com/golang/snappy v0.0.1 h1:Qgr9rKW7uDUkrbSmQeiDsGa8SjGyCOGtuasMWwvp2P4=
|
||||||
github.com/golang/snappy v0.0.1/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
|
github.com/golang/snappy v0.0.1/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
|
||||||
github.com/google/go-cmp v0.3.1 h1:Xye71clBPdm5HgqGwUkwhbynsUJZhDbS20FvLhQ2izg=
|
github.com/google/go-cmp v0.3.1 h1:Xye71clBPdm5HgqGwUkwhbynsUJZhDbS20FvLhQ2izg=
|
||||||
@@ -76,8 +76,8 @@ github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZb
|
|||||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||||
github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw=
|
github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw=
|
||||||
github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5FsnadC4Ky3P0J6CfImo=
|
github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5FsnadC4Ky3P0J6CfImo=
|
||||||
github.com/prometheus/client_golang v1.4.0 h1:YVIb/fVcOTMSqtqZWSKnHpSLBxu8DKgxq8z6RuBZwqI=
|
github.com/prometheus/client_golang v1.5.1 h1:bdHYieyGlH+6OLEk2YQha8THib30KP0/yD0YH9m6xcA=
|
||||||
github.com/prometheus/client_golang v1.4.0/go.mod h1:e9GMxYsXl05ICDXkRhurwBS4Q3OK1iX/F2sw+iXX5zU=
|
github.com/prometheus/client_golang v1.5.1/go.mod h1:e9GMxYsXl05ICDXkRhurwBS4Q3OK1iX/F2sw+iXX5zU=
|
||||||
github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910 h1:idejC8f05m9MGOsuEi1ATq9shN03HrxNkD/luQvxCv8=
|
github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910 h1:idejC8f05m9MGOsuEi1ATq9shN03HrxNkD/luQvxCv8=
|
||||||
github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo=
|
github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo=
|
||||||
github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90 h1:S/YWwWx/RA8rT8tKFRuGUZhuA90OyIBpPCXkcbwU8DE=
|
github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90 h1:S/YWwWx/RA8rT8tKFRuGUZhuA90OyIBpPCXkcbwU8DE=
|
||||||
@@ -94,6 +94,8 @@ github.com/prometheus/procfs v0.0.2 h1:6LJUbpNm42llc4HRCuvApCSWB/WfhuNo9K98Q9sNG
|
|||||||
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.0.8 h1:+fpWZdT24pJBiqJdAwYBjPSk+5YmQzYNPYzQsdzLkt8=
|
github.com/prometheus/procfs v0.0.8 h1:+fpWZdT24pJBiqJdAwYBjPSk+5YmQzYNPYzQsdzLkt8=
|
||||||
github.com/prometheus/procfs v0.0.8/go.mod h1:7Qr8sr6344vo1JqZ6HhLceV9o3AJ1Ff+GxbHq6oeK9A=
|
github.com/prometheus/procfs v0.0.8/go.mod h1:7Qr8sr6344vo1JqZ6HhLceV9o3AJ1Ff+GxbHq6oeK9A=
|
||||||
|
github.com/prometheus/procfs v0.0.11 h1:DhHlBtkHWPYi8O2y31JkK0TF+DGM+51OopZjH/Ia5qI=
|
||||||
|
github.com/prometheus/procfs v0.0.11/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU=
|
||||||
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/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo=
|
github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo=
|
||||||
github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE=
|
github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE=
|
||||||
@@ -107,38 +109,39 @@ github.com/stretchr/testify v1.3.0 h1:TivCn/peBQ7UY8ooIcPgZFpTNSz0Q2U6UrFlUfqbe0
|
|||||||
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 h1:2E4SXV/wtOkTonXsotYi4li6zVWxYlZuYNCXe9XRJyk=
|
github.com/stretchr/testify v1.4.0 h1:2E4SXV/wtOkTonXsotYi4li6zVWxYlZuYNCXe9XRJyk=
|
||||||
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
|
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
|
||||||
go.uber.org/atomic v1.5.0 h1:OI5t8sDa1Or+q8AeE+yKeB/SDYioSHAgcVljj9JIETY=
|
github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
||||||
go.uber.org/atomic v1.5.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ=
|
go.uber.org/atomic v1.6.0 h1:Ezj3JGmsOnG1MoRWQkPBsKLe9DwWD9QeXzTRzzldNVk=
|
||||||
go.uber.org/atomic v1.5.1 h1:rsqfU5vBkVknbhUGbAUwQKR2H4ItV8tjJ+6kJX4cxHM=
|
go.uber.org/atomic v1.6.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ=
|
||||||
go.uber.org/atomic v1.5.1/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ=
|
go.uber.org/multierr v1.5.0 h1:KCa4XfM8CWFCpxXRGok+Q0SS/0XBhMDbHHGABQLvD2A=
|
||||||
go.uber.org/multierr v1.3.0/go.mod h1:VgVr7evmIr6uPjLBxg28wmKNXyqE9akIJ5XnfpiKl+4=
|
go.uber.org/multierr v1.5.0/go.mod h1:FeouvMocqHpRaaGuG9EjoKcStLC43Zu/fmqdUMPcKYU=
|
||||||
go.uber.org/multierr v1.4.0 h1:f3WCSC2KzAcBXGATIxAB1E2XuCpNU255wNKZ505qi3E=
|
|
||||||
go.uber.org/multierr v1.4.0/go.mod h1:VgVr7evmIr6uPjLBxg28wmKNXyqE9akIJ5XnfpiKl+4=
|
|
||||||
go.uber.org/tools v0.0.0-20190618225709-2cfd321de3ee h1:0mgffUl7nfd+FpvXMVz4IDEaUSmT1ysygQC7qYo7sG4=
|
go.uber.org/tools v0.0.0-20190618225709-2cfd321de3ee h1:0mgffUl7nfd+FpvXMVz4IDEaUSmT1ysygQC7qYo7sG4=
|
||||||
go.uber.org/tools v0.0.0-20190618225709-2cfd321de3ee/go.mod h1:vJERXedbb3MVM5f9Ejo0C68/HhF8uaILCdgjnY+goOA=
|
go.uber.org/tools v0.0.0-20190618225709-2cfd321de3ee/go.mod h1:vJERXedbb3MVM5f9Ejo0C68/HhF8uaILCdgjnY+goOA=
|
||||||
go.uber.org/zap v1.13.0 h1:nR6NoDBgAf67s68NhaXbsojM+2gxp3S1hWkHDl27pVU=
|
go.uber.org/zap v1.14.1 h1:nYDKopTbvAPq/NrUVZwT15y2lpROBiLLyoRTbXOYWOo=
|
||||||
go.uber.org/zap v1.13.0/go.mod h1:zwrFLgMcdUuIBviXEYEH1YKNaOBnKXsx2IPda5bBwHM=
|
go.uber.org/zap v1.14.1/go.mod h1:Mb2vm2krFEG5DV0W9qcHBYFtp/Wku1cvYaqPsS/WYfc=
|
||||||
golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
|
golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
|
||||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2 h1:VklqNMn3ovrHsnt90PveolxSbWFaJdECFbxSq0Mqo2M=
|
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2 h1:VklqNMn3ovrHsnt90PveolxSbWFaJdECFbxSq0Mqo2M=
|
||||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||||
golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/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-20200128174031-69ecbb4d6d5d h1:9FCpayM9Egr1baVnV1SX0H87m+XB0B8S0hAMi99X/3U=
|
golang.org/x/crypto v0.0.0-20200323165209-0ec3e9974c59 h1:3zb4D3T4G8jdExgVU/95+vQXfpEPiMdCaZgmGVxjNHM=
|
||||||
golang.org/x/crypto v0.0.0-20200128174031-69ecbb4d6d5d/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
golang.org/x/crypto v0.0.0-20200323165209-0ec3e9974c59/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||||
golang.org/x/lint v0.0.0-20190930215403-16217165b5de h1:5hukYrvBGR8/eNkX5mdUezrA6JiaEZDtJb9Ei+1LlBs=
|
golang.org/x/lint v0.0.0-20190930215403-16217165b5de h1:5hukYrvBGR8/eNkX5mdUezrA6JiaEZDtJb9Ei+1LlBs=
|
||||||
golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
|
golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
|
||||||
golang.org/x/lint v0.0.0-20200130185559-910be7a94367 h1:0IiAsCRByjO2QjX7ZPkw5oU9x+n1YqRL802rjC0c3Aw=
|
golang.org/x/lint v0.0.0-20200302205851-738671d3881b h1:Wh+f8QHJXR411sJR8/vRBTZ7YapZaRvUcLFFJhusH0k=
|
||||||
golang.org/x/lint v0.0.0-20200130185559-910be7a94367/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY=
|
golang.org/x/lint v0.0.0-20200302205851-738671d3881b/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY=
|
||||||
golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc=
|
golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc=
|
||||||
golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee h1:WG0RUwxtNT4qqaXX3DPA8zHFNm/D9xaBpxzHt1WcA/E=
|
golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee h1:WG0RUwxtNT4qqaXX3DPA8zHFNm/D9xaBpxzHt1WcA/E=
|
||||||
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.2.0 h1:KU7oHjnv3XNWfa5COkzUifxZmxp1TyI7ImMXqFxLwvQ=
|
||||||
|
golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||||
golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||||
golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||||
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||||
golang.org/x/net v0.0.0-20190613194153-d28f0bde5980/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
golang.org/x/net v0.0.0-20190613194153-d28f0bde5980/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||||
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||||
golang.org/x/net v0.0.0-20200202094626-16171245cfb2 h1:CCH4IOTTfewWjGOlSp+zGcjutRKlBEZQ6wTn8ozI/nI=
|
golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||||
golang.org/x/net v0.0.0-20200202094626-16171245cfb2/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
golang.org/x/net v0.0.0-20200324143707-d3edc9973b7e h1:3G+cUijn7XD+S4eJFddp53Pv7+slrESplyjG25HgL+k=
|
||||||
|
golang.org/x/net v0.0.0-20200324143707-d3edc9973b7e/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
|
||||||
golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/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 h1:YUO/7uOKsKeq9UokNS62b8FYywz3ker1l1vDZRCRefw=
|
golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4 h1:YUO/7uOKsKeq9UokNS62b8FYywz3ker1l1vDZRCRefw=
|
||||||
golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||||
@@ -149,18 +152,21 @@ golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5h
|
|||||||
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-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=
|
||||||
|
golang.org/x/sys v0.0.0-20200106162015-b016eb3dc98e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20200122134326-e047566fdf82/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20200122134326-e047566fdf82/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20200202164722-d101bd2416d5 h1:LfCXLvNmTYH9kEmVgqbnsWfruoXZIrh4YBgqVHtDvw0=
|
golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd h1:xhmwyvizuTgC2qz7ZlMluP20uW+C3Rm0FD/WLDX8884=
|
||||||
golang.org/x/sys v0.0.0-20200202164722-d101bd2416d5/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
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=
|
||||||
golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
|
golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
|
||||||
golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
|
golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
|
||||||
golang.org/x/tools v0.0.0-20191029041327-9cc4af7d6b2c/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
golang.org/x/tools v0.0.0-20191029041327-9cc4af7d6b2c/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||||
golang.org/x/tools v0.0.0-20191029190741-b9c20aec41a5 h1:hKsoRgsbwY1NafxrwTs+k64bikrLBkAgPir1TNCj3Zs=
|
golang.org/x/tools v0.0.0-20191029190741-b9c20aec41a5 h1:hKsoRgsbwY1NafxrwTs+k64bikrLBkAgPir1TNCj3Zs=
|
||||||
golang.org/x/tools v0.0.0-20191029190741-b9c20aec41a5/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
golang.org/x/tools v0.0.0-20191029190741-b9c20aec41a5/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||||
|
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||||
|
golang.org/x/tools v0.0.0-20191130070609-6e064ea0cf2d/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||||
golang.org/x/tools v0.0.0-20200130002326-2f3ba24bd6e7/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
|
golang.org/x/tools v0.0.0-20200130002326-2f3ba24bd6e7/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
|
||||||
golang.org/x/tools v0.0.0-20200204074204-1cc6d1ef6c74 h1:KW20qMcLRWuIgjdCpHFJbVZA7zsDKtFXPNcm7/eI5ZA=
|
golang.org/x/tools v0.0.0-20200319210407-521f4a0cd458 h1:DgonIcqC7u+gVZX7lpuReBil5B/i8fvW/hAQdhT6/ao=
|
||||||
golang.org/x/tools v0.0.0-20200204074204-1cc6d1ef6c74/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
|
golang.org/x/tools v0.0.0-20200319210407-521f4a0cd458/go.mod h1:Sl4aGygMT6LrqrWclx+PTx3U+LnKx/seiNR+3G19Ar8=
|
||||||
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 h1:E7g+9GITq07hpfrRu66IVDexMakfv52eLZ2CXBWiKr4=
|
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543 h1:E7g+9GITq07hpfrRu66IVDexMakfv52eLZ2CXBWiKr4=
|
||||||
@@ -182,3 +188,5 @@ gopkg.in/yaml.v2 v2.2.5 h1:ymVxjfMaHvXD8RqPRmzHHsB3VvucivSkIAvJFDI5O3c=
|
|||||||
gopkg.in/yaml.v2 v2.2.5/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
gopkg.in/yaml.v2 v2.2.5/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||||
honnef.co/go/tools v0.0.1-2019.2.3 h1:3JgtbtFHMiCmsznwGVTUWbgGov+pVqnlf1dEJTNAXeM=
|
honnef.co/go/tools v0.0.1-2019.2.3 h1:3JgtbtFHMiCmsznwGVTUWbgGov+pVqnlf1dEJTNAXeM=
|
||||||
honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg=
|
honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg=
|
||||||
|
honnef.co/go/tools v0.0.1-2020.1.3 h1:sXmLre5bzIR6ypkjXCDI3jHPssRhc8KD/Ome589sc3U=
|
||||||
|
honnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k=
|
||||||
|
|||||||
@@ -43,6 +43,11 @@ var (
|
|||||||
Short('v').
|
Short('v').
|
||||||
Envar("MTG_VERBOSE").
|
Envar("MTG_VERBOSE").
|
||||||
Bool()
|
Bool()
|
||||||
|
runPreferIP = runCommand.Flag("prefer-ip",
|
||||||
|
"Prefer this IP protocol if possible. Valid options are 'ipv4' and 'ipv6'").
|
||||||
|
Envar("MTG_PREFER_DIRECT_IP").
|
||||||
|
Default("ipv6").
|
||||||
|
Enum("ipv4", "ipv6")
|
||||||
runBind = runCommand.Flag("bind",
|
runBind = runCommand.Flag("bind",
|
||||||
"Host:Port to bind proxy to.").
|
"Host:Port to bind proxy to.").
|
||||||
Short('b').
|
Short('b').
|
||||||
@@ -87,13 +92,13 @@ var (
|
|||||||
"Write buffer size. You can think about it as a buffer from client to Telegram.").
|
"Write buffer size. You can think about it as a buffer from client to Telegram.").
|
||||||
Short('w').
|
Short('w').
|
||||||
Envar("MTG_BUFFER_WRITE").
|
Envar("MTG_BUFFER_WRITE").
|
||||||
Default("64KB").
|
Default("32KB").
|
||||||
Bytes()
|
Bytes()
|
||||||
runReadBufferSize = runCommand.Flag("read-buffer",
|
runReadBufferSize = runCommand.Flag("read-buffer",
|
||||||
"Read buffer size. You can think about it as a buffer from Telegram to client.").
|
"Read buffer size. You can think about it as a buffer from Telegram to client.").
|
||||||
Short('r').
|
Short('r').
|
||||||
Envar("MTG_BUFFER_READ").
|
Envar("MTG_BUFFER_READ").
|
||||||
Default("128KB").
|
Default("32KB").
|
||||||
Bytes()
|
Bytes()
|
||||||
runTLSCloakPort = runCommand.Flag("cloak-port",
|
runTLSCloakPort = runCommand.Flag("cloak-port",
|
||||||
"Port which should be used for host cloaking.").
|
"Port which should be used for host cloaking.").
|
||||||
@@ -110,6 +115,11 @@ var (
|
|||||||
Envar("MTG_MULTIPLEX_PERCONNECTION").
|
Envar("MTG_MULTIPLEX_PERCONNECTION").
|
||||||
Default("50").
|
Default("50").
|
||||||
Uint()
|
Uint()
|
||||||
|
runNTPServers = runCommand.Flag("ntp-server",
|
||||||
|
"A list of NTP servers to use.").
|
||||||
|
Envar("MTG_NTP_SERVERS").
|
||||||
|
Default("0.pool.ntp.org", "1.pool.ntp.org", "2.pool.ntp.org", "3.pool.ntp.org").
|
||||||
|
Strings()
|
||||||
runSecret = runCommand.Arg("secret", "Secret of this proxy.").Required().HexBytes()
|
runSecret = runCommand.Arg("secret", "Secret of this proxy.").Required().HexBytes()
|
||||||
runAdtag = runCommand.Arg("adtag", "ADTag of the proxy.").HexBytes()
|
runAdtag = runCommand.Arg("adtag", "ADTag of the proxy.").HexBytes()
|
||||||
)
|
)
|
||||||
@@ -130,6 +140,7 @@ func main() {
|
|||||||
err := config.Init(
|
err := config.Init(
|
||||||
config.Opt{Option: config.OptionTypeDebug, Value: *runDebug},
|
config.Opt{Option: config.OptionTypeDebug, Value: *runDebug},
|
||||||
config.Opt{Option: config.OptionTypeVerbose, Value: *runVerbose},
|
config.Opt{Option: config.OptionTypeVerbose, Value: *runVerbose},
|
||||||
|
config.Opt{Option: config.OptionTypePreferIP, Value: *runPreferIP},
|
||||||
config.Opt{Option: config.OptionTypeBind, Value: *runBind},
|
config.Opt{Option: config.OptionTypeBind, Value: *runBind},
|
||||||
config.Opt{Option: config.OptionTypePublicIPv4, Value: *runPublicIPv4},
|
config.Opt{Option: config.OptionTypePublicIPv4, Value: *runPublicIPv4},
|
||||||
config.Opt{Option: config.OptionTypePublicIPv6, Value: *runPublicIPv6},
|
config.Opt{Option: config.OptionTypePublicIPv6, Value: *runPublicIPv6},
|
||||||
@@ -143,6 +154,7 @@ func main() {
|
|||||||
config.Opt{Option: config.OptionTypeCloakPort, Value: *runTLSCloakPort},
|
config.Opt{Option: config.OptionTypeCloakPort, Value: *runTLSCloakPort},
|
||||||
config.Opt{Option: config.OptionTypeAntiReplayMaxSize, Value: *runAntiReplayMaxSize},
|
config.Opt{Option: config.OptionTypeAntiReplayMaxSize, Value: *runAntiReplayMaxSize},
|
||||||
config.Opt{Option: config.OptionTypeMultiplexPerConnection, Value: *runMultiplexPerConnection},
|
config.Opt{Option: config.OptionTypeMultiplexPerConnection, Value: *runMultiplexPerConnection},
|
||||||
|
config.Opt{Option: config.OptionTypeNTPServers, Value: *runNTPServers},
|
||||||
config.Opt{Option: config.OptionTypeSecret, Value: *runSecret},
|
config.Opt{Option: config.OptionTypeSecret, Value: *runSecret},
|
||||||
config.Opt{Option: config.OptionTypeAdtag, Value: *runAdtag},
|
config.Opt{Option: config.OptionTypeAdtag, Value: *runAdtag},
|
||||||
)
|
)
|
||||||
|
|||||||
+3
-8
@@ -7,20 +7,15 @@ import (
|
|||||||
|
|
||||||
"github.com/beevik/ntp"
|
"github.com/beevik/ntp"
|
||||||
"go.uber.org/zap"
|
"go.uber.org/zap"
|
||||||
|
|
||||||
|
"github.com/9seconds/mtg/config"
|
||||||
)
|
)
|
||||||
|
|
||||||
const autoUpdatePeriod = time.Minute
|
const autoUpdatePeriod = time.Minute
|
||||||
|
|
||||||
var ntpEndpoints = [...]string{
|
|
||||||
"0.pool.ntp.org",
|
|
||||||
"1.pool.ntp.org",
|
|
||||||
"2.pool.ntp.org",
|
|
||||||
"3.pool.ntp.org",
|
|
||||||
}
|
|
||||||
|
|
||||||
// Fetch fetches the data on time drift.
|
// Fetch fetches the data on time drift.
|
||||||
func Fetch() (time.Duration, error) {
|
func Fetch() (time.Duration, error) {
|
||||||
url := ntpEndpoints[rand.Intn(len(ntpEndpoints))]
|
url := config.C.NTPServers[rand.Intn(len(config.C.NTPServers))]
|
||||||
|
|
||||||
resp, err := ntp.Query(url)
|
resp, err := ntp.Query(url)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|||||||
+4
-3
@@ -11,7 +11,7 @@ import (
|
|||||||
"github.com/9seconds/mtg/protocol"
|
"github.com/9seconds/mtg/protocol"
|
||||||
)
|
)
|
||||||
|
|
||||||
const directPipeBufferSize = 1024 * 1024
|
const directPipeBufferSize = 1024
|
||||||
|
|
||||||
func directConnection(request *protocol.TelegramRequest) error {
|
func directConnection(request *protocol.TelegramRequest) error {
|
||||||
telegramConnRaw, err := obfuscated2.TelegramProtocol(request)
|
telegramConnRaw, err := obfuscated2.TelegramProtocol(request)
|
||||||
@@ -42,8 +42,9 @@ func directPipe(dst io.WriteCloser, src io.ReadCloser, wg *sync.WaitGroup, logge
|
|||||||
wg.Done()
|
wg.Done()
|
||||||
}()
|
}()
|
||||||
|
|
||||||
buf := make([]byte, directPipeBufferSize)
|
buf := [directPipeBufferSize]byte{}
|
||||||
if _, err := io.CopyBuffer(dst, src, buf); err != nil {
|
|
||||||
|
if _, err := io.CopyBuffer(dst, src, buf[:]); err != nil {
|
||||||
logger.Debugw("Cannot pump sockets", "error", err)
|
logger.Debugw("Cannot pump sockets", "error", err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+26
-11
@@ -7,6 +7,7 @@ import (
|
|||||||
|
|
||||||
"go.uber.org/zap"
|
"go.uber.org/zap"
|
||||||
|
|
||||||
|
"github.com/9seconds/mtg/config"
|
||||||
"github.com/9seconds/mtg/conntypes"
|
"github.com/9seconds/mtg/conntypes"
|
||||||
"github.com/9seconds/mtg/utils"
|
"github.com/9seconds/mtg/utils"
|
||||||
"github.com/9seconds/mtg/wrappers/stream"
|
"github.com/9seconds/mtg/wrappers/stream"
|
||||||
@@ -29,17 +30,7 @@ func (b *baseTelegram) Secret() []byte {
|
|||||||
|
|
||||||
func (b *baseTelegram) dial(dc conntypes.DC,
|
func (b *baseTelegram) dial(dc conntypes.DC,
|
||||||
protocol conntypes.ConnectionProtocol) (conntypes.StreamReadWriteCloser, error) {
|
protocol conntypes.ConnectionProtocol) (conntypes.StreamReadWriteCloser, error) {
|
||||||
addresses := make([]string, 0, 2)
|
for _, addr := range b.getAddresses(dc, protocol) {
|
||||||
|
|
||||||
if protocol&conntypes.ConnectionProtocolIPv6 != 0 {
|
|
||||||
addresses = append(addresses, b.chooseAddress(b.v6Addresses, dc, b.v6DefaultDC))
|
|
||||||
}
|
|
||||||
|
|
||||||
if protocol&conntypes.ConnectionProtocolIPv4 != 0 {
|
|
||||||
addresses = append(addresses, b.chooseAddress(b.v4Addresses, dc, b.v4DefaultDC))
|
|
||||||
}
|
|
||||||
|
|
||||||
for _, addr := range addresses {
|
|
||||||
conn, err := b.dialer.Dial("tcp", addr)
|
conn, err := b.dialer.Dial("tcp", addr)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
b.logger.Infow("Cannot dial to Telegram", "address", addr, "error", err)
|
b.logger.Infow("Cannot dial to Telegram", "address", addr, "error", err)
|
||||||
@@ -57,6 +48,30 @@ func (b *baseTelegram) dial(dc conntypes.DC,
|
|||||||
return nil, errors.New("cannot dial to the chosen DC")
|
return nil, errors.New("cannot dial to the chosen DC")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (b *baseTelegram) getAddresses(dc conntypes.DC, protocol conntypes.ConnectionProtocol) []string {
|
||||||
|
addresses := make([]string, 0, 2)
|
||||||
|
protos := []conntypes.ConnectionProtocol{
|
||||||
|
conntypes.ConnectionProtocolIPv6,
|
||||||
|
conntypes.ConnectionProtocolIPv4,
|
||||||
|
}
|
||||||
|
|
||||||
|
if config.C.PreferIP == config.PreferIPv4 {
|
||||||
|
protos[0], protos[1] = protos[1], protos[0]
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, proto := range protos {
|
||||||
|
switch {
|
||||||
|
case proto&protocol == 0:
|
||||||
|
case proto&conntypes.ConnectionProtocolIPv6 != 0:
|
||||||
|
addresses = append(addresses, b.chooseAddress(b.v6Addresses, dc, b.v6DefaultDC))
|
||||||
|
case proto&conntypes.ConnectionProtocolIPv4 != 0:
|
||||||
|
addresses = append(addresses, b.chooseAddress(b.v4Addresses, dc, b.v4DefaultDC))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return addresses
|
||||||
|
}
|
||||||
|
|
||||||
func (b *baseTelegram) chooseAddress(addresses map[conntypes.DC][]string,
|
func (b *baseTelegram) chooseAddress(addresses map[conntypes.DC][]string,
|
||||||
dc, defaultDC conntypes.DC) string {
|
dc, defaultDC conntypes.DC) string {
|
||||||
addrs, ok := addresses[dc]
|
addrs, ok := addresses[dc]
|
||||||
|
|||||||
@@ -25,7 +25,7 @@ func (c ClientHello) Digest() []byte {
|
|||||||
}
|
}
|
||||||
|
|
||||||
mac := hmac.New(sha256.New, config.C.Secret)
|
mac := hmac.New(sha256.New, config.C.Secret)
|
||||||
mac.Write(rec.Bytes()) // nolint: errcheck
|
rec.WriteBytes(mac)
|
||||||
computedDigest := mac.Sum(nil)
|
computedDigest := mac.Sum(nil)
|
||||||
|
|
||||||
for i := range computedDigest {
|
for i := range computedDigest {
|
||||||
|
|||||||
+10
-3
@@ -1,5 +1,7 @@
|
|||||||
package tlstypes
|
package tlstypes
|
||||||
|
|
||||||
|
import "io"
|
||||||
|
|
||||||
type RecordType uint8
|
type RecordType uint8
|
||||||
|
|
||||||
const (
|
const (
|
||||||
@@ -69,11 +71,16 @@ var (
|
|||||||
)
|
)
|
||||||
|
|
||||||
type Byter interface {
|
type Byter interface {
|
||||||
Bytes() []byte
|
WriteBytes(io.Writer)
|
||||||
|
Len() int
|
||||||
}
|
}
|
||||||
|
|
||||||
type RawBytes []byte
|
type RawBytes []byte
|
||||||
|
|
||||||
func (r RawBytes) Bytes() []byte {
|
func (r RawBytes) WriteBytes(writer io.Writer) {
|
||||||
return []byte(r)
|
writer.Write(r) // nolint: errcheck
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r RawBytes) Len() int {
|
||||||
|
return len(r)
|
||||||
}
|
}
|
||||||
|
|||||||
+16
-9
@@ -1,7 +1,7 @@
|
|||||||
package tlstypes
|
package tlstypes
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"io"
|
||||||
|
|
||||||
"github.com/9seconds/mtg/utils"
|
"github.com/9seconds/mtg/utils"
|
||||||
)
|
)
|
||||||
@@ -14,24 +14,31 @@ type Handshake struct {
|
|||||||
Tail Byter
|
Tail Byter
|
||||||
}
|
}
|
||||||
|
|
||||||
func (h *Handshake) Bytes() []byte {
|
func (h *Handshake) WriteBytes(writer io.Writer) {
|
||||||
buf := bytes.Buffer{}
|
packetBuf := acquireBytesBuffer()
|
||||||
packetBuf := bytes.Buffer{}
|
defer releaseBytesBuffer(packetBuf)
|
||||||
|
|
||||||
buf.WriteByte(byte(h.Type))
|
writer.Write([]byte{byte(h.Type)}) // nolint: errcheck
|
||||||
|
|
||||||
packetBuf.Write(h.Version.Bytes())
|
packetBuf.Write(h.Version.Bytes())
|
||||||
packetBuf.Write(h.Random[:])
|
packetBuf.Write(h.Random[:])
|
||||||
packetBuf.WriteByte(byte(len(h.SessionID)))
|
packetBuf.WriteByte(byte(len(h.SessionID)))
|
||||||
packetBuf.Write(h.SessionID)
|
packetBuf.Write(h.SessionID)
|
||||||
packetBuf.Write(h.Tail.Bytes())
|
h.Tail.WriteBytes(packetBuf)
|
||||||
|
|
||||||
sizeUint24 := utils.ToUint24(uint32(packetBuf.Len()))
|
sizeUint24 := utils.ToUint24(uint32(packetBuf.Len()))
|
||||||
sizeUint24Bytes := sizeUint24[:]
|
sizeUint24Bytes := sizeUint24[:]
|
||||||
sizeUint24Bytes[0], sizeUint24Bytes[2] = sizeUint24Bytes[2], sizeUint24Bytes[0]
|
sizeUint24Bytes[0], sizeUint24Bytes[2] = sizeUint24Bytes[2], sizeUint24Bytes[0]
|
||||||
|
|
||||||
buf.Write(sizeUint24Bytes)
|
writer.Write(sizeUint24Bytes) // nolint: errcheck
|
||||||
packetBuf.WriteTo(&buf) // nolint: errcheck
|
packetBuf.WriteTo(writer) // nolint: errcheck
|
||||||
|
}
|
||||||
|
|
||||||
return buf.Bytes()
|
func (h *Handshake) Len() int {
|
||||||
|
buf := acquireBytesBuffer()
|
||||||
|
defer releaseBytesBuffer(buf)
|
||||||
|
|
||||||
|
h.WriteBytes(buf)
|
||||||
|
|
||||||
|
return buf.Len()
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,23 @@
|
|||||||
|
package tlstypes
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
"sync"
|
||||||
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
poolBytesBuffer = sync.Pool{
|
||||||
|
New: func() interface{} {
|
||||||
|
return &bytes.Buffer{}
|
||||||
|
},
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
func acquireBytesBuffer() *bytes.Buffer {
|
||||||
|
return poolBytesBuffer.Get().(*bytes.Buffer)
|
||||||
|
}
|
||||||
|
|
||||||
|
func releaseBytesBuffer(buf *bytes.Buffer) {
|
||||||
|
buf.Reset()
|
||||||
|
poolBytesBuffer.Put(buf)
|
||||||
|
}
|
||||||
+8
-9
@@ -15,16 +15,15 @@ type Record struct {
|
|||||||
Data Byter
|
Data Byter
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r Record) Bytes() []byte {
|
func (r Record) WriteBytes(writer io.Writer) {
|
||||||
buf := bytes.Buffer{}
|
writer.Write([]byte{byte(r.Type)}) // nolint: errcheck
|
||||||
data := r.Data.Bytes()
|
writer.Write(r.Version.Bytes()) // nolint: errcheck
|
||||||
|
binary.Write(writer, binary.BigEndian, uint16(r.Data.Len())) // nolint: errcheck
|
||||||
|
r.Data.WriteBytes(writer)
|
||||||
|
}
|
||||||
|
|
||||||
buf.WriteByte(byte(r.Type))
|
func (r Record) Len() int {
|
||||||
buf.Write(r.Version.Bytes())
|
return 1 + 2 + 2 + r.Data.Len()
|
||||||
binary.Write(&buf, binary.BigEndian, uint16(len(data))) // nolint: errcheck
|
|
||||||
buf.Write(data)
|
|
||||||
|
|
||||||
return buf.Bytes()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func ReadRecord(reader io.Reader) (Record, error) {
|
func ReadRecord(reader io.Reader) (Record, error) {
|
||||||
|
|||||||
@@ -20,20 +20,22 @@ type ServerHello struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (s ServerHello) WelcomePacket() []byte {
|
func (s ServerHello) WelcomePacket() []byte {
|
||||||
|
buf := &bytes.Buffer{}
|
||||||
|
|
||||||
s.Random = [32]byte{}
|
s.Random = [32]byte{}
|
||||||
rec := Record{
|
rec := Record{
|
||||||
Type: RecordTypeHandshake,
|
Type: RecordTypeHandshake,
|
||||||
Version: Version12,
|
Version: Version12,
|
||||||
Data: &s,
|
Data: &s,
|
||||||
}
|
}
|
||||||
buf := bytes.NewBuffer(rec.Bytes())
|
rec.WriteBytes(buf)
|
||||||
|
|
||||||
recChangeCipher := Record{
|
recChangeCipher := Record{
|
||||||
Type: RecordTypeChangeCipherSpec,
|
Type: RecordTypeChangeCipherSpec,
|
||||||
Version: Version12,
|
Version: Version12,
|
||||||
Data: RawBytes([]byte{0x01}),
|
Data: RawBytes([]byte{0x01}),
|
||||||
}
|
}
|
||||||
buf.Write(recChangeCipher.Bytes())
|
recChangeCipher.WriteBytes(buf)
|
||||||
|
|
||||||
hostCert := make([]byte, 1024+mrand.Intn(3092))
|
hostCert := make([]byte, 1024+mrand.Intn(3092))
|
||||||
rand.Read(hostCert) // nolint: errcheck
|
rand.Read(hostCert) // nolint: errcheck
|
||||||
@@ -43,7 +45,8 @@ func (s ServerHello) WelcomePacket() []byte {
|
|||||||
Version: Version12,
|
Version: Version12,
|
||||||
Data: RawBytes(hostCert),
|
Data: RawBytes(hostCert),
|
||||||
}
|
}
|
||||||
buf.Write(recData.Bytes())
|
recData.WriteBytes(buf)
|
||||||
|
|
||||||
packet := buf.Bytes()
|
packet := buf.Bytes()
|
||||||
|
|
||||||
mac := hmac.New(sha256.New, config.C.Secret)
|
mac := hmac.New(sha256.New, config.C.Secret)
|
||||||
|
|||||||
@@ -3,10 +3,13 @@ package utils
|
|||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"net"
|
"net"
|
||||||
|
"time"
|
||||||
|
|
||||||
"github.com/9seconds/mtg/config"
|
"github.com/9seconds/mtg/config"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
const tcpKeepAlivePingPeriod = 2 * time.Second
|
||||||
|
|
||||||
func InitTCP(conn net.Conn) error {
|
func InitTCP(conn net.Conn) error {
|
||||||
tcpConn := conn.(*net.TCPConn)
|
tcpConn := conn.(*net.TCPConn)
|
||||||
|
|
||||||
@@ -22,5 +25,13 @@ func InitTCP(conn net.Conn) error {
|
|||||||
return fmt.Errorf("cannot set write buffer size: %w", err)
|
return fmt.Errorf("cannot set write buffer size: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if err := tcpConn.SetKeepAlive(true); err != nil {
|
||||||
|
return fmt.Errorf("cannot enable keep-alive: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := tcpConn.SetKeepAlivePeriod(tcpKeepAlivePingPeriod); err != nil {
|
||||||
|
return fmt.Errorf("cannot set keep-alive period: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -42,7 +42,9 @@ type wrapperMtprotoFrame struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (w *wrapperMtprotoFrame) Read() (conntypes.Packet, error) { // nolint: funlen
|
func (w *wrapperMtprotoFrame) Read() (conntypes.Packet, error) { // nolint: funlen
|
||||||
buf := &bytes.Buffer{}
|
buf := acquireMtprotoFrameBytesBuffer()
|
||||||
|
defer releaseMtprotoFrameBytesBuffer(buf)
|
||||||
|
|
||||||
sum := crc32.NewIEEE()
|
sum := crc32.NewIEEE()
|
||||||
writer := io.MultiWriter(buf, sum)
|
writer := io.MultiWriter(buf, sum)
|
||||||
|
|
||||||
@@ -71,7 +73,6 @@ func (w *wrapperMtprotoFrame) Read() (conntypes.Packet, error) { // nolint: funl
|
|||||||
}
|
}
|
||||||
|
|
||||||
buf.Reset()
|
buf.Reset()
|
||||||
buf.Grow(int(messageLength) - 4 - 4)
|
|
||||||
|
|
||||||
if _, err := io.CopyN(writer, w.parent, int64(messageLength)-4-4); err != nil {
|
if _, err := io.CopyN(writer, w.parent, int64(messageLength)-4-4); err != nil {
|
||||||
return nil, fmt.Errorf("cannot read the message frame: %w", err)
|
return nil, fmt.Errorf("cannot read the message frame: %w", err)
|
||||||
@@ -113,8 +114,8 @@ func (w *wrapperMtprotoFrame) Write(p conntypes.Packet) error {
|
|||||||
messageLength := 4 + 4 + len(p) + 4
|
messageLength := 4 + 4 + len(p) + 4
|
||||||
paddingLength := (aes.BlockSize - messageLength%aes.BlockSize) % aes.BlockSize
|
paddingLength := (aes.BlockSize - messageLength%aes.BlockSize) % aes.BlockSize
|
||||||
|
|
||||||
buf := &bytes.Buffer{}
|
buf := acquireMtprotoFrameBytesBuffer()
|
||||||
buf.Grow(messageLength + paddingLength)
|
defer releaseMtprotoFrameBytesBuffer(buf)
|
||||||
|
|
||||||
binary.Write(buf, binary.LittleEndian, uint32(messageLength)) // nolint: errcheck
|
binary.Write(buf, binary.LittleEndian, uint32(messageLength)) // nolint: errcheck
|
||||||
binary.Write(buf, binary.LittleEndian, w.writeSeqNo) // nolint: errcheck
|
binary.Write(buf, binary.LittleEndian, w.writeSeqNo) // nolint: errcheck
|
||||||
|
|||||||
@@ -0,0 +1,23 @@
|
|||||||
|
package packet
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
"sync"
|
||||||
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
poolMtprotoFrameBytesBuffer = sync.Pool{
|
||||||
|
New: func() interface{} {
|
||||||
|
return &bytes.Buffer{}
|
||||||
|
},
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
func acquireMtprotoFrameBytesBuffer() *bytes.Buffer {
|
||||||
|
return poolMtprotoFrameBytesBuffer.Get().(*bytes.Buffer)
|
||||||
|
}
|
||||||
|
|
||||||
|
func releaseMtprotoFrameBytesBuffer(buf *bytes.Buffer) {
|
||||||
|
buf.Reset()
|
||||||
|
poolMtprotoFrameBytesBuffer.Put(buf)
|
||||||
|
}
|
||||||
@@ -88,7 +88,9 @@ func (w *wrapperClientAbridged) Write(packet conntypes.Packet, acks *conntypes.C
|
|||||||
return nil
|
return nil
|
||||||
case packetLength < clientAbridgedLargePacketLength:
|
case packetLength < clientAbridgedLargePacketLength:
|
||||||
length24 := utils.ToUint24(uint32(packetLength))
|
length24 := utils.ToUint24(uint32(packetLength))
|
||||||
buf := bytes.Buffer{}
|
|
||||||
|
buf := acquireClientBytesBuffer()
|
||||||
|
defer releaseClientBytesBuffer(buf)
|
||||||
|
|
||||||
buf.WriteByte(byte(clientAbridgedSmallPacketLength))
|
buf.WriteByte(byte(clientAbridgedSmallPacketLength))
|
||||||
buf.Write(length24[:])
|
buf.Write(length24[:])
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
package packetack
|
package packetack
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
|
||||||
"encoding/binary"
|
"encoding/binary"
|
||||||
"fmt"
|
"fmt"
|
||||||
"math/rand"
|
"math/rand"
|
||||||
@@ -35,11 +34,13 @@ func (w *wrapperClientIntermediateSecure) Write(packet conntypes.Packet, acks *c
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
buf := bytes.Buffer{}
|
buf := acquireClientBytesBuffer()
|
||||||
|
defer releaseClientBytesBuffer(buf)
|
||||||
|
|
||||||
paddingLength := rand.Intn(4)
|
paddingLength := rand.Intn(4)
|
||||||
buf.Grow(4 + len(packet) + paddingLength)
|
buf.Grow(4 + len(packet) + paddingLength)
|
||||||
|
|
||||||
binary.Write(&buf, binary.LittleEndian, uint32(len(packet)+paddingLength)) // nolint: errcheck
|
binary.Write(buf, binary.LittleEndian, uint32(len(packet)+paddingLength)) // nolint: errcheck
|
||||||
buf.Write(packet)
|
buf.Write(packet)
|
||||||
buf.Write(make([]byte, paddingLength))
|
buf.Write(make([]byte, paddingLength))
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,23 @@
|
|||||||
|
package packetack
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
"sync"
|
||||||
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
poolClientBytesBuffer = sync.Pool{
|
||||||
|
New: func() interface{} {
|
||||||
|
return &bytes.Buffer{}
|
||||||
|
},
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
func acquireClientBytesBuffer() *bytes.Buffer {
|
||||||
|
return poolClientBytesBuffer.Get().(*bytes.Buffer)
|
||||||
|
}
|
||||||
|
|
||||||
|
func releaseClientBytesBuffer(buf *bytes.Buffer) {
|
||||||
|
buf.Reset()
|
||||||
|
poolClientBytesBuffer.Put(buf)
|
||||||
|
}
|
||||||
@@ -23,8 +23,8 @@ type wrapperProxy struct {
|
|||||||
|
|
||||||
func (w *wrapperProxy) Write(packet conntypes.Packet, acks *conntypes.ConnectionAcks) error {
|
func (w *wrapperProxy) Write(packet conntypes.Packet, acks *conntypes.ConnectionAcks) error {
|
||||||
buf := bytes.Buffer{}
|
buf := bytes.Buffer{}
|
||||||
|
|
||||||
flags := w.flags
|
flags := w.flags
|
||||||
|
|
||||||
if acks.Quick {
|
if acks.Quick {
|
||||||
flags |= rpc.ProxyRequestFlagsQuickAck
|
flags |= rpc.ProxyRequestFlagsQuickAck
|
||||||
}
|
}
|
||||||
@@ -43,6 +43,7 @@ func (w *wrapperProxy) Write(packet conntypes.Packet, acks *conntypes.Connection
|
|||||||
buf.WriteByte(byte(len(config.C.AdTag)))
|
buf.WriteByte(byte(len(config.C.AdTag)))
|
||||||
buf.Write(config.C.AdTag)
|
buf.Write(config.C.AdTag)
|
||||||
buf.Write(make([]byte, (4-buf.Len()%4)%4))
|
buf.Write(make([]byte, (4-buf.Len()%4)%4))
|
||||||
|
buf.Grow(len(packet))
|
||||||
buf.Write(packet)
|
buf.Write(packet)
|
||||||
|
|
||||||
return w.proxy.Write(buf.Bytes())
|
return w.proxy.Write(buf.Bytes())
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
package stream
|
package stream
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"bytes"
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"net"
|
"net"
|
||||||
@@ -39,13 +40,19 @@ func (w *wrapperFakeTLS) WriteTimeout(p []byte, timeout time.Duration) (int, err
|
|||||||
func (w *wrapperFakeTLS) write(p []byte, writeFunc func([]byte) (int, error)) (int, error) {
|
func (w *wrapperFakeTLS) write(p []byte, writeFunc func([]byte) (int, error)) (int, error) {
|
||||||
sum := 0
|
sum := 0
|
||||||
|
|
||||||
|
buf := acquireBytesBuffer()
|
||||||
|
defer releaseBytesBuffer(buf)
|
||||||
|
|
||||||
for _, v := range tlstypes.MakeRecords(p) {
|
for _, v := range tlstypes.MakeRecords(p) {
|
||||||
_, err := writeFunc(v.Bytes())
|
buf.Reset()
|
||||||
|
v.WriteBytes(buf)
|
||||||
|
|
||||||
|
_, err := writeFunc(buf.Bytes())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return sum, err
|
return sum, err
|
||||||
}
|
}
|
||||||
|
|
||||||
sum += len(v.Data.Bytes())
|
sum += v.Data.Len()
|
||||||
}
|
}
|
||||||
|
|
||||||
return sum, nil
|
return sum, nil
|
||||||
@@ -86,7 +93,10 @@ func NewFakeTLS(socket conntypes.StreamReadWriteCloser) conntypes.StreamReadWrit
|
|||||||
switch rec.Type {
|
switch rec.Type {
|
||||||
case tlstypes.RecordTypeChangeCipherSpec:
|
case tlstypes.RecordTypeChangeCipherSpec:
|
||||||
case tlstypes.RecordTypeApplicationData:
|
case tlstypes.RecordTypeApplicationData:
|
||||||
return rec.Data.Bytes(), nil
|
buf := &bytes.Buffer{}
|
||||||
|
rec.Data.WriteBytes(buf)
|
||||||
|
|
||||||
|
return buf.Bytes(), nil
|
||||||
default:
|
default:
|
||||||
return nil, fmt.Errorf("unsupported record type %v", rec.Type)
|
return nil, fmt.Errorf("unsupported record type %v", rec.Type)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
package stream
|
package stream
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
|
||||||
"crypto/aes"
|
"crypto/aes"
|
||||||
"crypto/cipher"
|
"crypto/cipher"
|
||||||
"crypto/md5" // nolint: gosec
|
"crypto/md5" // nolint: gosec
|
||||||
@@ -54,7 +53,9 @@ func mtprotoDeriveKeys(purpose mtprotoCipherPurpose,
|
|||||||
resp *rpc.NonceResponse,
|
resp *rpc.NonceResponse,
|
||||||
client, remote *net.TCPAddr,
|
client, remote *net.TCPAddr,
|
||||||
secret []byte) ([]byte, []byte) {
|
secret []byte) ([]byte, []byte) {
|
||||||
message := bytes.Buffer{}
|
message := acquireBytesBuffer()
|
||||||
|
defer releaseBytesBuffer(message)
|
||||||
|
|
||||||
message.Write(resp.Nonce) // nolint: gosec
|
message.Write(resp.Nonce) // nolint: gosec
|
||||||
message.Write(req.Nonce) // nolint: gosec
|
message.Write(req.Nonce) // nolint: gosec
|
||||||
message.Write(req.CryptoTS) // nolint: gosec
|
message.Write(req.CryptoTS) // nolint: gosec
|
||||||
|
|||||||
@@ -40,16 +40,26 @@ func (w *wrapperObfuscated2) Read(p []byte) (int, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (w *wrapperObfuscated2) WriteTimeout(p []byte, timeout time.Duration) (int, error) {
|
func (w *wrapperObfuscated2) WriteTimeout(p []byte, timeout time.Duration) (int, error) {
|
||||||
buf := make([]byte, len(p))
|
buffer := acquireBytesBuffer()
|
||||||
copy(buf, p)
|
defer releaseBytesBuffer(buffer)
|
||||||
|
|
||||||
|
buffer.Write(p)
|
||||||
|
|
||||||
|
buf := buffer.Bytes()
|
||||||
|
|
||||||
w.encryptor.XORKeyStream(buf, buf)
|
w.encryptor.XORKeyStream(buf, buf)
|
||||||
|
|
||||||
return w.parent.WriteTimeout(buf, timeout)
|
return w.parent.WriteTimeout(buf, timeout)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (w *wrapperObfuscated2) Write(p []byte) (int, error) {
|
func (w *wrapperObfuscated2) Write(p []byte) (int, error) {
|
||||||
buf := make([]byte, len(p))
|
buffer := acquireBytesBuffer()
|
||||||
copy(buf, p)
|
defer releaseBytesBuffer(buffer)
|
||||||
|
|
||||||
|
buffer.Write(p)
|
||||||
|
|
||||||
|
buf := buffer.Bytes()
|
||||||
|
|
||||||
w.encryptor.XORKeyStream(buf, buf)
|
w.encryptor.XORKeyStream(buf, buf)
|
||||||
|
|
||||||
return w.parent.Write(buf)
|
return w.parent.Write(buf)
|
||||||
|
|||||||
@@ -0,0 +1,23 @@
|
|||||||
|
package stream
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
"sync"
|
||||||
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
poolBytesBuffer = sync.Pool{
|
||||||
|
New: func() interface{} {
|
||||||
|
return &bytes.Buffer{}
|
||||||
|
},
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
func acquireBytesBuffer() *bytes.Buffer {
|
||||||
|
return poolBytesBuffer.Get().(*bytes.Buffer)
|
||||||
|
}
|
||||||
|
|
||||||
|
func releaseBytesBuffer(buf *bytes.Buffer) {
|
||||||
|
buf.Reset()
|
||||||
|
poolBytesBuffer.Put(buf)
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user