Przeglądaj źródła

Reset a project

tags/v2.0.0-rc1
9seconds 5 lat temu
rodzic
commit
baee322cd7
95 zmienionych plików z 2 dodań i 6505 usunięć
  1. 0
    36
      antireplay/cache.go
  2. 0
    30
      antireplay/init.go
  3. 0
    8
      antireplay/nilcache.go
  4. 0
    26
      cli/generate.go
  5. 0
    101
      cli/proxy.go
  6. 0
    43
      cli/utils.go
  7. 0
    312
      config/config.go
  8. 0
    78
      config/global_ips.go
  9. 0
    99
      config/urls.go
  10. 0
    6
      conntypes/acks.go
  11. 0
    5
      conntypes/dc.go
  12. 0
    24
      conntypes/id.go
  13. 0
    3
      conntypes/packet.go
  14. 0
    22
      conntypes/protocol.go
  15. 0
    29
      conntypes/type.go
  16. 0
    14
      conntypes/wrap_interfaces.go
  17. 0
    41
      conntypes/wrap_packet_ack_interfaces.go
  18. 0
    51
      conntypes/wrap_packet_interfaces.go
  19. 0
    56
      conntypes/wrap_stream_interfaces.go
  20. 0
    122
      faketls/client_protocol.go
  21. 0
    73
      faketls/cloak.go
  22. 0
    30
      faketls/consts.go
  23. 2
    24
      go.mod
  24. 0
    472
      go.sum
  25. 0
    172
      hub/connection.go
  26. 0
    70
      hub/connection_list.go
  27. 0
    40
      hub/hub.go
  28. 0
    24
      hub/init.go
  29. 0
    7
      hub/interface.go
  30. 0
    90
      hub/mux.go
  31. 0
    79
      hub/proxy_conn.go
  32. 0
    178
      main.go
  33. 0
    102
      mtproto/protocol.go
  34. 0
    28
      mtproto/rpc/consts.go
  35. 0
    5
      mtproto/rpc/handshake_request.go
  36. 0
    54
      mtproto/rpc/handshake_response.go
  37. 0
    50
      mtproto/rpc/nonce_request.go
  38. 0
    60
      mtproto/rpc/nonce_response.go
  39. 0
    66
      mtproto/rpc/proxy_flags.go
  40. 0
    53
      mtproto/rpc/proxy_response.go
  41. 0
    57
      ntp/ntp.go
  42. 0
    114
      obfuscated2/client_protocol.go
  43. 0
    54
      obfuscated2/frame.go
  44. 0
    68
      obfuscated2/telegram_protocol.go
  45. 0
    12
      protocol/interfaces.go
  46. 0
    17
      protocol/request.go
  47. 0
    49
      proxy/direct.go
  48. 0
    70
      proxy/middle.go
  49. 0
    100
      proxy/proxy.go
  50. 0
    68
      run.sh
  51. 0
    60
      stats/interfaces.go
  52. 0
    69
      stats/multi_stats.go
  53. 0
    41
      stats/stats.go
  54. 0
    156
      stats/stats_prometheus.go
  55. 0
    204
      stats/stats_statsd.go
  56. 0
    109
      telegram/api/addresses.go
  57. 0
    44
      telegram/api/api.go
  58. 0
    24
      telegram/api/secret.go
  59. 0
    91
      telegram/base.go
  60. 0
    41
      telegram/direct.go
  61. 0
    48
      telegram/init.go
  62. 0
    8
      telegram/interfaces.go
  63. 0
    75
      telegram/middle.go
  64. 0
    86
      tlstypes/client_hello.go
  65. 0
    90
      tlstypes/consts.go
  66. 0
    43
      tlstypes/handshake.go
  67. 0
    84
      tlstypes/record.go
  68. 0
    97
      tlstypes/server_hello.go
  69. 0
    28
      utils/init_tcp.go
  70. 0
    21
      utils/read_full.go
  71. 0
    15
      utils/reverse_bytes.go
  72. 0
    24
      utils/rlimit.go
  73. 0
    7
      utils/rlimit_windows.go
  74. 0
    25
      utils/signal_context.go
  75. 0
    23
      utils/signal_context_windows.go
  76. 0
    12
      utils/stream_cipher.go
  77. 0
    11
      utils/uint24.go
  78. 0
    165
      wrappers/packet/mtproto_frame.go
  79. 0
    130
      wrappers/packetack/client_abridged.go
  80. 0
    89
      wrappers/packetack/client_intermediate.go
  81. 0
    63
      wrappers/packetack/client_intermediate_secure.go
  82. 0
    108
      wrappers/packetack/proxy.go
  83. 0
    48
      wrappers/rwc/ping.go
  84. 0
    21
      wrappers/stream/base.go
  85. 0
    96
      wrappers/stream/blockcipher.go
  86. 0
    44
      wrappers/stream/buffered_reader.go
  87. 0
    123
      wrappers/stream/conn.go
  88. 0
    93
      wrappers/stream/ctx.go
  89. 0
    107
      wrappers/stream/faketls.go
  90. 0
    117
      wrappers/stream/mtproto_cipher.go
  91. 0
    93
      wrappers/stream/obfuscated2.go
  92. 0
    83
      wrappers/stream/rewind.go
  93. 0
    71
      wrappers/stream/stats_telegram.go
  94. 0
    66
      wrappers/stream/stats_traffic.go
  95. 0
    60
      wrappers/stream/timeout.go

+ 0
- 36
antireplay/cache.go Wyświetl plik

@@ -1,36 +0,0 @@
1
-package antireplay
2
-
3
-import "github.com/VictoriaMetrics/fastcache"
4
-
5
-var (
6
-	prefixObfuscated2 = []byte{0x00}
7
-	prefixTLS         = []byte{0x01}
8
-)
9
-
10
-type cache struct {
11
-	data *fastcache.Cache
12
-}
13
-
14
-func (c cache) AddObfuscated2(data []byte) {
15
-	c.data.Set(keyObfuscated2(data), nil)
16
-}
17
-
18
-func (c cache) AddTLS(data []byte) {
19
-	c.data.Set(keyTLS(data), nil)
20
-}
21
-
22
-func (c cache) HasObfuscated2(data []byte) bool {
23
-	return c.data.Has(keyObfuscated2(data))
24
-}
25
-
26
-func (c cache) HasTLS(data []byte) bool {
27
-	return c.data.Has(keyTLS(data))
28
-}
29
-
30
-func keyObfuscated2(data []byte) []byte {
31
-	return append(prefixObfuscated2, data...)
32
-}
33
-
34
-func keyTLS(data []byte) []byte {
35
-	return append(prefixTLS, data...)
36
-}

+ 0
- 30
antireplay/init.go Wyświetl plik

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

+ 0
- 8
antireplay/nilcache.go Wyświetl plik

@@ -1,8 +0,0 @@
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 }

+ 0
- 26
cli/generate.go Wyświetl plik

@@ -1,26 +0,0 @@
1
-package cli
2
-
3
-import (
4
-	"crypto/rand"
5
-	"encoding/hex"
6
-
7
-	"github.com/9seconds/mtg/config"
8
-)
9
-
10
-func Generate(secretType, hostname string) {
11
-	data := make([]byte, config.SimpleSecretLength)
12
-	if _, err := rand.Read(data); err != nil {
13
-		panic(err)
14
-	}
15
-
16
-	secret := hex.EncodeToString(data)
17
-
18
-	switch secretType {
19
-	case "simple":
20
-		PrintStdout(secret)
21
-	case "secured":
22
-		PrintStdout("dd" + secret)
23
-	default:
24
-		PrintStdout("ee" + secret + hex.EncodeToString([]byte(hostname)))
25
-	}
26
-}

+ 0
- 101
cli/proxy.go Wyświetl plik

@@ -1,101 +0,0 @@
1
-package cli
2
-
3
-import (
4
-	"net"
5
-	"os"
6
-	"time"
7
-
8
-	"github.com/9seconds/mtg/antireplay"
9
-	"github.com/9seconds/mtg/config"
10
-	"github.com/9seconds/mtg/faketls"
11
-	"github.com/9seconds/mtg/hub"
12
-	"github.com/9seconds/mtg/ntp"
13
-	"github.com/9seconds/mtg/obfuscated2"
14
-	"github.com/9seconds/mtg/proxy"
15
-	"github.com/9seconds/mtg/stats"
16
-	"github.com/9seconds/mtg/telegram"
17
-	"github.com/9seconds/mtg/utils"
18
-	"go.uber.org/zap"
19
-	"go.uber.org/zap/zapcore"
20
-)
21
-
22
-func Proxy() error { // nolint: funlen,cyclop
23
-	ctx := utils.GetSignalContext()
24
-
25
-	atom := zap.NewAtomicLevel()
26
-
27
-	switch {
28
-	case config.C.Debug:
29
-		atom.SetLevel(zapcore.DebugLevel)
30
-	case config.C.Verbose:
31
-		atom.SetLevel(zapcore.InfoLevel)
32
-	default:
33
-		atom.SetLevel(zapcore.ErrorLevel)
34
-	}
35
-
36
-	encoderCfg := zap.NewProductionEncoderConfig()
37
-	logger := zap.New(zapcore.NewCore(
38
-		zapcore.NewJSONEncoder(encoderCfg),
39
-		zapcore.Lock(os.Stderr),
40
-		atom,
41
-	))
42
-
43
-	zap.ReplaceGlobals(logger)
44
-	defer logger.Sync() // nolint: errcheck
45
-
46
-	if err := config.InitPublicAddress(ctx); err != nil {
47
-		Fatal(err)
48
-	}
49
-
50
-	zap.S().Debugw("Configuration", "config", config.Printable())
51
-
52
-	if config.C.MiddleProxyMode() {
53
-		zap.S().Infow("Use middle proxy connection to Telegram")
54
-
55
-		diff, err := ntp.Fetch()
56
-		if err != nil {
57
-			Fatal("Cannot fetch time data from NTP")
58
-		}
59
-
60
-		if diff > time.Second {
61
-			Fatal("Your local time is skewed and drift is bigger than a second. Please sync your time.")
62
-		}
63
-
64
-		go ntp.AutoUpdate()
65
-	} else {
66
-		zap.S().Infow("Use direct connection to Telegram")
67
-	}
68
-
69
-	PrintJSONStdout(config.GetURLs())
70
-
71
-	if err := stats.Init(ctx); err != nil {
72
-		Fatal(err)
73
-	}
74
-
75
-	antireplay.Init()
76
-	telegram.Init()
77
-	hub.Init(ctx)
78
-
79
-	proxyListener, err := net.Listen("tcp", config.C.Bind.String())
80
-	if err != nil {
81
-		Fatal(err)
82
-	}
83
-
84
-	go func() {
85
-		<-ctx.Done()
86
-		proxyListener.Close()
87
-	}()
88
-
89
-	app := &proxy.Proxy{
90
-		Logger:              zap.S().Named("proxy"),
91
-		Context:             ctx,
92
-		ClientProtocolMaker: obfuscated2.MakeClientProtocol,
93
-	}
94
-	if config.C.SecretMode == config.SecretModeTLS {
95
-		app.ClientProtocolMaker = faketls.MakeClientProtocol
96
-	}
97
-
98
-	app.Serve(proxyListener)
99
-
100
-	return nil
101
-}

+ 0
- 43
cli/utils.go Wyświetl plik

@@ -1,43 +0,0 @@
1
-package cli
2
-
3
-import (
4
-	"encoding/json"
5
-	"fmt"
6
-	"io"
7
-	"os"
8
-)
9
-
10
-func Fatal(arg interface{}) {
11
-	if value, ok := arg.(error); ok {
12
-		arg = fmt.Errorf("fatal error: %+v", value) // nolint: errorlint
13
-	}
14
-
15
-	PrintStderr(arg)
16
-	os.Exit(1)
17
-}
18
-
19
-func PrintStderr(args ...interface{}) {
20
-	fmt.Fprintln(os.Stderr, args...)
21
-}
22
-
23
-func PrintStdout(args ...interface{}) {
24
-	fmt.Println(args...) // nolint: forbidigo
25
-}
26
-
27
-func PrintJSONStderr(data interface{}) {
28
-	printJSON(os.Stderr, data)
29
-}
30
-
31
-func PrintJSONStdout(data interface{}) {
32
-	printJSON(os.Stdout, data)
33
-}
34
-
35
-func printJSON(writer io.Writer, data interface{}) {
36
-	encoder := json.NewEncoder(writer)
37
-	encoder.SetEscapeHTML(false)
38
-	encoder.SetIndent("", "  ")
39
-
40
-	if err := encoder.Encode(data); err != nil {
41
-		panic(err)
42
-	}
43
-}

+ 0
- 312
config/config.go Wyświetl plik

@@ -1,312 +0,0 @@
1
-package config
2
-
3
-import (
4
-	"bytes"
5
-	"context"
6
-	"encoding/json"
7
-	"errors"
8
-	"fmt"
9
-	"math"
10
-	"net"
11
-
12
-	"github.com/alecthomas/units"
13
-	statsd "github.com/smira/go-statsd"
14
-	"go.uber.org/zap"
15
-)
16
-
17
-type SecretMode uint8
18
-
19
-func (s SecretMode) String() string {
20
-	switch s {
21
-	case SecretModeSimple:
22
-		return "simple"
23
-	case SecretModeSecured:
24
-		return "secured"
25
-	case SecretModeTLS:
26
-		return "tls"
27
-	}
28
-
29
-	return "tls"
30
-}
31
-
32
-const (
33
-	SecretModeSimple SecretMode = iota
34
-	SecretModeSecured
35
-	SecretModeTLS
36
-)
37
-
38
-type PreferIP uint8
39
-
40
-const (
41
-	PreferIPv4 PreferIP = iota
42
-	PreferIPv6
43
-)
44
-
45
-const SimpleSecretLength = 16
46
-
47
-type OptionType uint8
48
-
49
-const (
50
-	OptionTypeDebug OptionType = iota
51
-	OptionTypeVerbose
52
-
53
-	OptionTypePreferIP
54
-
55
-	OptionTypeBind
56
-	OptionTypePublicIPv4
57
-	OptionTypePublicIPv6
58
-
59
-	OptionTypeStatsBind
60
-	OptionTypeStatsNamespace
61
-	OptionTypeStatsdAddress
62
-	OptionTypeStatsdTagsFormat
63
-	OptionTypeStatsdTags
64
-
65
-	OptionTypeWriteBufferSize
66
-	OptionTypeReadBufferSize
67
-
68
-	OptionTypeCloakPort
69
-
70
-	OptionTypeAntiReplayMaxSize
71
-
72
-	OptionTypeMultiplexPerConnection
73
-
74
-	OptionTypeNTPServers
75
-
76
-	OptionTypeSecret
77
-	OptionTypeAdtag
78
-)
79
-
80
-type Config struct {
81
-	Bind             *net.TCPAddr      `json:"bind"`
82
-	PublicIPv4       *net.TCPAddr      `json:"public_ipv4"`
83
-	PublicIPv6       *net.TCPAddr      `json:"public_ipv6"`
84
-	StatsBind        *net.TCPAddr      `json:"stats_bind"`
85
-	StatsdAddr       *net.TCPAddr      `json:"stats_addr"`
86
-	StatsdTagsFormat *statsd.TagFormat `json:"statsd_tags_format"`
87
-
88
-	StatsNamespace string            `json:"stats_namespace"`
89
-	CloakHost      string            `json:"cloak_host"`
90
-	StatsdTags     map[string]string `json:"statsd_tags"`
91
-
92
-	WriteBuffer int `json:"write_buffer"`
93
-	ReadBuffer  int `json:"read_buffer"`
94
-	CloakPort   int `json:"cloak_port"`
95
-
96
-	AntiReplayMaxSize int `json:"anti_replay_max_size"`
97
-
98
-	MultiplexPerConnection int `json:"multiplex_per_connection"`
99
-
100
-	Debug      bool       `json:"debug"`
101
-	Verbose    bool       `json:"verbose"`
102
-	SecretMode SecretMode `json:"secret_mode"`
103
-	PreferIP   PreferIP   `json:"prefer_ip"`
104
-	NTPServers []string   `json:"ntp_servers"`
105
-
106
-	Secret []byte `json:"secret"`
107
-	AdTag  []byte `json:"adtag"`
108
-}
109
-
110
-func (c *Config) ClientReadBuffer() int {
111
-	return c.ReadBuffer
112
-}
113
-
114
-func (c *Config) ClientWriteBuffer() int {
115
-	return c.WriteBuffer
116
-}
117
-
118
-func (c *Config) MiddleProxyMode() bool {
119
-	return len(c.AdTag) > 0
120
-}
121
-
122
-func (c *Config) ProxyReadBuffer() int {
123
-	value := c.ReadBuffer
124
-
125
-	if c.MiddleProxyMode() {
126
-		value = c.adjustProxyValue(value)
127
-	}
128
-
129
-	return value
130
-}
131
-
132
-func (c *Config) ProxyWriteBuffer() int {
133
-	value := c.WriteBuffer
134
-
135
-	if c.MiddleProxyMode() {
136
-		value = c.adjustProxyValue(value)
137
-	}
138
-
139
-	return value
140
-}
141
-
142
-func (c *Config) adjustProxyValue(value int) int {
143
-	if c.MultiplexPerConnection == 0 {
144
-		return value
145
-	}
146
-
147
-	fvalue := float64(value)
148
-
149
-	newValue := fvalue * 2 * math.Log(float64(c.MultiplexPerConnection))
150
-	newValue = math.Ceil(newValue)
151
-	newValue = math.Max(fvalue, newValue)
152
-
153
-	return int(newValue)
154
-}
155
-
156
-type Opt struct {
157
-	Option OptionType
158
-	Value  interface{}
159
-}
160
-
161
-var C = Config{}
162
-
163
-func Init(options ...Opt) error { // nolint: gocyclo, funlen, cyclop
164
-	for _, opt := range options {
165
-		switch opt.Option {
166
-		case OptionTypeDebug:
167
-			C.Debug = opt.Value.(bool)
168
-		case OptionTypeVerbose:
169
-			C.Verbose = opt.Value.(bool)
170
-		case OptionTypePreferIP:
171
-			value := opt.Value.(string)
172
-			switch value {
173
-			case "ipv4":
174
-				C.PreferIP = PreferIPv4
175
-			case "ipv6":
176
-				C.PreferIP = PreferIPv6
177
-			default:
178
-				return fmt.Errorf("incorrect direct IP mode %s", value)
179
-			}
180
-		case OptionTypeBind:
181
-			C.Bind = opt.Value.(*net.TCPAddr)
182
-		case OptionTypePublicIPv4:
183
-			C.PublicIPv4 = opt.Value.(*net.TCPAddr)
184
-			if C.PublicIPv4 == nil {
185
-				C.PublicIPv4 = &net.TCPAddr{}
186
-			}
187
-		case OptionTypePublicIPv6:
188
-			C.PublicIPv6 = opt.Value.(*net.TCPAddr)
189
-			if C.PublicIPv6 == nil {
190
-				C.PublicIPv6 = &net.TCPAddr{}
191
-			}
192
-		case OptionTypeStatsBind:
193
-			C.StatsBind = opt.Value.(*net.TCPAddr)
194
-		case OptionTypeStatsNamespace:
195
-			C.StatsNamespace = opt.Value.(string)
196
-		case OptionTypeStatsdAddress:
197
-			C.StatsdAddr = opt.Value.(*net.TCPAddr)
198
-		case OptionTypeStatsdTagsFormat:
199
-			value := opt.Value.(string)
200
-			switch value {
201
-			case "datadog":
202
-				C.StatsdTagsFormat = statsd.TagFormatDatadog
203
-			case "influxdb":
204
-				C.StatsdTagsFormat = statsd.TagFormatInfluxDB
205
-			default:
206
-				return fmt.Errorf("incorrect statsd tag %s", value)
207
-			}
208
-		case OptionTypeStatsdTags:
209
-			C.StatsdTags = opt.Value.(map[string]string)
210
-		case OptionTypeWriteBufferSize:
211
-			C.WriteBuffer = int(opt.Value.(units.Base2Bytes))
212
-		case OptionTypeReadBufferSize:
213
-			C.ReadBuffer = int(opt.Value.(units.Base2Bytes))
214
-		case OptionTypeCloakPort:
215
-			C.CloakPort = int(opt.Value.(uint16))
216
-		case OptionTypeAntiReplayMaxSize:
217
-			C.AntiReplayMaxSize = int(opt.Value.(units.Base2Bytes))
218
-		case OptionTypeMultiplexPerConnection:
219
-			C.MultiplexPerConnection = int(opt.Value.(uint))
220
-		case OptionTypeNTPServers:
221
-			C.NTPServers = opt.Value.([]string)
222
-			if len(C.NTPServers) == 0 {
223
-				return errors.New("ntp server list is empty")
224
-			}
225
-		case OptionTypeSecret:
226
-			C.Secret = opt.Value.([]byte)
227
-		case OptionTypeAdtag:
228
-			C.AdTag = opt.Value.([]byte)
229
-		default:
230
-			return fmt.Errorf("unknown tag %v", opt.Option)
231
-		}
232
-	}
233
-
234
-	switch {
235
-	case len(C.Secret) == 1+SimpleSecretLength && bytes.HasPrefix(C.Secret, []byte{0xdd}):
236
-		C.SecretMode = SecretModeSecured
237
-		C.Secret = bytes.TrimPrefix(C.Secret, []byte{0xdd})
238
-	case len(C.Secret) > SimpleSecretLength && bytes.HasPrefix(C.Secret, []byte{0xee}):
239
-		C.SecretMode = SecretModeTLS
240
-		secret := bytes.TrimPrefix(C.Secret, []byte{0xee})
241
-		C.Secret = secret[:SimpleSecretLength]
242
-		C.CloakHost = string(secret[SimpleSecretLength:])
243
-	case len(C.Secret) == SimpleSecretLength:
244
-		C.SecretMode = SecretModeSimple
245
-	default:
246
-		return errors.New("incorrect secret")
247
-	}
248
-
249
-	if C.MultiplexPerConnection == 0 {
250
-		return errors.New("cannot use 0 clients per connection for multiplexing")
251
-	}
252
-
253
-	if C.CloakHost != "" {
254
-		if _, err := net.LookupHost(C.CloakHost); err != nil {
255
-			zap.S().Warnw("Cannot resolve address of host", "hostname", C.CloakHost, "error", err)
256
-		}
257
-	}
258
-
259
-	return nil
260
-}
261
-
262
-func InitPublicAddress(ctx context.Context) error {
263
-	if C.PublicIPv4.Port == 0 {
264
-		C.PublicIPv4.Port = C.Bind.Port
265
-	}
266
-
267
-	if C.PublicIPv6.Port == 0 {
268
-		C.PublicIPv6.Port = C.Bind.Port
269
-	}
270
-
271
-	foundAddress := C.PublicIPv4.IP != nil || C.PublicIPv6.IP != nil
272
-
273
-	if C.PublicIPv4.IP == nil {
274
-		ip, err := getGlobalIPv4(ctx)
275
-		if err != nil {
276
-			zap.S().Warnw("Cannot resolve public address", "error", err)
277
-		} else {
278
-			C.PublicIPv4.IP = ip
279
-			foundAddress = true
280
-		}
281
-	}
282
-
283
-	if C.PublicIPv6.IP == nil {
284
-		ip, err := getGlobalIPv6(ctx)
285
-		if err != nil {
286
-			zap.S().Warnw("Cannot resolve public address", "error", err)
287
-		} else {
288
-			C.PublicIPv6.IP = ip
289
-			foundAddress = true
290
-		}
291
-	}
292
-
293
-	if !foundAddress {
294
-		return errors.New("cannot resolve any public address")
295
-	}
296
-
297
-	return nil
298
-}
299
-
300
-func Printable() interface{} {
301
-	data, err := json.Marshal(C)
302
-	if err != nil {
303
-		panic(err)
304
-	}
305
-
306
-	rv := map[string]interface{}{}
307
-	if err := json.Unmarshal(data, &rv); err != nil {
308
-		panic(err)
309
-	}
310
-
311
-	return rv
312
-}

+ 0
- 78
config/global_ips.go Wyświetl plik

@@ -1,78 +0,0 @@
1
-package config
2
-
3
-import (
4
-	"context"
5
-	"fmt"
6
-	"io"
7
-	"io/ioutil"
8
-	"net"
9
-	"net/http"
10
-	"strings"
11
-	"time"
12
-)
13
-
14
-const (
15
-	ifconfigAddress = "https://ifconfig.co/ip"
16
-	ifconfigTimeout = 10 * time.Second
17
-)
18
-
19
-func getGlobalIPv4(ctx context.Context) (net.IP, error) {
20
-	ip, err := fetchIP(ctx, "tcp4")
21
-	if err != nil || ip.To4() == nil {
22
-		return nil, fmt.Errorf("cannot find public ipv4 address: %w", err)
23
-	}
24
-
25
-	return ip, nil
26
-}
27
-
28
-func getGlobalIPv6(ctx context.Context) (net.IP, error) {
29
-	ip, err := fetchIP(ctx, "tcp6")
30
-	if err != nil || ip.To4() != nil {
31
-		return nil, fmt.Errorf("cannot find public ipv6 address: %w", err)
32
-	}
33
-
34
-	return ip, nil
35
-}
36
-
37
-func fetchIP(ctx context.Context, network string) (net.IP, error) {
38
-	dialer := &net.Dialer{FallbackDelay: -1}
39
-	client := &http.Client{
40
-		Jar:     nil,
41
-		Timeout: ifconfigTimeout,
42
-		Transport: &http.Transport{
43
-			DialContext: func(ctx context.Context, _, addr string) (net.Conn, error) {
44
-				return dialer.DialContext(ctx, network, addr)
45
-			},
46
-		},
47
-	}
48
-
49
-	req, err := http.NewRequest("GET", ifconfigAddress, nil)
50
-	if err != nil {
51
-		return nil, fmt.Errorf("cannot create a request: %w", err)
52
-	}
53
-
54
-	resp, err := client.Do(req.WithContext(ctx))
55
-	if err != nil {
56
-		if resp != nil {
57
-			io.Copy(ioutil.Discard, resp.Body) // nolint: errcheck
58
-		}
59
-
60
-		return nil, fmt.Errorf("cannot perform a request: %w", err)
61
-	}
62
-
63
-	defer resp.Body.Close()
64
-
65
-	respDataBytes, err := ioutil.ReadAll(resp.Body)
66
-	if err != nil {
67
-		return nil, fmt.Errorf("cannot read response body: %w", err)
68
-	}
69
-
70
-	respData := strings.TrimSpace(string(respDataBytes))
71
-
72
-	ip := net.ParseIP(respData)
73
-	if ip == nil {
74
-		return nil, fmt.Errorf("ifconfig.co returns incorrect IP %s", respData)
75
-	}
76
-
77
-	return ip, nil
78
-}

+ 0
- 99
config/urls.go Wyświetl plik

@@ -1,99 +0,0 @@
1
-package config
2
-
3
-import (
4
-	"encoding/hex"
5
-	"net"
6
-	"net/url"
7
-	"strconv"
8
-)
9
-
10
-type URLs struct {
11
-	TG        string `json:"tg_url"`
12
-	TMe       string `json:"tme_url"`
13
-	TGQRCode  string `json:"tg_qrcode"`
14
-	TMeQRCode string `json:"tme_qrcode"`
15
-}
16
-
17
-type IPURLs struct {
18
-	IPv4      *URLs  `json:"ipv4,omitempty"`
19
-	IPv6      *URLs  `json:"ipv6,omitempty"`
20
-	BotSecret string `json:"secret_for_mtproxybot"`
21
-}
22
-
23
-func GetURLs() (urls IPURLs) {
24
-	secret := ""
25
-
26
-	switch C.SecretMode {
27
-	case SecretModeSimple:
28
-		secret = hex.EncodeToString(C.Secret)
29
-	case SecretModeSecured:
30
-		secret = "dd" + hex.EncodeToString(C.Secret)
31
-	case SecretModeTLS:
32
-		secret = "ee" + hex.EncodeToString(C.Secret) + hex.EncodeToString([]byte(C.CloakHost))
33
-	}
34
-
35
-	if C.PublicIPv4.IP != nil {
36
-		urls.IPv4 = makeURLs(C.PublicIPv4, secret)
37
-	}
38
-
39
-	if C.PublicIPv6.IP != nil {
40
-		urls.IPv6 = makeURLs(C.PublicIPv6, secret)
41
-	}
42
-
43
-	urls.BotSecret = hex.EncodeToString(C.Secret)
44
-
45
-	return urls
46
-}
47
-
48
-func makeURLs(addr *net.TCPAddr, secret string) *URLs {
49
-	urls := &URLs{}
50
-
51
-	values := url.Values{}
52
-	values.Set("server", addr.IP.String())
53
-	values.Set("port", strconv.Itoa(addr.Port))
54
-	values.Set("secret", secret)
55
-
56
-	return &URLs{
57
-		TG:        makeTGURL(values),
58
-		TMe:       makeTMeURL(values),
59
-		TGQRCode:  makeQRCodeURL(urls.TG),
60
-		TMeQRCode: makeQRCodeURL(urls.TMe),
61
-	}
62
-}
63
-
64
-func makeTGURL(values url.Values) string {
65
-	tgURL := url.URL{
66
-		Scheme:   "tg",
67
-		Host:     "proxy",
68
-		RawQuery: values.Encode(),
69
-	}
70
-
71
-	return tgURL.String()
72
-}
73
-
74
-func makeTMeURL(values url.Values) string {
75
-	tMeURL := url.URL{
76
-		Scheme:   "https",
77
-		Host:     "t.me",
78
-		Path:     "proxy",
79
-		RawQuery: values.Encode(),
80
-	}
81
-
82
-	return tMeURL.String()
83
-}
84
-
85
-func makeQRCodeURL(data string) string {
86
-	qr := url.URL{
87
-		Scheme: "https",
88
-		Host:   "api.qrserver.com",
89
-		Path:   "v1/create-qr-code",
90
-	}
91
-
92
-	values := url.Values{}
93
-	values.Set("qzone", "4")
94
-	values.Set("format", "svg")
95
-	values.Set("data", data)
96
-	qr.RawQuery = values.Encode()
97
-
98
-	return qr.String()
99
-}

+ 0
- 6
conntypes/acks.go Wyświetl plik

@@ -1,6 +0,0 @@
1
-package conntypes
2
-
3
-type ConnectionAcks struct {
4
-	Simple bool
5
-	Quick  bool
6
-}

+ 0
- 5
conntypes/dc.go Wyświetl plik

@@ -1,5 +0,0 @@
1
-package conntypes
2
-
3
-type DC int16
4
-
5
-const DCDefaultIdx DC = 1

+ 0
- 24
conntypes/id.go Wyświetl plik

@@ -1,24 +0,0 @@
1
-package conntypes
2
-
3
-import (
4
-	"crypto/rand"
5
-	"encoding/hex"
6
-)
7
-
8
-const ConnIDLength = 8
9
-
10
-type ConnID [ConnIDLength]byte
11
-
12
-func (c ConnID) String() string {
13
-	return hex.EncodeToString(c[:])
14
-}
15
-
16
-func NewConnID() ConnID {
17
-	var id ConnID
18
-
19
-	if _, err := rand.Read(id[:]); err != nil {
20
-		panic(err)
21
-	}
22
-
23
-	return id
24
-}

+ 0
- 3
conntypes/packet.go Wyświetl plik

@@ -1,3 +0,0 @@
1
-package conntypes
2
-
3
-type Packet []byte

+ 0
- 22
conntypes/protocol.go Wyświetl plik

@@ -1,22 +0,0 @@
1
-package conntypes
2
-
3
-type ConnectionProtocol uint8
4
-
5
-func (c ConnectionProtocol) String() string {
6
-	switch c {
7
-	case ConnectionProtocolAny:
8
-		return "any"
9
-	case ConnectionProtocolIPv4:
10
-		return "ipv4"
11
-	case ConnectionProtocolIPv6:
12
-		return "ipv6"
13
-	}
14
-
15
-	return "ipv6"
16
-}
17
-
18
-const (
19
-	ConnectionProtocolIPv4 ConnectionProtocol = 1
20
-	ConnectionProtocolIPv6                    = ConnectionProtocolIPv4 << 1
21
-	ConnectionProtocolAny                     = ConnectionProtocolIPv4 | ConnectionProtocolIPv6
22
-)

+ 0
- 29
conntypes/type.go Wyświetl plik

@@ -1,29 +0,0 @@
1
-package conntypes
2
-
3
-type ConnectionType uint8
4
-
5
-const (
6
-	ConnectionTypeUnknown ConnectionType = iota
7
-	ConnectionTypeAbridged
8
-	ConnectionTypeIntermediate
9
-	ConnectionTypeSecure
10
-)
11
-
12
-var (
13
-	ConnectionTagAbridged     = []byte{0xef, 0xef, 0xef, 0xef}
14
-	ConnectionTagIntermediate = []byte{0xee, 0xee, 0xee, 0xee}
15
-	ConnectionTagSecure       = []byte{0xdd, 0xdd, 0xdd, 0xdd}
16
-)
17
-
18
-func (t ConnectionType) Tag() []byte {
19
-	switch t {
20
-	case ConnectionTypeAbridged:
21
-		return ConnectionTagAbridged
22
-	case ConnectionTypeIntermediate:
23
-		return ConnectionTagIntermediate
24
-	case ConnectionTypeSecure, ConnectionTypeUnknown:
25
-		return ConnectionTagSecure
26
-	}
27
-
28
-	return ConnectionTagSecure
29
-}

