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

Merge remote-tracking branch 'origin/master' into stable

tags/v1.0.2
9seconds 6 лет назад
Родитель
Сommit
cdd93bd25f
22 измененных файлов: 328 добавлений и 108 удалений
  1. 1
    1
      .golangci.toml
  2. 1
    1
      Makefile
  3. 5
    2
      README.md
  4. 4
    4
      antireplay/cache.go
  5. 13
    2
      antireplay/init.go
  6. 8
    0
      antireplay/nilcache.go
  7. 3
    20
      faketls/client_protocol.go
  8. 71
    0
      faketls/cloak.go
  9. 9
    8
      go.mod
  10. 40
    34
      go.sum
  11. 9
    0
      hub/connection.go
  12. 4
    2
      proxy/proxy.go
  13. 22
    12
      run.sh
  14. 10
    0
      stats/interfaces.go
  15. 12
    0
      stats/multi_stats.go
  16. 27
    5
      stats/stats_prometheus.go
  17. 8
    0
      stats/stats_statsd.go
  18. 24
    14
      telegram/base.go
  19. 1
    1
      telegram/direct.go
  20. 7
    1
      telegram/init.go
  21. 1
    1
      telegram/middle.go
  22. 48
    0
      wrappers/rwc/ping.go

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

10
 
10
 
11
 [linters]
11
 [linters]
12
 enable-all = true
12
 enable-all = true
13
-disable = ["gochecknoglobals"]
13
+disable = ["gochecknoglobals", "gomnd"]

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

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

+ 5
- 2
README.md Просмотреть файл

159
 (probability is 1/(2^64)) but it could be quite effective to prevent
159
 (probability is 1/(2^64)) but it could be quite effective to prevent
160
 replays.
160
 replays.
161
 
161
 
162
+It is possible to disable this cache. To do that, please explicitly set
163
+its size to 0.
164
+
162
 
165
 
163
 ## FakeTLS
166
 ## FakeTLS
164
 
167
 
191
 | `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`.                                                                                                                                         |
194
 | `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`.                                                                                                                                         |
192
 | `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`.                                                   |
195
 | `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`.                                                   |
193
 | `MTG_STATSD_TAGS`             | `--statsd-tags`              |                                   | Which tags should we send to statsd with our metrics. Please specify them as `key=value` pairs.                                                                                                                                                                                 |
196
 | `MTG_STATSD_TAGS`             | `--statsd-tags`              |                                   | Which tags should we send to statsd with our metrics. Please specify them as `key=value` pairs.                                                                                                                                                                                 |
194
-| `MTG_BUFFER_WRITE`            | `-w`, `--write-buffer`       | `65536`                           | The size of TCP write buffer in bytes. Write buffer is the buffer for messages which are going from client to Telegram.                                                                                                                                                         |
195
-| `MTG_BUFFER_READ`             | `-r`, `--read-buffer`        | `131072`                          | The size of TCP read buffer in bytes. Read buffer is the buffer for messages from Telegram to client.                                                                                                                                                                           |
197
+| `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.                                                                                                                                                         |
198
+| `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.                                                                                                                                                                           |
196
 | `MTG_ANTIREPLAY_MAXSIZE`      | `--anti-replay-max-size`     | `128MB`                           | Max size of antireplay cache.                                                                                                                                                                                                                                                   |
199
 | `MTG_ANTIREPLAY_MAXSIZE`      | `--anti-replay-max-size`     | `128MB`                           | Max size of antireplay cache.                                                                                                                                                                                                                                                   |
197
 | `MTG_CLOAK_PORT`              | `--cloak-port`               | `443`                             | Which port we should use to connect to cloaked host in FakeTLS mode.                                                                                                                                                                                                            |
200
 | `MTG_CLOAK_PORT`              | `--cloak-port`               | `443`                             | Which port we should use to connect to cloaked host in FakeTLS mode.                                                                                                                                                                                                            |
198
 | `MTG_MULTIPLEX_PERCONNECTION` | `--multiplex-per-connection` | `50`                              | How many client connections can share a single Telegram connection in adtag mode                                                                                                                                                                                                |
201
 | `MTG_MULTIPLEX_PERCONNECTION` | `--multiplex-per-connection` | `50`                              | How many client connections can share a single Telegram connection in adtag mode                                                                                                                                                                                                |

+ 4
- 4
antireplay/cache.go Просмотреть файл

11
 	data *fastcache.Cache
11
 	data *fastcache.Cache
12
 }
12
 }
13
 
13
 
14
-func (c *cache) AddObfuscated2(data []byte) {
14
+func (c cache) AddObfuscated2(data []byte) {
15
 	c.data.Set(keyObfuscated2(data), nil)
15
 	c.data.Set(keyObfuscated2(data), nil)
16
 }
16
 }
17
 
17
 
18
-func (c *cache) AddTLS(data []byte) {
18
+func (c cache) AddTLS(data []byte) {
19
 	c.data.Set(keyTLS(data), nil)
19
 	c.data.Set(keyTLS(data), nil)
20
 }
20
 }
21
 
21
 
22
-func (c *cache) HasObfuscated2(data []byte) bool {
22
+func (c cache) HasObfuscated2(data []byte) bool {
23
 	return c.data.Has(keyObfuscated2(data))
23
 	return c.data.Has(keyObfuscated2(data))
24
 }
24
 }
25
 
25
 
26
-func (c *cache) HasTLS(data []byte) bool {
26
+func (c cache) HasTLS(data []byte) bool {
27
 	return c.data.Has(keyTLS(data))
27
 	return c.data.Has(keyTLS(data))
28
 }
28
 }
29
 
29
 

+ 13
- 2
antireplay/init.go Просмотреть файл

8
 	"github.com/9seconds/mtg/config"
8
 	"github.com/9seconds/mtg/config"
9
 )
9
 )
10
 
10
 
11
+type CacheInterface interface {
12
+	AddObfuscated2([]byte)
13
+	AddTLS([]byte)
14
+	HasObfuscated2([]byte) bool
15
+	HasTLS([]byte) bool
16
+}
17
+
11
 var (
18
 var (
12
-	Cache    cache
19
+	Cache    CacheInterface
13
 	initOnce sync.Once
20
 	initOnce sync.Once
14
 )
21
 )
15
 
22
 
16
 func Init() {
23
 func Init() {
17
 	initOnce.Do(func() {
24
 	initOnce.Do(func() {
18
-		Cache.data = fastcache.New(config.C.AntiReplayMaxSize)
25
+		if config.C.AntiReplayMaxSize == 0 {
26
+			Cache = nilCache{}
27
+		} else {
28
+			Cache = cache{fastcache.New(config.C.AntiReplayMaxSize)}
29
+		}
19
 	})
30
 	})
20
 }
31
 }

+ 8
- 0
antireplay/nilcache.go Просмотреть файл

1
+package antireplay
2
+
3
+type nilCache struct{}
4
+
5
+func (n nilCache) AddObfuscated2(_ []byte)      {}
6
+func (n nilCache) AddTLS(_ []byte)              {}
7
+func (n nilCache) HasObfuscated2(_ []byte) bool { return false }
8
+func (n nilCache) HasTLS(_ []byte) bool         { return false }

