mirror of
https://github.com/ScuroNeko/mtg.git
synced 2026-09-01 12:04:03 +03:00
REPOSITORY / ScuroNeko/mtg
Compare commits
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
b1074193a8 | ||
|
|
78dea9ae3f | ||
|
|
da8dba1585 | ||
|
|
33852ca481 | ||
|
|
eff53694a0 | ||
|
|
74a7c505eb | ||
|
|
9983f7fcba | ||
|
|
a90072260e | ||
|
|
b153240bc3 | ||
|
|
6dfbd26524 | ||
|
|
39e7663e0c | ||
|
|
71f7bf6cad | ||
|
|
fba0e235c1 | ||
|
|
70be70de3c | ||
|
|
b565d83d40 | ||
|
|
ebc459440c | ||
|
|
6e6049a73a | ||
|
|
916714a909 | ||
|
|
f68b195306 | ||
|
|
5f1d1ce883 |
@@ -10,3 +10,4 @@ format = "colored-line-number"
|
|||||||
|
|
||||||
[linters]
|
[linters]
|
||||||
enable-all = true
|
enable-all = true
|
||||||
|
disable = ["gochecknoglobals"]
|
||||||
|
|||||||
+1
-1
@@ -6,6 +6,7 @@ dist: trusty
|
|||||||
|
|
||||||
go:
|
go:
|
||||||
- "1.11.x"
|
- "1.11.x"
|
||||||
|
- 1.12.x
|
||||||
- master
|
- master
|
||||||
|
|
||||||
before_script: make prepare
|
before_script: make prepare
|
||||||
@@ -13,7 +14,6 @@ before_script: make prepare
|
|||||||
script:
|
script:
|
||||||
- make all
|
- make all
|
||||||
- make lint
|
- make lint
|
||||||
- make critic
|
|
||||||
- make test
|
- make test
|
||||||
|
|
||||||
matrix:
|
matrix:
|
||||||
|
|||||||
+1
-1
@@ -1,7 +1,7 @@
|
|||||||
###############################################################################
|
###############################################################################
|
||||||
# BUILD STAGE
|
# BUILD STAGE
|
||||||
|
|
||||||
FROM golang:1.11-alpine
|
FROM golang:1.12-alpine
|
||||||
|
|
||||||
RUN set -x \
|
RUN set -x \
|
||||||
&& apk --no-cache --update add \
|
&& apk --no-cache --update add \
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ APP_NAME := $(IMAGE_NAME)
|
|||||||
|
|
||||||
CC_BINARIES := $(shell bash -c "echo -n $(APP_NAME)-{linux,freebsd,openbsd}-{386,amd64} $(APP_NAME)-linux-{arm,arm64}")
|
CC_BINARIES := $(shell bash -c "echo -n $(APP_NAME)-{linux,freebsd,openbsd}-{386,amd64} $(APP_NAME)-linux-{arm,arm64}")
|
||||||
|
|
||||||
GOLANGCI_LINT_VERSION := v1.11.2
|
GOLANGCI_LINT_VERSION := v1.15.0
|
||||||
|
|
||||||
VERSION_GO := $(shell go version)
|
VERSION_GO := $(shell go version)
|
||||||
VERSION_DATE := $(shell date -Ru)
|
VERSION_DATE := $(shell date -Ru)
|
||||||
@@ -59,10 +59,6 @@ test: vendor
|
|||||||
lint: vendor
|
lint: vendor
|
||||||
@$(MOD_OFF) golangci-lint run
|
@$(MOD_OFF) golangci-lint run
|
||||||
|
|
||||||
.PHONY: critic
|
|
||||||
critic: vendor
|
|
||||||
@$(MOD_OFF) gocritic check-project "$(ROOT_DIR)"
|
|
||||||
|
|
||||||
.PHONY: clean
|
.PHONY: clean
|
||||||
clean:
|
clean:
|
||||||
@git clean -xfd && \
|
@git clean -xfd && \
|
||||||
@@ -74,13 +70,9 @@ docker:
|
|||||||
@docker build --pull -t "$(IMAGE_NAME)" "$(ROOT_DIR)"
|
@docker build --pull -t "$(IMAGE_NAME)" "$(ROOT_DIR)"
|
||||||
|
|
||||||
.PHONY: prepare
|
.PHONY: prepare
|
||||||
prepare: install-lint install-critic
|
prepare: install-lint
|
||||||
|
|
||||||
.PHONY: install-lint
|
.PHONY: install-lint
|
||||||
install-lint:
|
install-lint:
|
||||||
@curl -sfL https://install.goreleaser.com/github.com/golangci/golangci-lint.sh \
|
@curl -sfL https://install.goreleaser.com/github.com/golangci/golangci-lint.sh \
|
||||||
| $(MOD_OFF) bash -s -- -b $(GOPATH)/bin $(GOLANGCI_LINT_VERSION)
|
| $(MOD_OFF) bash -s -- -b $(GOPATH)/bin $(GOLANGCI_LINT_VERSION)
|
||||||
|
|
||||||
.PHONY: install-critic
|
|
||||||
install-critic:
|
|
||||||
@$(MOD_OFF) go get -u github.com/go-critic/go-critic/...
|
|
||||||
|
|||||||
@@ -95,6 +95,11 @@ docker pull nineseconds/mtg:stable
|
|||||||
docker pull nineseconds/mtg:0.10
|
docker pull nineseconds/mtg:0.10
|
||||||
```
|
```
|
||||||
|
|
||||||
|
# Ansible role
|
||||||
|
|
||||||
|
You can find unofficial Ansible role for mtg here: https://github.com/rlex/ansible-role-mtg
|
||||||
|
Also, there is another project on Ansible Galaxy: https://galaxy.ansible.com/ivansible/lin_mtproxy
|
||||||
|
|
||||||
# Configuration
|
# Configuration
|
||||||
|
|
||||||
Basically, to run this tool you need to configure as less as possible.
|
Basically, to run this tool you need to configure as less as possible.
|
||||||
@@ -113,6 +118,10 @@ head -c 512 /dev/urandom | md5sum | cut -f 1 -d ' '
|
|||||||
|
|
||||||
## Secure mode
|
## Secure mode
|
||||||
|
|
||||||
|
_tl;dr - use secret mode for all new installation of proxy; only clients
|
||||||
|
with dd-secrets will be able to connect. This mode abuses attempts to
|
||||||
|
DPI MTPROTO traffic._
|
||||||
|
|
||||||
Secure mode is not the best name and of course, it creates a lot of
|
Secure mode is not the best name and of course, it creates a lot of
|
||||||
confusion. To explain what it means, we need to tell you some bits on
|
confusion. To explain what it means, we need to tell you some bits on
|
||||||
dd-secrets.
|
dd-secrets.
|
||||||
@@ -157,6 +166,11 @@ suspicion that some ISPs start to filter MTPROTO traffic. If they detect
|
|||||||
the IP address which acts as a proxy, they block it and no clients can
|
the IP address which acts as a proxy, they block it and no clients can
|
||||||
use this proxy. This is an attempt to prevent such a situation.
|
use this proxy. This is an attempt to prevent such a situation.
|
||||||
|
|
||||||
|
General rule of thumb: with all new installation of proxies I would
|
||||||
|
advise to go with secure mode by default. But please do remember that it
|
||||||
|
means that clients, which do not pass dd-prefix to their secrets, will
|
||||||
|
not be able to connect. *Secure mode works only with dd-prefixes!*
|
||||||
|
|
||||||
Oneliners to generate such secrets:
|
Oneliners to generate such secrets:
|
||||||
|
|
||||||
```console
|
```console
|
||||||
@@ -170,6 +184,15 @@ echo dd$(head -c 512 /dev/urandom | md5sum | cut -f 1 -d ' ')
|
|||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
|
## Antireplay cache
|
||||||
|
|
||||||
|
In order to prevent replay attacks, we have internal storage of first
|
||||||
|
frames messages for connected clients. These frames are generated
|
||||||
|
randomly by design and we have negligible possibility of duplication
|
||||||
|
(probability is 1/(2^64)) but it could be quite effective in order to
|
||||||
|
prevent replays.
|
||||||
|
|
||||||
|
|
||||||
## Environment variables
|
## Environment variables
|
||||||
|
|
||||||
It is possible to configure this tool using environment variables. You
|
It is possible to configure this tool using environment variables. You
|
||||||
@@ -177,7 +200,7 @@ can configure any flag but not secret or adtag. Here is the list of
|
|||||||
supported environment variables:
|
supported environment variables:
|
||||||
|
|
||||||
| Environment variable | Corresponding flags | Default value | Description |
|
| Environment variable | Corresponding flags | Default value | Description |
|
||||||
|--------------------------|------------------------|-----------------------------------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
|
|-------------------------------|-----------------------------|-----------------------------------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
|
||||||
| `MTG_DEBUG` | `-d`, `--debug` | `false` | Run in debug mode. Usually, you need to run in this mode only if you develop this tool or its maintainer is asking you to provide logs with such verbosity. |
|
| `MTG_DEBUG` | `-d`, `--debug` | `false` | Run in debug mode. Usually, you need to run in this mode only if you develop this tool or its maintainer is asking you to provide logs with such verbosity. |
|
||||||
| `MTG_VERBOSE` | `-v`, `--verbose` | `false` | Run in verbose mode. This is way less chatty than debug mode. |
|
| `MTG_VERBOSE` | `-v`, `--verbose` | `false` | Run in verbose mode. This is way less chatty than debug mode. |
|
||||||
| `MTG_IP` | `-b`, `--bind-ip` | `127.0.0.1` | Which IP should we bind to. As usual, `0.0.0.0` means that we want to listen on all interfaces. Also, 4 zeroes will bind to both IPv4 and IPv6. |
|
| `MTG_IP` | `-b`, `--bind-ip` | `127.0.0.1` | Which IP should we bind to. As usual, `0.0.0.0` means that we want to listen on all interfaces. Also, 4 zeroes will bind to both IPv4 and IPv6. |
|
||||||
@@ -198,6 +221,8 @@ supported environment variables:
|
|||||||
| `MTG_BUFFER_WRITE` | `-w`, `--write-buffer` | `65536` | The size of TCP write buffer in bytes. Write buffer is the buffer for messages which are going from client to Telegram. |
|
| `MTG_BUFFER_WRITE` | `-w`, `--write-buffer` | `65536` | The size of TCP write buffer in bytes. Write buffer is the buffer for messages which are going from client to Telegram. |
|
||||||
| `MTG_BUFFER_READ` | `-r`, `--read-buffer` | `131072` | The size of TCP read buffer in bytes. Read buffer is the buffer for messages from Telegram to client. |
|
| `MTG_BUFFER_READ` | `-r`, `--read-buffer` | `131072` | The size of TCP read buffer in bytes. Read buffer is the buffer for messages from Telegram to client. |
|
||||||
| `MTG_SECURE_ONLY` | `-s`, `--secure-only` | `false` | Support only clients with secure mode (i.e only clients with dd-secrets). |
|
| `MTG_SECURE_ONLY` | `-s`, `--secure-only` | `false` | Support only clients with secure mode (i.e only clients with dd-secrets). |
|
||||||
|
| `MTG_ANTIREPLAY_MAXSIZE` | `anti-replay-max-size` | `128` | Max size of antireplay cache in megabytes. |
|
||||||
|
| `MTG_ANTIREPLAY_EVICTIONTIME` | `anti-replay-eviction-time` | `168h` | Eviction time for antireplay cache entries. |
|
||||||
|
|
||||||
Usually you want to modify only read/write buffer sizes. If you feel
|
Usually you want to modify only read/write buffer sizes. If you feel
|
||||||
that proxy is slow, try to increase both sizes giving more priority to
|
that proxy is slow, try to increase both sizes giving more priority to
|
||||||
@@ -226,13 +251,13 @@ This tool will listen on port 3128 by default with the given secret.
|
|||||||
# One-line runner
|
# One-line runner
|
||||||
|
|
||||||
```console
|
```console
|
||||||
docker run --name mtg --restart=unless-stopped -p 3128:3128 -q 3129:3129 -d nineseconds/mtg:stable $(openssl rand -hex 16)
|
docker run --name mtg --restart=unless-stopped -p 3128:3128 -p 3129:3129 -d nineseconds/mtg:stable $(openssl rand -hex 16)
|
||||||
```
|
```
|
||||||
|
|
||||||
or in secret mode:
|
or in secret mode:
|
||||||
|
|
||||||
```console
|
```console
|
||||||
docker run --name mtg --restart=unless-stopped -p 3128:3128 -q 3129:3129 -d nineseconds/mtg:stable dd$(openssl rand -hex 16)
|
docker run --name mtg --restart=unless-stopped -p 3128:3128 -p 3129:3129 -d nineseconds/mtg:stable dd$(openssl rand -hex 16)
|
||||||
```
|
```
|
||||||
|
|
||||||
You will have this tool up and running on port 3128. Now curl
|
You will have this tool up and running on port 3128. Now curl
|
||||||
|
|||||||
@@ -0,0 +1,37 @@
|
|||||||
|
package antireplay
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/allegro/bigcache"
|
||||||
|
"github.com/juju/errors"
|
||||||
|
|
||||||
|
"github.com/9seconds/mtg/config"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Cache defines storage for obfuscated2 handshake frames.
|
||||||
|
type Cache struct {
|
||||||
|
cache *bigcache.BigCache
|
||||||
|
}
|
||||||
|
|
||||||
|
func (a Cache) Add(frame []byte) {
|
||||||
|
a.cache.Set(string(frame), nil) // nolint: errcheck
|
||||||
|
}
|
||||||
|
|
||||||
|
func (a Cache) Has(frame []byte) bool {
|
||||||
|
_, err := a.cache.Get(string(frame))
|
||||||
|
|
||||||
|
return err == nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewCache(config *config.Config) (Cache, error) {
|
||||||
|
cache, err := bigcache.NewBigCache(bigcache.Config{
|
||||||
|
Shards: 1024,
|
||||||
|
LifeWindow: config.AntiReplayEvictionTime,
|
||||||
|
Hasher: hasher{},
|
||||||
|
HardMaxCacheSize: config.AntiReplayMaxSize,
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
return Cache{}, errors.Annotate(err, "Cannot make cache")
|
||||||
|
}
|
||||||
|
|
||||||
|
return Cache{cache}, nil
|
||||||
|
}
|
||||||
@@ -0,0 +1,9 @@
|
|||||||
|
package antireplay
|
||||||
|
|
||||||
|
import "github.com/cespare/xxhash"
|
||||||
|
|
||||||
|
type hasher struct{}
|
||||||
|
|
||||||
|
func (h hasher) Sum64(value string) uint64 {
|
||||||
|
return xxhash.Sum64String(value)
|
||||||
|
}
|
||||||
+2
-1
@@ -4,6 +4,7 @@ import (
|
|||||||
"context"
|
"context"
|
||||||
"net"
|
"net"
|
||||||
|
|
||||||
|
"github.com/9seconds/mtg/antireplay"
|
||||||
"github.com/9seconds/mtg/config"
|
"github.com/9seconds/mtg/config"
|
||||||
"github.com/9seconds/mtg/mtproto"
|
"github.com/9seconds/mtg/mtproto"
|
||||||
"github.com/9seconds/mtg/wrappers"
|
"github.com/9seconds/mtg/wrappers"
|
||||||
@@ -11,4 +12,4 @@ import (
|
|||||||
|
|
||||||
// Init defines common method for initializing client connections.
|
// Init defines common method for initializing client connections.
|
||||||
type Init func(context.Context, context.CancelFunc, net.Conn, string,
|
type Init func(context.Context, context.CancelFunc, net.Conn, string,
|
||||||
*config.Config) (wrappers.Wrap, *mtproto.ConnectionOpts, error)
|
antireplay.Cache, *config.Config) (wrappers.Wrap, *mtproto.ConnectionOpts, error)
|
||||||
|
|||||||
+9
-1
@@ -7,6 +7,7 @@ import (
|
|||||||
|
|
||||||
"github.com/juju/errors"
|
"github.com/juju/errors"
|
||||||
|
|
||||||
|
"github.com/9seconds/mtg/antireplay"
|
||||||
"github.com/9seconds/mtg/config"
|
"github.com/9seconds/mtg/config"
|
||||||
"github.com/9seconds/mtg/mtproto"
|
"github.com/9seconds/mtg/mtproto"
|
||||||
"github.com/9seconds/mtg/obfuscated2"
|
"github.com/9seconds/mtg/obfuscated2"
|
||||||
@@ -18,7 +19,8 @@ const handshakeTimeout = 10 * time.Second
|
|||||||
// DirectInit initializes client connection for proxy which connects to
|
// DirectInit initializes client connection for proxy which connects to
|
||||||
// Telegram directly.
|
// Telegram directly.
|
||||||
func DirectInit(ctx context.Context, cancel context.CancelFunc, socket net.Conn,
|
func DirectInit(ctx context.Context, cancel context.CancelFunc, socket net.Conn,
|
||||||
connID string, conf *config.Config) (wrappers.Wrap, *mtproto.ConnectionOpts, error) {
|
connID string, antiReplayCache antireplay.Cache,
|
||||||
|
conf *config.Config) (wrappers.Wrap, *mtproto.ConnectionOpts, error) {
|
||||||
tcpSocket := socket.(*net.TCPConn)
|
tcpSocket := socket.(*net.TCPConn)
|
||||||
if err := tcpSocket.SetNoDelay(false); err != nil {
|
if err := tcpSocket.SetNoDelay(false); err != nil {
|
||||||
return nil, nil, errors.Annotate(err, "Cannot disable NO_DELAY to client socket")
|
return nil, nil, errors.Annotate(err, "Cannot disable NO_DELAY to client socket")
|
||||||
@@ -42,6 +44,12 @@ func DirectInit(ctx context.Context, cancel context.CancelFunc, socket net.Conn,
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, nil, errors.Annotate(err, "Cannot parse obfuscated frame")
|
return nil, nil, errors.Annotate(err, "Cannot parse obfuscated frame")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if antiReplayCache.Has([]byte(frame)) {
|
||||||
|
return nil, nil, errors.New("Replay attack is detected")
|
||||||
|
}
|
||||||
|
antiReplayCache.Add([]byte(frame))
|
||||||
|
|
||||||
connOpts.ConnectionProto = mtproto.ConnectionProtocolAny
|
connOpts.ConnectionProto = mtproto.ConnectionProtocolAny
|
||||||
connOpts.ClientAddr = conn.RemoteAddr()
|
connOpts.ClientAddr = conn.RemoteAddr()
|
||||||
|
|
||||||
|
|||||||
+4
-2
@@ -4,6 +4,7 @@ import (
|
|||||||
"context"
|
"context"
|
||||||
"net"
|
"net"
|
||||||
|
|
||||||
|
"github.com/9seconds/mtg/antireplay"
|
||||||
"github.com/9seconds/mtg/config"
|
"github.com/9seconds/mtg/config"
|
||||||
"github.com/9seconds/mtg/mtproto"
|
"github.com/9seconds/mtg/mtproto"
|
||||||
"github.com/9seconds/mtg/wrappers"
|
"github.com/9seconds/mtg/wrappers"
|
||||||
@@ -12,8 +13,9 @@ import (
|
|||||||
// MiddleInit initializes client connection for proxy which has to
|
// MiddleInit initializes client connection for proxy which has to
|
||||||
// support promoted channels, connect to Telegram middle proxies etc.
|
// support promoted channels, connect to Telegram middle proxies etc.
|
||||||
func MiddleInit(ctx context.Context, cancel context.CancelFunc, socket net.Conn,
|
func MiddleInit(ctx context.Context, cancel context.CancelFunc, socket net.Conn,
|
||||||
connID string, conf *config.Config) (wrappers.Wrap, *mtproto.ConnectionOpts, error) {
|
connID string, antiReplayCache antireplay.Cache,
|
||||||
conn, opts, err := DirectInit(ctx, cancel, socket, connID, conf)
|
conf *config.Config) (wrappers.Wrap, *mtproto.ConnectionOpts, error) {
|
||||||
|
conn, opts, err := DirectInit(ctx, cancel, socket, connID, antiReplayCache, conf)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, nil, err
|
return nil, nil, err
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"net"
|
"net"
|
||||||
"strconv"
|
"strconv"
|
||||||
|
"time"
|
||||||
|
|
||||||
"github.com/juju/errors"
|
"github.com/juju/errors"
|
||||||
statsd "gopkg.in/alexcesaro/statsd.v2"
|
statsd "gopkg.in/alexcesaro/statsd.v2"
|
||||||
@@ -31,6 +32,9 @@ type Config struct {
|
|||||||
PublicIPv6 net.IP
|
PublicIPv6 net.IP
|
||||||
StatsIP net.IP
|
StatsIP net.IP
|
||||||
|
|
||||||
|
AntiReplayMaxSize int
|
||||||
|
AntiReplayEvictionTime time.Duration
|
||||||
|
|
||||||
StatsD struct {
|
StatsD struct {
|
||||||
Addr net.Addr
|
Addr net.Addr
|
||||||
Prefix string
|
Prefix string
|
||||||
@@ -121,6 +125,7 @@ func NewConfig(debug, verbose bool, // nolint: gocyclo
|
|||||||
statsdIP, statsdNetwork, statsdPrefix, statsdTagsFormat string,
|
statsdIP, statsdNetwork, statsdPrefix, statsdTagsFormat string,
|
||||||
statsdTags map[string]string, prometheusPrefix string,
|
statsdTags map[string]string, prometheusPrefix string,
|
||||||
secureOnly bool,
|
secureOnly bool,
|
||||||
|
antiReplayMaxSize int, antiReplayEvictionTime time.Duration,
|
||||||
secret, adtag []byte) (*Config, error) {
|
secret, adtag []byte) (*Config, error) {
|
||||||
secureMode := secureOnly
|
secureMode := secureOnly
|
||||||
if bytes.HasPrefix(secret, []byte{0xdd}) && len(secret) == 17 {
|
if bytes.HasPrefix(secret, []byte{0xdd}) && len(secret) == 17 {
|
||||||
@@ -176,6 +181,8 @@ func NewConfig(debug, verbose bool, // nolint: gocyclo
|
|||||||
SecureMode: secureMode,
|
SecureMode: secureMode,
|
||||||
ReadBufferSize: int(readBufferSize),
|
ReadBufferSize: int(readBufferSize),
|
||||||
WriteBufferSize: int(writeBufferSize),
|
WriteBufferSize: int(writeBufferSize),
|
||||||
|
AntiReplayMaxSize: antiReplayMaxSize,
|
||||||
|
AntiReplayEvictionTime: antiReplayEvictionTime,
|
||||||
}
|
}
|
||||||
conf.Prometheus.Prefix = prometheusPrefix
|
conf.Prometheus.Prefix = prometheusPrefix
|
||||||
|
|
||||||
|
|||||||
@@ -21,7 +21,7 @@ func getGlobalIPv6() (net.IP, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func fetchIP(network string) (net.IP, error) {
|
func fetchIP(network string) (net.IP, error) {
|
||||||
dialer := &net.Dialer{DualStack: false}
|
dialer := &net.Dialer{FallbackDelay: -1}
|
||||||
client := &http.Client{
|
client := &http.Client{
|
||||||
Jar: nil,
|
Jar: nil,
|
||||||
Transport: &http.Transport{
|
Transport: &http.Transport{
|
||||||
|
|||||||
@@ -1,35 +1,30 @@
|
|||||||
module github.com/9seconds/mtg
|
module github.com/9seconds/mtg
|
||||||
|
|
||||||
|
replace github.com/golang/lint => github.com/golang/lint v0.0.0-20190227174305-8f45f776aaf1
|
||||||
|
|
||||||
require (
|
require (
|
||||||
github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc // indirect
|
github.com/OneOfOne/xxhash v1.2.5 // indirect
|
||||||
github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf // indirect
|
github.com/allegro/bigcache v1.2.0
|
||||||
github.com/beevik/ntp v0.2.0
|
github.com/beevik/ntp v0.2.0
|
||||||
github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973 // indirect
|
github.com/cespare/xxhash v1.1.0
|
||||||
github.com/davecgh/go-spew v1.1.1 // indirect
|
|
||||||
github.com/dustin/go-humanize v1.0.0
|
github.com/dustin/go-humanize v1.0.0
|
||||||
github.com/gofrs/uuid v3.1.0+incompatible
|
github.com/gofrs/uuid v3.2.0+incompatible
|
||||||
github.com/gogo/protobuf v1.1.1 // indirect
|
github.com/juju/errors v0.0.0-20190207033735-e65537c515d7
|
||||||
github.com/golang/protobuf v1.2.0 // indirect
|
github.com/juju/loggo v0.0.0-20190526231331-6e530bcce5d8 // indirect
|
||||||
github.com/juju/errors v0.0.0-20181012004132-a4583d0a56ea
|
github.com/juju/testing v0.0.0-20190429233213-dfc56b8c09fc // indirect
|
||||||
github.com/juju/loggo v0.0.0-20180524022052-584905176618 // indirect
|
|
||||||
github.com/juju/testing v0.0.0-20180920084828-472a3e8b2073 // indirect
|
|
||||||
github.com/kr/pretty v0.1.0 // indirect
|
github.com/kr/pretty v0.1.0 // indirect
|
||||||
github.com/matttproud/golang_protobuf_extensions v1.0.1 // indirect
|
github.com/pkg/errors v0.8.1 // indirect
|
||||||
github.com/pkg/errors v0.8.0 // indirect
|
github.com/prometheus/client_golang v0.9.4
|
||||||
github.com/pmezard/go-difflib v1.0.0 // indirect
|
github.com/spaolacci/murmur3 v1.1.0 // indirect
|
||||||
github.com/prometheus/client_golang v0.9.0
|
github.com/stretchr/testify v1.3.0
|
||||||
github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910 // indirect
|
go.uber.org/atomic v1.4.0 // indirect
|
||||||
github.com/prometheus/common v0.0.0-20181020173914-7e9e6cabbd39 // indirect
|
|
||||||
github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d // indirect
|
|
||||||
github.com/stretchr/testify v1.2.2
|
|
||||||
go.uber.org/atomic v1.3.2 // indirect
|
|
||||||
go.uber.org/multierr v1.1.0 // indirect
|
go.uber.org/multierr v1.1.0 // indirect
|
||||||
go.uber.org/zap v1.9.1
|
go.uber.org/zap v1.10.0
|
||||||
golang.org/x/net v0.0.0-20181102091132-c10e9556a7bc // indirect
|
golang.org/x/net v0.0.0-20190607181551-461777fb6f67 // indirect
|
||||||
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f // indirect
|
golang.org/x/sys v0.0.0-20190610200419-93c9922d18ae // indirect
|
||||||
gopkg.in/alecthomas/kingpin.v2 v2.2.6
|
gopkg.in/alecthomas/kingpin.v2 v2.2.6
|
||||||
gopkg.in/alexcesaro/statsd.v2 v2.0.0
|
gopkg.in/alexcesaro/statsd.v2 v2.0.0
|
||||||
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 // indirect
|
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 // indirect
|
||||||
gopkg.in/mgo.v2 v2.0.0-20180705113604-9856a29383ce // indirect
|
gopkg.in/mgo.v2 v2.0.0-20180705113604-9856a29383ce // indirect
|
||||||
gopkg.in/yaml.v2 v2.2.1 // indirect
|
gopkg.in/yaml.v2 v2.2.2 // indirect
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -1,27 +1,46 @@
|
|||||||
|
github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU=
|
||||||
|
github.com/OneOfOne/xxhash v1.2.5 h1:zl/OfRA6nftbBK9qTohYBJ5xvw6C/oNKizR7cZGl3cI=
|
||||||
|
github.com/OneOfOne/xxhash v1.2.5/go.mod h1:eZbhyaAYD41SGSSsnmcpxVoRiQ/MPUTjUdIIOT9Um7Q=
|
||||||
github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc h1:cAKDfWh5VpdgMhJosfJnn5/FoN2SRZ4p7fJNX58YPaU=
|
github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc h1:cAKDfWh5VpdgMhJosfJnn5/FoN2SRZ4p7fJNX58YPaU=
|
||||||
github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=
|
github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=
|
||||||
github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf h1:qet1QNfXsQxTZqLG4oE62mJzwPIB8+Tee4RNCL9ulrY=
|
github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf h1:qet1QNfXsQxTZqLG4oE62mJzwPIB8+Tee4RNCL9ulrY=
|
||||||
github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=
|
github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=
|
||||||
|
github.com/allegro/bigcache v1.2.0 h1:qDaE0QoF29wKBb3+pXFrJFy1ihe5OT9OiXhg1t85SxM=
|
||||||
|
github.com/allegro/bigcache v1.2.0/go.mod h1:Cb/ax3seSYIx7SuZdm2G2xzfwmv3TPSk2ucNfQESPXM=
|
||||||
github.com/beevik/ntp v0.2.0 h1:sGsd+kAXzT0bfVfzJfce04g+dSRfrs+tbQW8lweuYgw=
|
github.com/beevik/ntp v0.2.0 h1:sGsd+kAXzT0bfVfzJfce04g+dSRfrs+tbQW8lweuYgw=
|
||||||
github.com/beevik/ntp v0.2.0/go.mod h1:hIHWr+l3+/clUnF44zdK+CWW7fO8dR5cIylAQ76NRpg=
|
github.com/beevik/ntp v0.2.0/go.mod h1:hIHWr+l3+/clUnF44zdK+CWW7fO8dR5cIylAQ76NRpg=
|
||||||
github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973 h1:xJ4a3vCFaGF/jqvzLMYoU8P317H5OQ+Via4RmuPwCS0=
|
github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973 h1:xJ4a3vCFaGF/jqvzLMYoU8P317H5OQ+Via4RmuPwCS0=
|
||||||
github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q=
|
github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q=
|
||||||
|
github.com/beorn7/perks v1.0.0 h1:HWo1m869IqiPhD389kmkxeTalrjNbbJTC8LXupb+sl0=
|
||||||
|
github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8=
|
||||||
|
github.com/cespare/xxhash v1.1.0 h1:a6HrQnmkObjyL+Gs60czilIUGqrzKutQD6XZog3p+ko=
|
||||||
|
github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc=
|
||||||
|
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||||
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
||||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||||
github.com/dustin/go-humanize v1.0.0 h1:VSnTsYCnlFHaM2/igO1h6X3HA71jcobQuxemgkq4zYo=
|
github.com/dustin/go-humanize v1.0.0 h1:VSnTsYCnlFHaM2/igO1h6X3HA71jcobQuxemgkq4zYo=
|
||||||
github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk=
|
github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk=
|
||||||
github.com/gofrs/uuid v3.1.0+incompatible h1:q2rtkjaKT4YEr6E1kamy0Ha4RtepWlQBedyHx0uzKwA=
|
github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as=
|
||||||
github.com/gofrs/uuid v3.1.0+incompatible/go.mod h1:b2aQJv3Z4Fp6yNu3cdSllBxTCLRxnplIgP/c0N/04lM=
|
github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE=
|
||||||
|
github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY=
|
||||||
|
github.com/gofrs/uuid v3.2.0+incompatible h1:y12jRkkFxsd7GpqdSZ+/KCs/fJbqpEXSGd4+jfEaewE=
|
||||||
|
github.com/gofrs/uuid v3.2.0+incompatible/go.mod h1:b2aQJv3Z4Fp6yNu3cdSllBxTCLRxnplIgP/c0N/04lM=
|
||||||
github.com/gogo/protobuf v1.1.1 h1:72R+M5VuhED/KujmZVcIquuo8mBgX4oVda//DQb3PXo=
|
github.com/gogo/protobuf v1.1.1 h1:72R+M5VuhED/KujmZVcIquuo8mBgX4oVda//DQb3PXo=
|
||||||
github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ=
|
github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ=
|
||||||
github.com/golang/protobuf v1.2.0 h1:P3YflyNX/ehuJFLhxviNdFxQPkGK5cDcApsge1SqnvM=
|
github.com/golang/protobuf v1.2.0 h1:P3YflyNX/ehuJFLhxviNdFxQPkGK5cDcApsge1SqnvM=
|
||||||
github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
||||||
github.com/juju/errors v0.0.0-20181012004132-a4583d0a56ea h1:g2k+8WR7cHch4g0tBDhfiEvAp7fXxTNBiD1oC1Oxj3E=
|
github.com/golang/protobuf v1.3.1 h1:YF8+flBXS5eO826T4nzqPrxfhQThhXl0YzfuUPu4SBg=
|
||||||
github.com/juju/errors v0.0.0-20181012004132-a4583d0a56ea/go.mod h1:W54LbzXuIE0boCoNJfwqpmkKJ1O4TCTZMetAt6jGk7Q=
|
github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
||||||
github.com/juju/loggo v0.0.0-20180524022052-584905176618 h1:MK144iBQF9hTSwBW/9eJm034bVoG30IshVm688T2hi8=
|
github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU=
|
||||||
github.com/juju/loggo v0.0.0-20180524022052-584905176618/go.mod h1:vgyd7OREkbtVEN/8IXZe5Ooef3LQePvuBm9UWj6ZL8U=
|
github.com/juju/errors v0.0.0-20190207033735-e65537c515d7 h1:dMIPRDg6gi7CUp0Kj2+HxqJ5kTr1iAdzsXYIrLCNSmU=
|
||||||
github.com/juju/testing v0.0.0-20180920084828-472a3e8b2073 h1:WQM1NildKThwdP7qWrNAFGzp4ijNLw8RlgENkaI4MJs=
|
github.com/juju/errors v0.0.0-20190207033735-e65537c515d7/go.mod h1:W54LbzXuIE0boCoNJfwqpmkKJ1O4TCTZMetAt6jGk7Q=
|
||||||
github.com/juju/testing v0.0.0-20180920084828-472a3e8b2073/go.mod h1:63prj8cnj0tU0S9OHjGJn+b1h0ZghCndfnbQolrYTwA=
|
github.com/juju/loggo v0.0.0-20190526231331-6e530bcce5d8 h1:UUHMLvzt/31azWTN/ifGWef4WUqvXk0iRqdhdy/2uzI=
|
||||||
|
github.com/juju/loggo v0.0.0-20190526231331-6e530bcce5d8/go.mod h1:vgyd7OREkbtVEN/8IXZe5Ooef3LQePvuBm9UWj6ZL8U=
|
||||||
|
github.com/juju/testing v0.0.0-20190429233213-dfc56b8c09fc h1:5xUWujf6ES9tEpFHFzI34vcHm8U07lGjxAuJML3qwqM=
|
||||||
|
github.com/juju/testing v0.0.0-20190429233213-dfc56b8c09fc/go.mod h1:63prj8cnj0tU0S9OHjGJn+b1h0ZghCndfnbQolrYTwA=
|
||||||
|
github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w=
|
||||||
|
github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
|
||||||
|
github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc=
|
||||||
github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI=
|
github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI=
|
||||||
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
|
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
|
||||||
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
|
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
|
||||||
@@ -29,30 +48,58 @@ github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE=
|
|||||||
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
|
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
|
||||||
github.com/matttproud/golang_protobuf_extensions v1.0.1 h1:4hp9jkHxhMHkqkrB3Ix0jegS5sx/RkqARlsWZ6pIwiU=
|
github.com/matttproud/golang_protobuf_extensions v1.0.1 h1:4hp9jkHxhMHkqkrB3Ix0jegS5sx/RkqARlsWZ6pIwiU=
|
||||||
github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0=
|
github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0=
|
||||||
|
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
|
||||||
|
github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
|
||||||
|
github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U=
|
||||||
github.com/pkg/errors v0.8.0 h1:WdK/asTD0HN+q6hsWO3/vpuAkAr+tw6aNJNDFFf0+qw=
|
github.com/pkg/errors v0.8.0 h1:WdK/asTD0HN+q6hsWO3/vpuAkAr+tw6aNJNDFFf0+qw=
|
||||||
github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||||
|
github.com/pkg/errors v0.8.1 h1:iURUrRGxPUNPdy5/HRSm+Yj6okJ6UtLINN0Q9M4+h3I=
|
||||||
|
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||||
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
||||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||||
github.com/prometheus/client_golang v0.9.0 h1:tXuTFVHC03mW0D+Ua1Q2d1EAVqLTuggX50V0VLICCzY=
|
github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw=
|
||||||
github.com/prometheus/client_golang v0.9.0/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw=
|
github.com/prometheus/client_golang v0.9.4 h1:Y8E/JaaPbmFSW2V81Ab/d8yZFYQQGbni1b1jPcG9Y6A=
|
||||||
|
github.com/prometheus/client_golang v0.9.4/go.mod h1:oCXIBxdI62A4cR6aTRJCgetEjecSIYzOEaeAn4iYEpM=
|
||||||
github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910 h1:idejC8f05m9MGOsuEi1ATq9shN03HrxNkD/luQvxCv8=
|
github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910 h1:idejC8f05m9MGOsuEi1ATq9shN03HrxNkD/luQvxCv8=
|
||||||
github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo=
|
github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo=
|
||||||
github.com/prometheus/common v0.0.0-20181020173914-7e9e6cabbd39 h1:Cto4X6SVMWRPBkJ/3YHn1iDGDGc/Z+sW+AEMKHMVvN4=
|
github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90 h1:S/YWwWx/RA8rT8tKFRuGUZhuA90OyIBpPCXkcbwU8DE=
|
||||||
github.com/prometheus/common v0.0.0-20181020173914-7e9e6cabbd39/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro=
|
github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
|
||||||
|
github.com/prometheus/common v0.4.1 h1:K0MGApIoQvMw27RTdJkPbr3JZ7DNbtxQNyi5STVM6Kw=
|
||||||
|
github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4=
|
||||||
github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d h1:GoAlyOgbOEIFdaDqxJVlbOQ1DtGmZWs/Qau0hIlk+WQ=
|
github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d h1:GoAlyOgbOEIFdaDqxJVlbOQ1DtGmZWs/Qau0hIlk+WQ=
|
||||||
github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
|
github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
|
||||||
|
github.com/prometheus/procfs v0.0.2 h1:6LJUbpNm42llc4HRCuvApCSWB/WfhuNo9K98Q9sNGfs=
|
||||||
|
github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA=
|
||||||
|
github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo=
|
||||||
|
github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA=
|
||||||
|
github.com/spaolacci/murmur3 v1.1.0 h1:7c1g84S4BPRrfL5Xrdp6fOJ206sU9y293DDHaoy0bLI=
|
||||||
|
github.com/spaolacci/murmur3 v1.1.0/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA=
|
||||||
|
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||||
|
github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||||
github.com/stretchr/testify v1.2.2 h1:bSDNvY7ZPG5RlJ8otE/7V6gMiyenm9RtJ7IUVIAoJ1w=
|
github.com/stretchr/testify v1.2.2 h1:bSDNvY7ZPG5RlJ8otE/7V6gMiyenm9RtJ7IUVIAoJ1w=
|
||||||
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
|
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
|
||||||
go.uber.org/atomic v1.3.2 h1:2Oa65PReHzfn29GpvgsYwloV9AVFHPDk8tYxt2c2tr4=
|
github.com/stretchr/testify v1.3.0 h1:TivCn/peBQ7UY8ooIcPgZFpTNSz0Q2U6UrFlUfqbe0Q=
|
||||||
go.uber.org/atomic v1.3.2/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE=
|
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
|
||||||
|
go.uber.org/atomic v1.4.0 h1:cxzIVoETapQEqDhQu3QfnvXAV4AlzcvUCxkVUFw3+EU=
|
||||||
|
go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE=
|
||||||
go.uber.org/multierr v1.1.0 h1:HoEmRHQPVSqub6w2z2d2EOVs2fjyFRGyofhKuyDq0QI=
|
go.uber.org/multierr v1.1.0 h1:HoEmRHQPVSqub6w2z2d2EOVs2fjyFRGyofhKuyDq0QI=
|
||||||
go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0=
|
go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0=
|
||||||
go.uber.org/zap v1.9.1 h1:XCJQEf3W6eZaVwhRBof6ImoYGJSITeKWsyeh3HFu/5o=
|
go.uber.org/zap v1.10.0 h1:ORx85nbTijNz8ljznvCMR1ZBIPKFn3jQrag10X2AsuM=
|
||||||
go.uber.org/zap v1.9.1/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q=
|
go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q=
|
||||||
golang.org/x/net v0.0.0-20181102091132-c10e9556a7bc h1:ZMCWScCvS2fUVFw8LOpxyUUW5qiviqr4Dg5NdjLeiLU=
|
golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
|
||||||
golang.org/x/net v0.0.0-20181102091132-c10e9556a7bc/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||||
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f h1:wMNYb4v58l5UBM7MYRLPG6ZhfOqbKu7X5eyFl8ZhKvA=
|
golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||||
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
golang.org/x/net v0.0.0-20190607181551-461777fb6f67 h1:rJJxsykSlULwd2P2+pg/rtnwN2FrWp4IuCxOSyS0V00=
|
||||||
|
golang.org/x/net v0.0.0-20190607181551-461777fb6f67/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||||
|
golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||||
|
golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4 h1:YUO/7uOKsKeq9UokNS62b8FYywz3ker1l1vDZRCRefw=
|
||||||
|
golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||||
|
golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||||
|
golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||||
|
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||||
|
golang.org/x/sys v0.0.0-20190610200419-93c9922d18ae h1:xiXzMMEQdQcric9hXtr1QU98MHunKK7OTtsoU6bYWs4=
|
||||||
|
golang.org/x/sys v0.0.0-20190610200419-93c9922d18ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
|
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||||
gopkg.in/alecthomas/kingpin.v2 v2.2.6 h1:jMFz6MfLP0/4fUyZle81rXUoxOBFi19VUFKVDOQfozc=
|
gopkg.in/alecthomas/kingpin.v2 v2.2.6 h1:jMFz6MfLP0/4fUyZle81rXUoxOBFi19VUFKVDOQfozc=
|
||||||
gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw=
|
gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw=
|
||||||
gopkg.in/alexcesaro/statsd.v2 v2.0.0 h1:FXkZSCZIH17vLCO5sO2UucTHsH9pc+17F6pl3JVCwMc=
|
gopkg.in/alexcesaro/statsd.v2 v2.0.0 h1:FXkZSCZIH17vLCO5sO2UucTHsH9pc+17F6pl3JVCwMc=
|
||||||
@@ -64,3 +111,5 @@ gopkg.in/mgo.v2 v2.0.0-20180705113604-9856a29383ce h1:xcEWjVhvbDy+nHP67nPDDpbYrY
|
|||||||
gopkg.in/mgo.v2 v2.0.0-20180705113604-9856a29383ce/go.mod h1:yeKp02qBN3iKW1OzL3MGk2IdtZzaj7SFntXj72NppTA=
|
gopkg.in/mgo.v2 v2.0.0-20180705113604-9856a29383ce/go.mod h1:yeKp02qBN3iKW1OzL3MGk2IdtZzaj7SFntXj72NppTA=
|
||||||
gopkg.in/yaml.v2 v2.2.1 h1:mUhvW9EsL+naU5Q3cakzfE91YhliOondGd6ZrsDBHQE=
|
gopkg.in/yaml.v2 v2.2.1 h1:mUhvW9EsL+naU5Q3cakzfE91YhliOondGd6ZrsDBHQE=
|
||||||
gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||||
|
gopkg.in/yaml.v2 v2.2.2 h1:ZCJp+EgiOT7lHqUV2J862kp8Qj64Jo6az82+3Td9dZw=
|
||||||
|
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||||
|
|||||||
@@ -134,17 +134,26 @@ var (
|
|||||||
Envar("MTG_SECURE_ONLY").
|
Envar("MTG_SECURE_ONLY").
|
||||||
Bool()
|
Bool()
|
||||||
|
|
||||||
|
antiReplayMaxSize = app.Flag("anti-replay-max-size",
|
||||||
|
"Max size of antireplay cache in megabytes.").
|
||||||
|
Envar("MTG_ANTIREPLAY_MAXSIZE").
|
||||||
|
Default("128").
|
||||||
|
Int()
|
||||||
|
antiReplayEvictionTime = app.Flag("anti-replay-eviction-time",
|
||||||
|
"Eviction time period for obfuscated2 handshakes").
|
||||||
|
Envar("MTG_ANTIREPLAY_EVICTIONTIME").
|
||||||
|
Default("168h").
|
||||||
|
Duration()
|
||||||
|
|
||||||
secret = app.Arg("secret", "Secret of this proxy.").Required().HexBytes()
|
secret = app.Arg("secret", "Secret of this proxy.").Required().HexBytes()
|
||||||
adtag = app.Arg("adtag", "ADTag of the proxy.").HexBytes()
|
adtag = app.Arg("adtag", "ADTag of the proxy.").HexBytes()
|
||||||
)
|
)
|
||||||
|
|
||||||
func init() {
|
func main() { // nolint: gocyclo
|
||||||
rand.Seed(time.Now().UTC().UnixNano())
|
rand.Seed(time.Now().UTC().UnixNano())
|
||||||
app.Version(version)
|
app.Version(version)
|
||||||
app.HelpFlag.Short('h')
|
app.HelpFlag.Short('h')
|
||||||
}
|
|
||||||
|
|
||||||
func main() { // nolint: gocyclo
|
|
||||||
kingpin.MustParse(app.Parse(os.Args[1:]))
|
kingpin.MustParse(app.Parse(os.Args[1:]))
|
||||||
|
|
||||||
err := setRLimit()
|
err := setRLimit()
|
||||||
@@ -158,6 +167,7 @@ func main() { // nolint: gocyclo
|
|||||||
*bindPort, *publicIPv4Port, *publicIPv6Port, *statsPort, *statsdPort,
|
*bindPort, *publicIPv4Port, *publicIPv6Port, *statsPort, *statsdPort,
|
||||||
*statsdIP, *statsdNetwork, *statsdPrefix, *statsdTagsFormat,
|
*statsdIP, *statsdNetwork, *statsdPrefix, *statsdTagsFormat,
|
||||||
*statsdTags, *prometheusPrefix, *secureOnly,
|
*statsdTags, *prometheusPrefix, *secureOnly,
|
||||||
|
*antiReplayMaxSize, *antiReplayEvictionTime,
|
||||||
*secret, *adtag,
|
*secret, *adtag,
|
||||||
)
|
)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -204,7 +214,10 @@ func main() { // nolint: gocyclo
|
|||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
server := proxy.NewProxy(conf)
|
server, err := proxy.NewProxy(conf)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
if err := server.Serve(); err != nil {
|
if err := server.Serve(); err != nil {
|
||||||
zap.S().Fatalw("Server stopped", "error", err)
|
zap.S().Fatalw("Server stopped", "error", err)
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-6
@@ -23,11 +23,6 @@ var (
|
|||||||
ProxyRequestExtraSize = []byte{0x18, 0x00, 0x00, 0x00}
|
ProxyRequestExtraSize = []byte{0x18, 0x00, 0x00, 0x00}
|
||||||
ProxyRequestProxyTag = []byte{0xae, 0x26, 0x1e, 0xdb}
|
ProxyRequestProxyTag = []byte{0xae, 0x26, 0x1e, 0xdb}
|
||||||
|
|
||||||
HandshakeSenderPID []byte
|
|
||||||
HandshakePeerPID []byte
|
|
||||||
)
|
|
||||||
|
|
||||||
func init() {
|
|
||||||
HandshakeSenderPID = []byte("IPIPPRPDTIME")
|
HandshakeSenderPID = []byte("IPIPPRPDTIME")
|
||||||
HandshakePeerPID = []byte("IPIPPRPDTIME")
|
HandshakePeerPID = []byte("IPIPPRPDTIME")
|
||||||
}
|
)
|
||||||
|
|||||||
@@ -78,10 +78,10 @@ func TestFrameGenerateValid(t *testing.T) {
|
|||||||
}
|
}
|
||||||
for _, test := range validTests {
|
for _, test := range validTests {
|
||||||
t.Run(strconv.Itoa(int(test)), func(tt *testing.T) {
|
t.Run(strconv.Itoa(int(test)), func(tt *testing.T) {
|
||||||
frame := generateFrame(test)
|
frame := generateFrame(test) // nolint: scopelint
|
||||||
conType, err := frame.ConnectionType()
|
conType, err := frame.ConnectionType()
|
||||||
assert.Nil(t, err)
|
assert.Nil(tt, err)
|
||||||
assert.Equal(t, conType, test)
|
assert.Equal(tt, conType, test) // nolint: scopelint
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+11
-3
@@ -10,6 +10,7 @@ import (
|
|||||||
"github.com/juju/errors"
|
"github.com/juju/errors"
|
||||||
"go.uber.org/zap"
|
"go.uber.org/zap"
|
||||||
|
|
||||||
|
"github.com/9seconds/mtg/antireplay"
|
||||||
"github.com/9seconds/mtg/client"
|
"github.com/9seconds/mtg/client"
|
||||||
"github.com/9seconds/mtg/config"
|
"github.com/9seconds/mtg/config"
|
||||||
"github.com/9seconds/mtg/mtproto"
|
"github.com/9seconds/mtg/mtproto"
|
||||||
@@ -20,6 +21,7 @@ import (
|
|||||||
|
|
||||||
// Proxy is a core of this program.
|
// Proxy is a core of this program.
|
||||||
type Proxy struct {
|
type Proxy struct {
|
||||||
|
antiReplayCache antireplay.Cache
|
||||||
clientInit client.Init
|
clientInit client.Init
|
||||||
tg telegram.Telegram
|
tg telegram.Telegram
|
||||||
conf *config.Config
|
conf *config.Config
|
||||||
@@ -58,7 +60,7 @@ func (p *Proxy) accept(conn net.Conn) {
|
|||||||
|
|
||||||
log.Infow("Client connected", "addr", conn.RemoteAddr())
|
log.Infow("Client connected", "addr", conn.RemoteAddr())
|
||||||
|
|
||||||
clientConn, opts, err := p.clientInit(ctx, cancel, conn, connID, p.conf)
|
clientConn, opts, err := p.clientInit(ctx, cancel, conn, connID, p.antiReplayCache, p.conf)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Errorw("Cannot initialize client connection", "error", err)
|
log.Errorw("Cannot initialize client connection", "error", err)
|
||||||
return
|
return
|
||||||
@@ -150,10 +152,15 @@ func (p *Proxy) directPipe(src wrappers.StreamReadCloser, dst io.Writer, wait *s
|
|||||||
}
|
}
|
||||||
|
|
||||||
// NewProxy returns new proxy instance.
|
// NewProxy returns new proxy instance.
|
||||||
func NewProxy(conf *config.Config) *Proxy {
|
func NewProxy(conf *config.Config) (*Proxy, error) {
|
||||||
var clientInit client.Init
|
var clientInit client.Init
|
||||||
var tg telegram.Telegram
|
var tg telegram.Telegram
|
||||||
|
|
||||||
|
cache, err := antireplay.NewCache(conf)
|
||||||
|
if err != nil {
|
||||||
|
return nil, errors.Annotate(err, "Cannot make proxy")
|
||||||
|
}
|
||||||
|
|
||||||
if conf.UseMiddleProxy() {
|
if conf.UseMiddleProxy() {
|
||||||
clientInit = client.MiddleInit
|
clientInit = client.MiddleInit
|
||||||
tg = telegram.NewMiddleTelegram(conf)
|
tg = telegram.NewMiddleTelegram(conf)
|
||||||
@@ -163,8 +170,9 @@ func NewProxy(conf *config.Config) *Proxy {
|
|||||||
}
|
}
|
||||||
|
|
||||||
return &Proxy{
|
return &Proxy{
|
||||||
|
antiReplayCache: cache,
|
||||||
conf: conf,
|
conf: conf,
|
||||||
clientInit: clientInit,
|
clientInit: clientInit,
|
||||||
tg: tg,
|
tg: tg,
|
||||||
}
|
}, nil
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-1
@@ -12,7 +12,7 @@ import (
|
|||||||
func startServer(conf *config.Config, prometheusHandler http.Handler) {
|
func startServer(conf *config.Config, prometheusHandler http.Handler) {
|
||||||
log := zap.S().Named("stats")
|
log := zap.S().Named("stats")
|
||||||
|
|
||||||
http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
|
http.HandleFunc("/", func(w http.ResponseWriter, _ *http.Request) {
|
||||||
w.Header().Set("Content-Type", "application/json")
|
w.Header().Set("Content-Type", "application/json")
|
||||||
|
|
||||||
first, err := json.Marshal(GetStats())
|
first, err := json.Marshal(GetStats())
|
||||||
|
|||||||
@@ -5,12 +5,10 @@ import (
|
|||||||
"sync"
|
"sync"
|
||||||
)
|
)
|
||||||
|
|
||||||
var streamCipherBufferPool sync.Pool
|
var (
|
||||||
|
|
||||||
func init() {
|
|
||||||
streamCipherBufferPool = sync.Pool{
|
streamCipherBufferPool = sync.Pool{
|
||||||
New: func() interface{} {
|
New: func() interface{} {
|
||||||
return &bytes.Buffer{}
|
return &bytes.Buffer{}
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
)
|
||||||
|
|||||||
Reference in New Issue
Block a user