+ 0
- 14
conntypes/wrap_interfaces.go Wyświetl plik

@@ -1,14 +0,0 @@
1
-package conntypes
2
-
3
-import (
4
-	"net"
5
-
6
-	"go.uber.org/zap"
7
-)
8
-
9
-type Wrap interface {
10
-	Conn() net.Conn
11
-	Logger() *zap.SugaredLogger
12
-	LocalAddr() *net.TCPAddr
13
-	RemoteAddr() *net.TCPAddr
14
-}

+ 0
- 41
conntypes/wrap_packet_ack_interfaces.go Wyświetl plik

@@ -1,41 +0,0 @@
1
-package conntypes
2
-
3
-import "io"
4
-
5
-type PacketAckReader interface {
6
-	Read(*ConnectionAcks) (Packet, error)
7
-}
8
-
9
-type PacketAckWriter interface {
10
-	Write(Packet, *ConnectionAcks) error
11
-}
12
-
13
-type PacketAckCloser interface {
14
-	io.Closer
15
-}
16
-
17
-type PacketAckReadCloser interface {
18
-	PacketAckReader
19
-	PacketAckCloser
20
-}
21
-
22
-type PacketAckWriteCloser interface {
23
-	PacketAckWriter
24
-	PacketAckCloser
25
-}
26
-
27
-type PacketAckReadWriter interface {
28
-	PacketAckReader
29
-	PacketAckWriter
30
-}
31
-
32
-type PacketAckReadWriteCloser interface {
33
-	PacketAckReader
34
-	PacketAckWriter
35
-	PacketAckCloser
36
-}
37
-
38
-type PacketAckFullReadWriteCloser interface {
39
-	Wrap
40
-	PacketAckReadWriteCloser
41
-}

+ 0
- 51
conntypes/wrap_packet_interfaces.go Wyświetl plik

@@ -1,51 +0,0 @@
1
-package conntypes
2
-
3
-import "io"
4
-
5
-type BasePacketReader interface {
6
-	Read() (Packet, error)
7
-}
8
-
9
-type BasePacketWriter interface {
10
-	Write(Packet) error
11
-}
12
-
13
-type PacketReader interface {
14
-	Wrap
15
-	BasePacketReader
16
-}
17
-
18
-type PacketWriter interface {
19
-	Wrap
20
-	BasePacketWriter
21
-}
22
-
23
-type PacketCloser interface {
24
-	Wrap
25
-	io.Closer
26
-}
27
-
28
-type PacketReadCloser interface {
29
-	Wrap
30
-	BasePacketReader
31
-	io.Closer
32
-}
33
-
34
-type PacketWriteCloser interface {
35
-	Wrap
36
-	BasePacketWriter
37
-	io.Closer
38
-}
39
-
40
-type PacketReadWriter interface {
41
-	Wrap
42
-	BasePacketWriter
43
-	BasePacketReader
44
-}
45
-
46
-type PacketReadWriteCloser interface {
47
-	Wrap
48
-	BasePacketWriter
49
-	BasePacketReader
50
-	io.Closer
51
-}

+ 0
- 56
conntypes/wrap_stream_interfaces.go Wyświetl plik

@@ -1,56 +0,0 @@
1
-package conntypes
2
-
3
-import (
4
-	"io"
5
-	"time"
6
-)
7
-
8
-type BaseStreamReaderWithTimeout interface {
9
-	ReadTimeout([]byte, time.Duration) (int, error)
10
-}
11
-
12
-type BaseStreamWriterWithTimeout interface {
13
-	WriteTimeout([]byte, time.Duration) (int, error)
14
-}
15
-
16
-type StreamReader interface {
17
-	Wrap
18
-	io.Reader
19
-	BaseStreamReaderWithTimeout
20
-}
21
-
22
-type StreamWriter interface {
23
-	Wrap
24
-	io.Writer
25
-	BaseStreamWriterWithTimeout
26
-}
27
-
28
-type StreamCloser interface {
29
-	Wrap
30
-	io.Closer
31
-}
32
-
33
-type StreamReadCloser interface {
34
-	Wrap
35
-	io.ReadCloser
36
-	BaseStreamReaderWithTimeout
37
-}
38
-
39
-type StreamWriteCloser interface {
40
-	Wrap
41
-	io.WriteCloser
42
-	BaseStreamWriterWithTimeout
43
-}
44
-
45
-type StreamReadWriter interface {
46
-	Wrap
47
-	io.ReadWriter
48
-	BaseStreamReaderWithTimeout
49
-}
50
-
51
-type StreamReadWriteCloser interface {
52
-	Wrap
53
-	io.ReadWriteCloser
54
-	BaseStreamReaderWithTimeout
55
-	BaseStreamWriterWithTimeout
56
-}

+ 0
- 122
faketls/client_protocol.go Wyświetl plik

@@ -1,122 +0,0 @@
1
-package faketls
2
-
3
-import (
4
-	"bufio"
5
-	"bytes"
6
-	"encoding/binary"
7
-	"errors"
8
-	"fmt"
9
-	"io"
10
-	"net"
11
-	"strconv"
12
-	"time"
13
-
14
-	"github.com/9seconds/mtg/antireplay"
15
-	"github.com/9seconds/mtg/config"
16
-	"github.com/9seconds/mtg/conntypes"
17
-	"github.com/9seconds/mtg/obfuscated2"
18
-	"github.com/9seconds/mtg/protocol"
19
-	"github.com/9seconds/mtg/stats"
20
-	"github.com/9seconds/mtg/tlstypes"
21
-	"github.com/9seconds/mtg/wrappers/stream"
22
-)
23
-
24
-type ClientProtocol struct {
25
-	obfuscated2.ClientProtocol
26
-}
27
-
28
-func (c *ClientProtocol) Handshake(socket conntypes.StreamReadWriteCloser) (conntypes.StreamReadWriteCloser, error) {
29
-	rewinded := stream.NewRewind(socket)
30
-	bufferedReader := bufio.NewReader(rewinded)
31
-
32
-	for _, expected := range faketlsStartBytes {
33
-		if actual, err := bufferedReader.ReadByte(); err != nil || actual != expected {
34
-			rewinded.Rewind()
35
-			c.cloakHost(rewinded)
36
-
37
-			return nil, errors.New("failed first bytes of tls handshake")
38
-		}
39
-	}
40
-
41
-	rewinded.Rewind()
42
-	rewinded = stream.NewRewind(rewinded)
43
-
44
-	if err := c.tlsHandshake(rewinded); err != nil {
45
-		rewinded.Rewind()
46
-		c.cloakHost(rewinded)
47
-
48
-		return nil, fmt.Errorf("failed tls handshake: %w", err)
49
-	}
50
-
51
-	conn := stream.NewFakeTLS(socket)
52
-
53
-	conn, err := c.ClientProtocol.Handshake(conn)
54
-	if err != nil {
55
-		return nil, err // nolint: wrapcheck
56
-	}
57
-
58
-	return conn, err // nolint: wrapcheck
59
-}
60
-
61
-func (c *ClientProtocol) tlsHandshake(conn io.ReadWriter) error {
62
-	helloRecord, err := tlstypes.ReadRecord(conn)
63
-	if err != nil {
64
-		return fmt.Errorf("cannot read initial record: %w", err)
65
-	}
66
-
67
-	buf := &bytes.Buffer{}
68
-	helloRecord.Data.WriteBytes(buf)
69
-
70
-	clientHello, err := tlstypes.ParseClientHello(buf.Bytes())
71
-	if err != nil {
72
-		return fmt.Errorf("cannot parse client hello: %w", err)
73
-	}
74
-
75
-	digest := clientHello.Digest()
76
-	for i := 0; i < len(digest)-4; i++ {
77
-		if digest[i] != 0 {
78
-			return errBadDigest
79
-		}
80
-	}
81
-
82
-	timestamp := int64(binary.LittleEndian.Uint32(digest[len(digest)-4:]))
83
-	createdAt := time.Unix(timestamp, 0)
84
-	timeDiff := time.Since(createdAt)
85
-
86
-	if (timeDiff > TimeSkew || timeDiff < -TimeSkew) && timestamp > TimeFromBoot {
87
-		return errBadTime
88
-	}
89
-
90
-	if antireplay.Cache.HasTLS(clientHello.Random[:]) {
91
-		stats.Stats.ReplayDetected()
92
-
93
-		return errors.New("replay attack is detected")
94
-	}
95
-
96
-	antireplay.Cache.AddTLS(clientHello.Random[:])
97
-	serverHello := tlstypes.NewServerHello(clientHello)
98
-	serverHelloPacket := serverHello.WelcomePacket()
99
-
100
-	if _, err := conn.Write(serverHelloPacket); err != nil {
101
-		return fmt.Errorf("cannot send welcome packet: %w", err)
102
-	}
103
-
104
-	return nil
105
-}
106
-
107
-func (c *ClientProtocol) cloakHost(clientConn io.ReadWriteCloser) {
108
-	stats.Stats.CloakedRequest()
109
-
110
-	addr := net.JoinHostPort(config.C.CloakHost, strconv.Itoa(config.C.CloakPort))
111
-
112
-	hostConn, err := net.Dial("tcp", addr)
113
-	if err != nil {
114
-		return
115
-	}
116
-
117
-	cloak(clientConn, hostConn)
118
-}
119
-
120
-func MakeClientProtocol() protocol.ClientProtocol {
121
-	return &ClientProtocol{}
122
-}

+ 0
- 73
faketls/cloak.go Wyświetl plik

@@ -1,73 +0,0 @@
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 cloakPipe(one, another, wg)
32
-
33
-	go cloakPipe(another, one, wg)
34
-
35
-	go func() {
36
-		wg.Wait()
37
-		cancel()
38
-	}()
39
-
40
-	go func() {
41
-		lastActivityTimer := time.NewTimer(cloakLastActivityTimeout)
42
-		defer lastActivityTimer.Stop()
43
-
44
-		maxTimer := time.NewTimer(cloakMaxTimeout)
45
-		defer maxTimer.Stop()
46
-
47
-		for {
48
-			select {
49
-			case <-channelPing:
50
-				lastActivityTimer.Stop()
51
-				lastActivityTimer = time.NewTimer(cloakLastActivityTimeout)
52
-			case <-ctx.Done():
53
-				return
54
-			case <-lastActivityTimer.C:
55
-				cancel()
56
-
57
-				return
58
-			case <-maxTimer.C:
59
-				cancel()
60
-
61
-				return
62
-			}
63
-		}
64
-	}()
65
-
66
-	<-ctx.Done()
67
-}
68
-
69
-func cloakPipe(one io.Writer, another io.Reader, wg *sync.WaitGroup) {
70
-	defer wg.Done()
71
-
72
-	io.Copy(one, another) // nolint: errcheck
73
-}

+ 0
- 30
faketls/consts.go Wyświetl plik

@@ -1,30 +0,0 @@
1
-package faketls
2
-
3
-import (
4
-	"errors"
5
-	"time"
6
-)
7
-
8
-const (
9
-	TimeSkew     = 5 * time.Second
10
-	TimeFromBoot = 24 * 60 * 60
11
-)
12
-
13
-var (
14
-	errBadDigest = errors.New("bad digest")
15
-	errBadTime   = errors.New("bad time")
16
-
17
-	faketlsStartBytes = [...]byte{
18
-		0x16,
19
-		0x03,
20
-		0x01,
21
-		0x02,
22
-		0x00,
23
-		0x01,
24
-		0x00,
25
-		0x01,
26
-		0xfc,
27
-		0x03,
28
-		0x03,
29
-	}
30
-)

+ 2
- 24
go.mod Wyświetl plik

@@ -1,25 +1,3 @@
1
-module github.com/9seconds/mtg
1
+module github.com/9seconds/mtg/v2
2 2
 
3
-go 1.13
4
-
5
-require (
6
-	github.com/VictoriaMetrics/fastcache v1.5.7
7
-	github.com/alecthomas/units v0.0.0-20210208195552-ff826a37aa15
8
-	github.com/beevik/ntp v0.3.0
9
-	github.com/golang/snappy v0.0.3 // indirect
10
-	github.com/prometheus/client_golang v1.9.0
11
-	github.com/prometheus/common v0.18.0 // indirect
12
-	github.com/prometheus/procfs v0.6.0 // indirect
13
-	github.com/smira/go-statsd v1.3.2
14
-	go.uber.org/multierr v1.6.0 // indirect
15
-	go.uber.org/zap v1.16.0
16
-	golang.org/x/crypto v0.0.0-20210220033148-5ea612d1eb83
17
-	golang.org/x/lint v0.0.0-20200302205851-738671d3881b // indirect
18
-	golang.org/x/mod v0.4.1 // indirect
19
-	golang.org/x/net v0.0.0-20210226172049-e18ecbb05110 // indirect
20
-	golang.org/x/sys v0.0.0-20210303074136-134d130e1a04
21
-	golang.org/x/tools v0.1.0 // indirect
22
-	google.golang.org/protobuf v1.25.0 // indirect
23
-	gopkg.in/alecthomas/kingpin.v2 v2.2.6
24
-	honnef.co/go/tools v0.0.1-2020.1.3 // indirect
25
-)
3
+go 1.16

+ 0
- 472
go.sum Wyświetl plik