+ 3
- 20
faketls/client_protocol.go Просмотреть файл

8
 	"io"
8
 	"io"
9
 	"net"
9
 	"net"
10
 	"strconv"
10
 	"strconv"
11
-	"sync"
12
 	"time"
11
 	"time"
13
 
12
 
14
 	"github.com/9seconds/mtg/antireplay"
13
 	"github.com/9seconds/mtg/antireplay"
101
 }
100
 }
102
 
101
 
103
 func (c *ClientProtocol) cloakHost(clientConn io.ReadWriteCloser) {
102
 func (c *ClientProtocol) cloakHost(clientConn io.ReadWriteCloser) {
103
+	stats.Stats.CloakedRequest()
104
+
104
 	addr := net.JoinHostPort(config.C.CloakHost, strconv.Itoa(config.C.CloakPort))
105
 	addr := net.JoinHostPort(config.C.CloakHost, strconv.Itoa(config.C.CloakPort))
105
 	hostConn, err := net.Dial("tcp", addr)
106
 	hostConn, err := net.Dial("tcp", addr)
106
 
107
 
108
 		return
109
 		return
109
 	}
110
 	}
110
 
111
 
111
-	defer hostConn.Close()
112
-
113
-	wg := &sync.WaitGroup{}
114
-	wg.Add(2)
115
-
116
-	go c.pipe(hostConn, clientConn, wg)
117
-
118
-	go c.pipe(clientConn, hostConn, wg)
119
-
120
-	wg.Wait()
121
-}
122
-
123
-func (c *ClientProtocol) pipe(dst io.WriteCloser, src io.Reader, wg *sync.WaitGroup) {
124
-	defer func() {
125
-		wg.Done()
126
-		dst.Close()
127
-	}()
128
-
129
-	io.Copy(dst, src) // nolint: errcheck
112
+	cloak(clientConn, hostConn)
130
 }
113
 }
131
 
114
 