@@ -1,472 +0,0 @@
1
-cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
2
-cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
3
-github.com/BurntSushi/toml v0.3.1 h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ=
4
-github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
5
-github.com/Knetic/govaluate v3.0.1-0.20171022003610-9aa49832a739+incompatible/go.mod h1:r7JcOSlj0wfOMncg0iLm8Leh48TZaKVeNIfJntJ2wa0=
6
-github.com/Shopify/sarama v1.19.0/go.mod h1:FVkBWblsNy7DGZRfXLU0O9RCGt5g3g3yEuWXgklEdEo=
7
-github.com/Shopify/toxiproxy v2.1.4+incompatible/go.mod h1:OXgGpZ6Cli1/URJOF1DMxUHB2q5Ap20/P/eIdh4G0pI=
8
-github.com/VictoriaMetrics/fastcache v1.5.7 h1:4y6y0G8PRzszQUYIQHHssv/jgPHAb5qQuuDNdCbyAgw=
9
-github.com/VictoriaMetrics/fastcache v1.5.7/go.mod h1:ptDBkNMQI4RtmVo8VS/XwRY6RoTu1dAWCbrk+6WsEM8=
10
-github.com/VividCortex/gohistogram v1.0.0/go.mod h1:Pf5mBqqDxYaXu3hDrrU+w6nw50o/4+TcAqDqk/vUH7g=
11
-github.com/afex/hystrix-go v0.0.0-20180502004556-fa1af6a1f4f5/go.mod h1:SkGFH1ia65gfNATL8TAiHDNxPzPdmEL5uirI2Uyuz6c=
12
-github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=
13
-github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751 h1:JYp7IbQjafoB+tBA3gMyHYHrpOtNuDiK/uB5uXxq5wM=
14
-github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=
15
-github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=
16
-github.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=
17
-github.com/alecthomas/units v0.0.0-20190924025748-f65c72e2690d/go.mod h1:rBZYJk541a8SKzHPHnH3zbiI+7dagKZ0cgpgrD7Fyho=
18
-github.com/alecthomas/units v0.0.0-20210208195552-ff826a37aa15 h1:AUNCr9CiJuwrRYS3XieqF+Z9B9gNxo/eANAJCF2eiN4=
19
-github.com/alecthomas/units v0.0.0-20210208195552-ff826a37aa15/go.mod h1:OMCwj8VM1Kc9e19TLln2VL61YJF0x1XFtfdL4JdbSyE=
20
-github.com/allegro/bigcache v1.2.1-0.20190218064605-e24eb225f156 h1:eMwmnE/GDgah4HI848JfFxHt+iPb26b4zyfspmqY0/8=
21
-github.com/allegro/bigcache v1.2.1-0.20190218064605-e24eb225f156/go.mod h1:Cb/ax3seSYIx7SuZdm2G2xzfwmv3TPSk2ucNfQESPXM=
22
-github.com/apache/thrift v0.12.0/go.mod h1:cp2SuWMxlEZw2r+iP2GNCdIi4C1qmUzdZFSVb+bacwQ=
23
-github.com/apache/thrift v0.13.0/go.mod h1:cp2SuWMxlEZw2r+iP2GNCdIi4C1qmUzdZFSVb+bacwQ=
24
-github.com/armon/circbuf v0.0.0-20150827004946-bbbad097214e/go.mod h1:3U/XgcO3hCbHZ8TKRvWD2dDTCfh9M9ya+I9JpbB7O8o=
25
-github.com/armon/go-metrics v0.0.0-20180917152333-f0300d1749da/go.mod h1:Q73ZrmVTwzkszR9V5SSuryQ31EELlFMUz1kKyl939pY=
26
-github.com/armon/go-radix v0.0.0-20180808171621-7fddfc383310/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8=
27
-github.com/aryann/difflib v0.0.0-20170710044230-e206f873d14a/go.mod h1:DAHtR1m6lCRdSC2Tm3DSWRPvIPr6xNKyeHdqDQSQT+A=
28
-github.com/aws/aws-lambda-go v1.13.3/go.mod h1:4UKl9IzQMoD+QF79YdCuzCwp8VbmG4VAQwij/eHl5CU=
29
-github.com/aws/aws-sdk-go v1.27.0/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo=
30
-github.com/aws/aws-sdk-go-v2 v0.18.0/go.mod h1:JWVYvqSMppoMJC0x5wdwiImzgXTI9FuZwxzkQq9wy+g=
31
-github.com/beevik/ntp v0.3.0 h1:xzVrPrE4ziasFXgBVBZJDP0Wg/KpMwk2KHJ4Ba8GrDw=
32
-github.com/beevik/ntp v0.3.0/go.mod h1:hIHWr+l3+/clUnF44zdK+CWW7fO8dR5cIylAQ76NRpg=
33
-github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q=
34
-github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8=
35
-github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM=
36
-github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw=
37
-github.com/bgentry/speakeasy v0.1.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kBD4zp0CCIs=
38
-github.com/casbin/casbin/v2 v2.1.2/go.mod h1:YcPU1XXisHhLzuxH9coDNf2FbKpjGlbCg3n9yuLkIJQ=
39
-github.com/cenkalti/backoff v2.2.1+incompatible/go.mod h1:90ReRw6GdpyfrHakVjL/QHaoyV4aDUVVkXQJJJ3NXXM=
40
-github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
41
-github.com/cespare/xxhash/v2 v2.1.1 h1:6MnRN8NT7+YBpUIWxHtefFZOKTAPgGjpQSxqLNn0+qY=
42
-github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
43
-github.com/clbanning/x2j v0.0.0-20191024224557-825249438eec/go.mod h1:jMjuTZXRI4dUb/I5gc9Hdhagfvm9+RyrPryS/auMzxE=
44
-github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
45
-github.com/cockroachdb/datadriven v0.0.0-20190809214429-80d97fb3cbaa/go.mod h1:zn76sxSg3SzpJ0PPJaLDCu+Bu0Lg3sKTORVIj19EIF8=
46
-github.com/codahale/hdrhistogram v0.0.0-20161010025455-3a0bb77429bd/go.mod h1:sE/e/2PUdi/liOCUjSTXgM1o87ZssimdTWN964YiIeI=
47
-github.com/coreos/go-semver v0.2.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk=
48
-github.com/coreos/go-systemd v0.0.0-20180511133405-39ca1b05acc7/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4=
49
-github.com/coreos/pkg v0.0.0-20160727233714-3ac0863d7acf/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA=
50
-github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU=
51
-github.com/creack/pty v1.1.7/go.mod h1:lj5s0c3V2DBrqTV7llrYr5NG6My20zk30Fl46Y7DoTY=
52
-github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
53
-github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
54
-github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
55
-github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ=
56
-github.com/dustin/go-humanize v0.0.0-20171111073723-bb3d318650d4/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk=
57
-github.com/eapache/go-resiliency v1.1.0/go.mod h1:kFI+JgMyC7bLPUVY133qvEBtVayf5mFgVsvEsIPBvNs=
58
-github.com/eapache/go-xerial-snappy v0.0.0-20180814174437-776d5712da21/go.mod h1:+020luEh2TKB4/GOp8oxxtq0Daoen/Cii55CzbTV6DU=
59
-github.com/eapache/queue v1.1.0/go.mod h1:6eCeP0CKFpHLu8blIFXhExK/dRa7WDZfr6jVFPTqq+I=
60
-github.com/edsrzf/mmap-go v1.0.0/go.mod h1:YO35OhQPt3KJa3ryjFM5Bs14WD66h8eGKpfaBNrHW5M=
61
-github.com/envoyproxy/go-control-plane v0.6.9/go.mod h1:SBwIajubJHhxtWwsL9s8ss4safvEdbitLhGGK48rN6g=
62
-github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
63
-github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c=
64
-github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4=
65
-github.com/franela/goblin v0.0.0-20200105215937-c9ffbefa60db/go.mod h1:7dvUGVsVBjqR7JHJk0brhHOZYGmfBYOrK0ZhYMEtBr4=
66
-github.com/franela/goreq v0.0.0-20171204163338-bcd34c9993f8/go.mod h1:ZhphrRTfi2rbfLwlschooIH4+wKKDR4Pdxhh+TRoA20=
67
-github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
68
-github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
69
-github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as=
70
-github.com/go-kit/kit v0.9.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as=
71
-github.com/go-kit/kit v0.10.0/go.mod h1:xUsJbQ/Fp4kEt7AFgCuvyX4a71u8h9jB8tj/ORgOZ7o=
72
-github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE=
73
-github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk=
74
-github.com/go-logfmt/logfmt v0.5.0/go.mod h1:wCYkCAKZfumFQihp8CzCvQ3paCTfi41vtzG1KdI/P7A=
75
-github.com/go-sql-driver/mysql v1.4.0/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w=
76
-github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY=
77
-github.com/gogo/googleapis v1.1.0/go.mod h1:gf4bu3Q80BeJ6H1S1vYPm8/ELATdvryBaNFGgqEef3s=
78
-github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ=
79
-github.com/gogo/protobuf v1.2.0/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ=
80
-github.com/gogo/protobuf v1.2.1/go.mod h1:hp+jE20tsWTFYpLwKvXlhS1hjn+gTNwPg2I6zVXpSg4=
81
-github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
82
-github.com/golang/groupcache v0.0.0-20160516000752-02826c3e7903/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
83
-github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
84
-github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
85
-github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
86
-github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
87
-github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
88
-github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8=
89
-github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA=
90
-github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs=
91
-github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w=
92
-github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0=
93
-github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QDs8UjoX8=
94
-github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=
95
-github.com/golang/protobuf v1.4.3 h1:JjCZWpVbqXDqFVmTfYWEVTMIYrL/NPdPSCHPJ0T/raM=
96
-github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=
97
-github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
98
-github.com/golang/snappy v0.0.1/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
99
-github.com/golang/snappy v0.0.3 h1:fHPg5GQYlCeLIPB9BZqMVR5nR9A+IM5zcgeTdjMYmLA=
100
-github.com/golang/snappy v0.0.3/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
101
-github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
102
-github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
103
-github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M=
104
-github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
105
-github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
106
-github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
107
-github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
108
-github.com/google/go-cmp v0.5.4 h1:L8R9j+yAqZuZjsqh/z+F1NCffTKKLShY6zXTItVIZ8M=
109
-github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
110
-github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
111
-github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI=
112
-github.com/google/uuid v1.0.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
113
-github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY=
114
-github.com/gorilla/context v1.1.1/go.mod h1:kBGZzfjB9CEq2AlWe17Uuf7NDRt0dE0s8S51q0aT7Yg=
115
-github.com/gorilla/mux v1.6.2/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs=
116
-github.com/gorilla/mux v1.7.3/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs=
117
-github.com/gorilla/websocket v0.0.0-20170926233335-4201258b820c/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ=
118
-github.com/grpc-ecosystem/go-grpc-middleware v1.0.1-0.20190118093823-f849b5445de4/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs=
119
-github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgfV/d3M/q6VIi02HzZEHgUlZvzk=
120
-github.com/grpc-ecosystem/grpc-gateway v1.9.5/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY=
121
-github.com/hashicorp/consul/api v1.3.0/go.mod h1:MmDNSzIMUjNpY/mQ398R4bk2FnqQLoPndWW5VkKPlCE=
122
-github.com/hashicorp/consul/sdk v0.3.0/go.mod h1:VKf9jXwCTEY1QZP2MOLRhb5i/I/ssyNV1vwHyQBF0x8=
123
-github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4=
124
-github.com/hashicorp/go-cleanhttp v0.5.1/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80=
125
-github.com/hashicorp/go-immutable-radix v1.0.0/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60=
126
-github.com/hashicorp/go-msgpack v0.5.3/go.mod h1:ahLV/dePpqEmjfWmKiqvPkv/twdG7iPBM1vqhUKIvfM=
127
-github.com/hashicorp/go-multierror v1.0.0/go.mod h1:dHtQlpGsu+cZNNAkkCN/P3hoUDHhCYQXV3UM06sGGrk=
128
-github.com/hashicorp/go-rootcerts v1.0.0/go.mod h1:K6zTfqpRlCUIjkwsN4Z+hiSfzSTQa6eBIzfwKfwNnHU=
129
-github.com/hashicorp/go-sockaddr v1.0.0/go.mod h1:7Xibr9yA9JjQq1JpNB2Vw7kxv8xerXegt+ozgdvDeDU=
130
-github.com/hashicorp/go-syslog v1.0.0/go.mod h1:qPfqrKkXGihmCqbJM2mZgkZGvKG1dFdvsLplgctolz4=
131
-github.com/hashicorp/go-uuid v1.0.0/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro=
132
-github.com/hashicorp/go-uuid v1.0.1/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro=
133
-github.com/hashicorp/go-version v1.2.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA=
134
-github.com/hashicorp/go.net v0.0.1/go.mod h1:hjKkEWcCURg++eb33jQU7oqQcI9XDCnUzHA0oac0k90=
135
-github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
136
-github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
137
-github.com/hashicorp/logutils v1.0.0/go.mod h1:QIAnNjmIWmVIIkWDTG1z5v++HQmx9WQRO+LraFDTW64=
138
-github.com/hashicorp/mdns v1.0.0/go.mod h1:tL+uN++7HEJ6SQLQ2/p+z2pH24WQKWjBPkE0mNTz8vQ=
139
-github.com/hashicorp/memberlist v0.1.3/go.mod h1:ajVTdAv/9Im8oMAAj5G31PhhMCZJV2pPBoIllUwCN7I=
140
-github.com/hashicorp/serf v0.8.2/go.mod h1:6hOLApaqBFA1NXqRQAsxw9QxuDEvNxSQRwA/JwenrHc=
141
-github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
142
-github.com/hudl/fargo v1.3.0/go.mod h1:y3CKSmjA+wD2gak7sUSXTAoopbhU08POFhmITJgmKTg=
143
-github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8=
144
-github.com/influxdata/influxdb1-client v0.0.0-20191209144304-8bf82d3c094d/go.mod h1:qj24IKcXYK6Iy9ceXlo3Tc+vtHo9lIhSX5JddghvEPo=
145
-github.com/jmespath/go-jmespath v0.0.0-20180206201540-c2b33e8439af/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k=
146
-github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo=
147
-github.com/jpillora/backoff v1.0.0/go.mod h1:J/6gKK9jxlEcS3zixgDgUAsiuZ7yrSoa/FX5e0EB2j4=
148
-github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU=
149
-github.com/json-iterator/go v1.1.7/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
150
-github.com/json-iterator/go v1.1.8/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
151
-github.com/json-iterator/go v1.1.10/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
152
-github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU=
153
-github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w=
154
-github.com/julienschmidt/httprouter v1.3.0/go.mod h1:JR6WtHb+2LUe8TCKY3cZOxFyyO8IZAc4RVcycCCAKdM=
155
-github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q=
156
-github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
157
-github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
158
-github.com/konsorten/go-windows-terminal-sequences v1.0.3/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
159
-github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc=
160
-github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI=
161
-github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
162
-github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
163
-github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE=
164
-github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
165
-github.com/lightstep/lightstep-tracer-common/golang/gogo v0.0.0-20190605223551-bc2310a04743/go.mod h1:qklhhLq1aX+mtWk9cPHPzaBjWImj5ULL6C7HFJtXQMM=
166
-github.com/lightstep/lightstep-tracer-go v0.18.1/go.mod h1:jlF1pusYV4pidLvZ+XD0UBX0ZE6WURAspgAczcDHrL4=
167
-github.com/lyft/protoc-gen-validate v0.0.13/go.mod h1:XbGvPuh87YZc5TdIa2/I4pLk0QoUACkjt2znoq26NVQ=
168
-github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU=
169
-github.com/mattn/go-isatty v0.0.3/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4=
170
-github.com/mattn/go-isatty v0.0.4/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4=
171
-github.com/mattn/go-runewidth v0.0.2/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU=
172
-github.com/matttproud/golang_protobuf_extensions v1.0.1 h1:4hp9jkHxhMHkqkrB3Ix0jegS5sx/RkqARlsWZ6pIwiU=
173
-github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0=
174
-github.com/miekg/dns v1.0.14/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg=
175
-github.com/mitchellh/cli v1.0.0/go.mod h1:hNIlj7HEI86fIcpObd7a0FcrxTWetlwJDGcceTlRvqc=
176
-github.com/mitchellh/go-homedir v1.0.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0=
177
-github.com/mitchellh/go-testing-interface v1.0.0/go.mod h1:kRemZodwjscx+RGhAo8eIhFbs2+BFgRtFPeD/KE+zxI=
178
-github.com/mitchellh/gox v0.4.0/go.mod h1:Sd9lOJ0+aimLBi73mGofS1ycjY8lL3uZM3JPS42BGNg=
179
-github.com/mitchellh/iochan v1.0.0/go.mod h1:JwYml1nuB7xOzsp52dPpHFffvOCDupsG0QubkSMEySY=
180
-github.com/mitchellh/mapstructure v0.0.0-20160808181253-ca63d7c062ee/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y=
181
-github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y=
182
-github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
183
-github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
184
-github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
185
-github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
186
-github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U=
187
-github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U=
188
-github.com/nats-io/jwt v0.3.0/go.mod h1:fRYCDE99xlTsqUzISS1Bi75UBJ6ljOJQOAAu5VglpSg=
189
-github.com/nats-io/jwt v0.3.2/go.mod h1:/euKqTS1ZD+zzjYrY7pseZrTtWQSjujC7xjPc8wL6eU=
190
-github.com/nats-io/nats-server/v2 v2.1.2/go.mod h1:Afk+wRZqkMQs/p45uXdrVLuab3gwv3Z8C4HTBu8GD/k=
191
-github.com/nats-io/nats.go v1.9.1/go.mod h1:ZjDU1L/7fJ09jvUSRVBR2e7+RnLiiIQyqyzEE/Zbp4w=
192
-github.com/nats-io/nkeys v0.1.0/go.mod h1:xpnFELMwJABBLVhffcfd1MZx6VsNRFpEugbxziKVo7w=
193
-github.com/nats-io/nkeys v0.1.3/go.mod h1:xpnFELMwJABBLVhffcfd1MZx6VsNRFpEugbxziKVo7w=
194
-github.com/nats-io/nuid v1.0.1/go.mod h1:19wcPz3Ph3q0Jbyiqsd0kePYG7A95tJPxeL+1OSON2c=
195
-github.com/oklog/oklog v0.3.2/go.mod h1:FCV+B7mhrz4o+ueLpx+KqkyXRGMWOYEvfiXtdGtbWGs=
196
-github.com/oklog/run v1.0.0/go.mod h1:dlhp/R75TPv97u0XWUtDeV/lRKWPKSdTuV0TZvrmrQA=
197
-github.com/olekukonko/tablewriter v0.0.0-20170122224234-a0225b3f23b5/go.mod h1:vsDQFd/mU46D+Z4whnwzcISnGGzXWMclvtLoiIKAKIo=
198
-github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
199
-github.com/onsi/ginkgo v1.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
200
-github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY=
201
-github.com/op/go-logging v0.0.0-20160315200505-970db520ece7/go.mod h1:HzydrMdWErDVzsI23lYNej1Htcns9BCg93Dk0bBINWk=
202
-github.com/opentracing-contrib/go-observer v0.0.0-20170622124052-a52f23424492/go.mod h1:Ngi6UdF0k5OKD5t5wlmGhe/EDKPoUM3BXZSSfIuJbis=
203
-github.com/opentracing/basictracer-go v1.0.0/go.mod h1:QfBfYuafItcjQuMwinw9GhYKwFXS9KnPs5lxoYwgW74=
204
-github.com/opentracing/opentracing-go v1.0.2/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o=
205
-github.com/opentracing/opentracing-go v1.1.0/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o=
206
-github.com/openzipkin-contrib/zipkin-go-opentracing v0.4.5/go.mod h1:/wsWhb9smxSfWAKL3wpBW7V8scJMt8N8gnaMCS9E/cA=
207
-github.com/openzipkin/zipkin-go v0.1.6/go.mod h1:QgAqvLzwWbR/WpD4A3cGpPtJrZXNIiJc5AZX7/PBEpw=
208
-github.com/openzipkin/zipkin-go v0.2.1/go.mod h1:NaW6tEwdmWMaCDZzg8sh+IBNOxHMPnhQw8ySjnjRyN4=
209
-github.com/openzipkin/zipkin-go v0.2.2/go.mod h1:NaW6tEwdmWMaCDZzg8sh+IBNOxHMPnhQw8ySjnjRyN4=
210
-github.com/pact-foundation/pact-go v1.0.4/go.mod h1:uExwJY4kCzNPcHRj+hCR/HBbOOIwwtUjcrb0b5/5kLM=
211
-github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc=
212
-github.com/pborman/uuid v1.2.0/go.mod h1:X/NO0urCmaxf9VXbdlT7C2Yzkj2IKimNn4k+gtPdI/k=
213
-github.com/performancecopilot/speed v3.0.0+incompatible/go.mod h1:/CLtqpZ5gBg1M9iaPbIdPPGyKcA8hKdoy6hAWba7Yac=
214
-github.com/pierrec/lz4 v1.0.2-0.20190131084431-473cd7ce01a1/go.mod h1:3/3N9NVKO0jef7pBehbT1qWhCMrIgbYNnFAZCqQ5LRc=
215
-github.com/pierrec/lz4 v2.0.5+incompatible/go.mod h1:pdkljMzZIN41W+lC3N2tnIh5sFi+IEE17M5jbnwPHcY=
216
-github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
217
-github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
218
-github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
219
-github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
220
-github.com/pkg/profile v1.2.1/go.mod h1:hJw3o1OdXxsrSjjVksARp5W95eeEaEfptyVZyv6JUPA=
221
-github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
222
-github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
223
-github.com/posener/complete v1.1.1/go.mod h1:em0nMJCgc9GFtwrmVmEMR/ZL6WyhyjMBndrE9hABlRI=
224
-github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw=
225
-github.com/prometheus/client_golang v0.9.3-0.20190127221311-3c4408c8b829/go.mod h1:p2iRAGwDERtqlqzRXnrOVns+ignqQo//hLXqYxZYVNs=
226
-github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5FsnadC4Ky3P0J6CfImo=
227
-github.com/prometheus/client_golang v1.3.0/go.mod h1:hJaj2vgQTGQmVCsAACORcieXFeDPbaTKGT+JTgUa3og=
228
-github.com/prometheus/client_golang v1.7.1/go.mod h1:PY5Wy2awLA44sXw4AOSfFBetzPP4j5+D6mVACh+pe2M=
229
-github.com/prometheus/client_golang v1.9.0 h1:Rrch9mh17XcxvEu9D9DEpb4isxjGBtcevQjKvxPRQIU=
230
-github.com/prometheus/client_golang v1.9.0/go.mod h1:FqZLKOZnGdFAhOK4nqGHa7D66IdsO+O441Eve7ptJDU=
231
-github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo=
232
-github.com/prometheus/client_model v0.0.0-20190115171406-56726106282f/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo=
233
-github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
234
-github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
235
-github.com/prometheus/client_model v0.1.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
236
-github.com/prometheus/client_model v0.2.0 h1:uq5h0d+GuxiXLJLNABMgp2qUWDPiLvgCzz2dUR+/W/M=
237
-github.com/prometheus/client_model v0.2.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
238
-github.com/prometheus/common v0.2.0/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4=
239
-github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4=
240
-github.com/prometheus/common v0.7.0/go.mod h1:DjGbpBbp5NYNiECxcL/VnbXCCaQpKd3tt26CguLLsqA=
241
-github.com/prometheus/common v0.10.0/go.mod h1:Tlit/dnDKsSWFlCLTWaA1cyBgKHSMdTB80sz/V91rCo=
242
-github.com/prometheus/common v0.15.0/go.mod h1:U+gB1OBLb1lF3O42bTCL+FK18tX9Oar16Clt/msog/s=
243
-github.com/prometheus/common v0.18.0 h1:WCVKW7aL6LEe1uryfI9dnEc2ZqNB1Fn0ok930v0iL1Y=
244
-github.com/prometheus/common v0.18.0/go.mod h1:U+gB1OBLb1lF3O42bTCL+FK18tX9Oar16Clt/msog/s=
245
-github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
246
-github.com/prometheus/procfs v0.0.0-20190117184657-bf6a532e95b1/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
247
-github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA=
248
-github.com/prometheus/procfs v0.0.8/go.mod h1:7Qr8sr6344vo1JqZ6HhLceV9o3AJ1Ff+GxbHq6oeK9A=
249
-github.com/prometheus/procfs v0.1.3/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU=
250
-github.com/prometheus/procfs v0.2.0/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU=
251
-github.com/prometheus/procfs v0.6.0 h1:mxy4L2jP6qMonqmq+aTtOx1ifVWUgG/TAmntgbh3xv4=
252
-github.com/prometheus/procfs v0.6.0/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA=
253
-github.com/rcrowley/go-metrics v0.0.0-20181016184325-3113b8401b8a/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4=
254
-github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg=
255
-github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
256
-github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
257
-github.com/ryanuber/columnize v0.0.0-20160712163229-9b3edd62028f/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts=
258
-github.com/samuel/go-zookeeper v0.0.0-20190923202752-2cc03de413da/go.mod h1:gi+0XIa01GRL2eRQVjQkKGqKF3SF9vZR/HnPullcV2E=
259
-github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg65j358z/aeFdxmN0P9QXhEzd20vsDc=
260
-github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc=
261
-github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo=
262
-github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE=
263
-github.com/sirupsen/logrus v1.6.0/go.mod h1:7uNnSEd1DgxDLC74fIahvMZmmYsHGZGEOFrfsX/uA88=
264
-github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc=
265
-github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA=
266
-github.com/smira/go-statsd v1.3.2 h1:1EeuzxNZ/TD9apbTOFSM9nulqfcsQFmT4u1A2DREabI=
267
-github.com/smira/go-statsd v1.3.2/go.mod h1:1srXJ9/pbnN04G8f4F1jUzsGOnwkPKXciyqpewGlkC4=
268
-github.com/soheilhy/cmux v0.1.4/go.mod h1:IM3LyeVVIOuxMH7sFAkER9+bJ4dT7Ms6E4xg4kGIyLM=
269
-github.com/sony/gobreaker v0.4.1/go.mod h1:ZKptC7FHNvhBz7dN2LGjPVBz2sZJmc0/PkyDJOjmxWY=
270
-github.com/spf13/cobra v0.0.3/go.mod h1:1l0Ry5zgKvJasoi3XT1TypsSe7PqH0Sj9dhYf7v3XqQ=
271
-github.com/spf13/pflag v1.0.1/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4=
272
-github.com/streadway/amqp v0.0.0-20190404075320-75d898a42a94/go.mod h1:AZpEONHx3DKn8O/DFsRAY58/XVQiIPMTMB1SddzLXVw=
273
-github.com/streadway/amqp v0.0.0-20190827072141-edfb9018d271/go.mod h1:AZpEONHx3DKn8O/DFsRAY58/XVQiIPMTMB1SddzLXVw=
274
-github.com/streadway/handy v0.0.0-20190108123426-d5acb3125c2a/go.mod h1:qNTQ5P5JnDBl6z3cMAg/SywNDC5ABu5ApDIw6lUbRmI=
275
-github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
276
-github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
277
-github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
278
-github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
279
-github.com/stretchr/testify v1.4.0 h1:2E4SXV/wtOkTonXsotYi4li6zVWxYlZuYNCXe9XRJyk=
280
-github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
281
-github.com/tmc/grpc-websocket-proxy v0.0.0-20170815181823-89b8d40f7ca8/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U=
282
-github.com/urfave/cli v1.20.0/go.mod h1:70zkFmudgCuE/ngEzBv17Jvp/497gISqfk5gWijbERA=
283
-github.com/urfave/cli v1.22.1/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0=
284
-github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU=
285
-github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
286
-go.etcd.io/bbolt v1.3.3/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU=
287
-go.etcd.io/etcd v0.0.0-20191023171146-3cf2f69b5738/go.mod h1:dnLIgRNXwCJa5e+c6mIZCrds/GIG4ncV9HhK5PX7jPg=
288
-go.opencensus.io v0.20.1/go.mod h1:6WKK9ahsWS3RSO+PY9ZHZUfv2irvY6gN279GOPZjmmk=
289
-go.opencensus.io v0.20.2/go.mod h1:6WKK9ahsWS3RSO+PY9ZHZUfv2irvY6gN279GOPZjmmk=
290
-go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
291
-go.uber.org/atomic v1.3.2/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE=
292
-go.uber.org/atomic v1.5.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ=
293
-go.uber.org/atomic v1.6.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ=
294
-go.uber.org/atomic v1.7.0 h1:ADUqmZGgLDDfbSL9ZmPxKTybcoEYHgpYfELNoN+7hsw=
295
-go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc=
296
-go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0=
297
-go.uber.org/multierr v1.3.0/go.mod h1:VgVr7evmIr6uPjLBxg28wmKNXyqE9akIJ5XnfpiKl+4=
298
-go.uber.org/multierr v1.5.0/go.mod h1:FeouvMocqHpRaaGuG9EjoKcStLC43Zu/fmqdUMPcKYU=
299
-go.uber.org/multierr v1.6.0 h1:y6IPFStTAIT5Ytl7/XYmHvzXQ7S3g/IeZW9hyZ5thw4=
300
-go.uber.org/multierr v1.6.0/go.mod h1:cdWPpRnG4AhwMwsgIHip0KRBQjJy5kYEpYjJxpXp9iU=
301
-go.uber.org/tools v0.0.0-20190618225709-2cfd321de3ee/go.mod h1:vJERXedbb3MVM5f9Ejo0C68/HhF8uaILCdgjnY+goOA=
302
-go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q=
303
-go.uber.org/zap v1.13.0/go.mod h1:zwrFLgMcdUuIBviXEYEH1YKNaOBnKXsx2IPda5bBwHM=
304
-go.uber.org/zap v1.16.0 h1:uFRZXykJGK9lLY4HtgSw44DnIcAM+kRBP7x5m+NpAOM=
305
-go.uber.org/zap v1.16.0/go.mod h1:MA8QOfq0BHJwdXa996Y4dYkAqRKB8/1K1QMMZVaNZjQ=
306
-golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
307
-golang.org/x/crypto v0.0.0-20181029021203-45a5f77698d3/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
308
-golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
309
-golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
310
-golang.org/x/crypto v0.0.0-20190701094942-4def268fd1a4/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
311
-golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
312
-golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
313
-golang.org/x/crypto v0.0.0-20210220033148-5ea612d1eb83 h1:/ZScEX8SfEmUGRHs0gxpqteO5nfNW6axyZbBdw9A12g=
314
-golang.org/x/crypto v0.0.0-20210220033148-5ea612d1eb83/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I=
315
-golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
316
-golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
317
-golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU=
318
-golang.org/x/lint v0.0.0-20190301231843-5614ed5bae6f/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
319
-golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
320
-golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
321
-golang.org/x/lint v0.0.0-20200302205851-738671d3881b h1:Wh+f8QHJXR411sJR8/vRBTZ7YapZaRvUcLFFJhusH0k=
322
-golang.org/x/lint v0.0.0-20200302205851-738671d3881b/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY=
323
-golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc=
324
-golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg=
325
-golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
326
-golang.org/x/mod v0.4.1 h1:Kvvh58BN8Y9/lBi7hTekvtMpm07eUZ0ck5pRHpsMWrY=
327
-golang.org/x/mod v0.4.1/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
328
-golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
329
-golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
330
-golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
331
-golang.org/x/net v0.0.0-20181023162649-9b4f9f5ad519/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
332
-golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
333
-golang.org/x/net v0.0.0-20181201002055-351d144fa1fc/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
334
-golang.org/x/net v0.0.0-20181220203305-927f97764cc3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
335
-golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
336
-golang.org/x/net v0.0.0-20190125091013-d26f9f9a57f3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
337
-golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
338
-golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
339
-golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
340
-golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks=
341
-golang.org/x/net v0.0.0-20190613194153-d28f0bde5980/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
342
-golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
343
-golang.org/x/net v0.0.0-20190813141303-74dc4d7220e7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
344
-golang.org/x/net v0.0.0-20200625001655-4c5254603344/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
345
-golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
346
-golang.org/x/net v0.0.0-20210226172049-e18ecbb05110 h1:qWPm9rbaAMKs8Bq/9LRpbMqxWRVUAQwMI9fVrssnTfw=
347
-golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
348
-golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
349
-golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
350
-golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
351
-golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
352
-golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
353
-golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
354
-golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
355
-golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
356
-golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
357
-golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
358
-golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
359
-golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
360
-golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
361
-golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
362
-golang.org/x/sys v0.0.0-20181026203630-95b1ffbd15a5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
363
-golang.org/x/sys v0.0.0-20181107165924-66b7b1311ac8/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
364
-golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
365
-golang.org/x/sys v0.0.0-20181122145206-62eef0e2fa9b/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
366
-golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
367
-golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
368
-golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
369
-golang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
370
-golang.org/x/sys v0.0.0-20190726091711-fc99dfbffb4e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
371
-golang.org/x/sys v0.0.0-20190826190057-c7b8b68b1456/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
372
-golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
373
-golang.org/x/sys v0.0.0-20191220142924-d4481acd189f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
374
-golang.org/x/sys v0.0.0-20200106162015-b016eb3dc98e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
375
-golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
376
-golang.org/x/sys v0.0.0-20200615200032-f1bc736245b1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
377
-golang.org/x/sys v0.0.0-20200625212154-ddb9806d33ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
378
-golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
379
-golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
380
-golang.org/x/sys v0.0.0-20201214210602-f9fddec55a1e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
381
-golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
382
-golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
383
-golang.org/x/sys v0.0.0-20210303074136-134d130e1a04 h1:cEhElsAv9LUt9ZUUocxzWe05oFLVd+AA2nstydTeI8g=
384
-golang.org/x/sys v0.0.0-20210303074136-134d130e1a04/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
385
-golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw=
386
-golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
387
-golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
388
-golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
389
-golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
390
-golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
391
-golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
392
-golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
393
-golang.org/x/tools v0.0.0-20180828015842-6cd1fcedba52/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
394
-golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
395
-golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
396
-golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY=
397
-golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
398
-golang.org/x/tools v0.0.0-20190312170243-e65039ee4138/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
399
-golang.org/x/tools v0.0.0-20190328211700-ab21143f2384/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
400
-golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
401
-golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
402
-golang.org/x/tools v0.0.0-20191029041327-9cc4af7d6b2c/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
403
-golang.org/x/tools v0.0.0-20191029190741-b9c20aec41a5/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
404
-golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
405
-golang.org/x/tools v0.0.0-20191130070609-6e064ea0cf2d/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
406
-golang.org/x/tools v0.0.0-20200103221440-774c71fcf114/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
407
-golang.org/x/tools v0.0.0-20200130002326-2f3ba24bd6e7/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
408
-golang.org/x/tools v0.1.0 h1:po9/4sTYwZU9lPhi1tOrb4hCv3qrhiQ77LZfGa2OjwY=
409
-golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0=
410
-golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
411
-golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
412
-golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
413
-golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE=
414
-golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
415
-google.golang.org/api v0.3.1/go.mod h1:6wY9I6uQWHQ8EM57III9mq/AjF+i8G65rmVagqKMtkk=
416
-google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=
417
-google.golang.org/appengine v1.2.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
418
-google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
419
-google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
420
-google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
421
-google.golang.org/genproto v0.0.0-20190425155659-357c62f0e4bb/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
422
-google.golang.org/genproto v0.0.0-20190530194941-fb225487d101/go.mod h1:z3L6/3dTEVtUr6QSP8miRzeRqwQOioJ9I66odjN4I7s=
423
-google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc=
424
-google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo=
425
-google.golang.org/grpc v1.17.0/go.mod h1:6QZJwpn2B+Zp71q/5VxRsJ6NXXVCE5NRUHRo+f3cWCs=
426
-google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
427
-google.golang.org/grpc v1.20.0/go.mod h1:chYK+tFQF0nDUGJgXMSgLCQk3phJEuONr2DCgLDdAQM=
428
-google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38=
429
-google.golang.org/grpc v1.21.0/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM=
430
-google.golang.org/grpc v1.22.1/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg=
431
-google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg=
432
-google.golang.org/grpc v1.23.1/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg=
433
-google.golang.org/grpc v1.26.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=
434
-google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=
435
-google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8=
436
-google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0=
437
-google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM=
438
-google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE=
439
-google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo=
440
-google.golang.org/protobuf v1.22.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
441
-google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
442
-google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
443
-google.golang.org/protobuf v1.25.0 h1:Ejskq+SyPohKW+1uil0JJMtmHCgJPJ/qWTxr8qp+R4c=
444
-google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c=
445
-gopkg.in/alecthomas/kingpin.v2 v2.2.6 h1:jMFz6MfLP0/4fUyZle81rXUoxOBFi19VUFKVDOQfozc=
446
-gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw=
447
-gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
448
-gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
449
-gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 h1:YR8cESwS4TdDjEe65xsg0ogRM/Nc3DYOhEAlW+xobZo=
450
-gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
451
-gopkg.in/cheggaaa/pb.v1 v1.0.25/go.mod h1:V/YB90LKu/1FcN3WVnfiiE5oMCibMjukxqG/qStrOgw=
452
-gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI=
453
-gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys=
454
-gopkg.in/gcfg.v1 v1.2.3/go.mod h1:yesOnuUOFQAhST5vPY4nbZsb/huCgGGXlipJsBn0b3o=
455
-gopkg.in/resty.v1 v1.12.0/go.mod h1:mDo4pnntr5jdWRML875a/NmxYqAlA73dVijT2AXvQQo=
456
-gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw=
457
-gopkg.in/warnings.v0 v0.1.2/go.mod h1:jksf8JmL6Qr/oQM2OXTHunEvvTAsrWBLb6OOjuVWRNI=
458
-gopkg.in/yaml.v2 v2.0.0-20170812160011-eb3733d160e7/go.mod h1:JAlM8MvJe8wmxCU4Bli9HhUf9+ttbYbLASfIpnQbh74=
459
-gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
460
-gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
461
-gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
462
-gopkg.in/yaml.v2 v2.2.5/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
463
-gopkg.in/yaml.v2 v2.3.0 h1:clyUAQHOM3G0M3f5vQj7LuJrETvjVot3Z5el9nffUtU=
464
-gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
465
-honnef.co/go/tools v0.0.0-20180728063816-88497007e858/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
466
-honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
467
-honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
468
-honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg=
469
-honnef.co/go/tools v0.0.1-2020.1.3 h1:sXmLre5bzIR6ypkjXCDI3jHPssRhc8KD/Ome589sc3U=
470
-honnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k=
471
-sigs.k8s.io/yaml v1.1.0/go.mod h1:UJmg0vDUVViEyp3mgSv9WPwZCDxu4rQW1olrI1uml+o=
472
-sourcegraph.com/sourcegraph/appdash v0.0.0-20190731080439-ebfcffb1b5c0/go.mod h1:hI742Nqp5OhwiqlzhgfbWU4mW4yO10fP+LoT9WOswdU=

+ 0
- 172
hub/connection.go Wyświetl plik

@@ -1,172 +0,0 @@
1
-package hub
2
-
3
-import (
4
-	"fmt"
5
-	"math/rand"
6
-	"sync"
7
-	"time"
8
-
9
-	"github.com/9seconds/mtg/conntypes"
10
-	"github.com/9seconds/mtg/mtproto"
11
-	"github.com/9seconds/mtg/mtproto/rpc"
12
-	"github.com/9seconds/mtg/protocol"
13
-	"go.uber.org/zap"
14
-)
15
-
16
-const connectionTTL = time.Hour
17
-
18
-type connection struct {
19
-	conn            conntypes.PacketReadWriteCloser
20
-	proxyConns      map[string]*ProxyConn
21
-	closeOnce       sync.Once
22
-	proxyConnsMutex sync.RWMutex
23
-	id              int
24
-	logger          *zap.SugaredLogger
25
-
26
-	channelDone       chan struct{}
27
-	channelWrite      chan conntypes.Packet
28
-	channelRead       chan *rpc.ProxyResponse
29
-	channelConnAttach chan *ProxyConn
30
-	channelConnDetach chan conntypes.ConnID
31
-}
32
-
33
-func (c *connection) run() { // nolint: cyclop
34
-	defer c.Close()
35
-
36
-	ttl := time.NewTimer(connectionTTL)
37
-	defer ttl.Stop()
38
-
39
-	for {
40
-		select {
41
-		case <-c.channelDone:
42
-			for _, v := range c.proxyConns {
43
-				v.Close()
44
-			}
45
-
46
-			return
47
-		case <-ttl.C:
48
-			c.logger.Debugw("Closing connection by TTL")
49
-			c.Close()
50
-		case resp := <-c.channelRead:
51
-			if channel, ok := c.proxyConns[string(resp.ConnID[:])]; ok {
52
-				if resp.Type == rpc.ProxyResponseTypeCloseExt {
53
-					channel.Close()
54
-				} else {
55
-					channel.put(resp)
56
-				}
57
-			}
58
-		case packet := <-c.channelWrite:
59
-			if err := c.conn.Write(packet); err != nil {
60
-				c.logger.Debugw("Cannot write packet", "error", err)
61
-				c.Close()
62
-			}
63
-		case conn := <-c.channelConnAttach:
64
-			c.proxyConnsMutex.Lock()
65
-			c.proxyConns[string(conn.req.ConnID[:])] = conn
66
-			c.proxyConnsMutex.Unlock()
67
-			conn.channelWrite = c.channelWrite
68
-		case connID := <-c.channelConnDetach:
69
-			if conn, ok := c.proxyConns[string(connID[:])]; ok {
70
-				c.proxyConnsMutex.Lock()
71
-				delete(c.proxyConns, string(connID[:]))
72
-				c.proxyConnsMutex.Unlock()
73
-				conn.Close()
74
-			}
75
-		}
76
-	}
77
-}
78
-
79
-func (c *connection) readLoop() {
80
-	for {
81
-		packet, err := c.conn.Read()
82
-		if err != nil {
83
-			c.logger.Debugw("Cannot read packet", "error", err)
84
-			c.Close()
85
-
86
-			return
87
-		}
88
-
89
-		response, err := rpc.ParseProxyResponse(packet)
90
-		if err != nil {
91
-			c.logger.Debugw("Failed response", "error", err)
92
-
93
-			continue
94
-		}
95
-
96
-		select {
97
-		case <-c.channelDone:
98
-			return
99
-		case c.channelRead <- response:
100
-		}
101
-	}
102
-}
103
-
104
-func (c *connection) Close() {
105
-	c.closeOnce.Do(func() {
106
-		c.logger.Debugw("Closing connection")
107
-
108
-		close(c.channelDone)
109
-		c.conn.Close()
110
-	})
111
-}
112
-
113
-func (c *connection) Done() bool {
114
-	select {
115
-	case <-c.channelDone:
116
-		return true
117
-	default:
118
-		return c.Len() == 0
119
-	}
120
-}
121
-
122
-func (c *connection) Len() int {
123
-	c.proxyConnsMutex.RLock()
124
-	defer c.proxyConnsMutex.RUnlock()
125
-
126
-	return len(c.proxyConns)
127
-}
128
-
129
-func (c *connection) Attach(conn *ProxyConn) error {
130
-	select {
131
-	case <-c.channelDone:
132
-		return ErrClosed
133
-	case c.channelConnAttach <- conn:
134
-		return nil
135
-	}
136
-}
137
-
138
-func (c *connection) Detach(connID conntypes.ConnID) {
139
-	select {
140
-	case <-c.channelDone:
141
-	case c.channelConnDetach <- connID:
142
-	}
143
-}
144
-
145
-func newConnection(req *protocol.TelegramRequest) (*connection, error) {
146
-	conn, err := mtproto.TelegramProtocol(req)
147
-	if err != nil {
148
-		return nil, fmt.Errorf("cannot create a new connection: %w", err)
149
-	}
150
-
151
-	id := rand.Int() // nolint: gosec
152
-	rv := &connection{
153
-		conn: conn,
154
-		id:   id,
155
-		logger: zap.S().Named("hub-connection").With("id", id,
156
-			"dc", req.ClientProtocol.DC(),
157
-			"protocol", req.ClientProtocol.ConnectionProtocol()),
158
-		proxyConns: make(map[string]*ProxyConn),
159
-
160
-		channelRead:       make(chan *rpc.ProxyResponse, 1),
161
-		channelDone:       make(chan struct{}),
162
-		channelWrite:      make(chan conntypes.Packet),
163
-		channelConnAttach: make(chan *ProxyConn),
164
-		channelConnDetach: make(chan conntypes.ConnID),
165
-	}
166
-
167
-	go rv.readLoop()
168
-
169
-	go rv.run()
170
-
171
-	return rv, nil
172
-}

+ 0
- 70
hub/connection_list.go Wyświetl plik

@@ -1,70 +0,0 @@
1
-package hub
2
-
3
-import (
4
-	"fmt"
5
-	"sort"
6
-
7
-	"github.com/9seconds/mtg/config"
8
-)
9
-
10
-type connectionList struct {
11
-	connections []*connection
12
-}
13
-
14
-func (c *connectionList) get(conn *ProxyConn) (*connection, error) {
15
-	if len(c.connections) > 0 && c.connections[0].Len() < config.C.MultiplexPerConnection {
16
-		if err := c.connections[0].Attach(conn); err == nil {
17
-			return c.connections[0], nil
18
-		}
19
-	}
20
-
21
-	newConn, err := newConnection(conn.req)
22
-	if err != nil {
23
-		return nil, fmt.Errorf("cannot allocate a new connection: %w", err)
24
-	}
25
-
26
-	if err = newConn.Attach(conn); err != nil {
27
-		newConn.Close()
28
-
29
-		return nil, fmt.Errorf("cannot attach to the newly created connection: %w", err)
30
-	}
31
-
32
-	c.connections = append(c.connections, newConn)
33
-	lastIndex := len(c.connections) - 1
34
-	c.connections[0], c.connections[lastIndex] = c.connections[lastIndex], c.connections[0]
35
-
36
-	return newConn, nil
37
-}
38
-
39
-func (c *connectionList) gc() {
40
-	prevLen := len(c.connections)
41
-	if prevLen == 0 {
42
-		return
43
-	}
44
-
45
-	for i := len(c.connections) - 1; i >= 0; i-- {
46
-		lastIndex := len(c.connections) - 1
47
-
48
-		if c.connections[i].Done() {
49
-			c.connections[i].Close()
50
-
51
-			if len(c.connections)-1 == i {
52
-				c.connections = c.connections[:lastIndex]
53
-			} else {
54
-				c.connections[i], c.connections[lastIndex] = c.connections[lastIndex], c.connections[i]
55
-			}
56
-		}
57
-	}
58
-
59
-	if prevLen != len(c.connections) {
60
-		c.sort()
61
-	}
62
-}
63
-
64
-func (c *connectionList) sort() {
65
-	if len(c.connections) > 1 {
66
-		sort.Slice(c.connections, func(i, j int) bool {
67
-			return c.connections[i].Len() < c.connections[j].Len()
68
-		})
69
-	}
70
-}

+ 0
- 40
hub/hub.go Wyświetl plik

@@ -1,40 +0,0 @@
1
-package hub
2
-
3
-import (
4
-	"context"
5
-	"sync"
6
-
7
-	"github.com/9seconds/mtg/protocol"
8
-)
9
-
10
-type hub struct {
11
-	muxes map[int32]*mux
12
-	mutex sync.RWMutex
13
-	ctx   context.Context
14
-}
15
-
16
-func (h *hub) Register(req *protocol.TelegramRequest) (*ProxyConn, error) {
17
-	return h.getMux(req).Get(req)
18
-}
19
-
20
-func (h *hub) getMux(req *protocol.TelegramRequest) *mux {
21
-	var key int32 = 32767 + int32(req.ClientProtocol.DC()) + 100000*int32(req.ClientProtocol.ConnectionProtocol())
22
-
23
-	h.mutex.RLock()
24
-	m, ok := h.muxes[key]
25
-	h.mutex.RUnlock()
26
-
27
-	if !ok {
28
-		h.mutex.Lock()
29
-		m, ok = h.muxes[key]
30
-
31
-		if !ok {
32
-			m = newMux(h.ctx)
33
-			h.muxes[key] = m
34
-		}
35
-
36
-		h.mutex.Unlock()
37
-	}
38
-
39
-	return m
40
-}

+ 0
- 24
hub/init.go Wyświetl plik

@@ -1,24 +0,0 @@
1
-package hub
2
-
3
-import (
4
-	"context"
5
-	"errors"
6
-	"sync"
7
-)
8
-
9
-var (
10
-	ErrTimeout = errors.New("timeout")
11
-	ErrClosed  = errors.New("context is closed")
12
-
13
-	Hub      Interface
14
-	initOnce sync.Once
15
-)
16
-
17
-func Init(ctx context.Context) {
18
-	initOnce.Do(func() {
19
-		Hub = &hub{
20
-			muxes: make(map[int32]*mux),
21
-			ctx:   ctx,
22
-		}
23
-	})
24
-}

+ 0
- 7
hub/interface.go Wyświetl plik

@@ -1,7 +0,0 @@
1
-package hub
2
-
3
-import "github.com/9seconds/mtg/protocol"
4
-
5
-type Interface interface {
6
-	Register(*protocol.TelegramRequest) (*ProxyConn, error)
7
-}

+ 0
- 90
hub/mux.go Wyświetl plik

@@ -1,90 +0,0 @@
1
-package hub
2
-
3
-import (
4
-	"context"
5
-	"time"
6
-
7
-	"github.com/9seconds/mtg/conntypes"
8
-	"github.com/9seconds/mtg/protocol"
9
-)
10
-
11
-const muxGCEvery = time.Minute
12
-
13
-type muxNewRequest struct {
14
-	req  *protocol.TelegramRequest
15
-	resp chan<- muxNewResponse
16
-}
17
-
18
-type muxNewResponse struct {
19
-	conn *ProxyConn
20
-	err  error
21
-}
22
-
23
-type mux struct {
24
-	connections   connectionList
25
-	clients       map[string]*connection
26
-	ctx           context.Context
27
-	channelClosed chan conntypes.ConnID
28
-	channelNew    chan muxNewRequest
29
-}
30
-
31
-func (m *mux) run() {
32
-	gcTicker := time.NewTicker(muxGCEvery)
33
-	defer gcTicker.Stop()
34
-
35
-	for {
36
-		select {
37
-		case <-m.ctx.Done():
38
-			for _, v := range m.clients {
39
-				v.Close()
40
-			}
41
-
42
-			return
43
-		case <-gcTicker.C:
44
-			m.connections.gc()
45
-		case req := <-m.channelNew:
46
-			m.connections.gc()
47
-			proxyConn := newProxyConn(req.req, m.channelClosed)
48
-			conn, err := m.connections.get(proxyConn)
49
-
50
-			if err == nil {
51
-				m.clients[string(req.req.ConnID[:])] = conn
52
-			}
53
-
54
-			req.resp <- muxNewResponse{
55
-				conn: proxyConn,
56
-				err:  err,
57
-			}
58
-			close(req.resp)
59
-		case connID := <-m.channelClosed:
60
-			if conn, ok := m.clients[string(connID[:])]; ok {
61
-				conn.Detach(connID)
62
-				delete(m.clients, string(connID[:]))
63
-			}
64
-		}
65
-	}
66
-}
67
-
68
-func (m *mux) Get(req *protocol.TelegramRequest) (*ProxyConn, error) {
69
-	resp := make(chan muxNewResponse)
70
-	m.channelNew <- muxNewRequest{
71
-		req:  req,
72
-		resp: resp,
73
-	}
74
-
75
-	rv := <-resp
76
-
77
-	return rv.conn, rv.err
78
-}
79
-
80
-func newMux(ctx context.Context) *mux {
81
-	m := &mux{
82
-		ctx:           ctx,
83
-		clients:       make(map[string]*connection),
84
-		channelClosed: make(chan conntypes.ConnID, 1),
85
-		channelNew:    make(chan muxNewRequest),
86
-	}
87
-	go m.run()
88
-
89
-	return m
90
-}

+ 0
- 79
hub/proxy_conn.go Wyświetl plik

@@ -1,79 +0,0 @@
1
-package hub
2
-
3
-import (
4
-	"sync"
5
-	"time"
6
-
7
-	"github.com/9seconds/mtg/conntypes"
8
-	"github.com/9seconds/mtg/mtproto/rpc"
9
-	"github.com/9seconds/mtg/protocol"
10
-)
11
-
12
-const (
13
-	proxyConnWriteTimeout = 2 * time.Minute
14
-	proxyConnReadTimeout  = 2 * time.Minute
15
-
16
-	proxyConnBackpressureAfter = 10
17
-)
18
-
19
-type ProxyConn struct {
20
-	closeOnce       sync.Once
21
-	req             *protocol.TelegramRequest
22
-	channelResponse chan *rpc.ProxyResponse
23
-	channelClosed   chan<- conntypes.ConnID
24
-	channelWrite    chan<- conntypes.Packet
25
-	channelDone     chan struct{}
26
-}
27
-
28
-func (p *ProxyConn) Read() (*rpc.ProxyResponse, error) {
29
-	timer := time.NewTimer(proxyConnReadTimeout)
30
-	defer timer.Stop()
31
-
32
-	select {
33
-	case <-timer.C:
34
-		return nil, ErrTimeout
35
-	case <-p.channelDone:
36
-		return nil, ErrClosed
37
-	case packet := <-p.channelResponse:
38
-		return packet, nil
39
-	}
40
-}
41
-
42
-func (p *ProxyConn) Write(packet conntypes.Packet) error {
43
-	timer := time.NewTimer(proxyConnWriteTimeout)
44
-	defer timer.Stop()
45
-
46
-	select {
47
-	case <-timer.C:
48
-		return ErrTimeout
49
-	case <-p.channelDone:
50
-		return ErrClosed
51
-	case p.channelWrite <- packet:
52
-		return nil
53
-	}
54
-}
55
-
56
-func (p *ProxyConn) put(response *rpc.ProxyResponse) {
57
-	select {
58
-	case <-p.channelDone:
59
-	case p.channelResponse <- response:
60
-	}
61
-}
62
-
63
-func (p *ProxyConn) Close() {
64
-	p.closeOnce.Do(func() {
65
-		close(p.channelDone)
66
-		go func() {
67
-			p.channelClosed <- p.req.ConnID
68
-		}()
69
-	})
70
-}
71
-
72
-func newProxyConn(req *protocol.TelegramRequest, channelClosed chan<- conntypes.ConnID) *ProxyConn {
73
-	return &ProxyConn{
74
-		channelResponse: make(chan *rpc.ProxyResponse, proxyConnBackpressureAfter),
75
-		channelDone:     make(chan struct{}),
76
-		channelClosed:   channelClosed,
77
-		req:             req,
78
-	}
79
-}

+ 0
- 178
main.go Wyświetl plik

@@ -2,189 +2,11 @@ package main
2 2
 
3 3
 import (
4 4
 	"math/rand"
5
-	"os"
6
-	"runtime/debug"
7
-	"strings"
8 5
 	"time"
9
-
10
-	"github.com/9seconds/mtg/cli"
11
-	"github.com/9seconds/mtg/config"
12
-	"github.com/9seconds/mtg/utils"
13
-	kingpin "gopkg.in/alecthomas/kingpin.v2"
14 6
 )
15 7
 
16 8
 var version = "dev" // has to be set by ldflags
17 9
 
18
-var (
19
-	app = kingpin.New("mtg", "Simple MTPROTO proxy.")
20
-
21
-	generateSecretCommand = app.Command("generate-secret",
22
-		"Generate new secret")
23
-	generateCloakHost = generateSecretCommand.Flag("cloak-host",
24
-		"A host to use for TLS cloaking.").
25
-		Short('c').
26
-		Default("storage.googleapis.com").
27
-		String()
28
-	generateSecretType = generateSecretCommand.Arg("type",
29
-		"A type of secret to generate. Valid options are 'simple', 'secured' and 'tls'").
30
-		Required().
31
-		Enum("simple", "secured", "tls")
32
-
33
-	runCommand = app.Command("run",
34
-		"Run new proxy instance")
35
-	runDebug = runCommand.Flag("debug",
36
-		"Run in debug mode.").
37
-		Short('d').
38
-		Envar("MTG_DEBUG").
39
-		Bool()
40
-	runVerbose = runCommand.Flag("verbose",
41
-		"Run in verbose mode.").
42
-		Short('v').
43
-		Envar("MTG_VERBOSE").
44
-		Bool()
45
-	runPreferIP = runCommand.Flag("prefer-ip",
46
-		"Prefer this IP protocol if possible. Valid options are 'ipv4' and 'ipv6'").
47
-		Envar("MTG_PREFER_DIRECT_IP").
48
-		Default("ipv6").
49
-		Enum("ipv4", "ipv6")
50
-	runBind = runCommand.Flag("bind",
51
-		"Host:Port to bind proxy to.").
52
-		Short('b').
53
-		Envar("MTG_BIND").
54
-		Default("0.0.0.0:3128").
55
-		TCP()
56
-	runPublicIPv4 = runCommand.Flag("public-ipv4",
57
-		"Which IPv4 host:port to use.").
58
-		Short('4').
59
-		Envar("MTG_IPV4").
60
-		TCP()
61
-	runPublicIPv6 = runCommand.Flag("public-ipv6",
62
-		"Which IPv6 host:port to use.").
63
-		Short('6').
64
-		Envar("MTG_IPV6").
65
-		TCP()
66
-	runStatsBind = runCommand.Flag("stats-bind",
67
-		"Which Host:Port to bind stats server to.").
68
-		Short('t').
69
-		Envar("MTG_STATS_BIND").
70
-		Default("127.0.0.1:3129").
71
-		TCP()
72
-	runStatsNamespace = runCommand.Flag("stats-namespace",
73
-		"Which namespace to use for Prometheus.").
74
-		Envar("MTG_STATS_NAMESPACE").
75
-		Default("mtg").
76
-		String()
77
-	runStatsdAddress = runCommand.Flag("statsd-addr",
78
-		"Host:port of statsd server").
79
-		Envar("MTG_STATSD_ADDR").
80
-		TCP()
81
-	runStatsdTagsFormat = runCommand.Flag("statsd-tags-format",
82
-		"Which tag format should we use to send stats metrics. Valid options are 'datadog' and 'influxdb'.").
83
-		Envar("MTG_STATSD_TAGS_FORMAT").
84
-		Default("influxdb").
85
-		Enum("datadog", "influxdb")
86
-	runStatsdTags = runCommand.Flag("statsd-tags",
87
-		"Tags to use for working with statsd (specified as 'key=value').").
88
-		Envar("MTG_STATSD_TAGS").
89
-		StringMap()
90
-	runWriteBufferSize = runCommand.Flag("write-buffer",
91
-		"Write buffer size. You can think about it as a buffer from client to Telegram.").
92
-		Short('w').
93
-		Envar("MTG_BUFFER_WRITE").
94
-		Default("32KB").
95
-		Bytes()
96
-	runReadBufferSize = runCommand.Flag("read-buffer",
97
-		"Read buffer size. You can think about it as a buffer from Telegram to client.").
98
-		Short('r').
99
-		Envar("MTG_BUFFER_READ").
100
-		Default("32KB").
101
-		Bytes()
102
-	runTLSCloakPort = runCommand.Flag("cloak-port",
103
-		"Port which should be used for host cloaking.").
104
-		Envar("MTG_CLOAK_PORT").
105
-		Default("443").
106
-		Uint16()
107
-	runAntiReplayMaxSize = runCommand.Flag("anti-replay-max-size",
108
-		"Max size of antireplay cache.").
109
-		Envar("MTG_ANTIREPLAY_MAXSIZE").
110
-		Default("128MB").
111
-		Bytes()
112
-	runMultiplexPerConnection = runCommand.Flag("multiplex-per-connection",
113
-		"How many clients can share a single connection to Telegram.").
114
-		Envar("MTG_MULTIPLEX_PERCONNECTION").
115
-		Default("50").
116
-		Uint()
117
-	runNTPServers = runCommand.Flag("ntp-server",
118
-		"A list of NTP servers to use.").
119
-		Envar("MTG_NTP_SERVERS").
120
-		Default("0.pool.ntp.org", "1.pool.ntp.org", "2.pool.ntp.org", "3.pool.ntp.org").
121
-		Strings()
122
-	runSecret = runCommand.Arg("secret", "Secret of this proxy.").Required().HexBytes()
123
-	runAdtag  = runCommand.Arg("adtag", "ADTag of the proxy.").HexBytes()
124
-)
125
-
126 10
 func main() {
127 11
 	rand.Seed(time.Now().UTC().UnixNano())
128
-	app.Version(getVersion())
129
-	app.HelpFlag.Short('h')
130
-
131
-	if err := utils.SetLimits(); err != nil {
132
-		cli.Fatal(err)
133
-	}
134
-
135
-	switch kingpin.MustParse(app.Parse(os.Args[1:])) {
136
-	case generateSecretCommand.FullCommand():
137
-		cli.Generate(*generateSecretType, *generateCloakHost)
138
-	case runCommand.FullCommand():
139
-		err := config.Init(
140
-			config.Opt{Option: config.OptionTypeDebug, Value: *runDebug},
141
-			config.Opt{Option: config.OptionTypeVerbose, Value: *runVerbose},
142
-			config.Opt{Option: config.OptionTypePreferIP, Value: *runPreferIP},
143
-			config.Opt{Option: config.OptionTypeBind, Value: *runBind},
144
-			config.Opt{Option: config.OptionTypePublicIPv4, Value: *runPublicIPv4},
145
-			config.Opt{Option: config.OptionTypePublicIPv6, Value: *runPublicIPv6},
146
-			config.Opt{Option: config.OptionTypeStatsBind, Value: *runStatsBind},
147
-			config.Opt{Option: config.OptionTypeStatsNamespace, Value: *runStatsNamespace},
148
-			config.Opt{Option: config.OptionTypeStatsdAddress, Value: *runStatsdAddress},
149
-			config.Opt{Option: config.OptionTypeStatsdTagsFormat, Value: *runStatsdTagsFormat},
150
-			config.Opt{Option: config.OptionTypeStatsdTags, Value: *runStatsdTags},
151
-			config.Opt{Option: config.OptionTypeWriteBufferSize, Value: *runWriteBufferSize},
152
-			config.Opt{Option: config.OptionTypeReadBufferSize, Value: *runReadBufferSize},
153
-			config.Opt{Option: config.OptionTypeCloakPort, Value: *runTLSCloakPort},
154
-			config.Opt{Option: config.OptionTypeAntiReplayMaxSize, Value: *runAntiReplayMaxSize},
155
-			config.Opt{Option: config.OptionTypeMultiplexPerConnection, Value: *runMultiplexPerConnection},
156
-			config.Opt{Option: config.OptionTypeNTPServers, Value: *runNTPServers},
157
-			config.Opt{Option: config.OptionTypeSecret, Value: *runSecret},
158
-			config.Opt{Option: config.OptionTypeAdtag, Value: *runAdtag},
159
-		)
160
-		if err != nil {
161
-			cli.Fatal(err)
162
-		}
163
-
164
-		if err := cli.Proxy(); err != nil {
165
-			cli.Fatal(err)
166
-		}
167
-	}
168
-}
169
-
170
-func getVersion() string {
171
-	if version != "dev" {
172
-		return version
173
-	}
174
-
175
-	info, ok := debug.ReadBuildInfo()
176
-	if !ok {
177
-		return version
178
-	}
179
-
180
-	builder := strings.Builder{}
181
-	builder.WriteString(info.Main.Version)
182
-
183
-	if info.Main.Sum != "" {
184
-		builder.WriteString(" (checksum: ")
185
-		builder.WriteString(info.Main.Sum)
186
-		builder.WriteRune(')')
187
-	}
188
-
189
-	return builder.String()
190 12
 }

+ 0
- 102
mtproto/protocol.go Wyświetl plik

@@ -1,102 +0,0 @@
1
-package mtproto
2
-
3
-import (
4
-	"fmt"
5
-
6
-	"github.com/9seconds/mtg/conntypes"
7
-	"github.com/9seconds/mtg/mtproto/rpc"
8
-	"github.com/9seconds/mtg/protocol"
9
-	"github.com/9seconds/mtg/telegram"
10
-	"github.com/9seconds/mtg/wrappers/packet"
11
-	"github.com/9seconds/mtg/wrappers/stream"
12
-)
13
-
14
-func TelegramProtocol(req *protocol.TelegramRequest) (conntypes.PacketReadWriteCloser, error) {
15
-	conn, err := telegram.Middle.Dial(req.ClientProtocol.DC(),
16
-		req.ClientProtocol.ConnectionProtocol())
17
-	if err != nil {
18
-		return nil, fmt.Errorf("cannot connect to telegram: %w", err)
19
-	}
20
-
21
-	rpcNonceConn := packet.NewMtprotoFrame(conn, rpc.SeqNoNonce)
22
-
23
-	rpcNonceReq, err := doRPCNonceRequest(rpcNonceConn)
24
-	if err != nil {
25
-		return nil, fmt.Errorf("cannot do nonce request: %w", err)
26
-	}
27
-
28
-	rpcNonceResp, err := getRPCNonceResponse(rpcNonceConn, rpcNonceReq)
29
-	if err != nil {
30
-		return nil, fmt.Errorf("cannot get nonce response: %w", err)
31
-	}
32
-
33
-	secureConn := stream.NewMiddleProxyCipher(conn, rpcNonceReq, rpcNonceResp, telegram.Middle.Secret())
34
-	frameConn := packet.NewMtprotoFrame(secureConn, rpc.SeqNoHandshake)
35
-
36
-	if err := doRPCHandshakeRequest(frameConn); err != nil {
37
-		return nil, fmt.Errorf("cannot do handshake request: %w", err)
38
-	}
39
-
40
-	if err := getRPCHandshakeResponse(frameConn); err != nil {
41
-		return nil, fmt.Errorf("cannot get handshake response: %w", err)
42
-	}
43
-
44
-	return frameConn, nil
45
-}
46
-
47
-func doRPCNonceRequest(conn conntypes.BasePacketWriter) (*rpc.NonceRequest, error) {
48
-	rpcNonceReq, err := rpc.NewNonceRequest(telegram.Middle.Secret())
49
-	if err != nil {
50
-		panic(err)
51
-	}
52
-
53
-	if err := conn.Write(rpcNonceReq.Bytes()); err != nil {
54
-		return nil, err // nolint: wrapcheck
55
-	}
56
-
57
-	return rpcNonceReq, nil
58
-}
59
-
60
-func getRPCNonceResponse(conn conntypes.BasePacketReader, req *rpc.NonceRequest) (*rpc.NonceResponse, error) {
61
-	packet, err := conn.Read()
62
-	if err != nil {
63
-		return nil, fmt.Errorf("cannot read from connection: %w", err)
64
-	}
65
-
66
-	resp, err := rpc.NewNonceResponse(packet)
67
-	if err != nil {
68
-		return nil, fmt.Errorf("cannot build rpc nonce response: %w", err)
69
-	}
70
-
71
-	if err = resp.Valid(req); err != nil {
72
-		return nil, fmt.Errorf("invalid nonce response: %w", err)
73
-	}
74
-
75
-	return resp, nil
76
-}
77
-
78
-func doRPCHandshakeRequest(conn conntypes.BasePacketWriter) error {
79
-	if err := conn.Write(rpc.HandshakeRequest); err != nil {
80
-		return fmt.Errorf("cannot make a request: %w", err)
81
-	}
82
-
83
-	return nil
84
-}
85
-
86
-func getRPCHandshakeResponse(conn conntypes.BasePacketReader) error {
87
-	packet, err := conn.Read()
88
-	if err != nil {
89
-		return fmt.Errorf("cannot read a response: %w", err)
90
-	}
91
-
92
-	resp, err := rpc.NewHandshakeResponse(packet)
93
-	if err != nil {
94
-		return fmt.Errorf("cannot build a handshake response: %w", err)
95
-	}
96
-
97
-	if err := resp.Valid(); err != nil {
98
-		return fmt.Errorf("invalid handshake response: %w", err)
99
-	}
100
-
101
-	return nil
102
-}

+ 0
- 28
mtproto/rpc/consts.go Wyświetl plik

@@ -1,28 +0,0 @@
1
-package rpc
2
-
3
-// SeqNo* is the number of the sequence which have special meaning for
4
-// the Telegram.
5
-const (
6
-	SeqNoNonce     = -2
7
-	SeqNoHandshake = -1
8
-)
9
-
10
-// Different constants for RPC protocol.
11
-var (
12
-	TagCloseExt     = []byte{0xa2, 0x34, 0xb6, 0x5e}
13
-	TagProxyAns     = []byte{0x0d, 0xda, 0x03, 0x44}
14
-	TagSimpleAck    = []byte{0x9b, 0x40, 0xac, 0x3b}
15
-	TagHandshake    = []byte{0xf5, 0xee, 0x82, 0x76}
16
-	TagNonce        = []byte{0xaa, 0x87, 0xcb, 0x7a}
17
-	TagProxyRequest = []byte{0xee, 0xf1, 0xce, 0x36}
18
-
19
-	NonceCryptoAES = []byte{0x01, 0x00, 0x00, 0x00}
20
-
21
-	HandshakeFlags = []byte{0x00, 0x00, 0x00, 0x00}
22
-
23
-	ProxyRequestExtraSize = []byte{0x18, 0x00, 0x00, 0x00}
24
-	ProxyRequestProxyTag  = []byte{0xae, 0x26, 0x1e, 0xdb}
25
-
26
-	HandshakeSenderPID = []byte("IPIPPRPDTIME")
27
-	HandshakePeerPID   = []byte("IPIPPRPDTIME")
28
-)

+ 0
- 5
mtproto/rpc/handshake_request.go Wyświetl plik

@@ -1,5 +0,0 @@
1
-package rpc
2
-
3
-var HandshakeRequest = append(TagHandshake,
4
-	append(HandshakeFlags,
5
-		append(HandshakeSenderPID, HandshakePeerPID...)...)...)

+ 0
- 54
mtproto/rpc/handshake_response.go Wyświetl plik

@@ -1,54 +0,0 @@
1
-package rpc
2
-
3
-import (
4
-	"bytes"
5
-	"errors"
6
-	"fmt"
7
-)
8
-
9
-type HandshakeResponse struct {
10
-	Type      []byte
11
-	Flags     []byte
12
-	SenderPID []byte
13
-	PeerPID   []byte
14
-}
15
-
16
-// Bytes returns a serialized handshake response.
17
-func (r *HandshakeResponse) Bytes() []byte {
18
-	buf := &bytes.Buffer{}
19
-
20
-	buf.Write(r.Type)
21
-	buf.Write(r.Flags)
22
-	buf.Write(r.SenderPID)
23
-	buf.Write(r.PeerPID)
24
-
25
-	return buf.Bytes()
26
-}
27
-
28
-// Valid checks that handshake response compliments request.
29
-func (r *HandshakeResponse) Valid() error {
30
-	if !bytes.Equal(r.Type, TagHandshake) {
31
-		return errors.New("unexpected handshake tag")
32
-	}
33
-
34
-	if !bytes.Equal(r.PeerPID, HandshakeSenderPID) {
35
-		return errors.New("incorrect sender PID")
36
-	}
37
-
38
-	return nil
39
-}
40
-
41
-// NewHandshakeResponse constructs new handshake response from the given
42
-// data.
43
-func NewHandshakeResponse(data []byte) (*HandshakeResponse, error) {
44
-	if len(data) != 32 {
45
-		return nil, fmt.Errorf("incorrect handshake response length %d", len(data))
46
-	}
47
-
48
-	return &HandshakeResponse{
49
-		Type:      data[:4],
50
-		Flags:     data[4:8],
51
-		SenderPID: data[8:20],
52
-		PeerPID:   data[20:],
53
-	}, nil
54
-}

+ 0
- 50
mtproto/rpc/nonce_request.go Wyświetl plik

@@ -1,50 +0,0 @@
1
-package rpc
2
-
3
-import (
4
-	"bytes"
5
-	"crypto/rand"
6
-	"encoding/binary"
7
-	"fmt"
8
-	"time"
9
-)
10
-
11
-type NonceRequest struct {
12
-	KeySelector []byte
13
-	CryptoTS    []byte
14
-	Nonce       []byte
15
-}
16
-
17
-// Bytes returns serialized nonce request.
18
-func (r *NonceRequest) Bytes() []byte {
19
-	buf := &bytes.Buffer{}
20
-
21
-	buf.Write(TagNonce)
22
-	buf.Write(r.KeySelector)
23
-	buf.Write(NonceCryptoAES)
24
-	buf.Write(r.CryptoTS)
25
-	buf.Write(r.Nonce)
26
-
27
-	return buf.Bytes()
28
-}
29
-
30
-// NewNonceRequest builds new none request based on proxy secret.
31
-func NewNonceRequest(proxySecret []byte) (*NonceRequest, error) {
32
-	nonce := make([]byte, 16)
33
-	keySelector := make([]byte, 4)
34
-	cryptoTS := make([]byte, 4)
35
-
36
-	if _, err := rand.Read(nonce); err != nil {
37
-		return nil, fmt.Errorf("cannot generate nonce: %w", err)
38
-	}
39
-
40
-	copy(keySelector, proxySecret)
41
-
42
-	timestamp := time.Now().Truncate(time.Second).Unix() % 4294967296 // 256 ^ 4 - do not know how to name
43
-	binary.LittleEndian.PutUint32(cryptoTS, uint32(timestamp))
44
-
45
-	return &NonceRequest{
46
-		KeySelector: keySelector,
47
-		CryptoTS:    cryptoTS,
48
-		Nonce:       nonce,
49
-	}, nil
50
-}

+ 0
- 60
mtproto/rpc/nonce_response.go Wyświetl plik

@@ -1,60 +0,0 @@
1
-package rpc
2
-
3
-import (
4
-	"bytes"
5
-	"errors"
6
-	"fmt"
7
-)
8
-
9
-type NonceResponse struct {
10
-	NonceRequest
11
-
12
-	Type   []byte
13
-	Crypto []byte
14
-}
15
-
16
-// Bytes returns serialized form of the nonce response.
17
-func (r *NonceResponse) Bytes() []byte {
18
-	buf := bytes.Buffer{}
19
-
20
-	buf.Write(r.Type)
21
-	buf.Write(r.KeySelector)
22
-	buf.Write(r.Crypto)
23
-	buf.Write(r.CryptoTS)
24
-	buf.Write(r.Nonce)
25
-
26
-	return buf.Bytes()
27
-}
28
-
29
-func (r *NonceResponse) Valid(req *NonceRequest) error {
30
-	if !bytes.Equal(r.Type, TagNonce) {
31
-		return errors.New("unexpected RPC type")
32
-	}
33
-
34
-	if !bytes.Equal(r.Crypto, NonceCryptoAES) {
35
-		return errors.New("unexpected crypto type")
36
-	}
37
-
38
-	if !bytes.Equal(r.KeySelector, req.KeySelector) {
39
-		return errors.New("unexpected key selector")
40
-	}
41
-
42
-	return nil
43
-}
44
-
45
-// NewNonceResponse build new nonce response based on the given data.
46
-func NewNonceResponse(data []byte) (*NonceResponse, error) {
47
-	if len(data) != 32 {
48
-		return nil, fmt.Errorf("unexpected message length %d", len(data))
49
-	}
50
-
51
-	return &NonceResponse{
52
-		NonceRequest: NonceRequest{
53
-			KeySelector: data[4:8],
54
-			CryptoTS:    data[12:16],
55
-			Nonce:       data[16:],
56
-		},
57
-		Type:   data[:4],
58
-		Crypto: data[8:12],
59
-	}, nil
60
-}

+ 0
- 66
mtproto/rpc/proxy_flags.go Wyświetl plik

@@ -1,66 +0,0 @@
1
-package rpc
2
-
3
-import (
4
-	"encoding/binary"
5
-	"strings"
6
-)
7
-
8
-type ProxyRequestFlags uint32
9
-
10
-const (
11
-	ProxyRequestFlagsHasAdTag     ProxyRequestFlags = 0x8
12
-	ProxyRequestFlagsEncrypted    ProxyRequestFlags = 0x2
13
-	ProxyRequestFlagsMagic        ProxyRequestFlags = 0x1000
14
-	ProxyRequestFlagsExtMode2     ProxyRequestFlags = 0x20000
15
-	ProxyRequestFlagsIntermediate ProxyRequestFlags = 0x20000000
16
-	ProxyRequestFlagsAbdridged    ProxyRequestFlags = 0x40000000
17
-	ProxyRequestFlagsQuickAck     ProxyRequestFlags = 0x80000000
18
-	ProxyRequestFlagsPad          ProxyRequestFlags = 0x8000000
19
-)
20
-
21
-var ProxyRequestFlagsEncryptedPrefix [8]byte
22
-
23
-func (r ProxyRequestFlags) Bytes() []byte {
24
-	converted := make([]byte, 4)
25
-	binary.LittleEndian.PutUint32(converted, uint32(r))
26
-
27
-	return converted
28
-}
29
-
30
-func (r ProxyRequestFlags) String() string {
31
-	flags := make([]string, 0, 7)
32
-
33
-	if r&ProxyRequestFlagsHasAdTag != 0 {
34
-		flags = append(flags, "HAS_AD_TAG")
35
-	}
36
-
37
-	if r&ProxyRequestFlagsEncrypted != 0 {
38
-		flags = append(flags, "ENCRYPTED")
39
-	}
40
-
41
-	if r&ProxyRequestFlagsMagic != 0 {
42
-		flags = append(flags, "MAGIC")
43
-	}
44
-
45
-	if r&ProxyRequestFlagsExtMode2 != 0 {
46
-		flags = append(flags, "EXT_MODE_2")
47
-	}
48
-
49
-	if r&ProxyRequestFlagsIntermediate != 0 {
50
-		flags = append(flags, "INTERMEDIATE")
51
-	}
52
-
53
-	if r&ProxyRequestFlagsAbdridged != 0 {
54
-		flags = append(flags, "ABRIDGED")
55
-	}
56
-
57
-	if r&ProxyRequestFlagsQuickAck != 0 {
58
-		flags = append(flags, "QUICK_ACK")
59
-	}
60
-
61
-	if r&ProxyRequestFlagsPad != 0 {
62
-		flags = append(flags, "PAD")
63
-	}
64
-
65
-	return strings.Join(flags, " | ")
66
-}

+ 0
- 53
mtproto/rpc/proxy_response.go Wyświetl plik

@@ -1,53 +0,0 @@
1
-package rpc
2
-
3
-import (
4
-	"bytes"
5
-	"fmt"
6
-
7
-	"github.com/9seconds/mtg/conntypes"
8
-)
9
-
10
-type ProxyResponseType uint8
11
-
12
-const (
13
-	ProxyResponseTypeAns ProxyResponseType = iota
14
-	ProxyResponseTypeSimpleAck
15
-	ProxyResponseTypeCloseExt
16
-)
17
-
18
-type ProxyResponse struct {
19
-	Type    ProxyResponseType
20
-	ConnID  conntypes.ConnID
21
-	Payload conntypes.Packet
22
-}
23
-
24
-func ParseProxyResponse(packet conntypes.Packet) (*ProxyResponse, error) {
25
-	var response ProxyResponse
26
-
27
-	if len(packet) < 4 {
28
-		return nil, fmt.Errorf("incorrect packet length: %d", len(packet))
29
-	}
30
-
31
-	tag := packet[:4]
32
-
33
-	switch {
34
-	case bytes.Equal(tag, TagProxyAns):
35
-		response.Type = ProxyResponseTypeAns
36
-		copy(response.ConnID[:], packet[8:16])
37
-		response.Payload = packet[16:]
38
-
39
-		return &response, nil
40
-	case bytes.Equal(tag, TagSimpleAck):
41
-		response.Type = ProxyResponseTypeSimpleAck
42
-		copy(response.ConnID[:], packet[4:12])
43
-		response.Payload = packet[12:]
44
-
45
-		return &response, nil
46
-	case bytes.Equal(tag, TagCloseExt):
47
-		response.Type = ProxyResponseTypeCloseExt
48
-
49
-		return &response, nil
50
-	}
51
-
52
-	return nil, fmt.Errorf("unknown response type %x", tag)
53
-}

+ 0
- 57
ntp/ntp.go Wyświetl plik

@@ -1,57 +0,0 @@
1
-package ntp
2
-
3
-import (
4
-	"fmt"
5
-	"math/rand"
6
-	"time"
7
-
8
-	"github.com/9seconds/mtg/config"
9
-	"github.com/beevik/ntp"
10
-	"go.uber.org/zap"
11
-)
12
-
13
-const autoUpdatePeriod = time.Minute
14
-
15
-// Fetch fetches the data on time drift.
16
-func Fetch() (time.Duration, error) {
17
-	url := config.C.NTPServers[rand.Intn(len(config.C.NTPServers))] // nolint: gosec
18
-
19
-	resp, err := ntp.Query(url)
20
-	if err != nil {
21
-		return 0, fmt.Errorf("cannot fetch NTP server %s: %w", url, err)
22
-	}
23
-
24
-	offsetInt := int64(resp.ClockOffset)
25
-	if offsetInt < 0 {
26
-		offsetInt = -offsetInt
27
-	}
28
-
29
-	offset := time.Duration(offsetInt)
30
-
31
-	return offset, nil
32
-}
33
-
34
-// AutoUpdate runs periodic check of current time .drift state.
35
-func AutoUpdate() {
36
-	logger := zap.S().Named("ntp")
37
-
38
-	for range time.Tick(autoUpdatePeriod) {
39
-		diff, err := Fetch()
40
-		if err != nil {
41
-			logger.Debugw("Cannot fetch time from NTP", "error", err)
42
-
43
-			continue
44
-		}
45
-
46
-		switch {
47
-		case diff < 400*time.Millisecond:
48
-			logger.Debugw("NTP time drift", "value", diff.String())
49
-		case diff < 600*time.Millisecond:
50
-			logger.Infow("NTP time drift", "value", diff.String())
51
-		case diff < 800*time.Millisecond:
52
-			logger.Warnw("NTP time drift", "value", diff.String())
53
-		default:
54
-			logger.Errorw("NTP time drift", "value", diff.String())
55
-		}
56
-	}
57
-}

+ 0
- 114
obfuscated2/client_protocol.go Wyświetl plik

@@ -1,114 +0,0 @@
1
-package obfuscated2
2
-
3
-import (
4
-	"bytes"
5
-	"crypto/sha256"
6
-	"encoding/binary"
7
-	"errors"
8
-	"fmt"
9
-	"io"
10
-	"time"
11
-
12
-	"github.com/9seconds/mtg/antireplay"
13
-	"github.com/9seconds/mtg/config"
14
-	"github.com/9seconds/mtg/conntypes"
15
-	"github.com/9seconds/mtg/protocol"
16
-	"github.com/9seconds/mtg/stats"
17
-	"github.com/9seconds/mtg/utils"
18
-	"github.com/9seconds/mtg/wrappers/stream"
19
-)
20
-
21
-const clientProtocolHandshakeTimeout = 10 * time.Second
22
-
23
-type ClientProtocol struct {
24
-	connectionType     conntypes.ConnectionType
25
-	connectionProtocol conntypes.ConnectionProtocol
26
-	dc                 conntypes.DC
27
-}
28
-
29
-func (c *ClientProtocol) ConnectionType() conntypes.ConnectionType {
30
-	return c.connectionType
31
-}
32
-
33
-func (c *ClientProtocol) ConnectionProtocol() conntypes.ConnectionProtocol {
34
-	return c.connectionProtocol
35
-}
36
-
37
-func (c *ClientProtocol) DC() conntypes.DC {
38
-	return c.dc
39
-}
40
-
41
-func (c *ClientProtocol) Handshake(socket conntypes.StreamReadWriteCloser) (conntypes.StreamReadWriteCloser, error) {
42
-	fm, err := c.ReadFrame(socket)
43
-	if err != nil {
44
-		return nil, fmt.Errorf("cannot make a client handshake: %w", err)
45
-	}
46
-
47
-	decHasher := sha256.New()
48
-	decHasher.Write(fm.Key())        // nolint: errcheck
49
-	decHasher.Write(config.C.Secret) // nolint: errcheck
50
-	decryptor := utils.MakeStreamCipher(decHasher.Sum(nil), fm.IV())
51
-
52
-	invertedFrame := fm.Invert()
53
-	encHasher := sha256.New()
54
-	encHasher.Write(invertedFrame.Key()) // nolint: errcheck
55
-	encHasher.Write(config.C.Secret)     // nolint: errcheck
56
-	encryptor := utils.MakeStreamCipher(encHasher.Sum(nil), invertedFrame.IV())
57
-
58
-	decryptedFrame := Frame{}
59
-	decryptor.XORKeyStream(decryptedFrame.Bytes(), fm.Bytes())
60
-
61
-	magic := decryptedFrame.Magic()
62
-
63
-	switch {
64
-	case bytes.Equal(magic, conntypes.ConnectionTagAbridged):
65
-		c.connectionType = conntypes.ConnectionTypeAbridged
66
-	case bytes.Equal(magic, conntypes.ConnectionTagIntermediate):
67
-		c.connectionType = conntypes.ConnectionTypeIntermediate
68
-	case bytes.Equal(magic, conntypes.ConnectionTagSecure):
69
-		c.connectionType = conntypes.ConnectionTypeSecure
70
-	default:
71
-		return nil, errors.New("unknown connection type")
72
-	}
73
-
74
-	c.connectionProtocol = conntypes.ConnectionProtocolIPv4
75
-	if socket.LocalAddr().IP.To4() == nil {
76
-		c.connectionProtocol = conntypes.ConnectionProtocolIPv6
77
-	}
78
-
79
-	buf := bytes.NewReader(decryptedFrame.DC())
80
-	if err := binary.Read(buf, binary.LittleEndian, &c.dc); err != nil {
81
-		c.dc = conntypes.DCDefaultIdx
82
-	}
83
-
84
-	replayKey := decryptedFrame.Unique()
85
-	if antireplay.Cache.HasObfuscated2(replayKey) {
86
-		stats.Stats.ReplayDetected()
87
-
88
-		return nil, errors.New("replay attack is detected")
89
-	}
90
-
91
-	antireplay.Cache.AddObfuscated2(replayKey)
92
-
93
-	return stream.NewObfuscated2(socket, encryptor, decryptor), nil
94
-}
95
-
96
-func (c *ClientProtocol) ReadFrame(socket conntypes.StreamReader) (fm Frame, err error) {
97
-	if _, err = io.ReadFull(handshakeReader{socket}, fm.Bytes()); err != nil {
98
-		err = fmt.Errorf("cannot extract obfuscated2 frame: %w", err)
99
-	}
100
-
101
-	return
102
-}
103
-
104
-type handshakeReader struct {
105
-	parent conntypes.StreamReader
106
-}
107
-
108
-func (h handshakeReader) Read(p []byte) (int, error) {
109
-	return h.parent.ReadTimeout(p, clientProtocolHandshakeTimeout)
110
-}
111
-
112
-func MakeClientProtocol() protocol.ClientProtocol {
113
-	return &ClientProtocol{}
114
-}