132
 func MakeClientProtocol() protocol.ClientProtocol {
115
 func MakeClientProtocol() protocol.ClientProtocol {

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

1
+package faketls
2
+
3
+import (
4
+	"context"
5
+	"io"
6
+	"sync"
7
+	"time"
8
+
9
+	"github.com/9seconds/mtg/wrappers/rwc"
10
+)
11
+
12
+const (
13
+	cloakLastActivityTimeout = 5 * time.Second
14
+	cloakMaxTimeout          = 30 * time.Second
15
+)
16
+
17
+func cloak(one, another io.ReadWriteCloser) {
18
+	defer func() {
19
+		one.Close()
20
+		another.Close()
21
+	}()
22
+
23
+	channelPing := make(chan struct{}, 1)
24
+	ctx, cancel := context.WithCancel(context.Background())
25
+	one = rwc.NewPing(ctx, one, channelPing)
26
+	another = rwc.NewPing(ctx, another, channelPing)
27
+	wg := &sync.WaitGroup{}
28
+
29
+	wg.Add(2)
30
+
31
+	go func() {
32
+		defer wg.Done()
33
+		io.Copy(one, another) // nolint: errcheck
34
+	}()
35
+
36
+	go func() {
37
+		defer wg.Done()
38
+		io.Copy(another, one) // nolint: errcheck
39
+	}()
40
+
41
+	go func() {
42
+		wg.Wait()
43
+		cancel()
44
+	}()
45
+
46
+	go func() {
47
+		lastActivityTimer := time.NewTimer(cloakLastActivityTimeout)
48
+		defer lastActivityTimer.Stop()
49
+
50
+		maxTimer := time.NewTimer(cloakMaxTimeout)
51
+		defer maxTimer.Stop()
52
+
53
+		for {
54
+			select {
55
+			case <-channelPing:
56
+				lastActivityTimer.Stop()
57
+				lastActivityTimer = time.NewTimer(cloakLastActivityTimeout)
58
+			case <-ctx.Done():
59
+				return
60
+			case <-lastActivityTimer.C:
61
+				cancel()
62
+				return
63
+			case <-maxTimer.C:
64
+				cancel()
65
+				return
66
+			}
67
+		}
68
+	}()
69
+
70
+	<-ctx.Done()
71
+}

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

3
 go 1.13
3
 go 1.13
4
 
4
 
5
 require (
5
 require (
6
-	github.com/VictoriaMetrics/fastcache v1.5.2
6
+	github.com/VictoriaMetrics/fastcache v1.5.7
7
 	github.com/alecthomas/units v0.0.0-20190924025748-f65c72e2690d
7
 	github.com/alecthomas/units v0.0.0-20190924025748-f65c72e2690d
8
 	github.com/beevik/ntp v0.2.0
8
 	github.com/beevik/ntp v0.2.0
9
-	github.com/cespare/xxhash/v2 v2.1.1 // indirect
10
-	github.com/prometheus/client_golang v1.2.1
11
-	github.com/prometheus/procfs v0.0.7 // indirect
9
+	github.com/golang/protobuf v1.3.3 // indirect
10
+	github.com/prometheus/client_golang v1.4.0
12
 	github.com/smira/go-statsd v1.3.1
11
 	github.com/smira/go-statsd v1.3.1
12
+	go.uber.org/atomic v1.5.1 // indirect
13
 	go.uber.org/multierr v1.4.0 // indirect
13
 	go.uber.org/multierr v1.4.0 // indirect
14
 	go.uber.org/zap v1.13.0
14
 	go.uber.org/zap v1.13.0
15
-	golang.org/x/crypto v0.0.0-20191117063200-497ca9f6d64f
16
-	golang.org/x/net v0.0.0-20191119073136-fc4aabc6c914 // indirect
17
-	golang.org/x/sys v0.0.0-20191119060738-e882bf8e40c2
18
-	golang.org/x/tools v0.0.0-20191118222007-07fc4c7f2b98 // indirect
15
+	golang.org/x/crypto v0.0.0-20200128174031-69ecbb4d6d5d
16
+	golang.org/x/lint v0.0.0-20200130185559-910be7a94367 // indirect
17
+	golang.org/x/net v0.0.0-20200202094626-16171245cfb2 // indirect
18
+	golang.org/x/sys v0.0.0-20200202164722-d101bd2416d5
19
+	golang.org/x/tools v0.0.0-20200204074204-1cc6d1ef6c74 // indirect
19
 	gopkg.in/alecthomas/kingpin.v2 v2.2.6
20
 	gopkg.in/alecthomas/kingpin.v2 v2.2.6
20
 )
21
 )

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

1
 github.com/BurntSushi/toml v0.3.1 h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ=
1
 github.com/BurntSushi/toml v0.3.1 h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ=
2
 github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
2
 github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
3
-github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU=
4
-github.com/OneOfOne/xxhash v1.2.5/go.mod h1:eZbhyaAYD41SGSSsnmcpxVoRiQ/MPUTjUdIIOT9Um7Q=
5
-github.com/VictoriaMetrics/fastcache v1.5.2 h1:Erd8iIuBAL9kke8JzM4+WxkKuFkHh3ktwLanJvDgR44=
6
-github.com/VictoriaMetrics/fastcache v1.5.2/go.mod h1:+jv9Ckb+za/P1ZRg/sulP5Ni1v49daAVERr0H3CuscE=
3
+github.com/VictoriaMetrics/fastcache v1.5.7 h1:4y6y0G8PRzszQUYIQHHssv/jgPHAb5qQuuDNdCbyAgw=
4
+github.com/VictoriaMetrics/fastcache v1.5.7/go.mod h1:ptDBkNMQI4RtmVo8VS/XwRY6RoTu1dAWCbrk+6WsEM8=
7
 github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc h1:cAKDfWh5VpdgMhJosfJnn5/FoN2SRZ4p7fJNX58YPaU=
5
 github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc h1:cAKDfWh5VpdgMhJosfJnn5/FoN2SRZ4p7fJNX58YPaU=
8
 github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=
6
 github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=
9
 github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751 h1:JYp7IbQjafoB+tBA3gMyHYHrpOtNuDiK/uB5uXxq5wM=
7
 github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751 h1:JYp7IbQjafoB+tBA3gMyHYHrpOtNuDiK/uB5uXxq5wM=
24
 github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8=
22
 github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8=
25
 github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM=
23
 github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM=
26
 github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw=
24
 github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw=
27
-github.com/cespare/xxhash v1.1.0 h1:a6HrQnmkObjyL+Gs60czilIUGqrzKutQD6XZog3p+ko=
28
-github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc=
29
-github.com/cespare/xxhash/v2 v2.0.1-0.20190104013014-3767db7a7e18/go.mod h1:HD5P3vAIAh+Y2GAxg0PrPN1P8WkepXGpjbUPDHJqqKM=
30
-github.com/cespare/xxhash/v2 v2.1.0 h1:yTUvW7Vhb89inJ+8irsUqiWjh8iT6sQPZiQzI6ReGkA=
31
-github.com/cespare/xxhash/v2 v2.1.0/go.mod h1:dgIUBU3pDso/gPgZ1osOZ0iQf77oPR28Tjxl5dIMyVM=
32
 github.com/cespare/xxhash/v2 v2.1.1 h1:6MnRN8NT7+YBpUIWxHtefFZOKTAPgGjpQSxqLNn0+qY=
25
 github.com/cespare/xxhash/v2 v2.1.1 h1:6MnRN8NT7+YBpUIWxHtefFZOKTAPgGjpQSxqLNn0+qY=
33
 github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
26
 github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
34
 github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
27
 github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
47
 github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
40
 github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
48
 github.com/golang/protobuf v1.3.2 h1:6nsPYzhq5kReh6QImI3k5qWzO4PEbvbIW2cwSfR/6xs=
41
 github.com/golang/protobuf v1.3.2 h1:6nsPYzhq5kReh6QImI3k5qWzO4PEbvbIW2cwSfR/6xs=
49
 github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
42
 github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
43
+github.com/golang/protobuf v1.3.3 h1:gyjaxf+svBWX08ZjK86iN9geUJF0H6gp2IRKX6Nf6/I=
44
+github.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw=
50
 github.com/golang/snappy v0.0.1 h1:Qgr9rKW7uDUkrbSmQeiDsGa8SjGyCOGtuasMWwvp2P4=
45
 github.com/golang/snappy v0.0.1 h1:Qgr9rKW7uDUkrbSmQeiDsGa8SjGyCOGtuasMWwvp2P4=
51
 github.com/golang/snappy v0.0.1/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
46
 github.com/golang/snappy v0.0.1/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
52
-github.com/google/go-cmp v0.3.0 h1:crn/baboCvb5fXaQ0IJ1SGTsTVrWpDsCWC8EGETZijY=
53
-github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
54
 github.com/google/go-cmp v0.3.1 h1:Xye71clBPdm5HgqGwUkwhbynsUJZhDbS20FvLhQ2izg=
47
 github.com/google/go-cmp v0.3.1 h1:Xye71clBPdm5HgqGwUkwhbynsUJZhDbS20FvLhQ2izg=
55
 github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
48
 github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
49
+github.com/google/go-cmp v0.4.0 h1:xsAVV57WRhGj6kEIi8ReJzQlHHqcBYCElAvkovg3B/4=
50
+github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
56
 github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
51
 github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
57
 github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI=
52
 github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI=
58
 github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU=
53
 github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU=
59
-github.com/json-iterator/go v1.1.7/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
54
+github.com/json-iterator/go v1.1.9/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
60
 github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w=
55
 github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w=
61
 github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
56
 github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
62
 github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
57
 github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
81
 github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
76
 github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
82
 github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw=
77
 github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw=
83
 github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5FsnadC4Ky3P0J6CfImo=
78
 github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5FsnadC4Ky3P0J6CfImo=
84
-github.com/prometheus/client_golang v1.2.1 h1:JnMpQc6ppsNgw9QPAGF6Dod479itz7lvlsMzzNayLOI=
85
-github.com/prometheus/client_golang v1.2.1/go.mod h1:XMU6Z2MjaRKVu/dC1qupJI9SiNkDYzz3xecMgSW/F+U=
79
+github.com/prometheus/client_golang v1.4.0 h1:YVIb/fVcOTMSqtqZWSKnHpSLBxu8DKgxq8z6RuBZwqI=
80
+github.com/prometheus/client_golang v1.4.0/go.mod h1:e9GMxYsXl05ICDXkRhurwBS4Q3OK1iX/F2sw+iXX5zU=
86
 github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910 h1:idejC8f05m9MGOsuEi1ATq9shN03HrxNkD/luQvxCv8=
81
 github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910 h1:idejC8f05m9MGOsuEi1ATq9shN03HrxNkD/luQvxCv8=
87
 github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo=
82
 github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo=
88
 github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90 h1:S/YWwWx/RA8rT8tKFRuGUZhuA90OyIBpPCXkcbwU8DE=
83
 github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90 h1:S/YWwWx/RA8rT8tKFRuGUZhuA90OyIBpPCXkcbwU8DE=
89
 github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
84
 github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
90
-github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4 h1:gQz4mCbXsO+nc9n1hCxHcGA3Zx3Eo+UHZoInFGUIXNM=
91
-github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
85
+github.com/prometheus/client_model v0.2.0 h1:uq5h0d+GuxiXLJLNABMgp2qUWDPiLvgCzz2dUR+/W/M=
86
+github.com/prometheus/client_model v0.2.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
92
 github.com/prometheus/common v0.4.1 h1:K0MGApIoQvMw27RTdJkPbr3JZ7DNbtxQNyi5STVM6Kw=
87
 github.com/prometheus/common v0.4.1 h1:K0MGApIoQvMw27RTdJkPbr3JZ7DNbtxQNyi5STVM6Kw=
93
 github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4=
88
 github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4=
94
-github.com/prometheus/common v0.7.0 h1:L+1lyG48J1zAQXA3RBX/nG/B3gjlHq0zTt2tlbJLyCY=
95
-github.com/prometheus/common v0.7.0/go.mod h1:DjGbpBbp5NYNiECxcL/VnbXCCaQpKd3tt26CguLLsqA=
89
+github.com/prometheus/common v0.9.1 h1:KOMtN28tlbam3/7ZKEYKHhKoJZYYj3gMH4uc62x7X7U=
90
+github.com/prometheus/common v0.9.1/go.mod h1:yhUN8i9wzaXS3w1O07YhxHEBxD+W35wd8bs7vj7HSQ4=
96
 github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d h1:GoAlyOgbOEIFdaDqxJVlbOQ1DtGmZWs/Qau0hIlk+WQ=
91
 github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d h1:GoAlyOgbOEIFdaDqxJVlbOQ1DtGmZWs/Qau0hIlk+WQ=
97
 github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
92
 github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
98
 github.com/prometheus/procfs v0.0.2 h1:6LJUbpNm42llc4HRCuvApCSWB/WfhuNo9K98Q9sNGfs=
93
 github.com/prometheus/procfs v0.0.2 h1:6LJUbpNm42llc4HRCuvApCSWB/WfhuNo9K98Q9sNGfs=
99
 github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA=
94
 github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA=
100
-github.com/prometheus/procfs v0.0.5 h1:3+auTFlqw+ZaQYJARz6ArODtkaIwtvBTx3N2NehQlL8=
101
-github.com/prometheus/procfs v0.0.5/go.mod h1:4A/X28fw3Fc593LaREMrKMqOKvUAntwMDaekg4FpcdQ=
102
-github.com/prometheus/procfs v0.0.7 h1:RS5GAlMbnkWkhs4+bPocMTmGjYkuCY5djjqEDdXOhcQ=
103
-github.com/prometheus/procfs v0.0.7/go.mod h1:7Qr8sr6344vo1JqZ6HhLceV9o3AJ1Ff+GxbHq6oeK9A=
95
+github.com/prometheus/procfs v0.0.8 h1:+fpWZdT24pJBiqJdAwYBjPSk+5YmQzYNPYzQsdzLkt8=
96
+github.com/prometheus/procfs v0.0.8/go.mod h1:7Qr8sr6344vo1JqZ6HhLceV9o3AJ1Ff+GxbHq6oeK9A=
104
 github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
97
 github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
105
 github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo=
98
 github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo=
106
 github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE=
99
 github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE=
107
 github.com/smira/go-statsd v1.3.1 h1:JalGiHNdK7GqVAPpg7j0Kwp2jZrz/fCg/B4ZuNuBY2w=
100
 github.com/smira/go-statsd v1.3.1 h1:JalGiHNdK7GqVAPpg7j0Kwp2jZrz/fCg/B4ZuNuBY2w=
108
 github.com/smira/go-statsd v1.3.1/go.mod h1:1srXJ9/pbnN04G8f4F1jUzsGOnwkPKXciyqpewGlkC4=
101
 github.com/smira/go-statsd v1.3.1/go.mod h1:1srXJ9/pbnN04G8f4F1jUzsGOnwkPKXciyqpewGlkC4=
109
-github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA=
110
-github.com/spaolacci/murmur3 v1.0.1-0.20190317074736-539464a789e9/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA=
111
 github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
102
 github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
112
 github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
103
 github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
113
 github.com/stretchr/testify v1.2.2 h1:bSDNvY7ZPG5RlJ8otE/7V6gMiyenm9RtJ7IUVIAoJ1w=
104
 github.com/stretchr/testify v1.2.2 h1:bSDNvY7ZPG5RlJ8otE/7V6gMiyenm9RtJ7IUVIAoJ1w=
118
 github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
109
 github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
119
 go.uber.org/atomic v1.5.0 h1:OI5t8sDa1Or+q8AeE+yKeB/SDYioSHAgcVljj9JIETY=
110
 go.uber.org/atomic v1.5.0 h1:OI5t8sDa1Or+q8AeE+yKeB/SDYioSHAgcVljj9JIETY=
120
 go.uber.org/atomic v1.5.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ=
111
 go.uber.org/atomic v1.5.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ=
112
+go.uber.org/atomic v1.5.1 h1:rsqfU5vBkVknbhUGbAUwQKR2H4ItV8tjJ+6kJX4cxHM=
113
+go.uber.org/atomic v1.5.1/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ=
121
 go.uber.org/multierr v1.3.0/go.mod h1:VgVr7evmIr6uPjLBxg28wmKNXyqE9akIJ5XnfpiKl+4=
114
 go.uber.org/multierr v1.3.0/go.mod h1:VgVr7evmIr6uPjLBxg28wmKNXyqE9akIJ5XnfpiKl+4=
122
 go.uber.org/multierr v1.4.0 h1:f3WCSC2KzAcBXGATIxAB1E2XuCpNU255wNKZ505qi3E=
115
 go.uber.org/multierr v1.4.0 h1:f3WCSC2KzAcBXGATIxAB1E2XuCpNU255wNKZ505qi3E=
123
 go.uber.org/multierr v1.4.0/go.mod h1:VgVr7evmIr6uPjLBxg28wmKNXyqE9akIJ5XnfpiKl+4=
116
 go.uber.org/multierr v1.4.0/go.mod h1:VgVr7evmIr6uPjLBxg28wmKNXyqE9akIJ5XnfpiKl+4=
129
 golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2 h1:VklqNMn3ovrHsnt90PveolxSbWFaJdECFbxSq0Mqo2M=
122
 golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2 h1:VklqNMn3ovrHsnt90PveolxSbWFaJdECFbxSq0Mqo2M=
130
 golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
123
 golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
131
 golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
124
 golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
132
-golang.org/x/crypto v0.0.0-20191117063200-497ca9f6d64f h1:kz4KIr+xcPUsI3VMoqWfPMvtnJ6MGfiVwsWSVzphMO4=
133
-golang.org/x/crypto v0.0.0-20191117063200-497ca9f6d64f/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
125
+golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
126
+golang.org/x/crypto v0.0.0-20200128174031-69ecbb4d6d5d h1:9FCpayM9Egr1baVnV1SX0H87m+XB0B8S0hAMi99X/3U=
127
+golang.org/x/crypto v0.0.0-20200128174031-69ecbb4d6d5d/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
134
 golang.org/x/lint v0.0.0-20190930215403-16217165b5de h1:5hukYrvBGR8/eNkX5mdUezrA6JiaEZDtJb9Ei+1LlBs=
128
 golang.org/x/lint v0.0.0-20190930215403-16217165b5de h1:5hukYrvBGR8/eNkX5mdUezrA6JiaEZDtJb9Ei+1LlBs=
135
 golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
129
 golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
130
+golang.org/x/lint v0.0.0-20200130185559-910be7a94367 h1:0IiAsCRByjO2QjX7ZPkw5oU9x+n1YqRL802rjC0c3Aw=
131
+golang.org/x/lint v0.0.0-20200130185559-910be7a94367/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY=
136
 golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc=
132
 golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc=
133
+golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee h1:WG0RUwxtNT4qqaXX3DPA8zHFNm/D9xaBpxzHt1WcA/E=
134
+golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg=
137
 golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
135
 golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
138
 golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
136
 golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
139
 golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
137
 golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
140
 golang.org/x/net v0.0.0-20190613194153-d28f0bde5980/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
138
 golang.org/x/net v0.0.0-20190613194153-d28f0bde5980/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
141
 golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
139
 golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
142
-golang.org/x/net v0.0.0-20191119073136-fc4aabc6c914 h1:MlY3mEfbnWGmUi4rtHOtNnnnN4UJRGSyLPx+DXA5Sq4=
143
-golang.org/x/net v0.0.0-20191119073136-fc4aabc6c914/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
140
+golang.org/x/net v0.0.0-20200202094626-16171245cfb2 h1:CCH4IOTTfewWjGOlSp+zGcjutRKlBEZQ6wTn8ozI/nI=
141
+golang.org/x/net v0.0.0-20200202094626-16171245cfb2/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
144
 golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
142
 golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
145
 golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4 h1:YUO/7uOKsKeq9UokNS62b8FYywz3ker1l1vDZRCRefw=
143
 golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4 h1:YUO/7uOKsKeq9UokNS62b8FYywz3ker1l1vDZRCRefw=
146
 golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
144
 golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
151
 golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
149
 golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
152
 golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
150
 golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
153
 golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
151
 golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
154
-golang.org/x/sys v0.0.0-20191010194322-b09406accb47 h1:/XfQ9z7ib8eEJX2hdgFTZJ/ntt0swNk5oYBziWeTCvY=
155
-golang.org/x/sys v0.0.0-20191010194322-b09406accb47/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
156
-golang.org/x/sys v0.0.0-20191119060738-e882bf8e40c2 h1:wAW1U21MfVN0sUipAD8952TBjGXMRHFKQugDlQ9RwwE=
157
-golang.org/x/sys v0.0.0-20191119060738-e882bf8e40c2/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
152
+golang.org/x/sys v0.0.0-20200122134326-e047566fdf82/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
153
+golang.org/x/sys v0.0.0-20200202164722-d101bd2416d5 h1:LfCXLvNmTYH9kEmVgqbnsWfruoXZIrh4YBgqVHtDvw0=
154
+golang.org/x/sys v0.0.0-20200202164722-d101bd2416d5/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
158
 golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
155
 golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
159
 golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
156
 golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
160
 golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
157
 golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
161
 golang.org/x/tools v0.0.0-20191029041327-9cc4af7d6b2c/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
158
 golang.org/x/tools v0.0.0-20191029041327-9cc4af7d6b2c/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
162
 golang.org/x/tools v0.0.0-20191029190741-b9c20aec41a5 h1:hKsoRgsbwY1NafxrwTs+k64bikrLBkAgPir1TNCj3Zs=
159
 golang.org/x/tools v0.0.0-20191029190741-b9c20aec41a5 h1:hKsoRgsbwY1NafxrwTs+k64bikrLBkAgPir1TNCj3Zs=
163
 golang.org/x/tools v0.0.0-20191029190741-b9c20aec41a5/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
160
 golang.org/x/tools v0.0.0-20191029190741-b9c20aec41a5/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
164
-golang.org/x/tools v0.0.0-20191118222007-07fc4c7f2b98 h1:tZwpOHmF1OEL9wJGSgBALnhFg/8VKjQTtctCX51GLNI=
165
-golang.org/x/tools v0.0.0-20191118222007-07fc4c7f2b98/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
161
+golang.org/x/tools v0.0.0-20200130002326-2f3ba24bd6e7/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
162
+golang.org/x/tools v0.0.0-20200204074204-1cc6d1ef6c74 h1:KW20qMcLRWuIgjdCpHFJbVZA7zsDKtFXPNcm7/eI5ZA=
163
+golang.org/x/tools v0.0.0-20200204074204-1cc6d1ef6c74/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
166
 golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
164
 golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
165
+golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
166
+golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543 h1:E7g+9GITq07hpfrRu66IVDexMakfv52eLZ2CXBWiKr4=
167
+golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
167
 gopkg.in/alecthomas/kingpin.v2 v2.2.6 h1:jMFz6MfLP0/4fUyZle81rXUoxOBFi19VUFKVDOQfozc=
168
 gopkg.in/alecthomas/kingpin.v2 v2.2.6 h1:jMFz6MfLP0/4fUyZle81rXUoxOBFi19VUFKVDOQfozc=
168
 gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw=
169
 gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw=
169
 gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
170
 gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
170
 gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY=
171
 gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY=
171
 gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
172
 gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
173
+gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 h1:YR8cESwS4TdDjEe65xsg0ogRM/Nc3DYOhEAlW+xobZo=
174
+gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
172
 gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI=
175
 gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI=
173
 gopkg.in/yaml.v2 v2.2.1 h1:mUhvW9EsL+naU5Q3cakzfE91YhliOondGd6ZrsDBHQE=
176
 gopkg.in/yaml.v2 v2.2.1 h1:mUhvW9EsL+naU5Q3cakzfE91YhliOondGd6ZrsDBHQE=
174
 gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
177
 gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
175
 gopkg.in/yaml.v2 v2.2.2 h1:ZCJp+EgiOT7lHqUV2J862kp8Qj64Jo6az82+3Td9dZw=
178
 gopkg.in/yaml.v2 v2.2.2 h1:ZCJp+EgiOT7lHqUV2J862kp8Qj64Jo6az82+3Td9dZw=
176
 gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
179
 gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
180
+gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
181
+gopkg.in/yaml.v2 v2.2.5 h1:ymVxjfMaHvXD8RqPRmzHHsB3VvucivSkIAvJFDI5O3c=
182
+gopkg.in/yaml.v2 v2.2.5/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
177
 honnef.co/go/tools v0.0.1-2019.2.3 h1:3JgtbtFHMiCmsznwGVTUWbgGov+pVqnlf1dEJTNAXeM=
183
 honnef.co/go/tools v0.0.1-2019.2.3 h1:3JgtbtFHMiCmsznwGVTUWbgGov+pVqnlf1dEJTNAXeM=
178
 honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg=
184
 honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg=

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

4
 	"fmt"
4
 	"fmt"
5
 	"math/rand"
5
 	"math/rand"
6
 	"sync"
6
 	"sync"
7
+	"time"
7
 
8
 
8
 	"go.uber.org/zap"
9
 	"go.uber.org/zap"
9
 
10
 
13
 	"github.com/9seconds/mtg/protocol"
14
 	"github.com/9seconds/mtg/protocol"
14
 )
15
 )