+ 0
- 54
obfuscated2/frame.go Wyświetl plik

@@ -1,54 +0,0 @@
1
-package obfuscated2
2
-
3
-const (
4
-	frameLenKey   = 32
5
-	frameLenIV    = 16
6
-	frameLenMagic = 4
7
-	frameLenDC    = 2
8
-
9
-	frameOffsetFirst = 8
10
-	frameOffsetKey   = frameOffsetFirst + frameLenKey
11
-	frameOffsetIV    = frameOffsetKey + frameLenIV
12
-	frameOffsetMagic = frameOffsetIV + frameLenMagic
13
-	frameOffsetDC    = frameOffsetMagic + frameLenDC
14
-
15
-	frameLen = 64
16
-)
17
-
18
-// [frameOffsetFirst:frameOffsetKey:frameOffsetIV:frameOffsetMagic:frameOffsetDC:frameOffsetEnd].
19
-type Frame struct {
20
-	data [frameLen]byte
21
-}
22
-
23
-func (f *Frame) Bytes() []byte {
24
-	return f.data[:]
25
-}
26
-
27
-func (f *Frame) Key() []byte {
28
-	return f.data[frameOffsetFirst:frameOffsetKey]
29
-}
30
-
31
-func (f *Frame) IV() []byte {
32
-	return f.data[frameOffsetKey:frameOffsetIV]
33
-}
34
-
35
-func (f *Frame) Magic() []byte {
36
-	return f.data[frameOffsetIV:frameOffsetMagic]
37
-}
38
-
39
-func (f *Frame) DC() []byte {
40
-	return f.data[frameOffsetMagic:frameOffsetDC]
41
-}
42
-
43
-func (f *Frame) Unique() []byte {
44
-	return f.data[frameOffsetFirst:frameOffsetDC]
45
-}
46
-
47
-func (f *Frame) Invert() (nf Frame) {
48
-	nf = *f
49
-	for i := 0; i < frameLenKey+frameLenIV; i++ {
50
-		nf.data[frameOffsetFirst+i] = f.data[frameOffsetIV-1-i]
51
-	}
52
-
53
-	return
54
-}

+ 0
- 68
obfuscated2/telegram_protocol.go Wyświetl plik

@@ -1,68 +0,0 @@
1
-package obfuscated2
2
-
3
-import (
4
-	"crypto/rand"
5
-	"fmt"
6
-
7
-	"github.com/9seconds/mtg/conntypes"
8
-	"github.com/9seconds/mtg/protocol"
9
-	"github.com/9seconds/mtg/telegram"
10
-	"github.com/9seconds/mtg/utils"
11
-	"github.com/9seconds/mtg/wrappers/stream"
12
-)
13
-
14
-func TelegramProtocol(req *protocol.TelegramRequest) (conntypes.StreamReadWriteCloser, error) {
15
-	conn, err := telegram.Direct.Dial(req.ClientProtocol.DC(),
16
-		req.ClientProtocol.ConnectionProtocol())
17
-	if err != nil {
18
-		return nil, fmt.Errorf("cannot dial to telegram: %w", err)
19
-	}
20
-
21
-	conn = stream.NewTimeout(conn)
22
-	conn = stream.NewCtx(req.Ctx, req.Cancel, conn)
23
-	fm := generateFrame(req.ClientProtocol)
24
-	data := fm.Bytes()
25
-
26
-	encryptor := utils.MakeStreamCipher(fm.Key(), fm.IV())
27
-	decryptedFrame := fm.Invert()
28
-	decryptor := utils.MakeStreamCipher(decryptedFrame.Key(), decryptedFrame.IV())
29
-
30
-	copyFrame := make([]byte, frameLen)
31
-	copy(copyFrame[:frameOffsetIV], data[:frameOffsetIV])
32
-	encryptor.XORKeyStream(data, data)
33
-	copy(data[:frameOffsetIV], copyFrame[:frameOffsetIV])
34
-
35
-	if _, err := conn.Write(data); err != nil {
36
-		return nil, fmt.Errorf("cannot write handshake frame to telegram: %w", err)
37
-	}
38
-
39
-	return stream.NewObfuscated2(conn, encryptor, decryptor), nil
40
-}
41
-
42
-func generateFrame(cp protocol.ClientProtocol) (fm Frame) {
43
-	data := fm.Bytes()
44
-
45
-	for {
46
-		if _, err := rand.Read(data); err != nil {
47
-			continue
48
-		}
49
-
50
-		if data[0] == 0xef {
51
-			continue
52
-		}
53
-
54
-		val := (uint32(data[3]) << 24) | (uint32(data[2]) << 16) | (uint32(data[1]) << 8) | uint32(data[0])
55
-		if val == 0x44414548 || val == 0x54534f50 || val == 0x20544547 || val == 0x4954504f || val == 0xeeeeeeee {
56
-			continue
57
-		}
58
-
59
-		val = (uint32(data[7]) << 24) | (uint32(data[6]) << 16) | (uint32(data[5]) << 8) | uint32(data[4])
60
-		if val == 0x00000000 {
61
-			continue
62
-		}
63
-
64
-		copy(fm.Magic(), cp.ConnectionType().Tag())
65
-
66
-		return
67
-	}
68
-}

+ 0
- 12
protocol/interfaces.go Wyświetl plik

@@ -1,12 +0,0 @@
1
-package protocol
2
-
3
-import "github.com/9seconds/mtg/conntypes"
4
-
5
-type ClientProtocol interface {
6
-	Handshake(conntypes.StreamReadWriteCloser) (conntypes.StreamReadWriteCloser, error)
7
-	ConnectionType() conntypes.ConnectionType
8
-	ConnectionProtocol() conntypes.ConnectionProtocol
9
-	DC() conntypes.DC
10
-}
11
-
12
-type ClientProtocolMaker func() ClientProtocol

+ 0
- 17
protocol/request.go Wyświetl plik

@@ -1,17 +0,0 @@
1
-package protocol
2
-
3
-import (
4
-	"context"
5
-
6
-	"github.com/9seconds/mtg/conntypes"
7
-	"go.uber.org/zap"
8
-)
9
-
10
-type TelegramRequest struct {
11
-	Logger         *zap.SugaredLogger
12
-	ClientConn     conntypes.StreamReadWriteCloser
13
-	ConnID         conntypes.ConnID
14
-	Ctx            context.Context
15
-	Cancel         context.CancelFunc
16
-	ClientProtocol ClientProtocol
17
-}

+ 0
- 49
proxy/direct.go Wyświetl plik

@@ -1,49 +0,0 @@
1
-package proxy
2
-
3
-import (
4
-	"io"
5
-	"sync"
6
-
7
-	"github.com/9seconds/mtg/conntypes"
8
-	"github.com/9seconds/mtg/obfuscated2"
9
-	"github.com/9seconds/mtg/protocol"
10
-	"go.uber.org/zap"
11
-)
12
-
13
-const directPipeBufferSize = 1024
14
-
15
-func directConnection(request *protocol.TelegramRequest) error {
16
-	telegramConnRaw, err := obfuscated2.TelegramProtocol(request)
17
-	if err != nil {
18
-		return err // nolint: wrapcheck
19
-	}
20
-
21
-	telegramConn := telegramConnRaw.(conntypes.StreamReadWriteCloser)
22
-
23
-	defer telegramConn.Close()
24
-
25
-	wg := &sync.WaitGroup{}
26
-	wg.Add(2)
27
-
28
-	go directPipe(telegramConn, request.ClientConn, wg, request.Logger)
29
-
30
-	go directPipe(request.ClientConn, telegramConn, wg, request.Logger)
31
-
32
-	wg.Wait()
33
-
34
-	return nil
35
-}
36
-
37
-func directPipe(dst io.WriteCloser, src io.ReadCloser, wg *sync.WaitGroup, logger *zap.SugaredLogger) {
38
-	defer func() {
39
-		dst.Close()
40
-		src.Close()
41
-		wg.Done()
42
-	}()
43
-
44
-	buf := [directPipeBufferSize]byte{}
45
-
46
-	if _, err := io.CopyBuffer(dst, src, buf[:]); err != nil {
47
-		logger.Debugw("Cannot pump sockets", "error", err)
48
-	}
49
-}

+ 0
- 70
proxy/middle.go Wyświetl plik

@@ -1,70 +0,0 @@
1
-package proxy
2
-
3
-import (
4
-	"sync"
5
-
6
-	"github.com/9seconds/mtg/conntypes"
7
-	"github.com/9seconds/mtg/protocol"
8
-	"github.com/9seconds/mtg/wrappers/packetack"
9
-	"go.uber.org/zap"
10
-)
11
-
12
-func middleConnection(request *protocol.TelegramRequest) {
13
-	telegramConn, err := packetack.NewProxy(request)
14
-	if err != nil {
15
-		request.Logger.Debugw("Cannot dial to Telegram", "error", err)
16
-
17
-		return
18
-	}
19
-	defer telegramConn.Close()
20
-
21
-	var clientConn conntypes.PacketAckFullReadWriteCloser
22
-
23
-	switch request.ClientProtocol.ConnectionType() {
24
-	case conntypes.ConnectionTypeAbridged:
25
-		clientConn = packetack.NewClientAbridged(request.ClientConn)
26
-	case conntypes.ConnectionTypeIntermediate:
27
-		clientConn = packetack.NewClientIntermediate(request.ClientConn)
28
-	case conntypes.ConnectionTypeSecure:
29
-		clientConn = packetack.NewClientIntermediateSecure(request.ClientConn)
30
-	case conntypes.ConnectionTypeUnknown:
31
-		panic("unknown connection type")
32
-	}
33
-
34
-	wg := &sync.WaitGroup{}
35
-	wg.Add(2)
36
-
37
-	go middlePipe(telegramConn, clientConn, wg, request.Logger)
38
-
39
-	go middlePipe(clientConn, telegramConn, wg, request.Logger)
40
-
41
-	wg.Wait()
42
-}
43
-
44
-func middlePipe(dst conntypes.PacketAckWriteCloser,
45
-	src conntypes.PacketAckReadCloser,
46
-	wg *sync.WaitGroup,
47
-	logger *zap.SugaredLogger) {
48
-	defer func() {
49
-		dst.Close()
50
-		src.Close()
51
-		wg.Done()
52
-	}()
53
-
54
-	for {
55
-		acks := conntypes.ConnectionAcks{}
56
-
57
-		packet, err := src.Read(&acks)
58
-		if err != nil {
59
-			logger.Debugw("Cannot read packet", "error", err)
60
-
61
-			return
62
-		}
63
-
64
-		if err = dst.Write(packet, &acks); err != nil {
65
-			logger.Debugw("Cannot send packet", "error", err)
66
-
67
-			return
68
-		}
69
-	}
70
-}

+ 0
- 100
proxy/proxy.go Wyświetl plik

@@ -1,100 +0,0 @@
1
-package proxy
2
-
3
-import (
4
-	"context"
5
-	"net"
6
-
7
-	"github.com/9seconds/mtg/config"
8
-	"github.com/9seconds/mtg/conntypes"
9
-	"github.com/9seconds/mtg/protocol"
10
-	"github.com/9seconds/mtg/stats"
11
-	"github.com/9seconds/mtg/utils"
12
-	"github.com/9seconds/mtg/wrappers/stream"
13
-	"go.uber.org/zap"
14
-)
15
-
16
-type Proxy struct {
17
-	Logger              *zap.SugaredLogger
18
-	Context             context.Context
19
-	ClientProtocolMaker protocol.ClientProtocolMaker
20
-}
21
-
22
-func (p *Proxy) Serve(listener net.Listener) {
23
-	doneChan := p.Context.Done()
24
-
25
-	for {
26
-		conn, err := listener.Accept()
27
-		if err != nil {
28
-			select {
29
-			case <-doneChan:
30
-				return
31
-			default:
32
-				p.Logger.Fatalw("Cannot allocate incoming connection", "error", err)
33
-			}
34
-		}
35
-
36
-		go p.accept(conn)
37
-	}
38
-}
39
-
40
-func (p *Proxy) accept(conn net.Conn) {
41
-	defer func() {
42
-		conn.Close()
43
-
44
-		if err := recover(); err != nil {
45
-			stats.Stats.Crash()
46
-			p.Logger.Errorw("Crash of accept handler", "error", err)
47
-		}
48
-	}()
49
-
50
-	connID := conntypes.NewConnID()
51
-	logger := p.Logger.With("connection_id", connID)
52
-
53
-	if err := utils.InitTCP(conn, config.C.ClientReadBuffer(), config.C.ClientWriteBuffer()); err != nil {
54
-		logger.Errorw("Cannot initialize client TCP connection", "error", err)
55
-
56
-		return
57
-	}
58
-
59
-	ctx, cancel := context.WithCancel(p.Context)
60
-	defer cancel()
61
-
62
-	clientConn := stream.NewClientConn(conn, connID)
63
-	clientConn = stream.NewCtx(ctx, cancel, clientConn)
64
-	clientConn = stream.NewTimeout(clientConn)
65
-
66
-	defer clientConn.Close()
67
-
68
-	clientProtocol := p.ClientProtocolMaker()
69
-
70
-	clientConn, err := clientProtocol.Handshake(clientConn)
71
-	if err != nil {
72
-		stats.Stats.AuthenticationFailed()
73
-		logger.Warnw("Cannot perform client handshake", "error", err)
74
-
75
-		return
76
-	}
77
-
78
-	stats.Stats.ClientConnected(clientProtocol.ConnectionType(), clientConn.RemoteAddr())
79
-	defer stats.Stats.ClientDisconnected(clientProtocol.ConnectionType(), clientConn.RemoteAddr())
80
-	logger.Infow("Client connected", "addr", conn.RemoteAddr())
81
-
82
-	req := &protocol.TelegramRequest{
83
-		Logger:         logger,
84
-		ClientConn:     clientConn,
85
-		ConnID:         connID,
86
-		Ctx:            ctx,
87
-		Cancel:         cancel,
88
-		ClientProtocol: clientProtocol,
89
-	}
90
-
91
-	err = nil
92
-
93
-	if config.C.MiddleProxyMode() {
94
-		middleConnection(req)
95
-	} else {
96
-		err = directConnection(req)
97
-	}
98
-
99
-	logger.Infow("Client disconnected", "error", err, "addr", conn.RemoteAddr())
100
-}

+ 0
- 68
run.sh Wyświetl plik

@@ -1,68 +0,0 @@
1
-#!/bin/bash
2
-#
3
-# Configuration options (set by environment variables during script execution)
4
-#   - MTG_CONFIG    - directory where mtg stores its configuration
5
-#   - MTG_IMAGENAME - a name of the docker image to use
6
-#   - MTG_PORT      - which port of the host system should be used
7
-#   - MTG_CONTAINER - a name of the container to use
8
-#
9
-# Example:
10
-#   export MTG_CONFIG="$HOME/mtg_config"
11
-#   export MTG_IMAGENAME="nineseconds/mtg:latest"
12
-#   curl -sfL --compressed https://raw.githubusercontent.com/9seconds/mtg/master/run.sh | bash
13
-
14
-set -eu
15
-
16
-export XDG_CONFIG_HOME="${XDG_CONFIG_HOME:-$HOME/.config}"
17
-export MTG_CONFIG="${MTG_CONFIG:-$XDG_CONFIG_HOME/mtg}"
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
-
31
-mkdir -p "$MTG_CONFIG" || true
32
-
33
-MTG_SECRET="$MTG_CONFIG/secret"
34
-MTG_ENV="$MTG_CONFIG/env"
35
-
36
-if [ ! -f "$MTG_ENV" ]; then
37
-    MTG_IMAGENAME="${MTG_IMAGENAME:-nineseconds/mtg:stable}"
38
-    MTG_PORT="${MTG_PORT:-3128}"
39
-    MTG_CONTAINER="${MTG_CONTAINER:-mtg}"
40
-
41
-    echo "MTG_IMAGENAME=$MTG_IMAGENAME" > "$MTG_ENV"
42
-    echo "MTG_PORT=$MTG_PORT" >> "$MTG_ENV"
43
-    echo "MTG_CONTAINER=$MTG_CONTAINER" >> "$MTG_ENV"
44
-fi
45
-
46
-set -a
47
-source "$MTG_ENV"
48
-set +a
49
-
50
-$DOCKER_CMD pull "$MTG_IMAGENAME" > /dev/null
51
-if [ ! -f "$MTG_SECRET" ]; then
52
-    $DOCKER_CMD run \
53
-            --rm \
54
-            "$MTG_IMAGENAME" \
55
-        generate-secret tls -c "$(openssl rand -hex 16).com" \
56
-    > "$MTG_SECRET"
57
-fi
58
-
59
-echo "Proxy secret is $(cat "$MTG_SECRET"). Port is $MTG_PORT."
60
-
61
-$DOCKER_CMD ps --filter "Name=$MTG_CONTAINER" -aq | xargs -r $DOCKER_CMD rm -fv > /dev/null
62
-$DOCKER_CMD run \
63
-        -d \
64
-        --restart=unless-stopped \
65
-        --name "$MTG_CONTAINER" \
66
-        --ulimit nofile=51200:51200 \
67
-        -p "$MTG_PORT:3128" \
68
-    "$MTG_IMAGENAME" run "$(cat "$MTG_SECRET")" > /dev/null

+ 0
- 60
stats/interfaces.go Wyświetl plik

@@ -1,60 +0,0 @@
1
-package stats
2
-
3
-import (
4
-	"net"
5
-
6
-	"github.com/9seconds/mtg/conntypes"
7
-)
8
-
9
-type IngressTrafficInterface interface {
10
-	IngressTraffic(int)
11
-}
12
-
13
-type EgressTrafficInterface interface {
14
-	EgressTraffic(int)
15
-}
16
-
17
-type ClientConnectedInterface interface {
18
-	ClientConnected(conntypes.ConnectionType, *net.TCPAddr)
19
-}
20
-
21
-type ClientDisconnectedInterface interface {
22
-	ClientDisconnected(conntypes.ConnectionType, *net.TCPAddr)
23
-}
24
-
25
-type TelegramConnectedInterface interface {
26
-	TelegramConnected(conntypes.DC, *net.TCPAddr)
27
-}
28
-
29
-type TelegramDisconnectedInterface interface {
30
-	TelegramDisconnected(conntypes.DC, *net.TCPAddr)
31
-}
32
-
33
-type CrashInterface interface {
34
-	Crash()
35
-}
36
-
37
-type ReplayDetectedInterface interface {
38
-	ReplayDetected()
39
-}
40
-
41
-type AuthenticationFailedInterface interface {
42
-	AuthenticationFailed()
43
-}
44
-
45
-type CloakedRequestInterface interface {
46
-	CloakedRequest()
47
-}
48
-
49
-type Interface interface {
50
-	IngressTrafficInterface
51
-	EgressTrafficInterface
52
-	ClientConnectedInterface
53
-	ClientDisconnectedInterface
54
-	TelegramConnectedInterface
55
-	TelegramDisconnectedInterface
56
-	CrashInterface
57
-	ReplayDetectedInterface
58
-	AuthenticationFailedInterface
59
-	CloakedRequestInterface
60
-}

+ 0
- 69
stats/multi_stats.go Wyświetl plik

@@ -1,69 +0,0 @@
1
-package stats
2
-
3
-import (
4
-	"net"
5
-
6
-	"github.com/9seconds/mtg/conntypes"
7
-)
8
-
9
-type multiStats []Interface
10
-
11
-func (m multiStats) IngressTraffic(traffic int) {
12
-	for i := range m {
13
-		go m[i].IngressTraffic(traffic)
14
-	}
15
-}
16
-
17
-func (m multiStats) EgressTraffic(traffic int) {
18
-	for i := range m {
19
-		go m[i].EgressTraffic(traffic)
20
-	}
21
-}
22
-
23
-func (m multiStats) ClientConnected(connectionType conntypes.ConnectionType, addr *net.TCPAddr) {
24
-	for i := range m {
25
-		go m[i].ClientConnected(connectionType, addr)
26
-	}
27
-}
28
-
29
-func (m multiStats) ClientDisconnected(connectionType conntypes.ConnectionType, addr *net.TCPAddr) {
30
-	for i := range m {
31
-		go m[i].ClientDisconnected(connectionType, addr)
32
-	}
33
-}
34
-
35
-func (m multiStats) TelegramConnected(dc conntypes.DC, addr *net.TCPAddr) {
36
-	for i := range m {
37
-		go m[i].TelegramConnected(dc, addr)
38
-	}
39
-}
40
-
41
-func (m multiStats) TelegramDisconnected(dc conntypes.DC, addr *net.TCPAddr) {
42
-	for i := range m {
43
-		go m[i].TelegramDisconnected(dc, addr)
44
-	}
45
-}
46
-
47
-func (m multiStats) Crash() {
48
-	for i := range m {
49
-		go m[i].Crash()
50
-	}
51
-}
52
-
53
-func (m multiStats) ReplayDetected() {
54
-	for i := range m {
55
-		go m[i].ReplayDetected()
56
-	}
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
-}

+ 0
- 41
stats/stats.go Wyświetl plik

@@ -1,41 +0,0 @@
1
-package stats
2
-
3
-import (
4
-	"context"
5
-	"fmt"
6
-	"net"
7
-	"net/http"
8
-
9
-	"github.com/9seconds/mtg/config"
10
-)
11
-
12
-var Stats Interface
13
-
14
-func Init(ctx context.Context) error {
15
-	mux := http.NewServeMux()
16
-
17
-	stats := []Interface{newStatsPrometheus(mux)}
18
-	if config.C.StatsdAddr != nil {
19
-		stats = append(stats, newStatsStatsd())
20
-	}
21
-
22
-	listener, err := net.Listen("tcp", config.C.StatsBind.String())
23
-	if err != nil {
24
-		return fmt.Errorf("cannot initialize stats server: %w", err)
25
-	}
26
-
27
-	srv := http.Server{
28
-		Handler: mux,
29
-	}
30
-
31
-	go srv.Serve(listener) // nolint: errcheck
32
-
33
-	go func() {
34
-		<-ctx.Done()
35
-		srv.Shutdown(context.Background()) // nolint: errcheck
36
-	}()
37
-
38
-	Stats = multiStats(stats)
39
-
40
-	return nil
41
-}

+ 0
- 156
stats/stats_prometheus.go Wyświetl plik

@@ -1,156 +0,0 @@
1
-package stats
2
-
3
-import (
4
-	"net"
5
-	"net/http"
6
-	"strconv"
7
-
8
-	"github.com/9seconds/mtg/config"
9
-	"github.com/9seconds/mtg/conntypes"
10
-	"github.com/prometheus/client_golang/prometheus"
11
-	"github.com/prometheus/client_golang/prometheus/promhttp"
12
-)
13
-
14
-type statsPrometheus struct {
15
-	connections          *prometheus.GaugeVec
16
-	telegramConnections  *prometheus.GaugeVec
17
-	traffic              *prometheus.GaugeVec
18
-	crashes              prometheus.Counter
19
-	replayAttacks        prometheus.Counter
20
-	authenticationFailed prometheus.Counter
21
-	cloakedRequests      prometheus.Counter
22
-}
23
-
24
-func (s *statsPrometheus) IngressTraffic(traffic int) {
25
-	s.traffic.WithLabelValues("ingress").Add(float64(traffic))
26
-}
27
-
28
-func (s *statsPrometheus) EgressTraffic(traffic int) {
29
-	s.traffic.WithLabelValues("egress").Add(float64(traffic))
30
-}
31
-
32
-func (s *statsPrometheus) ClientConnected(connectionType conntypes.ConnectionType, addr *net.TCPAddr) {
33
-	s.changeConnections(connectionType, addr, 1.0)
34
-}
35
-
36
-func (s *statsPrometheus) ClientDisconnected(connectionType conntypes.ConnectionType, addr *net.TCPAddr) {
37
-	s.changeConnections(connectionType, addr, -1.0)
38
-}
39
-
40
-func (s *statsPrometheus) changeConnections(connectionType conntypes.ConnectionType,
41
-	addr *net.TCPAddr,
42
-	increment float64) {
43
-	labels := [...]string{
44
-		"intermediate",
45
-		"ipv4",
46
-	}
47
-
48
-	switch connectionType {
49
-	case conntypes.ConnectionTypeAbridged:
50
-		labels[0] = "abridged"
51
-	case conntypes.ConnectionTypeSecure:
52
-		labels[0] = "secured"
53
-	case conntypes.ConnectionTypeIntermediate:
54
-		labels[0] = "intermediate"
55
-	case conntypes.ConnectionTypeUnknown:
56
-		panic("unknown connection type")
57
-	}
58
-
59
-	if addr.IP.To4() == nil {
60
-		labels[1] = "ipv6"
61
-	}
62
-
63
-	s.connections.WithLabelValues(labels[:]...).Add(increment)
64
-}
65
-
66
-func (s *statsPrometheus) TelegramConnected(dc conntypes.DC, addr *net.TCPAddr) {
67
-	s.changeTelegramConnections(dc, addr, 1.0)
68
-}
69
-
70
-func (s *statsPrometheus) TelegramDisconnected(dc conntypes.DC, addr *net.TCPAddr) {
71
-	s.changeTelegramConnections(dc, addr, -1.0)
72
-}
73
-
74
-func (s *statsPrometheus) changeTelegramConnections(dc conntypes.DC, addr *net.TCPAddr, increment float64) {
75
-	labels := [...]string{
76
-		strconv.Itoa(int(dc)),
77
-		"ipv4",
78
-	}
79
-
80
-	if addr.IP.To4() == nil {
81
-		labels[1] = "ipv6"
82
-	}
83
-
84
-	s.telegramConnections.WithLabelValues(labels[:]...).Add(increment)
85
-}
86
-
87
-func (s *statsPrometheus) Crash() {
88
-	s.crashes.Inc()
89
-}
90
-
91
-func (s *statsPrometheus) ReplayDetected() {
92
-	s.replayAttacks.Inc()
93
-}
94
-
95
-func (s *statsPrometheus) AuthenticationFailed() {
96
-	s.authenticationFailed.Inc()
97
-}
98
-
99
-func (s *statsPrometheus) CloakedRequest() {
100
-	s.cloakedRequests.Inc()
101
-}
102
-
103
-func newStatsPrometheus(mux *http.ServeMux) Interface {
104
-	registry := prometheus.NewPedanticRegistry()
105
-
106
-	instance := &statsPrometheus{
107
-		connections: prometheus.NewGaugeVec(prometheus.GaugeOpts{
108
-			Namespace: config.C.StatsNamespace,
109
-			Name:      "connections",
110
-			Help:      "Current number of client connections to the proxy.",
111
-		}, []string{"type", "protocol"}),
112
-		telegramConnections: prometheus.NewGaugeVec(prometheus.GaugeOpts{
113
-			Namespace: config.C.StatsNamespace,
114
-			Name:      "telegram_connections",
115
-			Help:      "Current number of telegram connections established by this proxy.",
116
-		}, []string{"dc", "protocol"}),
117
-		traffic: prometheus.NewGaugeVec(prometheus.GaugeOpts{
118
-			Namespace: config.C.StatsNamespace,
119
-			Name:      "traffic",
120
-			Help:      "Traffic passed through the proxy in bytes.",
121
-		}, []string{"direction"}),
122
-		crashes: prometheus.NewCounter(prometheus.CounterOpts{
123
-			Namespace: config.C.StatsNamespace,
124
-			Name:      "crashes",
125
-			Help:      "How many crashes happened.",
126
-		}),
127
-		replayAttacks: prometheus.NewCounter(prometheus.CounterOpts{
128
-			Namespace: config.C.StatsNamespace,
129
-			Name:      "replay_attacks",
130
-			Help:      "How many replay attacks were prevented.",
131
-		}),
132
-		authenticationFailed: prometheus.NewCounter(prometheus.CounterOpts{
133
-			Namespace: config.C.StatsNamespace,
134
-			Name:      "authentication_failed",
135
-			Help:      "How many authentication failed events we've seen.",
136
-		}),
137
-		cloakedRequests: prometheus.NewCounter(prometheus.CounterOpts{
138
-			Namespace: config.C.StatsNamespace,
139
-			Name:      "cloaked_requests",
140
-			Help:      "How many requests were proxified during cloaking.",
141
-		}),
142
-	}
143
-
144
-	registry.MustRegister(instance.connections)
145
-	registry.MustRegister(instance.telegramConnections)
146
-	registry.MustRegister(instance.traffic)
147
-	registry.MustRegister(instance.crashes)
148
-	registry.MustRegister(instance.replayAttacks)
149
-	registry.MustRegister(instance.authenticationFailed)
150
-	registry.MustRegister(instance.cloakedRequests)
151
-
152
-	handler := promhttp.HandlerFor(registry, promhttp.HandlerOpts{})
153
-	mux.Handle("/", handler)
154
-
155
-	return instance
156
-}

+ 0
- 204
stats/stats_statsd.go Wyświetl plik

@@ -1,204 +0,0 @@
1
-package stats
2
-
3
-import (
4
-	"fmt"
5
-	"net"
6
-	"strconv"
7
-	"strings"
8
-	"sync"
9
-	"time"
10
-
11
-	"github.com/9seconds/mtg/config"
12
-	"github.com/9seconds/mtg/conntypes"
13
-	statsd "github.com/smira/go-statsd"
14
-	"go.uber.org/zap"
15
-)
16
-
17
-var (
18
-	tagTrafficIngress = &statsStatsdTag{
19
-		name: "ingress",
20
-		tag:  statsd.StringTag("type", "ingress"),
21
-	}
22
-	tagTrafficEgress = &statsStatsdTag{
23
-		name: "egress",
24
-		tag:  statsd.StringTag("type", "egress"),
25
-	}
26
-
27
-	tagConnectionTypeAbridged = &statsStatsdTag{
28
-		name: "abridged",
29
-		tag:  statsd.StringTag("type", "abridged"),
30
-	}
31
-	tagConnectionTypeIntermediate = &statsStatsdTag{
32
-		name: "intermediate",
33
-		tag:  statsd.StringTag("type", "intermediate"),
34
-	}
35
-	tagConnectionTypeSecured = &statsStatsdTag{
36
-		name: "secured",
37
-		tag:  statsd.StringTag("type", "secured"),
38
-	}
39
-
40
-	tagConnectionProtocol4 = &statsStatsdTag{
41
-		name: "ipv4",
42
-		tag:  statsd.StringTag("protocol", "ipv4"),
43
-	}
44
-	tagConnectionProtocol6 = &statsStatsdTag{
45
-		name: "ipv6",
46
-		tag:  statsd.StringTag("protocol", "ipv6"),
47
-	}
48
-)
49
-
50
-type statsStatsdTag struct {
51
-	tag  statsd.Tag
52
-	name string
53
-}
54
-
55
-type statsStatsdLogger struct {
56
-	log *zap.SugaredLogger
57
-}
58
-
59
-func (s statsStatsdLogger) Printf(msg string, args ...interface{}) {
60
-	s.log.Debugw(fmt.Sprintf(msg, args...))
61
-}
62
-
63
-type statsStatsd struct {
64
-	seen      map[string]struct{}
65
-	seenMutex sync.RWMutex
66
-	client    *statsd.Client
67
-}
68
-
69
-func (s *statsStatsd) IngressTraffic(traffic int) {
70
-	s.gauge("traffic", int64(traffic), tagTrafficIngress)
71
-}
72
-
73
-func (s *statsStatsd) EgressTraffic(traffic int) {
74
-	s.gauge("traffic", int64(traffic), tagTrafficEgress)
75
-}
76
-
77
-func (s *statsStatsd) ClientConnected(connectionType conntypes.ConnectionType, addr *net.TCPAddr) {
78
-	s.changeConnections(connectionType, addr, 1)
79
-}
80
-
81
-func (s *statsStatsd) ClientDisconnected(connectionType conntypes.ConnectionType, addr *net.TCPAddr) {
82
-	s.changeConnections(connectionType, addr, -1)
83
-}
84
-
85
-func (s *statsStatsd) changeConnections(connectionType conntypes.ConnectionType, addr *net.TCPAddr, increment int64) {
86
-	tags := make([]*statsStatsdTag, 0, 2)
87
-
88
-	switch connectionType {
89
-	case conntypes.ConnectionTypeAbridged:
90
-		tags = append(tags, tagConnectionTypeAbridged)
91
-	case conntypes.ConnectionTypeIntermediate:
92
-		tags = append(tags, tagConnectionTypeIntermediate)
93
-	case conntypes.ConnectionTypeSecure:
94
-		tags = append(tags, tagConnectionTypeSecured)
95
-	case conntypes.ConnectionTypeUnknown:
96
-		panic("Unknown connection type")
97
-	}
98
-
99
-	if addr.IP.To4() == nil {
100
-		tags = append(tags, tagConnectionProtocol6)
101
-	} else {
102
-		tags = append(tags, tagConnectionProtocol4)
103
-	}
104
-
105
-	s.gauge("connections", increment, tags...)
106
-}
107
-
108
-func (s *statsStatsd) TelegramConnected(dc conntypes.DC, addr *net.TCPAddr) {
109
-	s.changeTelegramConnections(dc, addr, 1)
110
-}
111
-
112
-func (s *statsStatsd) TelegramDisconnected(dc conntypes.DC, addr *net.TCPAddr) {
113
-	s.changeTelegramConnections(dc, addr, -1)
114
-}
115
-
116
-func (s *statsStatsd) changeTelegramConnections(dc conntypes.DC, addr *net.TCPAddr, increment int64) {
117
-	tags := []*statsStatsdTag{
118
-		{
119
-			name: "dc" + strconv.Itoa(int(dc)),
120
-			tag:  statsd.IntTag("dc", int(dc)),
121
-		},
122
-	}
123
-
124
-	if addr.IP.To4() == nil {
125
-		tags = append(tags, tagConnectionProtocol6)
126
-	} else {
127
-		tags = append(tags, tagConnectionProtocol4)
128
-	}
129
-
130
-	s.gauge("telegram_connections", increment, tags...)
131
-}
132
-
133
-func (s *statsStatsd) Crash() {
134
-	s.gauge("crashes", 1)
135
-}
136
-
137
-func (s *statsStatsd) ReplayDetected() {
138
-	s.gauge("replay_attacks", 1)
139
-}
140
-
141
-func (s *statsStatsd) AuthenticationFailed() {
142
-	s.gauge("authentication_failed", 1)
143
-}
144
-
145
-func (s *statsStatsd) CloakedRequest() {
146
-	s.gauge("cloaked_requests", 1)
147
-}
148
-
149
-func (s *statsStatsd) gauge(metric string, value int64, tags ...*statsStatsdTag) {
150
-	key, tagList := s.prepareVals(metric, tags)
151
-	s.initGauge(metric, key, tagList)
152
-	s.client.GaugeDelta(metric, value, tagList...)
153
-}
154
-
155
-func (s *statsStatsd) prepareVals(metric string, tags []*statsStatsdTag) (string, []statsd.Tag) {
156
-	tagList := make([]statsd.Tag, len(tags))
157
-	builder := strings.Builder{}
158
-	builder.WriteString(metric)
159
-
160
-	for i, v := range tags {
161
-		builder.WriteRune('.')
162
-		builder.WriteString(v.name)
163
-		tagList[i] = v.tag
164
-	}
165
-
166
-	return builder.String(), tagList
167
-}
168
-
169
-func (s *statsStatsd) initGauge(metric, key string, tags []statsd.Tag) {
170
-	s.seenMutex.RLock()
171
-	if _, ok := s.seen[key]; ok {
172
-		s.seenMutex.RUnlock()
173
-
174
-		return
175
-	} else { // nolint: golint,revive
176
-		s.seenMutex.RUnlock()
177
-	}
178
-
179
-	s.seenMutex.Lock()
180
-	defer s.seenMutex.Unlock()
181
-
182
-	if _, ok := s.seen[key]; !ok {
183
-		s.seen[key] = struct{}{}
184
-		s.client.Gauge(metric, 0, tags...)
185
-	}
186
-}
187
-
188
-func newStatsStatsd() Interface {
189
-	prefix := strings.TrimSuffix(config.C.StatsNamespace, ".") + "."
190
-	logger := statsStatsdLogger{
191
-		log: zap.S().Named("stats").Named("statsd"),
192
-	}
193
-
194
-	return &statsStatsd{
195
-		seen: make(map[string]struct{}),
196
-		client: statsd.NewClient(config.C.StatsdAddr.String(),
197
-			statsd.SendLoopCount(2),
198
-			statsd.ReconnectInterval(10*time.Second),
199
-			statsd.Logger(logger),
200
-			statsd.MetricPrefix(prefix),
201
-			statsd.TagStyle(config.C.StatsdTagsFormat),
202
-		),
203
-	}
204
-}

+ 0
- 109
telegram/api/addresses.go Wyświetl plik

@@ -1,109 +0,0 @@
1
-package api
2
-
3
-import (
4
-	"bufio"
5
-	"fmt"
6
-	"net"
7
-	"regexp"
8
-	"strconv"
9
-	"strings"
10
-
11
-	"github.com/9seconds/mtg/conntypes"
12
-)
13
-
14
-const (
15
-	addressesURLV4 = "https://core.telegram.org/getProxyConfig"   // nolint: gas
16
-	addressesURLV6 = "https://core.telegram.org/getProxyConfigV6" // nolint: gas
17
-)
18
-
19
-var addressesProxyForSplitter = regexp.MustCompile(`\s+`)
20
-
21
-func AddressesV4() (map[conntypes.DC][]string, conntypes.DC, error) {
22
-	return getAddresses(addressesURLV4)
23
-}
24
-
25
-func AddressesV6() (map[conntypes.DC][]string, conntypes.DC, error) {
26
-	return getAddresses(addressesURLV6)
27
-}
28
-
29
-func getAddresses(url string) (map[conntypes.DC][]string, conntypes.DC, error) {
30
-	resp, err := request(url)
31
-	if err != nil {
32
-		return nil, 0, fmt.Errorf("cannot get http response: %w", err)
33
-	}
34
-
35
-	defer resp.Close()
36
-
37
-	scanner := bufio.NewScanner(resp)
38
-	data := map[conntypes.DC][]string{}
39
-	defaultDC := conntypes.DCDefaultIdx
40
-
41
-	for scanner.Scan() {
42
-		text := strings.TrimSpace(scanner.Text())
43
-
44
-		switch {
45
-		case strings.HasPrefix(text, "#"):
46
-			continue
47
-		case strings.HasPrefix(text, "proxy_for"):
48
-			addr, idx, err := addressesParseProxyFor(text)
49
-			if err != nil {
50
-				return nil, 0, fmt.Errorf("cannot parse 'proxy_for' section: %w", err)
51
-			}
52
-
53
-			if addresses, ok := data[idx]; ok {
54
-				data[idx] = append(addresses, addr)
55
-			} else {
56
-				data[idx] = []string{addr}
57
-			}
58
-		case strings.HasPrefix(text, "default"):
59
-			idx, err := addressesParseDefault(text)
60
-			if err != nil {
61
-				return nil, 0, fmt.Errorf("cannot parse 'default' section: %w", err)
62
-			}
63
-
64
-			defaultDC = idx
65
-		}
66
-	}
67
-
68
-	err = scanner.Err()
69
-	if err != nil {
70
-		return nil, 0, fmt.Errorf("cannot parse http response: %w", err)
71
-	}
72
-
73
-	return data, defaultDC, nil
74
-}
75
-
76
-func addressesParseProxyFor(text string) (string, conntypes.DC, error) {
77
-	chunks := addressesProxyForSplitter.Split(text, 3)
78
-	if len(chunks) != 3 || chunks[0] != "proxy_for" {
79
-		return "", 0, fmt.Errorf("incorrect config %s", text)
80
-	}
81
-
82
-	dc, err := strconv.ParseInt(chunks[1], 10, 16)
83
-	if err != nil {
84
-		return "", 0, fmt.Errorf("incorrect config '%s': %w", text, err)
85
-	}
86
-
87
-	addr := strings.TrimRight(chunks[2], ";")
88
-	if _, _, err = net.SplitHostPort(addr); err != nil {
89
-		return "", 0, fmt.Errorf("incorrect config '%s': %w", text, err)
90
-	}
91
-
92
-	return addr, conntypes.DC(dc), nil
93
-}
94
-
95
-func addressesParseDefault(text string) (conntypes.DC, error) {
96
-	chunks := addressesProxyForSplitter.Split(text, 2)
97
-	if len(chunks) != 2 || chunks[0] != "default" {
98
-		return 0, fmt.Errorf("incorrect config '%s'", text)
99
-	}
100
-
101
-	dcString := strings.TrimRight(chunks[1], ";")
102
-
103
-	dc, err := strconv.ParseInt(dcString, 10, 16)
104
-	if err != nil {
105
-		return 0, fmt.Errorf("incorrect config '%s': %w", text, err)
106
-	}
107
-
108
-	return conntypes.DC(dc), nil
109
-}

+ 0
- 44
telegram/api/api.go Wyświetl plik

@@ -1,44 +0,0 @@
1
-package api
2
-
3
-import (
4
-	"context"
5
-	"fmt"
6
-	"io"
7
-	"io/ioutil"
8
-	"net/http"
9
-	"time"
10
-)
11
-
12
-const (
13
-	apiUserAgent   = "github.com/9seconds/mtg"
14
-	apiHTTPTimeout = 30 * time.Second
15
-)
16
-
17
-var httpClient = http.Client{
18
-	Timeout: apiHTTPTimeout,
19
-}
20
-
21
-func request(url string) (io.ReadCloser, error) {
22
-	ctx, cancel := context.WithTimeout(context.Background(), apiHTTPTimeout)
23
-	defer cancel()
24
-
25
-	req, err := http.NewRequestWithContext(ctx, "GET", url, nil)
26
-	if err != nil {
27
-		panic(err)
28
-	}
29
-
30
-	req.Header.Set("Accept", "text/plan")
31
-	req.Header.Set("User-Agent", apiUserAgent)
32
-
33
-	resp, err := httpClient.Do(req)
34
-	if err != nil {
35
-		if resp != nil {
36
-			io.Copy(ioutil.Discard, resp.Body) // nolint: errcheck
37
-			resp.Body.Close()
38
-		}
39
-
40
-		return nil, fmt.Errorf("cannot perform a request: %w", err)
41
-	}
42
-
43
-	return resp.Body, err // nolint: wrapcheck
44
-}

+ 0
- 24
telegram/api/secret.go Wyświetl plik

@@ -1,24 +0,0 @@
1
-package api
2
-
3
-import (
4
-	"fmt"
5
-	"io/ioutil"
6
-)
7
-
8
-const secretURL = "https://core.telegram.org/getProxySecret" // nolint: gas
9
-
10
-func Secret() ([]byte, error) {
11
-	resp, err := request(secretURL)
12
-	if err != nil {
13
-		return nil, fmt.Errorf("cannot access telegram server: %w", err)
14
-	}
15
-
16
-	defer resp.Close()
17
-
18
-	secret, err := ioutil.ReadAll(resp)
19
-	if err != nil {
20
-		return nil, fmt.Errorf("cannot read response: %w", err)
21
-	}
22
-
23
-	return secret, nil
24
-}

+ 0
- 91
telegram/base.go Wyświetl plik

@@ -1,91 +0,0 @@
1
-package telegram
2
-
3
-import (
4
-	"errors"
5
-	"math/rand"
6
-	"net"
7
-
8
-	"github.com/9seconds/mtg/config"
9
-	"github.com/9seconds/mtg/conntypes"
10
-	"github.com/9seconds/mtg/utils"
11
-	"github.com/9seconds/mtg/wrappers/stream"
12
-	"go.uber.org/zap"
13
-)
14
-
15
-type baseTelegram struct {
16
-	dialer net.Dialer
17
-	logger *zap.SugaredLogger
18
-
19
-	secret      []byte
20
-	v4DefaultDC conntypes.DC
21
-	v6DefaultDC conntypes.DC
22
-	v4Addresses map[conntypes.DC][]string
23
-	v6Addresses map[conntypes.DC][]string
24
-}
25
-
26
-func (b *baseTelegram) Secret() []byte {
27
-	return b.secret
28
-}
29
-
30
-func (b *baseTelegram) dial(dc conntypes.DC,
31
-	protocol conntypes.ConnectionProtocol) (conntypes.StreamReadWriteCloser, error) {
32
-	for _, addr := range b.getAddresses(dc, protocol) {
33
-		conn, err := b.dialer.Dial("tcp", addr)
34
-		if err != nil {
35
-			b.logger.Infow("Cannot dial to Telegram", "address", addr, "error", err)
36
-
37
-			continue
38
-		}
39
-
40
-		if err := utils.InitTCP(conn, config.C.ProxyReadBuffer(), config.C.ProxyWriteBuffer()); err != nil {
41
-			b.logger.Infow("Cannot initialize TCP socket", "address", addr, "error", err)
42
-
43
-			continue
44
-		}
45
-
46
-		return stream.NewTelegramConn(dc, conn), nil
47
-	}
48
-
49
-	return nil, errors.New("cannot dial to the chosen DC")
50
-}
51
-
52
-func (b *baseTelegram) getAddresses(dc conntypes.DC, protocol conntypes.ConnectionProtocol) []string {
53
-	addresses := make([]string, 0, 2)
54
-	protos := []conntypes.ConnectionProtocol{
55
-		conntypes.ConnectionProtocolIPv6,
56
-		conntypes.ConnectionProtocolIPv4,
57
-	}
58
-
59
-	if config.C.PreferIP == config.PreferIPv4 {
60
-		protos[0], protos[1] = protos[1], protos[0]
61
-	}
62
-
63
-	for _, proto := range protos {
64
-		switch {
65
-		case proto&protocol == 0:
66
-		case proto&conntypes.ConnectionProtocolIPv6 != 0:
67
-			addresses = append(addresses, b.chooseAddress(b.v6Addresses, dc, b.v6DefaultDC))
68
-		case proto&conntypes.ConnectionProtocolIPv4 != 0:
69
-			addresses = append(addresses, b.chooseAddress(b.v4Addresses, dc, b.v4DefaultDC))
70
-		}
71
-	}
72
-
73
-	return addresses
74
-}
75
-
76
-func (b *baseTelegram) chooseAddress(addresses map[conntypes.DC][]string,
77
-	dc, defaultDC conntypes.DC) string {
78
-	addrs, ok := addresses[dc]
79
-	if !ok {
80
-		addrs = addresses[defaultDC]
81
-	}
82
-
83
-	switch {
84
-	case len(addrs) == 1:
85
-		return addrs[0]
86
-	case len(addrs) > 1:
87
-		return addrs[rand.Intn(len(addrs))] // nolint: gosec
88
-	}
89
-
90
-	return ""
91
-}

+ 0
- 41
telegram/direct.go Wyświetl plik

@@ -1,41 +0,0 @@
1
-package telegram
2
-
3
-import "github.com/9seconds/mtg/conntypes"
4
-
5
-const (
6
-	directV4DefaultIdx conntypes.DC = 1
7
-	directV6DefaultIdx conntypes.DC = 1
8
-)
9
-
10
-var (
11
-	directV4Addresses = map[conntypes.DC][]string{
12
-		0: {"149.154.175.50:443"},
13
-		1: {"149.154.167.51:443"},
14
-		2: {"149.154.175.100:443"},
15
-		3: {"149.154.167.91:443"},
16
-		4: {"149.154.171.5:443"},
17
-	}
18
-	directV6Addresses = map[conntypes.DC][]string{
19
-		0: {"[2001:b28:f23d:f001::a]:443"},
20
-		1: {"[2001:67c:04e8:f002::a]:443"},
21
-		2: {"[2001:b28:f23d:f003::a]:443"},
22
-		3: {"[2001:67c:04e8:f004::a]:443"},
23
-		4: {"[2001:b28:f23f:f005::a]:443"},
24
-	}
25
-)
26
-
27
-type directTelegram struct {
28
-	baseTelegram
29
-}
30
-
31
-func (d *directTelegram) Dial(dc conntypes.DC,
32
-	protocol conntypes.ConnectionProtocol) (conntypes.StreamReadWriteCloser, error) {
33
-	switch {
34
-	case dc < 0:
35
-		dc = -dc
36
-	case dc == 0:
37
-		dc = conntypes.DCDefaultIdx
38
-	}
39
-
40
-	return d.baseTelegram.dial(dc-1, conntypes.ConnectionProtocolAny)
41
-}

+ 0
- 48
telegram/init.go Wyświetl plik

@@ -1,48 +0,0 @@
1
-package telegram
2
-
3
-import (
4
-	"net"
5
-	"sync"
6
-	"time"
7
-
8
-	"go.uber.org/zap"
9
-)
10
-
11
-const telegramDialTimeout = 10 * time.Second
12
-
13
-var (
14
-	Direct Telegram
15
-	Middle Telegram
16
-
17
-	initOnce sync.Once
18
-)
19
-
20
-func Init() {
21
-	initOnce.Do(func() {
22
-		logger := zap.S().Named("telegram")
23
-
24
-		Direct = &directTelegram{
25
-			baseTelegram: baseTelegram{
26
-				dialer:      net.Dialer{Timeout: telegramDialTimeout},
27
-				logger:      logger.Named("direct"),
28
-				v4DefaultDC: directV4DefaultIdx,
29
-				v6DefaultDC: directV6DefaultIdx,
30
-				v4Addresses: directV4Addresses,
31
-				v6Addresses: directV6Addresses,
32
-			},
33
-		}
34
-
35
-		tg := &middleTelegram{
36
-			baseTelegram: baseTelegram{
37
-				dialer: net.Dialer{Timeout: telegramDialTimeout},
38
-				logger: logger.Named("middle"),
39
-			},
40
-		}
41
-		if err := tg.update(); err != nil {
42
-			panic(err)
43
-		}
44
-		go tg.backgroundUpdate()
45
-
46
-		Middle = tg
47
-	})
48
-}

+ 0
- 8
telegram/interfaces.go Wyświetl plik

@@ -1,8 +0,0 @@
1
-package telegram
2
-
3
-import "github.com/9seconds/mtg/conntypes"
4
-
5
-type Telegram interface {
6
-	Dial(conntypes.DC, conntypes.ConnectionProtocol) (conntypes.StreamReadWriteCloser, error)
7
-	Secret() []byte
8
-}

+ 0
- 75
telegram/middle.go Wyświetl plik

@@ -1,75 +0,0 @@
1
-package telegram
2
-
3
-import (
4
-	"fmt"
5
-	"sync"
6
-	"time"
7
-
8
-	"github.com/9seconds/mtg/conntypes"
9
-	"github.com/9seconds/mtg/telegram/api"
10
-	"go.uber.org/zap"
11
-)
12
-
13
-const middleTelegramBackgroundUpdateEvery = time.Hour
14
-
15
-type middleTelegram struct {
16
-	baseTelegram
17
-
18
-	mutex sync.RWMutex
19
-}
20
-
21
-func (m *middleTelegram) Secret() []byte {
22
-	m.mutex.RLock()
23
-	defer m.mutex.RUnlock()
24
-
25
-	return m.baseTelegram.Secret()
26
-}
27
-
28
-func (m *middleTelegram) update() error {
29
-	secret, err := api.Secret()
30
-	if err != nil {
31
-		return fmt.Errorf("cannot fetch secret: %w", err)
32
-	}
33
-
34
-	v4Addresses, v4DefaultDC, err := api.AddressesV4()
35
-	if err != nil {
36
-		return fmt.Errorf("cannot fetch addresses for ipv4: %w", err)
37
-	}
38
-
39
-	v6Addresses, v6DefaultDC, err := api.AddressesV6()
40
-	if err != nil {
41
-		return fmt.Errorf("cannot fetch addresses for ipv6: %w", err)
42
-	}
43
-
44
-	m.mutex.Lock()
45
-	m.secret = secret
46
-	m.v4DefaultDC = v4DefaultDC
47
-	m.v6DefaultDC = v6DefaultDC
48
-	m.v4Addresses = v4Addresses
49
-	m.v6Addresses = v6Addresses
50
-	m.mutex.Unlock()
51
-
52
-	return nil
53
-}
54
-
55
-func (m *middleTelegram) backgroundUpdate() {
56
-	logger := zap.S().Named("telegram")
57
-
58
-	for range time.Tick(middleTelegramBackgroundUpdateEvery) {
59
-		if err := m.update(); err != nil {
60
-			logger.Warnw("Cannot update Telegram proxies", "error", err)
61
-		}
62
-	}
63
-}
64
-
65
-func (m *middleTelegram) Dial(dc conntypes.DC,
66
-	protocol conntypes.ConnectionProtocol) (conntypes.StreamReadWriteCloser, error) {
67
-	if dc == 0 {
68
-		dc = conntypes.DCDefaultIdx
69
-	}
70
-
71
-	m.mutex.RLock()
72
-	defer m.mutex.RUnlock()
73
-
74
-	return m.baseTelegram.dial(dc, protocol)
75
-}

+ 0
- 86
tlstypes/client_hello.go Wyświetl plik

@@ -1,86 +0,0 @@
1
-package tlstypes
2
-
3
-import (
4
-	"bytes"
5
-	"crypto/hmac"
6
-	"crypto/sha256"
7
-	"fmt"
8
-
9
-	"github.com/9seconds/mtg/config"
10
-	"github.com/9seconds/mtg/utils"
11
-)
12
-
13
-type ClientHello struct {
14
-	Handshake
15
-}
16
-
17
-func (c ClientHello) Digest() []byte {
18
-	dirtyDigest := c.Random
19
-	c.Random = [32]byte{}
20
-
21
-	rec := Record{
22
-		Type:    RecordTypeHandshake,
23
-		Version: Version10,
24
-		Data:    &c,
25
-	}
26
-
27
-	mac := hmac.New(sha256.New, config.C.Secret)
28
-	rec.WriteBytes(mac)
29
-	computedDigest := mac.Sum(nil)
30
-
31
-	for i := range computedDigest {
32
-		computedDigest[i] ^= dirtyDigest[i]
33
-	}
34
-
35
-	return computedDigest
36
-}
37
-
38
-func ParseClientHello(raw []byte) (*ClientHello, error) {
39
-	rv := &ClientHello{}
40
-
41
-	rv.Type = HandshakeType(raw[0])
42
-	if rv.Type != HandshakeTypeClient {
43
-		return nil, fmt.Errorf("incorrect handshake type %v", rv.Type)
44
-	}
45
-
46
-	raw = raw[1:]
47
-	sizeUint24 := utils.Uint24{}
48
-	copy(sizeUint24[:], utils.ReverseBytes(raw[:3]))
49
-	size := int(utils.FromUint24(sizeUint24))
50
-
51
-	raw = raw[3:]
52
-	if len(raw) != size {
53
-		return nil, fmt.Errorf("payload size mismatch (%d != %d)", len(raw), size)
54
-	}
55
-
56
-	versionRaw := raw[:2]
57
-
58
-	switch {
59
-	case bytes.Equal(versionRaw, Version13Bytes):
60
-		rv.Version = Version13
61
-	case bytes.Equal(versionRaw, Version12Bytes):
62
-		rv.Version = Version12
63
-	case bytes.Equal(versionRaw, Version11Bytes):
64
-		rv.Version = Version11
65
-	case bytes.Equal(versionRaw, Version10Bytes):
66
-		rv.Version = Version10
67
-	default:
68
-		return nil, fmt.Errorf("unknown protocol version %v", versionRaw)
69
-	}
70
-
71
-	raw = raw[2:]
72
-	copy(rv.Random[:], raw[:32])
73
-	raw = raw[32:]
74
-
75
-	sessionIDLength := int(raw[0])
76
-	raw = raw[1:]
77
-	rv.SessionID = make([]byte, sessionIDLength)
78
-	copy(rv.SessionID, raw)
79
-	raw = raw[sessionIDLength:]
80
-
81
-	tail := make([]byte, len(raw))
82
-	copy(tail, raw)
83
-	rv.Tail = RawBytes(tail)
84
-
85
-	return rv, nil
86
-}

+ 0
- 90
tlstypes/consts.go Wyświetl plik

@@ -1,90 +0,0 @@
1
-package tlstypes
2
-
3
-import "io"
4
-
5
-type RecordType uint8
6
-
7
-const (
8
-	RecordTypeHandshake        RecordType = 0x16
9
-	RecordTypeApplicationData  RecordType = 0x17
10
-	RecordTypeChangeCipherSpec RecordType = 0x14
11
-)
12
-
13
-type HandshakeType uint8
14
-
15
-const (
16
-	HandshakeTypeClient HandshakeType = 0x01
17
-	HandshakeTypeServer HandshakeType = 0x02
18
-)
19
-
20
-type CipherSuiteType uint8
21
-
22
-const (
23
-	CipherSuiteType_TLS_AES_128_GCM_SHA256       CipherSuiteType = iota // nolint: stylecheck,golint,revive
24
-	CipherSuiteType_TLS_AES_256_GCM_SHA384                              // nolint: stylecheck,golint,revive
25
-	CipherSuiteType_TLS_CHACHA20_POLY1305_SHA256                        // nolint: stylecheck,golint,revive
26
-)
27
-
28
-func (c CipherSuiteType) Bytes() []byte {
29
-	switch c {
30
-	case CipherSuiteType_TLS_AES_128_GCM_SHA256:
31
-		return CipherSuiteType_TLS_AES_128_GCM_SHA256_Bytes
32
-	case CipherSuiteType_TLS_AES_256_GCM_SHA384:
33
-		return CipherSuiteType_TLS_AES_256_GCM_SHA384_Bytes
34
-	case CipherSuiteType_TLS_CHACHA20_POLY1305_SHA256:
35
-		return CipherSuiteType_TLS_CHACHA20_POLY1305_SHA256_Bytes
36
-	}
37
-
38
-	return CipherSuiteType_TLS_CHACHA20_POLY1305_SHA256_Bytes
39
-}
40
-
41
-type Version uint8
42
-
43
-func (v Version) Bytes() []byte {
44
-	switch v {
45
-	case Version13:
46
-		return Version13Bytes
47
-	case Version12:
48
-		return Version12Bytes
49
-	case Version11:
50
-		return Version11Bytes
51
-	case Version10, VersionUnknown:
52
-		return Version10Bytes
53
-	}
54
-
55
-	return Version10Bytes
56
-}
57
-
58
-const (
59
-	VersionUnknown Version = iota
60
-	Version10
61
-	Version11
62
-	Version12
63
-	Version13
64
-)
65
-
66
-var (
67
-	Version10Bytes = []byte{0x03, 0x01}
68
-	Version11Bytes = []byte{0x03, 0x02}
69
-	Version12Bytes = []byte{0x03, 0x03}
70
-	Version13Bytes = []byte{0x03, 0x04}
71
-
72
-	CipherSuiteType_TLS_AES_128_GCM_SHA256_Bytes       = []byte{0x13, 0x01} // nolint: stylecheck,golint,revive
73
-	CipherSuiteType_TLS_AES_256_GCM_SHA384_Bytes       = []byte{0x13, 0x02} // nolint: stylecheck,golint,revive
74
-	CipherSuiteType_TLS_CHACHA20_POLY1305_SHA256_Bytes = []byte{0x13, 0x03} // nolint: stylecheck,golint,revive
75
-)
76
-
77
-type Byter interface {
78
-	WriteBytes(io.Writer)
79
-	Len() int
80
-}
81
-
82
-type RawBytes []byte
83
-
84
-func (r RawBytes) WriteBytes(writer io.Writer) {
85
-	writer.Write(r) // nolint: errcheck
86
-}
87
-
88
-func (r RawBytes) Len() int {
89
-	return len(r)
90
-}

+ 0
- 43
tlstypes/handshake.go Wyświetl plik

@@ -1,43 +0,0 @@
1
-package tlstypes
2
-
3
-import (
4
-	"bytes"
5
-	"io"
6
-
7
-	"github.com/9seconds/mtg/utils"
8
-)
9
-
10
-type Handshake struct {
11
-	Type      HandshakeType
12
-	Version   Version
13
-	Random    [32]byte
14
-	SessionID []byte
15
-	Tail      Byter
16
-}
17
-
18
-func (h *Handshake) WriteBytes(writer io.Writer) {
19
-	packetBuf := bytes.Buffer{}
20
-
21
-	writer.Write([]byte{byte(h.Type)}) // nolint: errcheck
22
-
23
-	packetBuf.Write(h.Version.Bytes())
24
-	packetBuf.Write(h.Random[:])
25
-	packetBuf.WriteByte(byte(len(h.SessionID)))
26
-	packetBuf.Write(h.SessionID)
27
-	h.Tail.WriteBytes(&packetBuf)
28
-
29
-	sizeUint24 := utils.ToUint24(uint32(packetBuf.Len()))
30
-	sizeUint24Bytes := sizeUint24[:]
31
-	sizeUint24Bytes[0], sizeUint24Bytes[2] = sizeUint24Bytes[2], sizeUint24Bytes[0]
32
-
33
-	writer.Write(sizeUint24Bytes) // nolint: errcheck
34
-	packetBuf.WriteTo(writer)     // nolint: errcheck
35
-}
36
-
37
-func (h *Handshake) Len() int {
38
-	buf := bytes.Buffer{}
39
-
40
-	h.WriteBytes(&buf)
41
-
42
-	return buf.Len()
43
-}

+ 0
- 84
tlstypes/record.go Wyświetl plik

@@ -1,84 +0,0 @@
1
-package tlstypes
2
-
3
-import (
4
-	"bytes"
5
-	"encoding/binary"
6
-	"fmt"
7
-	"io"
8
-)
9
-
10
-const recordMaxChunkSize = 16384 + 24
11
-
12
-type Record struct {
13
-	Type    RecordType
14
-	Version Version
15
-	Data    Byter
16
-}
17
-
18
-func (r Record) WriteBytes(writer io.Writer) {
19
-	writer.Write([]byte{byte(r.Type)})                           // nolint: errcheck
20
-	writer.Write(r.Version.Bytes())                              // nolint: errcheck
21
-	binary.Write(writer, binary.BigEndian, uint16(r.Data.Len())) // nolint: errcheck
22
-	r.Data.WriteBytes(writer)
23
-}
24
-
25
-func (r Record) Len() int {
26
-	return 1 + 2 + 2 + r.Data.Len()
27
-}
28
-
29
-func ReadRecord(reader io.Reader) (Record, error) {
30
-	buf := [2]byte{}
31
-	rec := Record{}
32
-
33
-	if _, err := io.ReadFull(reader, buf[:1]); err != nil {
34
-		return rec, fmt.Errorf("cannot read record type: %w", err)
35
-	}
36
-
37
-	rec.Type = RecordType(buf[0])
38
-
39
-	if _, err := io.ReadFull(reader, buf[:]); err != nil {
40
-		return rec, fmt.Errorf("cannot read version: %w", err)
41
-	}
42
-
43
-	switch {
44
-	case bytes.Equal(buf[:], Version13Bytes):
45
-		rec.Version = Version13
46
-	case bytes.Equal(buf[:], Version12Bytes):
47
-		rec.Version = Version12
48
-	case bytes.Equal(buf[:], Version11Bytes):
49
-		rec.Version = Version11
50
-	case bytes.Equal(buf[:], Version10Bytes):
51
-		rec.Version = Version10
52
-	}
53
-
54
-	if _, err := io.ReadFull(reader, buf[:]); err != nil {
55
-		return rec, fmt.Errorf("cannot read data length: %w", err)
56
-	}
57
-
58
-	data := make([]byte, binary.BigEndian.Uint16(buf[:]))
59
-	if _, err := io.ReadFull(reader, data); err != nil {
60
-		return rec, fmt.Errorf("cannot read data: %w", err)
61
-	}
62
-
63
-	rec.Data = RawBytes(data)
64
-
65
-	return rec, nil
66
-}
67
-
68
-func MakeRecords(raw []byte) (arr []Record) {
69
-	for len(raw) > 0 {
70
-		chunkSize := recordMaxChunkSize
71
-		if chunkSize > len(raw) {
72
-			chunkSize = len(raw)
73
-		}
74
-
75
-		arr = append(arr, Record{
76
-			Type:    RecordTypeApplicationData,
77
-			Version: Version12,
78
-			Data:    RawBytes(raw[:chunkSize]),
79
-		})
80
-		raw = raw[chunkSize:]
81
-	}
82
-
83
-	return
84
-}