15
 
16
 
17
+const connectionTTL = time.Hour
18
+
16
 type connection struct {
19
 type connection struct {
17
 	conn            conntypes.PacketReadWriteCloser
20
 	conn            conntypes.PacketReadWriteCloser
18
 	proxyConns      map[string]*ProxyConn
21
 	proxyConns      map[string]*ProxyConn
31
 func (c *connection) run() {
34
 func (c *connection) run() {
32
 	defer c.Close()
35
 	defer c.Close()
33
 
36
 
37
+	ttl := time.NewTimer(connectionTTL)
38
+	defer ttl.Stop()
39
+
34
 	for {
40
 	for {
35
 		select {
41
 		select {
36
 		case <-c.channelDone:
42
 		case <-c.channelDone:
39
 			}
45
 			}
40
 
46
 
41
 			return
47
 			return
48
+		case <-ttl.C:
49
+			c.logger.Debugw("Closing connection by TTL")
50
+			c.Close()
42
 		case resp := <-c.channelRead:
51
 		case resp := <-c.channelRead:
43
 			if channel, ok := c.proxyConns[string(resp.ConnID[:])]; ok {
52
 			if channel, ok := c.proxyConns[string(resp.ConnID[:])]; ok {
44
 				if resp.Type == rpc.ProxyResponseTypeCloseExt {
53
 				if resp.Type == rpc.ProxyResponseTypeCloseExt {

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

30
 			case <-doneChan:
30
 			case <-doneChan:
31
 				return
31
 				return
32
 			default:
32
 			default:
33
-				p.Logger.Errorw("Cannot allocate incoming connection", "error", err)
34
-				continue
33
+				p.Logger.Fatalw("Cannot allocate incoming connection", "error", err)
35
 			}
34
 			}
36
 		}
35
 		}
37
 
36
 
42
 func (p *Proxy) accept(conn net.Conn) {
41
 func (p *Proxy) accept(conn net.Conn) {
43
 	defer func() {
42
 	defer func() {
44
 		conn.Close()
43
 		conn.Close()
44
+
45
 		if err := recover(); err != nil {
45
 		if err := recover(); err != nil {
46
 			stats.Stats.Crash()
46
 			stats.Stats.Crash()
47
 			p.Logger.Errorw("Crash of accept handler", "error", err)
47
 			p.Logger.Errorw("Crash of accept handler", "error", err)
69
 	clientConn, err := clientProtocol.Handshake(clientConn)
69
 	clientConn, err := clientProtocol.Handshake(clientConn)
70
 
70
 
71
 	if err != nil {
71
 	if err != nil {
72
+		stats.Stats.AuthenticationFailed()
72
 		logger.Warnw("Cannot perform client handshake", "error", err)
73
 		logger.Warnw("Cannot perform client handshake", "error", err)
74
+
73
 		return
75
 		return
74
 	}
76
 	}
75
 
77
 

+ 22
- 12
run.sh Просмотреть файл

11
 #   export MTG_IMAGENAME="nineseconds/mtg:latest"
11
 #   export MTG_IMAGENAME="nineseconds/mtg:latest"
12
 #   curl -sfL --compressed https://raw.githubusercontent.com/9seconds/mtg/master/run.sh | bash
12
 #   curl -sfL --compressed https://raw.githubusercontent.com/9seconds/mtg/master/run.sh | bash
13
 
13
 
14
-set -eu -o pipefail
14
+set -eu
15
 
15
 
16
 export XDG_CONFIG_HOME="${XDG_CONFIG_HOME:-$HOME/.config}"
16
 export XDG_CONFIG_HOME="${XDG_CONFIG_HOME:-$HOME/.config}"
17
 export MTG_CONFIG="${MTG_CONFIG:-$XDG_CONFIG_HOME/mtg}"
17
 export MTG_CONFIG="${MTG_CONFIG:-$XDG_CONFIG_HOME/mtg}"
18
 
18
 
19
+if ! [ -x "$(command -v docker)" ]; then
20
+    echo 'Error: docker is not installed.' >&2
21
+    exit 1
22
+fi
23
+
24
+id -Gn "$USER" | grep -qw 'docker' > /dev/null
25
+if [ $? -eq 0 ] || [ "$(id -u)" -eq '0' ]; then
26
+    DOCKER_CMD="$(command -v docker)"
27
+else
28
+    DOCKER_CMD="sudo $(command -v docker)"
29
+fi
30
+
19
 mkdir -p "$MTG_CONFIG" || true
31
 mkdir -p "$MTG_CONFIG" || true
20
 
32
 
21
 MTG_SECRET="$MTG_CONFIG/secret"
33
 MTG_SECRET="$MTG_CONFIG/secret"
22
 MTG_ENV="$MTG_CONFIG/env"
34
 MTG_ENV="$MTG_CONFIG/env"
23
 
35
 
24
 if [ ! -f "$MTG_ENV" ]; then
36
 if [ ! -f "$MTG_ENV" ]; then
25
-    MTG_IMAGENAME="${MTG_IMAGENAME:-nineseconds/mtg:latest}"
37
+    MTG_IMAGENAME="${MTG_IMAGENAME:-nineseconds/mtg:stable}"
26
     MTG_PORT="${MTG_PORT:-3128}"
38
     MTG_PORT="${MTG_PORT:-3128}"
27
     MTG_CONTAINER="${MTG_CONTAINER:-mtg}"
39
     MTG_CONTAINER="${MTG_CONTAINER:-mtg}"
28
 
40
 
29
-    echo "MTG_IMAGENAME=${MTG_IMAGENAME}" > "$MTG_ENV"
30
-    echo "MTG_PORT=${MTG_PORT}" >> "$MTG_ENV"
31
-    echo "MTG_CONTAINER=${MTG_CONTAINER}" >> "$MTG_ENV"
41
+    echo "MTG_IMAGENAME=$MTG_IMAGENAME" > "$MTG_ENV"
42
+    echo "MTG_PORT=$MTG_PORT" >> "$MTG_ENV"
43
+    echo "MTG_CONTAINER=$MTG_CONTAINER" >> "$MTG_ENV"
32
 fi
44
 fi
33
 
45
 
34
 set -a
46
 set -a
35
 source "$MTG_ENV"
47
 source "$MTG_ENV"
36
 set +a
48
 set +a
37
 
49
 
38
-docker pull "$MTG_IMAGENAME"
50
+$DOCKER_CMD pull "$MTG_IMAGENAME" > /dev/null
39
 if [ ! -f "$MTG_SECRET" ]; then
51
 if [ ! -f "$MTG_SECRET" ]; then
40
-    docker run \
52
+    $DOCKER_CMD run \
41
             --rm \
53
             --rm \
42
             "$MTG_IMAGENAME" \
54
             "$MTG_IMAGENAME" \
43
         generate-secret tls -c "$(openssl rand -hex 16).com" \
55
         generate-secret tls -c "$(openssl rand -hex 16).com" \
44
     > "$MTG_SECRET"
56
     > "$MTG_SECRET"
45
 fi
57
 fi
46
 
58
 
47
-echo
48
 echo "Proxy secret is $(cat "$MTG_SECRET"). Port is $MTG_PORT."
59
 echo "Proxy secret is $(cat "$MTG_SECRET"). Port is $MTG_PORT."
49
-echo
50
 
60
 
51
-docker ps --filter "Name=$MTG_CONTAINER" -aq | xargs -r docker rm -fv
52
-docker run \
61
+$DOCKER_CMD ps --filter "Name=$MTG_CONTAINER" -aq | xargs -r $DOCKER_CMD rm -fv > /dev/null
62
+$DOCKER_CMD run \
53
         -d \
63
         -d \
54
         --restart=unless-stopped \
64
         --restart=unless-stopped \
55
         --name "$MTG_CONTAINER" \
65
         --name "$MTG_CONTAINER" \
56
         --ulimit nofile=51200:51200 \
66
         --ulimit nofile=51200:51200 \
57
         -p "$MTG_PORT:3128" \
67
         -p "$MTG_PORT:3128" \
58
-    "$MTG_IMAGENAME" run "$(cat "$MTG_SECRET")"
68
+    "$MTG_IMAGENAME" run "$(cat "$MTG_SECRET")" > /dev/null

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

38
 	ReplayDetected()
38
 	ReplayDetected()
39
 }
39
 }
40
 
40
 
41
+type AuthenticationFailedInterface interface {
42
+	AuthenticationFailed()
43
+}
44
+
45
+type CloakedRequestInterface interface {
46
+	CloakedRequest()
47
+}
48
+
41
 type Interface interface {
49
 type Interface interface {
42
 	IngressTrafficInterface
50
 	IngressTrafficInterface
43
 	EgressTrafficInterface
51
 	EgressTrafficInterface
47
 	TelegramDisconnectedInterface
55
 	TelegramDisconnectedInterface
48
 	CrashInterface
56
 	CrashInterface
49
 	ReplayDetectedInterface
57
 	ReplayDetectedInterface
58
+	AuthenticationFailedInterface
59
+	CloakedRequestInterface
50
 }
60
 }

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

55
 		go m[i].ReplayDetected()
55
 		go m[i].ReplayDetected()
56
 	}
56
 	}
57
 }
57
 }
58
+
59
+func (m multiStats) AuthenticationFailed() {
60
+	for i := range m {
61
+		go m[i].AuthenticationFailed()
62
+	}
63
+}
64
+
65
+func (m multiStats) CloakedRequest() {
66
+	for i := range m {
67
+		go m[i].CloakedRequest()
68
+	}
69
+}

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

13
 )
13
 )
14
 
14
 
15
 type statsPrometheus struct {
15
 type statsPrometheus struct {
16
-	connections         *prometheus.GaugeVec
17
-	telegramConnections *prometheus.GaugeVec
18
-	traffic             *prometheus.GaugeVec
19
-	crashes             prometheus.Counter
20
-	replayAttacks       prometheus.Counter
16
+	connections          *prometheus.GaugeVec
17
+	telegramConnections  *prometheus.GaugeVec
18
+	traffic              *prometheus.GaugeVec
19
+	crashes              prometheus.Counter
20
+	replayAttacks        prometheus.Counter
21
+	authenticationFailed prometheus.Counter
22
+	cloakedRequests      prometheus.Counter
21
 }
23
 }
22
 
24
 
23
 func (s *statsPrometheus) IngressTraffic(traffic int) {
25
 func (s *statsPrometheus) IngressTraffic(traffic int) {
87
 	s.replayAttacks.Inc()
89
 	s.replayAttacks.Inc()
88
 }
90
 }
89
 
91
 
92
+func (s *statsPrometheus) AuthenticationFailed() {
93
+	s.authenticationFailed.Inc()
94
+}
95
+
96
+func (s *statsPrometheus) CloakedRequest() {
97
+	s.cloakedRequests.Inc()
98
+}
99
+
90
 func newStatsPrometheus(mux *http.ServeMux) Interface {
100
 func newStatsPrometheus(mux *http.ServeMux) Interface {
91
 	registry := prometheus.NewPedanticRegistry()
101
 	registry := prometheus.NewPedanticRegistry()
92
 
102
 
116
 			Name:      "replay_attacks",
126
 			Name:      "replay_attacks",
117
 			Help:      "How many replay attacks were prevented.",
127
 			Help:      "How many replay attacks were prevented.",
118
 		}),
128
 		}),
129
+		authenticationFailed: prometheus.NewCounter(prometheus.CounterOpts{
130
+			Namespace: config.C.StatsNamespace,
131
+			Name:      "authentication_failed",
132
+			Help:      "How many authentication failed events we've seen.",
133
+		}),
134
+		cloakedRequests: prometheus.NewCounter(prometheus.CounterOpts{
135
+			Namespace: config.C.StatsNamespace,
136
+			Name:      "cloaked_requests",
137
+			Help:      "How many requests were proxified during cloaking.",
138
+		}),
119
 	}
139
 	}