+ 0
- 97
tlstypes/server_hello.go Wyświetl plik

@@ -1,97 +0,0 @@
1
-package tlstypes
2
-
3
-import (
4
-	"bytes"
5
-	"crypto/hmac"
6
-	"crypto/rand"
7
-	"crypto/sha256"
8
-	"io"
9
-	mrand "math/rand"
10
-
11
-	"github.com/9seconds/mtg/config"
12
-	"golang.org/x/crypto/curve25519"
13
-)
14
-
15
-type ServerHello struct {
16
-	Handshake
17
-
18
-	clientHello *ClientHello
19
-}
20
-
21
-func (s ServerHello) WelcomePacket() []byte {
22
-	buf := &bytes.Buffer{}
23
-
24
-	s.Random = [32]byte{}
25
-	rec := Record{
26
-		Type:    RecordTypeHandshake,
27
-		Version: Version12,
28
-		Data:    &s,
29
-	}
30
-	rec.WriteBytes(buf)
31
-
32
-	recChangeCipher := Record{
33
-		Type:    RecordTypeChangeCipherSpec,
34
-		Version: Version12,
35
-		Data:    RawBytes([]byte{0x01}),
36
-	}
37
-	recChangeCipher.WriteBytes(buf)
38
-
39
-	hostCert := make([]byte, 1024+mrand.Intn(3092)) // nolint: gosec
40
-	rand.Read(hostCert)                             // nolint: errcheck
41
-
42
-	recData := Record{
43
-		Type:    RecordTypeApplicationData,
44
-		Version: Version12,
45
-		Data:    RawBytes(hostCert),
46
-	}
47
-	recData.WriteBytes(buf)
48
-
49
-	packet := buf.Bytes()
50
-
51
-	mac := hmac.New(sha256.New, config.C.Secret)
52
-	mac.Write(s.clientHello.Random[:]) // nolint: errcheck
53
-	mac.Write(packet)                  // nolint: errcheck
54
-	copy(packet[11:], mac.Sum(nil))
55
-
56
-	return packet
57
-}
58
-
59
-func NewServerHello(clientHello *ClientHello) *ServerHello {
60
-	rv := &ServerHello{
61
-		clientHello: clientHello,
62
-	}
63
-
64
-	rv.Type = HandshakeTypeServer
65
-	rv.Version = Version12
66
-	rv.SessionID = make([]byte, len(clientHello.SessionID))
67
-	copy(rv.SessionID, clientHello.SessionID)
68
-
69
-	tail := bytes.NewBuffer(CipherSuiteType_TLS_AES_128_GCM_SHA256_Bytes)
70
-	tail.WriteByte(0x00) // no compression
71
-	makeTLSExtensions(tail)
72
-	rv.Tail = RawBytes(tail.Bytes())
73
-
74
-	return rv
75
-}
76
-
77
-func makeTLSExtensions(buf io.Writer) {
78
-	buf.Write([]byte{ // nolint: errcheck
79
-		0x00, 0x2e, // 46 bytes of data
80
-		0x00, 0x33, // Extension - Key Share
81
-		0x00, 0x24, // 36 bytes
82
-		0x00, 0x1d, // x25519 curve
83
-		0x00, 0x20, // 32 bytes of key
84
-	})
85
-
86
-	var scalar [32]byte
87
-
88
-	rand.Read(scalar[:]) // nolint: errcheck
89
-	curve, _ := curve25519.X25519(scalar[:], curve25519.Basepoint)
90
-	buf.Write(curve) // nolint: errcheck
91
-
92
-	buf.Write([]byte{ // nolint: errcheck
93
-		0x00, 0x2b, // Extension - Supported Versions
94
-		0x00, 0x02, // 2 bytes are following
95
-		0x03, 0x04, // TLS 1.3
96
-	})
97
-}

+ 0
- 28
utils/init_tcp.go Wyświetl plik

@@ -1,28 +0,0 @@
1
-package utils
2
-
3
-import (
4
-	"fmt"
5
-	"net"
6
-)
7
-
8
-func InitTCP(conn net.Conn, readBufferSize int, writeBufferSize int) error {
9
-	tcpConn := conn.(*net.TCPConn)
10
-
11
-	if err := tcpConn.SetNoDelay(true); err != nil {
12
-		return fmt.Errorf("cannot set TCP_NO_DELAY: %w", err)
13
-	}
14
-
15
-	if err := tcpConn.SetReadBuffer(readBufferSize); err != nil {
16
-		return fmt.Errorf("cannot set read buffer size: %w", err)
17
-	}
18
-
19
-	if err := tcpConn.SetWriteBuffer(writeBufferSize); err != nil {
20
-		return fmt.Errorf("cannot set write buffer size: %w", err)
21
-	}
22
-
23
-	if err := tcpConn.SetKeepAlive(true); err != nil {
24
-		return fmt.Errorf("cannot enable keep-alive: %w", err)
25
-	}
26
-
27
-	return nil
28
-}

+ 0
- 21
utils/read_full.go Wyświetl plik

@@ -1,21 +0,0 @@
1
-package utils
2
-
3
-import "io"
4
-
5
-const readFullBufferSize = 1024 + 1 // +1 because telegram opreates with blocks mod 4
6
-
7
-func ReadFull(src io.Reader) (rv []byte, err error) {
8
-	buf := make([]byte, readFullBufferSize)
9
-	n := readFullBufferSize
10
-
11
-	for n == len(buf) {
12
-		n, err = src.Read(buf)
13
-		if err != nil {
14
-			return nil, err // nolint: wrapcheck
15
-		}
16
-
17
-		rv = append(rv, buf[:n]...)
18
-	}
19
-
20
-	return rv, nil
21
-}

+ 0
- 15
utils/reverse_bytes.go Wyświetl plik

@@ -1,15 +0,0 @@
1
-package utils
2
-
3
-// ReverseBytes is a common slice reverser.
4
-func ReverseBytes(data []byte) []byte {
5
-	dataLen := len(data)
6
-	rv := make([]byte, dataLen)
7
-	rv[dataLen/2] = data[dataLen/2]
8
-
9
-	for i := dataLen/2 - 1; i >= 0; i-- {
10
-		opp := dataLen - i - 1
11
-		rv[i], rv[opp] = data[opp], data[i]
12
-	}
13
-
14
-	return rv
15
-}

+ 0
- 24
utils/rlimit.go Wyświetl plik

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

+ 0
- 7
utils/rlimit_windows.go Wyświetl plik

@@ -1,7 +0,0 @@
1
-// +build windows
2
-
3
-package utils
4
-
5
-func SetLimits() error {
6
-	return nil
7
-}

+ 0
- 25
utils/signal_context.go Wyświetl plik

@@ -1,25 +0,0 @@
1
-// +build !windows
2
-
3
-package utils
4
-
5
-import (
6
-	"context"
7
-	"os"
8
-	"os/signal"
9
-	"syscall"
10
-)
11
-
12
-func GetSignalContext() context.Context {
13
-	ctx, cancel := context.WithCancel(context.Background())
14
-	sigChan := make(chan os.Signal, 1)
15
-
16
-	signal.Notify(sigChan, syscall.SIGINT, syscall.SIGTERM)
17
-
18
-	go func() {
19
-		for range sigChan {
20
-			cancel()
21
-		}
22
-	}()
23
-
24
-	return ctx
25
-}

+ 0
- 23
utils/signal_context_windows.go Wyświetl plik

@@ -1,23 +0,0 @@
1
-// +build windows
2
-
3
-package utils
4
-
5
-import (
6
-	"context"
7
-	"os"
8
-	"os/signal"
9
-)
10
-
11
-func GetSignalContext() context.Context {
12
-	ctx, cancel := context.WithCancel(context.Background())
13
-	sigChan := make(chan os.Signal, 1)
14
-
15
-	signal.Notify(sigChan, os.Interrupt)
16
-	go func() {
17
-		for range sigChan {
18
-			cancel()
19
-		}
20
-	}()
21
-
22
-	return ctx
23
-}

+ 0
- 12
utils/stream_cipher.go Wyświetl plik

@@ -1,12 +0,0 @@
1
-package utils
2
-
3
-import (
4
-	"crypto/aes"
5
-	"crypto/cipher"
6
-)
7
-
8
-func MakeStreamCipher(key, iv []byte) cipher.Stream {
9
-	block, _ := aes.NewCipher(key)
10
-
11
-	return cipher.NewCTR(block, iv)
12
-}

+ 0
- 11
utils/uint24.go Wyświetl plik

@@ -1,11 +0,0 @@
1
-package utils
2
-
3
-type Uint24 [3]byte
4
-
5
-func ToUint24(number uint32) Uint24 {
6
-	return Uint24{byte(number), byte(number >> 8), byte(number >> 16)}
7
-}
8
-
9
-func FromUint24(number Uint24) uint32 {
10
-	return uint32(number[0]) + (uint32(number[1]) << 8) + (uint32(number[2]) << 16)
11
-}

+ 0
- 165
wrappers/packet/mtproto_frame.go Wyświetl plik

@@ -1,165 +0,0 @@
1
-package packet
2
-
3
-import (
4
-	"bytes"
5
-	"crypto/aes"
6
-	"encoding/binary"
7
-	"fmt"
8
-	"hash/crc32"
9
-	"io"
10
-	"io/ioutil"
11
-	"net"
12
-
13
-	"github.com/9seconds/mtg/conntypes"
14
-	"go.uber.org/zap"
15
-)
16
-
17
-const (
18
-	mtprotoFrameMinMessageLength = 12
19
-	mtprotoFrameMaxMessageLength = 16777216
20
-)
21
-
22
-var mtprotoFramePadding = []byte{0x04, 0x00, 0x00, 0x00}
23
-
24
-// MTProtoFrame is a wrapper which converts written data to the MTProtoFrame.
25
-// The format of the frame:
26
-//
27
-// [ MSGLEN(4) | SEQNO(4) | MSG(...) | CRC32(4) | PADDING(4*x) ]
28
-//
29
-// MSGLEN is the length of the message + len of seqno and msglen.
30
-// SEQNO is the number of frame in the receive/send sequence. If client
31
-//   sends a message with SeqNo 18, it has to receive message with SeqNo 18.
32
-// MSG is the data which has to be written
33
-// CRC32 is the CRC32 checksum of MSGLEN + SEQNO + MSG
34
-// PADDING is custom padding schema to complete frame length to such that
35
-//    len(frame) % 16 == 0
36
-type wrapperMtprotoFrame struct {
37
-	parent     conntypes.StreamReadWriteCloser
38
-	logger     *zap.SugaredLogger
39
-	readSeqNo  int32
40
-	writeSeqNo int32
41
-}
42
-
43
-func (w *wrapperMtprotoFrame) Read() (conntypes.Packet, error) { // nolint: funlen, cyclop
44
-	buf := &bytes.Buffer{}
45
-
46
-	sum := crc32.NewIEEE()
47
-	writer := io.MultiWriter(buf, sum)
48
-
49
-	for {
50
-		buf.Reset()
51
-		sum.Reset()
52
-
53
-		if _, err := io.CopyN(writer, w.parent, 4); err != nil {
54
-			return nil, fmt.Errorf("cannot read frame padding: %w", err)
55
-		}
56
-
57
-		if !bytes.Equal(buf.Bytes(), mtprotoFramePadding) {
58
-			break
59
-		}
60
-	}
61
-
62
-	messageLength := binary.LittleEndian.Uint32(buf.Bytes())
63
-	w.logger.Debugw("Read MTProto frame",
64
-		"messageLength", messageLength,
65
-		"sequence_number", w.readSeqNo,
66
-	)
67
-
68
-	if messageLength%4 != 0 || messageLength < mtprotoFrameMinMessageLength ||
69
-		messageLength > mtprotoFrameMaxMessageLength {
70
-		return nil, fmt.Errorf("incorrect frame message length %d", messageLength)
71
-	}
72
-
73
-	buf.Reset()
74
-
75
-	if _, err := io.CopyN(writer, w.parent, int64(messageLength)-4-4); err != nil {
76
-		return nil, fmt.Errorf("cannot read the message frame: %w", err)
77
-	}
78
-
79
-	var seqNo int32
80
-
81
-	binary.Read(buf, binary.LittleEndian, &seqNo) // nolint: errcheck
82
-
83
-	if seqNo != w.readSeqNo {
84
-		return nil, fmt.Errorf("unexpected sequence number %d (wait for %d)", seqNo, w.readSeqNo)
85
-	}
86
-
87
-	data, _ := ioutil.ReadAll(buf)
88
-	buf.Reset()
89
-	// write to buf, not to writer. This is because we are going to fetch
90
-	// crc32 checksum.
91
-	if _, err := io.CopyN(buf, w.parent, 4); err != nil {
92
-		return nil, fmt.Errorf("cannot read checksum: %w", err)
93
-	}
94
-
95
-	checksum := binary.LittleEndian.Uint32(buf.Bytes())
96
-	if checksum != sum.Sum32() {
97
-		return nil, fmt.Errorf("CRC32 checksum mismatch. wait for %d, got %d", sum.Sum32(), checksum)
98
-	}
99
-
100
-	w.logger.Debugw("Read MTProto frame",
101
-		"messageLength", messageLength,
102
-		"sequence_number", w.readSeqNo,
103
-		"dataLength", len(data),
104
-		"checksum", checksum,
105
-	)
106
-	w.readSeqNo++
107
-
108
-	return data, nil
109
-}
110
-
111
-func (w *wrapperMtprotoFrame) Write(p conntypes.Packet) error {
112
-	messageLength := 4 + 4 + len(p) + 4
113
-	paddingLength := (aes.BlockSize - messageLength%aes.BlockSize) % aes.BlockSize
114
-
115
-	buf := &bytes.Buffer{}
116
-
117
-	binary.Write(buf, binary.LittleEndian, uint32(messageLength)) // nolint: errcheck
118
-	binary.Write(buf, binary.LittleEndian, w.writeSeqNo)          // nolint: errcheck
119
-	buf.Write(p)
120
-
121
-	checksum := crc32.ChecksumIEEE(buf.Bytes())
122
-	binary.Write(buf, binary.LittleEndian, checksum) // nolint: errcheck
123
-	buf.Write(bytes.Repeat(mtprotoFramePadding, paddingLength/4))
124
-
125
-	w.logger.Debugw("Write MTProto frame",
126
-		"length", len(p),
127
-		"sequence_number", w.writeSeqNo,
128
-		"crc32", checksum,
129
-		"frame_length", buf.Len(),
130
-	)
131
-	w.writeSeqNo++
132
-
133
-	_, err := w.parent.Write(buf.Bytes())
134
-
135
-	return err // nolint: wrapcheck
136
-}
137
-
138
-func (w *wrapperMtprotoFrame) Close() error {
139
-	return w.parent.Close()
140
-}
141
-
142
-func (w *wrapperMtprotoFrame) Conn() net.Conn {
143
-	return w.parent.Conn()
144
-}
145
-
146
-func (w *wrapperMtprotoFrame) Logger() *zap.SugaredLogger {
147
-	return w.logger
148
-}
149
-
150
-func (w *wrapperMtprotoFrame) LocalAddr() *net.TCPAddr {
151
-	return w.parent.LocalAddr()
152
-}
153
-
154
-func (w *wrapperMtprotoFrame) RemoteAddr() *net.TCPAddr {
155
-	return w.parent.RemoteAddr()
156
-}
157
-
158
-func NewMtprotoFrame(parent conntypes.StreamReadWriteCloser, seqNo int32) conntypes.PacketReadWriteCloser {
159
-	return &wrapperMtprotoFrame{
160
-		parent:     parent,
161
-		logger:     parent.Logger().Named("mtproto-frame"),
162
-		readSeqNo:  seqNo,
163
-		writeSeqNo: seqNo,
164
-	}
165
-}

+ 0
- 130
wrappers/packetack/client_abridged.go Wyświetl plik

@@ -1,130 +0,0 @@
1
-package packetack
2
-
3
-import (
4
-	"bytes"
5
-	"fmt"
6
-	"io"
7
-	"net"
8
-
9
-	"github.com/9seconds/mtg/conntypes"
10
-	"github.com/9seconds/mtg/utils"
11
-	"go.uber.org/zap"
12
-)
13
-
14
-const (
15
-	clientAbridgedSmallPacketLength = 0x7f
16
-	clientAbridgedQuickAckLength    = 0x80
17
-	clientAbridgedLargePacketLength = 16777216 // 256 ^ 3
18
-)
19
-
20
-type wrapperClientAbridged struct {
21
-	parent conntypes.StreamReadWriteCloser
22
-}
23
-
24
-func (w *wrapperClientAbridged) Read(acks *conntypes.ConnectionAcks) (conntypes.Packet, error) {
25
-	buf := bytes.Buffer{}
26
-
27
-	buf.Grow(1)
28
-
29
-	if _, err := io.CopyN(&buf, w.parent, 1); err != nil {
30
-		return nil, fmt.Errorf("cannot read message length: %w", err)
31
-	}
32
-
33
-	msgLength := uint32(buf.Bytes()[0])
34
-	buf.Reset()
35
-
36
-	if msgLength >= clientAbridgedQuickAckLength {
37
-		acks.Quick = true
38
-		msgLength -= clientAbridgedQuickAckLength
39
-	}
40
-
41
-	if msgLength == clientAbridgedSmallPacketLength {
42
-		buf.Grow(3)
43
-
44
-		if _, err := io.CopyN(&buf, w.parent, 3); err != nil {
45
-			return nil, fmt.Errorf("cannot read correct message length: %w", err)
46
-		}
47
-
48
-		number := utils.Uint24{}
49
-		copy(number[:], buf.Bytes())
50
-		msgLength = utils.FromUint24(number)
51
-	}
52
-
53
-	msgLength *= 4
54
-
55
-	buf.Reset()
56
-	buf.Grow(int(msgLength))
57
-
58
-	if _, err := io.CopyN(&buf, w.parent, int64(msgLength)); err != nil {
59
-		return nil, fmt.Errorf("cannot read message: %w", err)
60
-	}
61
-
62
-	return conntypes.Packet(buf.Bytes()), nil
63
-}
64
-
65
-func (w *wrapperClientAbridged) Write(packet conntypes.Packet, acks *conntypes.ConnectionAcks) error {
66
-	if len(packet)%4 != 0 {
67
-		return fmt.Errorf("incorrect packet length %d", len(packet))
68
-	}
69
-
70
-	if acks.Simple {
71
-		if _, err := w.parent.Write(utils.ReverseBytes(packet)); err != nil {
72
-			return fmt.Errorf("cannot send a simpleacked packet: %w", err)
73
-		}
74
-
75
-		return nil
76
-	}
77
-
78
-	packetLength := len(packet) / 4
79
-
80
-	switch {
81
-	case packetLength < clientAbridgedSmallPacketLength:
82
-		data := append([]byte{byte(packetLength)}, packet...)
83
-		if _, err := w.parent.Write(data); err != nil {
84
-			return fmt.Errorf("cannot send small packet: %w", err)
85
-		}
86
-
87
-		return nil
88
-	case packetLength < clientAbridgedLargePacketLength:
89
-		length24 := utils.ToUint24(uint32(packetLength))
90
-		buf := bytes.Buffer{}
91
-
92
-		buf.WriteByte(byte(clientAbridgedSmallPacketLength))
93
-		buf.Write(length24[:])
94
-		buf.Write(packet)
95
-
96
-		if _, err := w.parent.Write(buf.Bytes()); err != nil {
97
-			return fmt.Errorf("cannot send large packet: %w", err)
98
-		}
99
-
100
-		return nil
101
-	}
102
-
103
-	return fmt.Errorf("packet is too big: %d", len(packet))
104
-}
105
-
106
-func (w *wrapperClientAbridged) Close() error {
107
-	return w.parent.Close()
108
-}
109
-
110
-func (w *wrapperClientAbridged) Conn() net.Conn {
111
-	return w.parent.Conn()
112
-}
113
-
114
-func (w *wrapperClientAbridged) LocalAddr() *net.TCPAddr {
115
-	return w.parent.LocalAddr()
116
-}
117
-
118
-func (w *wrapperClientAbridged) RemoteAddr() *net.TCPAddr {
119
-	return w.parent.RemoteAddr()
120
-}
121
-
122
-func (w *wrapperClientAbridged) Logger() *zap.SugaredLogger {
123
-	return w.parent.Logger().Named("client-abridged")
124
-}
125
-
126
-func NewClientAbridged(parent conntypes.StreamReadWriteCloser) conntypes.PacketAckFullReadWriteCloser {
127
-	return &wrapperClientAbridged{
128
-		parent: parent,
129
-	}
130
-}

+ 0
- 89
wrappers/packetack/client_intermediate.go Wyświetl plik

@@ -1,89 +0,0 @@
1
-package packetack
2
-
3
-import (
4
-	"bytes"
5
-	"encoding/binary"
6
-	"fmt"
7
-	"io"
8
-	"net"
9
-
10
-	"github.com/9seconds/mtg/conntypes"
11
-	"go.uber.org/zap"
12
-)
13
-
14
-const clientIntermediateQuickAckLength = 0x80000000
15
-
16
-type wrapperClientIntermediate struct {
17
-	parent conntypes.StreamReadWriteCloser
18
-}
19
-
20
-func (w *wrapperClientIntermediate) Read(acks *conntypes.ConnectionAcks) (conntypes.Packet, error) {
21
-	buf := bytes.Buffer{}
22
-
23
-	buf.Grow(4)
24
-
25
-	if _, err := io.CopyN(&buf, w.parent, 4); err != nil {
26
-		return nil, fmt.Errorf("cannot read message length: %w", err)
27
-	}
28
-
29
-	length := binary.LittleEndian.Uint32(buf.Bytes())
30
-
31
-	if length > clientIntermediateQuickAckLength {
32
-		acks.Quick = true
33
-		length -= clientIntermediateQuickAckLength
34
-	}
35
-
36
-	buf.Reset()
37
-	buf.Grow(int(length))
38
-
39
-	if _, err := io.CopyN(&buf, w.parent, int64(length)); err != nil {
40
-		return nil, fmt.Errorf("cannot read the message: %w", err)
41
-	}
42
-
43
-	return buf.Bytes(), nil
44
-}
45
-
46
-func (w *wrapperClientIntermediate) Write(packet conntypes.Packet, acks *conntypes.ConnectionAcks) error {
47
-	if acks.Simple {
48
-		if _, err := w.parent.Write(packet); err != nil {
49
-			return fmt.Errorf("cannot send simpleacked packet: %w", err)
50
-		}
51
-
52
-		return nil
53
-	}
54
-
55
-	length := [4]byte{}
56
-	binary.LittleEndian.PutUint32(length[:], uint32(len(packet)))
57
-
58
-	if _, err := w.parent.Write(append(length[:], packet...)); err != nil {
59
-		return fmt.Errorf("cannot send packet: %w", err)
60
-	}
61
-
62
-	return nil
63
-}
64
-
65
-func (w *wrapperClientIntermediate) Close() error {
66
-	return w.parent.Close()
67
-}
68
-
69
-func (w *wrapperClientIntermediate) Conn() net.Conn {
70
-	return w.parent.Conn()
71
-}
72
-
73
-func (w *wrapperClientIntermediate) LocalAddr() *net.TCPAddr {
74
-	return w.parent.LocalAddr()
75
-}
76
-
77
-func (w *wrapperClientIntermediate) RemoteAddr() *net.TCPAddr {
78
-	return w.parent.RemoteAddr()
79
-}
80
-
81
-func (w *wrapperClientIntermediate) Logger() *zap.SugaredLogger {
82
-	return w.parent.Logger().Named("client-intermediate")
83
-}
84
-
85
-func NewClientIntermediate(parent conntypes.StreamReadWriteCloser) conntypes.PacketAckFullReadWriteCloser {
86
-	return &wrapperClientIntermediate{
87
-		parent: parent,
88
-	}
89
-}

+ 0
- 63
wrappers/packetack/client_intermediate_secure.go Wyświetl plik

@@ -1,63 +0,0 @@
1
-package packetack
2
-
3
-import (
4
-	"bytes"
5
-	"encoding/binary"
6
-	"fmt"
7
-	"math/rand"
8
-
9
-	"github.com/9seconds/mtg/conntypes"
10
-	"go.uber.org/zap"
11
-)
12
-
13
-type wrapperClientIntermediateSecure struct {
14
-	wrapperClientIntermediate
15
-}
16
-
17
-func (w *wrapperClientIntermediateSecure) Read(acks *conntypes.ConnectionAcks) (conntypes.Packet, error) {
18
-	data, err := w.wrapperClientIntermediate.Read(acks)
19
-	if err != nil {
20
-		return nil, err
21
-	}
22
-
23
-	length := len(data) - (len(data) % 4)
24
-
25
-	return data[:length], nil
26
-}
27
-
28
-func (w *wrapperClientIntermediateSecure) Write(packet conntypes.Packet, acks *conntypes.ConnectionAcks) error {
29
-	if acks.Simple {
30
-		if _, err := w.parent.Write(packet); err != nil {
31
-			return fmt.Errorf("cannot send simpleacked packet: %w", err)
32
-		}
33
-
34
-		return nil
35
-	}
36
-
37
-	buf := &bytes.Buffer{}
38
-	paddingLength := rand.Intn(4) // nolint: gosec
39
-
40
-	buf.Grow(4 + len(packet) + paddingLength)
41
-
42
-	binary.Write(buf, binary.LittleEndian, uint32(len(packet)+paddingLength)) // nolint: errcheck
43
-	buf.Write(packet)
44
-	buf.Write(make([]byte, paddingLength))
45
-
46
-	if _, err := w.parent.Write(buf.Bytes()); err != nil {
47
-		return fmt.Errorf("cannot send packet: %w", err)
48
-	}
49
-
50
-	return nil
51
-}
52
-
53
-func (w *wrapperClientIntermediateSecure) Logger() *zap.SugaredLogger {
54
-	return w.parent.Logger().Named("client-intermediate-secure")
55
-}
56
-
57
-func NewClientIntermediateSecure(parent conntypes.StreamReadWriteCloser) conntypes.PacketAckFullReadWriteCloser {
58
-	return &wrapperClientIntermediateSecure{
59
-		wrapperClientIntermediate: wrapperClientIntermediate{
60
-			parent: parent,
61
-		},
62
-	}
63
-}

+ 0
- 108
wrappers/packetack/proxy.go Wyświetl plik

@@ -1,108 +0,0 @@
1
-package packetack
2
-
3
-import (
4
-	"bytes"
5
-	"encoding/binary"
6
-	"fmt"
7
-	"net"
8
-
9
-	"github.com/9seconds/mtg/config"
10
-	"github.com/9seconds/mtg/conntypes"
11
-	"github.com/9seconds/mtg/hub"
12
-	"github.com/9seconds/mtg/mtproto/rpc"
13
-	"github.com/9seconds/mtg/protocol"
14
-)
15
-
16
-type wrapperProxy struct {
17
-	request      *protocol.TelegramRequest
18
-	proxy        *hub.ProxyConn
19
-	clientIPPort []byte
20
-	ourIPPort    []byte
21
-	flags        rpc.ProxyRequestFlags
22
-}
23
-
24
-func (w *wrapperProxy) Write(packet conntypes.Packet, acks *conntypes.ConnectionAcks) error {
25
-	buf := bytes.Buffer{}
26
-	flags := w.flags
27
-
28
-	if acks.Quick {
29
-		flags |= rpc.ProxyRequestFlagsQuickAck
30
-	}
31
-
32
-	if bytes.HasPrefix(packet, rpc.ProxyRequestFlagsEncryptedPrefix[:]) {
33
-		flags |= rpc.ProxyRequestFlagsEncrypted
34
-	}
35
-
36
-	buf.Write(rpc.TagProxyRequest)
37
-	buf.Write(flags.Bytes())
38
-	buf.Write(w.request.ConnID[:])
39
-	buf.Write(w.clientIPPort)
40
-	buf.Write(w.ourIPPort)
41
-	buf.Write(rpc.ProxyRequestExtraSize)
42
-	buf.Write(rpc.ProxyRequestProxyTag)
43
-	buf.WriteByte(byte(len(config.C.AdTag)))
44
-	buf.Write(config.C.AdTag)
45
-	buf.Write(make([]byte, (4-buf.Len()%4)%4))
46
-	buf.Grow(len(packet))
47
-	buf.Write(packet)
48
-
49
-	return w.proxy.Write(buf.Bytes())
50
-}
51
-
52
-func (w *wrapperProxy) Read(acks *conntypes.ConnectionAcks) (conntypes.Packet, error) {
53
-	resp, err := w.proxy.Read()
54
-	if err != nil {
55
-		return nil, fmt.Errorf("cannot read a response: %w", err)
56
-	}
57
-
58
-	if resp.Type == rpc.ProxyResponseTypeSimpleAck {
59
-		acks.Simple = true
60
-	}
61
-
62
-	return resp.Payload, nil
63
-}
64
-
65
-func (w *wrapperProxy) Close() error {
66
-	w.proxy.Close()
67
-
68
-	return nil
69
-}
70
-
71
-func NewProxy(request *protocol.TelegramRequest) (conntypes.PacketAckReadWriteCloser, error) {
72
-	flags := rpc.ProxyRequestFlagsHasAdTag | rpc.ProxyRequestFlagsMagic | rpc.ProxyRequestFlagsExtMode2
73
-
74
-	switch request.ClientProtocol.ConnectionType() {
75
-	case conntypes.ConnectionTypeAbridged:
76
-		flags |= rpc.ProxyRequestFlagsAbdridged
77
-	case conntypes.ConnectionTypeIntermediate:
78
-		flags |= rpc.ProxyRequestFlagsIntermediate
79
-	case conntypes.ConnectionTypeSecure:
80
-		flags |= rpc.ProxyRequestFlagsIntermediate | rpc.ProxyRequestFlagsPad
81
-	case conntypes.ConnectionTypeUnknown:
82
-		panic("unknown connection type")
83
-	}
84
-
85
-	proxy, err := hub.Hub.Register(request)
86
-	if err != nil {
87
-		return nil, fmt.Errorf("cannot make a new proxy wrapper: %w", err)
88
-	}
89
-
90
-	return &wrapperProxy{
91
-		flags:        flags,
92
-		request:      request,
93
-		proxy:        proxy,
94
-		clientIPPort: proxyGetIPPort(request.ClientConn.RemoteAddr()),
95
-		ourIPPort:    proxyGetIPPort(request.ClientConn.LocalAddr()),
96
-	}, nil
97
-}
98
-
99
-func proxyGetIPPort(addr *net.TCPAddr) []byte {
100
-	rv := [16 + 4]byte{}
101
-	port := [4]byte{}
102
-
103
-	copy(rv[:16], addr.IP.To16())
104
-	binary.LittleEndian.PutUint32(port[:], uint32(addr.Port))
105
-	copy(rv[16:], port[:])
106
-
107
-	return rv[:]
108
-}

+ 0
- 48
wrappers/rwc/ping.go Wyświetl plik

@@ -1,48 +0,0 @@
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 // nolint: wrapcheck
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 // nolint: wrapcheck
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
-}

+ 0
- 21
wrappers/stream/base.go Wyświetl plik

@@ -1,21 +0,0 @@
1
-package stream
2
-
3
-import (
4
-	"net"
5
-
6
-	"github.com/9seconds/mtg/conntypes"
7
-)
8
-
9
-func NewClientConn(parent net.Conn, connID conntypes.ConnID) conntypes.StreamReadWriteCloser {
10
-	conn := newConn(parent, connID, connPurposeClient)
11
-	conn = NewTrafficStats(conn)
12
-
13
-	return conn
14
-}
15
-
16
-func NewTelegramConn(dc conntypes.DC, parent net.Conn) conntypes.StreamReadWriteCloser {
17
-	conn := newConn(parent, conntypes.ConnID{}, connPurposeTelegram)
18
-	conn = NewTelegramStats(dc, conn)
19
-
20
-	return conn
21
-}

+ 0
- 96
wrappers/stream/blockcipher.go Wyświetl plik

@@ -1,96 +0,0 @@
1
-package stream
2
-
3
-import (
4
-	"crypto/aes"
5
-	"crypto/cipher"
6
-	"fmt"
7
-	"net"
8
-	"time"
9
-
10
-	"github.com/9seconds/mtg/conntypes"
11
-	"github.com/9seconds/mtg/utils"
12
-	"go.uber.org/zap"
13
-)
14
-
15
-type wrapperBlockCipher struct {
16
-	bufferedReader
17
-
18
-	parent    conntypes.StreamReadWriteCloser
19
-	encryptor cipher.BlockMode
20
-	decryptor cipher.BlockMode
21
-}
22
-
23
-func (w *wrapperBlockCipher) Write(p []byte) (int, error) {
24
-	encrypted, err := w.encrypt(p)
25
-	if err != nil {
26
-		return 0, err
27
-	}
28
-
29
-	return w.parent.Write(encrypted)
30
-}
31
-
32
-func (w *wrapperBlockCipher) WriteTimeout(p []byte, timeout time.Duration) (int, error) {
33
-	encrypted, err := w.encrypt(p)
34
-	if err != nil {
35
-		return 0, err
36
-	}
37
-
38
-	return w.parent.WriteTimeout(encrypted, timeout)
39
-}
40
-
41
-func (w *wrapperBlockCipher) encrypt(p []byte) ([]byte, error) {
42
-	if len(p)%aes.BlockSize > 0 {
43
-		return nil, fmt.Errorf("incorrect block size %d", len(p))
44
-	}
45
-
46
-	encrypted := make([]byte, len(p))
47
-	w.encryptor.CryptBlocks(encrypted, p)
48
-
49
-	return encrypted, nil
50
-}
51
-
52
-func (w *wrapperBlockCipher) Close() error {
53
-	return w.parent.Close()
54
-}
55
-
56
-func (w *wrapperBlockCipher) Conn() net.Conn {
57
-	return w.parent.Conn()
58
-}
59
-
60
-func (w *wrapperBlockCipher) Logger() *zap.SugaredLogger {
61
-	return w.parent.Logger().Named("block-cipher")
62
-}
63
-
64
-func (w *wrapperBlockCipher) LocalAddr() *net.TCPAddr {
65
-	return w.parent.LocalAddr()
66
-}
67
-
68
-func (w *wrapperBlockCipher) RemoteAddr() *net.TCPAddr {
69
-	return w.parent.RemoteAddr()
70
-}
71
-
72
-func newBlockCipher(parent conntypes.StreamReadWriteCloser,
73
-	encryptor, decryptor cipher.BlockMode) conntypes.StreamReadWriteCloser {
74
-	cipher := &wrapperBlockCipher{
75
-		parent:    parent,
76
-		encryptor: encryptor,
77
-		decryptor: decryptor,
78
-	}
79
-
80
-	cipher.readFunc = func() ([]byte, error) {
81
-		var currentBuffer []byte
82
-		for len(currentBuffer) == 0 || len(currentBuffer)%aes.BlockSize != 0 {
83
-			rv, err := utils.ReadFull(cipher.parent)
84
-			if err != nil {
85
-				return nil, fmt.Errorf("cannot read data: %w", err)
86
-			}
87
-
88
-			currentBuffer = append(currentBuffer, rv...)
89
-		}
90
-		cipher.decryptor.CryptBlocks(currentBuffer, currentBuffer)
91
-
92
-		return currentBuffer, nil
93
-	}
94
-
95
-	return cipher
96
-}

+ 0
- 44
wrappers/stream/buffered_reader.go Wyświetl plik

@@ -1,44 +0,0 @@
1
-package stream
2
-
3
-import (
4
-	"bytes"
5
-	"time"
6
-)
7
-
8
-type bufferedReaderReadFunc func() ([]byte, error)
9
-
10
-type bufferedReader struct {
11
-	buf      bytes.Buffer
12
-	readFunc bufferedReaderReadFunc
13
-}
14
-
15
-func (b *bufferedReader) Read(p []byte) (int, error) {
16
-	if b.buf.Len() > 0 {
17
-		return b.flush(p)
18
-	}
19
-
20
-	res, err := b.readFunc()
21
-	if err != nil {
22
-		return 0, err
23
-	}
24
-
25
-	b.buf.Write(res)
26
-
27
-	return b.flush(p)
28
-}
29
-
30
-func (b *bufferedReader) ReadTimeout(p []byte, _ time.Duration) (int, error) {
31
-	return b.Read(p)
32
-}
33
-
34
-func (b *bufferedReader) flush(p []byte) (int, error) {
35
-	if b.buf.Len() > len(p) {
36
-		return b.buf.Read(p)
37
-	}
38
-
39
-	sizeToReturn := b.buf.Len()
40
-	copy(p, b.buf.Bytes())
41
-	b.buf.Reset()
42
-
43
-	return sizeToReturn, nil
44
-}

+ 0
- 123
wrappers/stream/conn.go Wyświetl plik

@@ -1,123 +0,0 @@
1
-package stream
2
-
3
-import (
4
-	"fmt"
5
-	"net"
6
-	"time"
7
-
8
-	"github.com/9seconds/mtg/config"
9
-	"github.com/9seconds/mtg/conntypes"
10
-	"go.uber.org/zap"
11
-)
12
-
13
-type connPurpose uint8
14
-
15
-const (
16
-	connPurposeClient connPurpose = 1 << iota
17
-	connPurposeTelegram
18
-)
19
-
20
-type wrapperConn struct {
21
-	parent     net.Conn
22
-	connID     conntypes.ConnID
23
-	logger     *zap.SugaredLogger
24
-	localAddr  *net.TCPAddr
25
-	remoteAddr *net.TCPAddr
26
-}
27
-
28
-func (w *wrapperConn) WriteTimeout(p []byte, timeout time.Duration) (int, error) {
29
-	if err := w.parent.SetWriteDeadline(time.Now().Add(timeout)); err != nil {
30
-		w.Close()
31
-
32
-		return 0, fmt.Errorf("cannot set write deadline to the socket: %w", err)
33
-	}
34
-
35
-	return w.Write(p)
36
-}
37
-
38
-func (w *wrapperConn) Write(p []byte) (int, error) {
39
-	n, err := w.parent.Write(p)
40
-	w.logger.Debugw("write to stream", "bytes", n, "error", err)
41
-
42
-	if err != nil {
43
-		w.Close()
44
-	}
45
-
46
-	return n, err // nolint: wrapcheck
47
-}
48
-
49
-func (w *wrapperConn) ReadTimeout(p []byte, timeout time.Duration) (int, error) {
50
-	if err := w.parent.SetReadDeadline(time.Now().Add(timeout)); err != nil {
51
-		w.Close()
52
-
53
-		return 0, fmt.Errorf("cannot set read deadline to the socket: %w", err)
54
-	}
55
-
56
-	return w.Read(p)
57
-}
58
-
59
-func (w *wrapperConn) Read(p []byte) (int, error) {
60
-	n, err := w.parent.Read(p)
61
-	w.logger.Debugw("Read from stream", "bytes", n, "error", err)
62
-
63
-	if err != nil {
64
-		w.Close()
65
-	}
66
-
67
-	return n, err // nolint: wrapcheck
68
-}
69
-
70
-func (w *wrapperConn) Close() error {
71
-	w.logger.Debugw("Close connection")
72
-
73
-	return w.parent.Close()
74
-}
75
-
76
-func (w *wrapperConn) Conn() net.Conn {
77
-	return w.parent
78
-}
79
-
80
-func (w *wrapperConn) Logger() *zap.SugaredLogger {
81
-	return w.logger
82
-}
83
-
84
-func (w *wrapperConn) LocalAddr() *net.TCPAddr {
85
-	return w.localAddr
86
-}
87
-
88
-func (w *wrapperConn) RemoteAddr() *net.TCPAddr {
89
-	return w.remoteAddr
90
-}
91
-
92
-func newConn(parent net.Conn,
93
-	connID conntypes.ConnID,
94
-	purpose connPurpose) conntypes.StreamReadWriteCloser {
95
-	localAddr := *parent.LocalAddr().(*net.TCPAddr)
96
-
97
-	if parent.RemoteAddr().(*net.TCPAddr).IP.To4() != nil {
98
-		if config.C.PublicIPv4.IP != nil {
99
-			localAddr.IP = config.C.PublicIPv4.IP
100
-		}
101
-	} else if config.C.PublicIPv6.IP != nil {
102
-		localAddr.IP = config.C.PublicIPv6.IP
103
-	}
104
-
105
-	logger := zap.S().With(
106
-		"local_address", localAddr,
107
-		"remote_address", parent.RemoteAddr(),
108
-	).Named("conn")
109
-
110
-	if purpose == connPurposeClient {
111
-		logger = logger.Named("client").With("connection_id", connID.String())
112
-	} else {
113
-		logger = logger.Named("telegram")
114
-	}
115
-
116
-	return &wrapperConn{
117
-		parent:     parent,
118
-		connID:     connID,
119
-		logger:     logger,
120
-		remoteAddr: parent.RemoteAddr().(*net.TCPAddr),
121
-		localAddr:  &localAddr,
122
-	}
123
-}

+ 0
- 93
wrappers/stream/ctx.go Wyświetl plik

@@ -1,93 +0,0 @@
1
-package stream
2
-
3
-import (
4
-	"context"
5
-	"fmt"
6
-	"net"
7
-	"time"
8
-
9
-	"github.com/9seconds/mtg/conntypes"
10
-	"go.uber.org/zap"
11
-)
12
-
13
-type wrapperCtx struct {
14
-	parent conntypes.StreamReadWriteCloser
15
-	ctx    context.Context
16
-	cancel context.CancelFunc
17
-}
18
-
19
-func (w *wrapperCtx) WriteTimeout(p []byte, timeout time.Duration) (int, error) {
20
-	select {
21
-	case <-w.ctx.Done():
22
-		w.Close()
23
-
24
-		return 0, fmt.Errorf("cannot write because context was closed: %w", w.ctx.Err())
25
-	default:
26
-		return w.parent.WriteTimeout(p, timeout)
27
-	}
28
-}
29
-
30
-func (w *wrapperCtx) Write(p []byte) (int, error) {
31
-	select {
32
-	case <-w.ctx.Done():
33
-		w.Close()
34
-
35
-		return 0, fmt.Errorf("cannot write because context was closed: %w", w.ctx.Err())
36
-	default:
37
-		return w.parent.Write(p)
38
-	}
39
-}
40
-
41
-func (w *wrapperCtx) ReadTimeout(p []byte, timeout time.Duration) (int, error) {
42
-	select {
43
-	case <-w.ctx.Done():
44
-		w.Close()
45
-
46
-		return 0, fmt.Errorf("cannot write because context was closed: %w", w.ctx.Err())
47
-	default:
48
-		return w.parent.ReadTimeout(p, timeout)
49
-	}
50
-}
51
-
52
-func (w *wrapperCtx) Read(p []byte) (int, error) {
53
-	select {
54
-	case <-w.ctx.Done():
55
-		w.Close()
56
-
57
-		return 0, fmt.Errorf("cannot write because context was closed: %w", w.ctx.Err())
58
-	default:
59
-		return w.parent.Read(p)
60
-	}
61
-}
62
-
63
-func (w *wrapperCtx) Close() error {
64
-	w.cancel()
65
-
66
-	return w.parent.Close()
67
-}
68
-
69
-func (w *wrapperCtx) Conn() net.Conn {
70
-	return w.parent.Conn()
71
-}
72
-
73
-func (w *wrapperCtx) Logger() *zap.SugaredLogger {
74
-	return w.parent.Logger().Named("ctx")
75
-}
76
-
77
-func (w *wrapperCtx) LocalAddr() *net.TCPAddr {
78
-	return w.parent.LocalAddr()
79
-}
80
-
81
-func (w *wrapperCtx) RemoteAddr() *net.TCPAddr {
82
-	return w.parent.RemoteAddr()
83
-}
84
-
85
-func NewCtx(ctx context.Context,
86
-	cancel context.CancelFunc,
87
-	parent conntypes.StreamReadWriteCloser) conntypes.StreamReadWriteCloser {
88
-	return &wrapperCtx{
89
-		parent: parent,
90
-		ctx:    ctx,
91
-		cancel: cancel,
92
-	}
93
-}

+ 0
- 107
wrappers/stream/faketls.go Wyświetl plik

@@ -1,107 +0,0 @@
1
-package stream
2
-
3
-import (
4
-	"bytes"
5
-	"errors"
6
-	"fmt"
7
-	"net"
8
-	"time"
9
-
10
-	"github.com/9seconds/mtg/conntypes"
11
-	"github.com/9seconds/mtg/tlstypes"
12
-	"go.uber.org/zap"
13
-)
14
-
15
-type wrapperFakeTLS struct {
16
-	bufferedReader
17
-
18
-	parent conntypes.StreamReadWriteCloser
19
-}
20
-
21
-func (w *wrapperFakeTLS) Write(p []byte) (int, error) {
22
-	return w.write(p, func(b []byte) (int, error) {
23
-		return w.parent.Write(b)
24
-	})
25
-}
26
-
27
-func (w *wrapperFakeTLS) WriteTimeout(p []byte, timeout time.Duration) (int, error) {
28
-	startTime := time.Now()
29
-
30
-	return w.write(p, func(b []byte) (int, error) {
31
-		elapsed := time.Since(startTime)
32
-		if elapsed > timeout {
33
-			return w.parent.WriteTimeout(b, timeout-elapsed)
34
-		}
35
-
36
-		return 0, errors.New("timeout")
37
-	})
38
-}
39
-
40
-func (w *wrapperFakeTLS) write(p []byte, writeFunc func([]byte) (int, error)) (int, error) {
41
-	sum := 0
42
-	buf := bytes.Buffer{}
43
-
44
-	for _, v := range tlstypes.MakeRecords(p) {
45
-		buf.Reset()
46
-		v.WriteBytes(&buf)
47
-
48
-		_, err := writeFunc(buf.Bytes())
49
-		if err != nil {
50
-			return sum, err
51
-		}
52
-
53
-		sum += v.Data.Len()
54
-	}
55
-
56
-	return sum, nil
57
-}
58
-
59
-func (w *wrapperFakeTLS) Conn() net.Conn {
60
-	return w.parent.Conn()
61
-}
62
-
63
-func (w *wrapperFakeTLS) Logger() *zap.SugaredLogger {
64
-	return w.parent.Logger().Named("faketls")
65
-}
66
-
67
-func (w *wrapperFakeTLS) LocalAddr() *net.TCPAddr {
68
-	return w.parent.LocalAddr()
69
-}
70
-
71
-func (w *wrapperFakeTLS) RemoteAddr() *net.TCPAddr {
72
-	return w.parent.RemoteAddr()
73
-}
74
-
75
-func (w *wrapperFakeTLS) Close() error {
76
-	return w.parent.Close()
77
-}
78
-
79
-func NewFakeTLS(socket conntypes.StreamReadWriteCloser) conntypes.StreamReadWriteCloser {
80
-	faketls := &wrapperFakeTLS{
81
-		parent: socket,
82
-	}
83
-
84
-	faketls.readFunc = func() ([]byte, error) {
85
-		for {
86
-			rec, err := tlstypes.ReadRecord(faketls.parent)
87
-			if err != nil {
88
-				return nil, err // nolint: wrapcheck
89
-			}
90
-
91
-			switch rec.Type {
92
-			case tlstypes.RecordTypeChangeCipherSpec:
93
-			case tlstypes.RecordTypeApplicationData:
94
-				buf := &bytes.Buffer{}
95
-				rec.Data.WriteBytes(buf)
96
-
97
-				return buf.Bytes(), nil
98
-			case tlstypes.RecordTypeHandshake:
99
-				return nil, errors.New("unsupported record type handshake")
100
-			default:
101
-				return nil, fmt.Errorf("unsupported record type %v", rec.Type)
102
-			}
103
-		}
104
-	}
105
-
106
-	return faketls
107
-}

+ 0
- 117
wrappers/stream/mtproto_cipher.go Wyświetl plik

@@ -1,117 +0,0 @@
1
-package stream
2
-
3
-import (
4
-	"bytes"
5
-	"crypto/aes"
6
-	"crypto/cipher"
7
-	"crypto/md5"
8
-	"crypto/sha1"
9
-	"encoding/binary"
10
-	"net"
11
-
12
-	"github.com/9seconds/mtg/conntypes"
13
-	"github.com/9seconds/mtg/mtproto/rpc"
14
-	"github.com/9seconds/mtg/utils"
15
-)
16
-
17
-type mtprotoCipherPurpose uint8
18
-
19
-const (
20
-	mtprotoCipherPurposeClient mtprotoCipherPurpose = iota
21
-	mtprotoCipherPurposeServer
22
-)
23
-
24
-var mtprotoEmptyIP = [4]byte{0x00, 0x00, 0x00, 0x00}
25
-
26
-func NewMiddleProxyCipher(parent conntypes.StreamReadWriteCloser,
27
-	req *rpc.NonceRequest,
28
-	resp *rpc.NonceResponse,
29
-	secret []byte) conntypes.StreamReadWriteCloser {
30
-	localAddr := parent.LocalAddr()
31
-	remoteAddr := parent.RemoteAddr()
32
-
33
-	encKey, encIV := mtprotoDeriveKeys(mtprotoCipherPurposeClient,
34
-		req,
35
-		resp,
36
-		localAddr,
37
-		remoteAddr,
38
-		secret)
39
-	decKey, decIV := mtprotoDeriveKeys(mtprotoCipherPurposeServer,
40
-		req,
41
-		resp,
42
-		localAddr,
43
-		remoteAddr,
44
-		secret)
45
-
46
-	enc, _ := mtprotoMakeEncrypterDecrypter(encKey, encIV)
47
-	_, dec := mtprotoMakeEncrypterDecrypter(decKey, decIV)
48
-
49
-	return newBlockCipher(parent, enc, dec)
50
-}
51
-
52
-func mtprotoDeriveKeys(purpose mtprotoCipherPurpose,
53
-	req *rpc.NonceRequest,
54
-	resp *rpc.NonceResponse,
55
-	client, remote *net.TCPAddr,
56
-	secret []byte) ([]byte, []byte) {
57
-	message := bytes.Buffer{}
58
-
59
-	message.Write(resp.Nonce)
60
-	message.Write(req.Nonce)
61
-	message.Write(req.CryptoTS)
62
-
63
-	clientIPv4 := mtprotoEmptyIP[:]
64
-	serverIPv4 := mtprotoEmptyIP[:]
65
-
66
-	if client.IP.To4() != nil {
67
-		clientIPv4 = utils.ReverseBytes(client.IP.To4())
68
-		serverIPv4 = utils.ReverseBytes(remote.IP.To4())
69
-	}
70
-
71
-	message.Write(serverIPv4)
72
-
73
-	var port [2]byte
74
-
75
-	binary.LittleEndian.PutUint16(port[:], uint16(client.Port))
76
-	message.Write(port[:])
77
-
78
-	switch purpose {
79
-	case mtprotoCipherPurposeClient:
80
-		message.WriteString("CLIENT")
81
-	case mtprotoCipherPurposeServer:
82
-		message.WriteString("SERVER")
83
-	default:
84
-		panic("Unexpected cipher purpose")
85
-	}
86
-
87
-	message.Write(clientIPv4)
88
-	binary.LittleEndian.PutUint16(port[:], uint16(remote.Port))
89
-	message.Write(port[:])
90
-	message.Write(secret)
91
-	message.Write(resp.Nonce)
92
-
93
-	if client.IP.To4() == nil {
94
-		message.Write(client.IP.To16())
95
-		message.Write(remote.IP.To16())
96
-	}
97
-
98
-	message.Write(req.Nonce)
99
-
100
-	data := message.Bytes()
101
-	md5sum := md5.Sum(data[1:]) // nolint: gas
102
-	sha1sum := sha1.Sum(data)   // nolint: gosec
103
-
104
-	key := append(md5sum[:12], sha1sum[:]...)
105
-	iv := md5.Sum(data[2:]) // nolint: gas
106
-
107
-	return key, iv[:]
108
-}
109
-
110
-func mtprotoMakeEncrypterDecrypter(key, iv []byte) (cipher.BlockMode, cipher.BlockMode) {
111
-	block, err := aes.NewCipher(key)
112
-	if err != nil {
113
-		panic(err)
114
-	}
115
-
116
-	return cipher.NewCBCEncrypter(block, iv), cipher.NewCBCDecrypter(block, iv)
117
-}

+ 0
- 93
wrappers/stream/obfuscated2.go Wyświetl plik

@@ -1,93 +0,0 @@
1
-package stream
2
-
3
-import (
4
-	"bytes"
5
-	"crypto/cipher"
6
-	"fmt"
7
-	"net"
8
-	"time"
9
-
10
-	"github.com/9seconds/mtg/conntypes"
11
-	"go.uber.org/zap"
12
-)
13
-
14
-type wrapperObfuscated2 struct {
15
-	encryptor cipher.Stream
16
-	decryptor cipher.Stream
17
-	parent    conntypes.StreamReadWriteCloser
18
-}
19
-
20
-func (w *wrapperObfuscated2) ReadTimeout(p []byte, timeout time.Duration) (int, error) {
21
-	n, err := w.parent.ReadTimeout(p, timeout)
22
-	if err != nil {
23
-		return 0, fmt.Errorf("cannot read stream ciphered data: %w", err)
24
-	}
25
-
26
-	w.decryptor.XORKeyStream(p, p[:n])
27
-
28
-	return n, nil
29
-}
30
-
31
-func (w *wrapperObfuscated2) Read(p []byte) (int, error) {
32
-	n, err := w.parent.Read(p)
33
-	if err != nil {
34
-		return n, err // nolint: wrapcheck
35
-	}
36
-
37
-	w.decryptor.XORKeyStream(p, p[:n])
38
-
39
-	return n, nil
40
-}
41
-
42
-func (w *wrapperObfuscated2) WriteTimeout(p []byte, timeout time.Duration) (int, error) {
43
-	buffer := bytes.Buffer{}
44
-
45
-	buffer.Write(p)
46
-
47
-	buf := buffer.Bytes()
48
-
49
-	w.encryptor.XORKeyStream(buf, buf)
50
-
51
-	return w.parent.WriteTimeout(buf, timeout)
52
-}
53
-
54
-func (w *wrapperObfuscated2) Write(p []byte) (int, error) {
55
-	buffer := bytes.Buffer{}
56
-
57
-	buffer.Write(p)
58
-
59
-	buf := buffer.Bytes()
60
-
61
-	w.encryptor.XORKeyStream(buf, buf)
62
-
63
-	return w.parent.Write(buf)
64
-}
65
-
66
-func (w *wrapperObfuscated2) Conn() net.Conn {
67
-	return w.parent.Conn()
68
-}
69
-
70
-func (w *wrapperObfuscated2) Logger() *zap.SugaredLogger {
71
-	return w.parent.Logger().Named("obfuscated2")
72
-}
73
-
74
-func (w *wrapperObfuscated2) LocalAddr() *net.TCPAddr {
75
-	return w.parent.LocalAddr()
76
-}
77
-
78
-func (w *wrapperObfuscated2) RemoteAddr() *net.TCPAddr {
79
-	return w.parent.RemoteAddr()
80
-}
81
-
82
-func (w *wrapperObfuscated2) Close() error {
83
-	return w.parent.Close()
84
-}
85
-
86
-func NewObfuscated2(socket conntypes.StreamReadWriteCloser,
87
-	encryptor, decryptor cipher.Stream) conntypes.StreamReadWriteCloser {
88
-	return &wrapperObfuscated2{
89
-		parent:    socket,
90
-		encryptor: encryptor,
91
-		decryptor: decryptor,
92
-	}
93
-}

+ 0
- 83
wrappers/stream/rewind.go Wyświetl plik

@@ -1,83 +0,0 @@
1
-package stream
2
-
3
-import (
4
-	"bytes"
5
-	"io"
6
-	"net"
7
-	"sync"
8
-	"time"
9
-
10
-	"github.com/9seconds/mtg/conntypes"
11
-	"go.uber.org/zap"
12
-)
13
-
14
-type ReadWriteCloseRewinder interface {
15
-	conntypes.StreamReadWriteCloser
16
-	Rewind()
17
-}
18
-
19
-type wrapperRewind struct {
20
-	parent       conntypes.StreamReadWriteCloser
21
-	activeReader io.Reader
22
-	buf          bytes.Buffer
23
-	mutex        sync.Mutex
24
-}
25
-
26
-func (w *wrapperRewind) Write(p []byte) (int, error) {
27
-	return w.parent.Write(p)
28
-}
29
-
30
-func (w *wrapperRewind) WriteTimeout(p []byte, timeout time.Duration) (int, error) {
31
-	return w.parent.WriteTimeout(p, timeout)
32
-}
33
-
34
-func (w *wrapperRewind) Read(p []byte) (int, error) {
35
-	w.mutex.Lock()
36
-	defer w.mutex.Unlock()
37
-
38
-	return w.activeReader.Read(p)
39
-}
40
-
41
-func (w *wrapperRewind) ReadTimeout(p []byte, _ time.Duration) (int, error) {
42
-	w.mutex.Lock()
43
-	defer w.mutex.Unlock()
44
-
45
-	return w.activeReader.Read(p)
46
-}
47
-
48
-func (w *wrapperRewind) Conn() net.Conn {
49
-	return w.parent.Conn()
50
-}
51
-
52
-func (w *wrapperRewind) Logger() *zap.SugaredLogger {
53
-	return w.parent.Logger().Named("rewinded")
54
-}
55
-
56
-func (w *wrapperRewind) LocalAddr() *net.TCPAddr {
57
-	return w.parent.LocalAddr()
58
-}
59
-
60
-func (w *wrapperRewind) RemoteAddr() *net.TCPAddr {
61
-	return w.parent.RemoteAddr()
62
-}
63
-
64
-func (w *wrapperRewind) Close() error {
65
-	w.buf.Reset()
66
-
67
-	return w.parent.Close()
68
-}
69
-
70
-func (w *wrapperRewind) Rewind() {
71
-	w.mutex.Lock()
72
-	w.activeReader = io.MultiReader(&w.buf, w.parent)
73
-	w.mutex.Unlock()
74
-}
75
-
76
-func NewRewind(parent conntypes.StreamReadWriteCloser) ReadWriteCloseRewinder {
77
-	rv := &wrapperRewind{
78
-		parent: parent,
79
-	}
80
-	rv.activeReader = io.TeeReader(parent, &rv.buf)
81
-
82
-	return rv
83
-}

+ 0
- 71
wrappers/stream/stats_telegram.go Wyświetl plik

@@ -1,71 +0,0 @@
1
-package stream
2
-
3
-import (
4
-	"net"
5
-	"sync"
6
-	"time"
7
-
8
-	"github.com/9seconds/mtg/conntypes"
9
-	"github.com/9seconds/mtg/stats"
10
-	"go.uber.org/zap"
11
-)
12
-
13
-type wrapperTelegramStats struct {
14
-	parent conntypes.StreamReadWriteCloser
15
-	dc     conntypes.DC
16
-	once   sync.Once
17
-}
18
-
19
-func (w *wrapperTelegramStats) Write(p []byte) (int, error) {
20
-	return w.parent.Write(p)
21
-}
22
-
23
-func (w *wrapperTelegramStats) WriteTimeout(p []byte, timeout time.Duration) (int, error) {
24
-	return w.parent.WriteTimeout(p, timeout)
25
-}
26
-
27
-func (w *wrapperTelegramStats) Read(p []byte) (int, error) {
28
-	return w.parent.Read(p)
29
-}
30
-
31
-func (w *wrapperTelegramStats) ReadTimeout(p []byte, timeout time.Duration) (int, error) {
32
-	return w.parent.ReadTimeout(p, timeout)
33
-}
34
-
35
-func (w *wrapperTelegramStats) Conn() net.Conn {
36
-	return w.parent.Conn()
37
-}
38
-
39
-func (w *wrapperTelegramStats) Logger() *zap.SugaredLogger {
40
-	return w.parent.Logger().Named("stats-telegram")
41
-}
42
-
43
-func (w *wrapperTelegramStats) LocalAddr() *net.TCPAddr {
44
-	return w.parent.LocalAddr()
45
-}
46
-
47
-func (w *wrapperTelegramStats) RemoteAddr() *net.TCPAddr {
48
-	return w.parent.RemoteAddr()
49
-}
50
-
51
-func (w *wrapperTelegramStats) Close() error {
52
-	var err error
53
-
54
-	w.once.Do(func() {
55
-		err = w.parent.Close()
56
-		stats.Stats.TelegramDisconnected(w.dc, w.RemoteAddr())
57
-	})
58
-
59
-	return err // nolint: wrapcheck
60
-}
61
-
62
-func NewTelegramStats(dc conntypes.DC, parent conntypes.StreamReadWriteCloser) conntypes.StreamReadWriteCloser {
63
-	conn := &wrapperTelegramStats{
64
-		parent: parent,
65
-		dc:     dc,
66
-	}
67
-
68
-	stats.Stats.TelegramConnected(dc, parent.RemoteAddr())
69
-
70
-	return conn
71
-}

+ 0
- 66
wrappers/stream/stats_traffic.go Wyświetl plik

@@ -1,66 +0,0 @@
1
-package stream
2
-
3
-import (
4
-	"net"
5
-	"time"
6
-
7
-	"github.com/9seconds/mtg/conntypes"
8
-	"github.com/9seconds/mtg/stats"
9
-	"go.uber.org/zap"
10
-)
11
-
12
-type wrapperTrafficStats struct {
13
-	parent conntypes.StreamReadWriteCloser
14
-}
15
-
16
-func (w *wrapperTrafficStats) Write(p []byte) (int, error) {
17
-	n, err := w.parent.Write(p)
18
-	stats.Stats.EgressTraffic(n)
19
-
20
-	return n, err // nolint: wrapcheck
21
-}
22
-
23
-func (w *wrapperTrafficStats) WriteTimeout(p []byte, timeout time.Duration) (int, error) {
24
-	n, err := w.parent.WriteTimeout(p, timeout)
25
-	stats.Stats.EgressTraffic(n)
26
-
27
-	return n, err // nolint: wrapcheck
28
-}
29
-
30
-func (w *wrapperTrafficStats) Read(p []byte) (int, error) {
31
-	n, err := w.parent.Read(p)
32
-	stats.Stats.IngressTraffic(n)
33
-
34
-	return n, err // nolint: wrapcheck
35
-}
36
-
37
-func (w *wrapperTrafficStats) ReadTimeout(p []byte, timeout time.Duration) (int, error) {
38
-	n, err := w.parent.ReadTimeout(p, timeout)
39
-	stats.Stats.IngressTraffic(n)
40
-
41
-	return n, err // nolint: wrapcheck
42
-}
43
-
44
-func (w *wrapperTrafficStats) Conn() net.Conn {
45
-	return w.parent.Conn()
46
-}
47
-
48
-func (w *wrapperTrafficStats) Logger() *zap.SugaredLogger {
49
-	return w.parent.Logger().Named("stats-traffic")
50
-}
51
-
52
-func (w *wrapperTrafficStats) LocalAddr() *net.TCPAddr {
53
-	return w.parent.LocalAddr()
54
-}
55
-
56
-func (w *wrapperTrafficStats) RemoteAddr() *net.TCPAddr {
57
-	return w.parent.RemoteAddr()
58
-}
59
-
60
-func (w *wrapperTrafficStats) Close() error {
61
-	return w.parent.Close()
62
-}
63
-
64
-func NewTrafficStats(parent conntypes.StreamReadWriteCloser) conntypes.StreamReadWriteCloser {
65
-	return &wrapperTrafficStats{parent}
66
-}

+ 0
- 60
wrappers/stream/timeout.go Wyświetl plik

@@ -1,60 +0,0 @@
1
-package stream
2
-
3
-import (
4
-	"net"
5
-	"time"
6
-
7
-	"github.com/9seconds/mtg/conntypes"
8
-	"go.uber.org/zap"
9
-)
10
-
11
-const (
12
-	timeoutRead  = 2 * time.Minute
13
-	timeoutWrite = 2 * time.Minute
14
-)
15
-
16
-type wrapperTimeout struct {
17
-	parent conntypes.StreamReadWriteCloser
18
-}
19
-
20
-func (w *wrapperTimeout) WriteTimeout(p []byte, timeout time.Duration) (int, error) {
21
-	return w.parent.WriteTimeout(p, timeout)
22
-}
23
-
24
-func (w *wrapperTimeout) Write(p []byte) (int, error) {
25
-	return w.parent.WriteTimeout(p, timeoutWrite)
26
-}
27
-
28
-func (w *wrapperTimeout) ReadTimeout(p []byte, timeout time.Duration) (int, error) {
29
-	return w.parent.ReadTimeout(p, timeout)
30
-}
31
-
32
-func (w *wrapperTimeout) Read(p []byte) (int, error) {
33
-	return w.parent.ReadTimeout(p, timeoutRead)
34
-}
35
-
36
-func (w *wrapperTimeout) Close() error {
37
-	return w.parent.Close()
38
-}
39
-
40
-func (w *wrapperTimeout) Conn() net.Conn {
41
-	return w.parent.Conn()
42
-}
43
-
44
-func (w *wrapperTimeout) Logger() *zap.SugaredLogger {
45
-	return w.parent.Logger().Named("timeout")
46
-}
47
-
48
-func (w *wrapperTimeout) LocalAddr() *net.TCPAddr {
49
-	return w.parent.LocalAddr()
50
-}
51
-
52
-func (w *wrapperTimeout) RemoteAddr() *net.TCPAddr {
53
-	return w.parent.RemoteAddr()
54
-}
55
-
56
-func NewTimeout(parent conntypes.StreamReadWriteCloser) conntypes.StreamReadWriteCloser {
57
-	return &wrapperTimeout{
58
-		parent: parent,
59
-	}
60
-}

Ładowanie…
Anuluj
Zapisz