120
 
140
 
121
 	registry.MustRegister(instance.connections)
141
 	registry.MustRegister(instance.connections)
123
 	registry.MustRegister(instance.traffic)
143
 	registry.MustRegister(instance.traffic)
124
 	registry.MustRegister(instance.crashes)
144
 	registry.MustRegister(instance.crashes)
125
 	registry.MustRegister(instance.replayAttacks)
145
 	registry.MustRegister(instance.replayAttacks)
146
+	registry.MustRegister(instance.authenticationFailed)
147
+	registry.MustRegister(instance.cloakedRequests)
126
 
148
 
127
 	handler := promhttp.HandlerFor(registry, promhttp.HandlerOpts{})
149
 	handler := promhttp.HandlerFor(registry, promhttp.HandlerOpts{})
128
 	mux.Handle("/", handler)
150
 	mux.Handle("/", handler)

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

137
 	s.gauge("replay_attacks", 1)
137
 	s.gauge("replay_attacks", 1)
138
 }
138
 }
139
 
139
 
140
+func (s *statsStatsd) AuthenticationFailed() {
141
+	s.gauge("authentication_failed", 1)
142
+}
143
+
144
+func (s *statsStatsd) CloakedRequest() {
145
+	s.gauge("cloaked_requests", 1)
146
+}
147
+
140
 func (s *statsStatsd) gauge(metric string, value int64, tags ...*statsStatsdTag) {
148
 func (s *statsStatsd) gauge(metric string, value int64, tags ...*statsStatsdTag) {
141
 	key, tagList := s.prepareVals(metric, tags)
149
 	key, tagList := s.prepareVals(metric, tags)
142
 	s.initGauge(metric, key, tagList)
150
 	s.initGauge(metric, key, tagList)

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

1
 package telegram
1
 package telegram
2
 
2
 
3
 import (
3
 import (
4
-	"fmt"
4
+	"errors"
5
 	"math/rand"
5
 	"math/rand"
6
 	"net"
6
 	"net"
7
 
7
 
8
+	"go.uber.org/zap"
9
+
8
 	"github.com/9seconds/mtg/conntypes"
10
 	"github.com/9seconds/mtg/conntypes"
9
 	"github.com/9seconds/mtg/utils"
11
 	"github.com/9seconds/mtg/utils"
10
 	"github.com/9seconds/mtg/wrappers/stream"
12
 	"github.com/9seconds/mtg/wrappers/stream"
12
 
14
 
13
 type baseTelegram struct {
15
 type baseTelegram struct {
14
 	dialer net.Dialer
16
 	dialer net.Dialer
17
+	logger *zap.SugaredLogger
15
 
18
 
16
 	secret      []byte
19
 	secret      []byte
17
 	v4DefaultDC conntypes.DC
20
 	v4DefaultDC conntypes.DC
18
-	V6DefaultDC conntypes.DC
21
+	v6DefaultDC conntypes.DC
19
 	v4Addresses map[conntypes.DC][]string
22
 	v4Addresses map[conntypes.DC][]string
20
 	v6Addresses map[conntypes.DC][]string
23
 	v6Addresses map[conntypes.DC][]string
21
 }
24
 }
26
 
29
 
27
 func (b *baseTelegram) dial(dc conntypes.DC,
30
 func (b *baseTelegram) dial(dc conntypes.DC,
28
 	protocol conntypes.ConnectionProtocol) (conntypes.StreamReadWriteCloser, error) {
31
 	protocol conntypes.ConnectionProtocol) (conntypes.StreamReadWriteCloser, error) {
29
-	addr := ""
32
+	addresses := make([]string, 0, 2)
30
 
33
 
31
-	switch protocol {
32
-	case conntypes.ConnectionProtocolIPv4:
33
-		addr = b.chooseAddress(b.v4Addresses, dc, b.v4DefaultDC)
34
-	default:
35
-		addr = b.chooseAddress(b.v6Addresses, dc, b.V6DefaultDC)
34
+	if protocol&conntypes.ConnectionProtocolIPv6 != 0 {
35
+		addresses = append(addresses, b.chooseAddress(b.v6Addresses, dc, b.v6DefaultDC))
36
 	}
36
 	}
37
 
37
 
38
-	conn, err := b.dialer.Dial("tcp", addr)
39
-	if err != nil {
40
-		return nil, fmt.Errorf("dial has failed: %w", err)
38
+	if protocol&conntypes.ConnectionProtocolIPv4 != 0 {
39
+		addresses = append(addresses, b.chooseAddress(b.v4Addresses, dc, b.v4DefaultDC))
41
 	}
40
 	}
42
 
41
 
43
-	if err := utils.InitTCP(conn); err != nil {
44
-		return nil, fmt.Errorf("cannot initialize tcp socket: %w", err)
42
+	for _, addr := range addresses {
43
+		conn, err := b.dialer.Dial("tcp", addr)
44
+		if err != nil {
45
+			b.logger.Infow("Cannot dial to Telegram", "address", addr, "error", err)
46
+			continue
47
+		}
48
+
49
+		if err := utils.InitTCP(conn); err != nil {
50
+			b.logger.Infow("Cannot initialize TCP socket", "address", addr, "error", err)
51
+			continue
52
+		}
53
+
54
+		return stream.NewTelegramConn(dc, conn), nil
45
 	}
55
 	}
46
 
56
 
47
-	return stream.NewTelegramConn(dc, conn), nil
57
+	return nil, errors.New("cannot dial to the chosen DC")
48
 }
58
 }
49
 
59
 
50
 func (b *baseTelegram) chooseAddress(addresses map[conntypes.DC][]string,
60
 func (b *baseTelegram) chooseAddress(addresses map[conntypes.DC][]string,

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

37
 		dc = conntypes.DCDefaultIdx
37
 		dc = conntypes.DCDefaultIdx
38
 	}
38
 	}
39
 
39
 
40
-	return d.baseTelegram.dial(dc-1, protocol)
40
+	return d.baseTelegram.dial(dc-1, conntypes.ConnectionProtocolAny)
41
 }
41
 }

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

4
 	"net"
4
 	"net"
5
 	"sync"
5
 	"sync"
6
 	"time"
6
 	"time"
7
+
8
+	"go.uber.org/zap"
7
 )
9
 )
8
 
10
 
9
 const telegramDialTimeout = 10 * time.Second
11
 const telegramDialTimeout = 10 * time.Second
17
 
19
 
18
 func Init() {
20
 func Init() {
19
 	initOnce.Do(func() {
21
 	initOnce.Do(func() {
22
+		logger := zap.S().Named("telegram")
23
+
20
 		Direct = &directTelegram{
24
 		Direct = &directTelegram{
21
 			baseTelegram: baseTelegram{
25
 			baseTelegram: baseTelegram{
22
 				dialer:      net.Dialer{Timeout: telegramDialTimeout},
26
 				dialer:      net.Dialer{Timeout: telegramDialTimeout},
27
+				logger:      logger.Named("direct"),
23
 				v4DefaultDC: directV4DefaultIdx,
28
 				v4DefaultDC: directV4DefaultIdx,
24
-				V6DefaultDC: directV6DefaultIdx,
29
+				v6DefaultDC: directV6DefaultIdx,
25
 				v4Addresses: directV4Addresses,
30
 				v4Addresses: directV4Addresses,
26
 				v6Addresses: directV6Addresses,
31
 				v6Addresses: directV6Addresses,
27
 			},
32
 			},
30
 		tg := &middleTelegram{
35
 		tg := &middleTelegram{
31
 			baseTelegram: baseTelegram{
36
 			baseTelegram: baseTelegram{
32
 				dialer: net.Dialer{Timeout: telegramDialTimeout},
37
 				dialer: net.Dialer{Timeout: telegramDialTimeout},
38
+				logger: logger.Named("middle"),
33
 			},
39
 			},
34
 		}
40
 		}
35
 		if err := tg.update(); err != nil {
41
 		if err := tg.update(); err != nil {

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

45
 	m.mutex.Lock()
45
 	m.mutex.Lock()
46
 	m.secret = secret
46
 	m.secret = secret
47
 	m.v4DefaultDC = v4DefaultDC
47
 	m.v4DefaultDC = v4DefaultDC
48
-	m.V6DefaultDC = v6DefaultDC
48
+	m.v6DefaultDC = v6DefaultDC
49
 	m.v4Addresses = v4Addresses
49
 	m.v4Addresses = v4Addresses
50
 	m.v6Addresses = v6Addresses
50
 	m.v6Addresses = v6Addresses
51
 	m.mutex.Unlock()
51
 	m.mutex.Unlock()

+ 48
- 0
wrappers/rwc/ping.go Просмотреть файл

1
+package rwc
2
+
3
+import (
4
+	"context"
5
+	"io"
6
+)
7
+
8
+type wrapperPing struct {
9
+	parent      io.ReadWriteCloser
10
+	ctx         context.Context
11
+	channelPing chan<- struct{}
12
+}
13
+
14
+func (w *wrapperPing) Read(p []byte) (int, error) {
15
+	n, err := w.parent.Read(p)
16
+	if err == nil {
17
+		select {
18
+		case <-w.ctx.Done():
19
+		case w.channelPing <- struct{}{}:
20
+		}
21
+	}
22
+
23
+	return n, err
24
+}
25
+
26
+func (w *wrapperPing) Write(p []byte) (int, error) {
27
+	n, err := w.parent.Write(p)
28
+	if err == nil {
29
+		select {
30
+		case <-w.ctx.Done():
31
+		case w.channelPing <- struct{}{}:
32
+		}
33
+	}
34
+
35
+	return n, err
36
+}
37
+
38
+func (w *wrapperPing) Close() error {
39
+	return w.parent.Close()
40
+}
41
+
42
+func NewPing(ctx context.Context, parent io.ReadWriteCloser, channelPing chan<- struct{}) io.ReadWriteCloser {
43
+	return &wrapperPing{
44
+		parent:      parent,
45
+		ctx:         ctx,
46
+		channelPing: channelPing,
47
+	}
48
+}

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