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

This commit is contained in:
9seconds
2020-02-04 11:23:40 +03:00
22 changed files with 328 additions and 108 deletions
+1 -1
View File
@@ -10,4 +10,4 @@ format = "colored-line-number"
[linters]
enable-all = true
disable = ["gochecknoglobals"]
disable = ["gochecknoglobals", "gomnd"]
+1 -1
View File
@@ -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}")
GOLANGCI_LINT_VERSION := v1.21.0
GOLANGCI_LINT_VERSION := v1.23.3
VERSION_GO := $(shell go version)
VERSION_DATE := $(shell date -Ru)
+5 -2
View File
@@ -159,6 +159,9 @@ by design and we have the negligible possibility of duplication
(probability is 1/(2^64)) but it could be quite effective to prevent
replays.
It is possible to disable this cache. To do that, please explicitly set
its size to 0.
## FakeTLS
@@ -191,8 +194,8 @@ supported environment variables:
| `MTG_STATSD_PREFIX` | `--statsd-prefix` | `mtg` | Which bucket prefix we should use. For example, if you set `mtg`, then metric `traffic.ingress` would be send as `mtg.traffic.ingress`. |
| `MTG_STATSD_TAGS_FORMAT` | `--statsd-tags-format` | | Which tags format we should use. By default, we are using default vanilla statsd tags format but if you want to send directly to InfluxDB or Datadog, please specify it there. Possible options are `influxdb` and `datadog`. |
| `MTG_STATSD_TAGS` | `--statsd-tags` | | Which tags should we send to statsd with our metrics. Please specify them as `key=value` pairs. |
| `MTG_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_WRITE` | `-w`, `--write-buffer` | `64KB` | The size of TCP write buffer in bytes. Write buffer is the buffer for messages which are going from client to Telegram. |
| `MTG_BUFFER_READ` | `-r`, `--read-buffer` | `128KB` | The size of TCP read buffer in bytes. Read buffer is the buffer for messages from Telegram to client. |
| `MTG_ANTIREPLAY_MAXSIZE` | `--anti-replay-max-size` | `128MB` | Max size of antireplay cache. |
| `MTG_CLOAK_PORT` | `--cloak-port` | `443` | Which port we should use to connect to cloaked host in FakeTLS mode. |
| `MTG_MULTIPLEX_PERCONNECTION` | `--multiplex-per-connection` | `50` | How many client connections can share a single Telegram connection in adtag mode |
+4 -4
View File
@@ -11,19 +11,19 @@ type cache struct {
data *fastcache.Cache
}
func (c *cache) AddObfuscated2(data []byte) {
func (c cache) AddObfuscated2(data []byte) {
c.data.Set(keyObfuscated2(data), nil)
}
func (c *cache) AddTLS(data []byte) {
func (c cache) AddTLS(data []byte) {
c.data.Set(keyTLS(data), nil)
}
func (c *cache) HasObfuscated2(data []byte) bool {
func (c cache) HasObfuscated2(data []byte) bool {
return c.data.Has(keyObfuscated2(data))
}
func (c *cache) HasTLS(data []byte) bool {
func (c cache) HasTLS(data []byte) bool {
return c.data.Has(keyTLS(data))
}
+13 -2
View File
@@ -8,13 +8,24 @@ import (
"github.com/9seconds/mtg/config"
)
type CacheInterface interface {
AddObfuscated2([]byte)
AddTLS([]byte)
HasObfuscated2([]byte) bool
HasTLS([]byte) bool
}
var (
Cache cache
Cache CacheInterface
initOnce sync.Once
)
func Init() {
initOnce.Do(func() {
Cache.data = fastcache.New(config.C.AntiReplayMaxSize)
if config.C.AntiReplayMaxSize == 0 {
Cache = nilCache{}
} else {
Cache = cache{fastcache.New(config.C.AntiReplayMaxSize)}
}
})
}
+8
View File
@@ -0,0 +1,8 @@
package antireplay
type nilCache struct{}
func (n nilCache) AddObfuscated2(_ []byte) {}
func (n nilCache) AddTLS(_ []byte) {}
func (n nilCache) HasObfuscated2(_ []byte) bool { return false }
func (n nilCache) HasTLS(_ []byte) bool { return false }
+3 -20
View File
@@ -8,7 +8,6 @@ import (
"io"
"net"
"strconv"
"sync"
"time"
"github.com/9seconds/mtg/antireplay"
@@ -101,6 +100,8 @@ func (c *ClientProtocol) tlsHandshake(conn io.ReadWriter) error {
}
func (c *ClientProtocol) cloakHost(clientConn io.ReadWriteCloser) {
stats.Stats.CloakedRequest()
addr := net.JoinHostPort(config.C.CloakHost, strconv.Itoa(config.C.CloakPort))
hostConn, err := net.Dial("tcp", addr)
@@ -108,25 +109,7 @@ func (c *ClientProtocol) cloakHost(clientConn io.ReadWriteCloser) {
return
}
defer hostConn.Close()
wg := &sync.WaitGroup{}
wg.Add(2)
go c.pipe(hostConn, clientConn, wg)
go c.pipe(clientConn, hostConn, wg)
wg.Wait()
}
func (c *ClientProtocol) pipe(dst io.WriteCloser, src io.Reader, wg *sync.WaitGroup) {
defer func() {
wg.Done()
dst.Close()
}()
io.Copy(dst, src) // nolint: errcheck
cloak(clientConn, hostConn)
}
func MakeClientProtocol() protocol.ClientProtocol {
+71
View File
@@ -0,0 +1,71 @@
package faketls
import (
"context"
"io"
"sync"
"time"
"github.com/9seconds/mtg/wrappers/rwc"
)
const (
cloakLastActivityTimeout = 5 * time.Second
cloakMaxTimeout = 30 * time.Second
)
func cloak(one, another io.ReadWriteCloser) {
defer func() {
one.Close()
another.Close()
}()
channelPing := make(chan struct{}, 1)
ctx, cancel := context.WithCancel(context.Background())
one = rwc.NewPing(ctx, one, channelPing)
another = rwc.NewPing(ctx, another, channelPing)
wg := &sync.WaitGroup{}
wg.Add(2)
go func() {
defer wg.Done()
io.Copy(one, another) // nolint: errcheck
}()
go func() {
defer wg.Done()
io.Copy(another, one) // nolint: errcheck
}()
go func() {
wg.Wait()
cancel()
}()
go func() {
lastActivityTimer := time.NewTimer(cloakLastActivityTimeout)
defer lastActivityTimer.Stop()
maxTimer := time.NewTimer(cloakMaxTimeout)
defer maxTimer.Stop()
for {
select {
case <-channelPing:
lastActivityTimer.Stop()
lastActivityTimer = time.NewTimer(cloakLastActivityTimeout)
case <-ctx.Done():
return
case <-lastActivityTimer.C:
cancel()
return
case <-maxTimer.C:
cancel()
return
}
}
}()
<-ctx.Done()
}
+9 -8
View File
@@ -3,18 +3,19 @@ module github.com/9seconds/mtg
go 1.13
require (
github.com/VictoriaMetrics/fastcache v1.5.2
github.com/VictoriaMetrics/fastcache v1.5.7
github.com/alecthomas/units v0.0.0-20190924025748-f65c72e2690d
github.com/beevik/ntp v0.2.0
github.com/cespare/xxhash/v2 v2.1.1 // indirect
github.com/prometheus/client_golang v1.2.1
github.com/prometheus/procfs v0.0.7 // indirect
github.com/golang/protobuf v1.3.3 // indirect
github.com/prometheus/client_golang v1.4.0
github.com/smira/go-statsd v1.3.1
go.uber.org/atomic v1.5.1 // indirect
go.uber.org/multierr v1.4.0 // indirect
go.uber.org/zap v1.13.0
golang.org/x/crypto v0.0.0-20191117063200-497ca9f6d64f
golang.org/x/net v0.0.0-20191119073136-fc4aabc6c914 // indirect
golang.org/x/sys v0.0.0-20191119060738-e882bf8e40c2
golang.org/x/tools v0.0.0-20191118222007-07fc4c7f2b98 // indirect
golang.org/x/crypto v0.0.0-20200128174031-69ecbb4d6d5d
golang.org/x/lint v0.0.0-20200130185559-910be7a94367 // indirect
golang.org/x/net v0.0.0-20200202094626-16171245cfb2 // indirect
golang.org/x/sys v0.0.0-20200202164722-d101bd2416d5
golang.org/x/tools v0.0.0-20200204074204-1cc6d1ef6c74 // indirect
gopkg.in/alecthomas/kingpin.v2 v2.2.6
)
+40 -34
View File
@@ -1,9 +1,7 @@
github.com/BurntSushi/toml v0.3.1 h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ=
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU=
github.com/OneOfOne/xxhash v1.2.5/go.mod h1:eZbhyaAYD41SGSSsnmcpxVoRiQ/MPUTjUdIIOT9Um7Q=
github.com/VictoriaMetrics/fastcache v1.5.2 h1:Erd8iIuBAL9kke8JzM4+WxkKuFkHh3ktwLanJvDgR44=
github.com/VictoriaMetrics/fastcache v1.5.2/go.mod h1:+jv9Ckb+za/P1ZRg/sulP5Ni1v49daAVERr0H3CuscE=
github.com/VictoriaMetrics/fastcache v1.5.7 h1:4y6y0G8PRzszQUYIQHHssv/jgPHAb5qQuuDNdCbyAgw=
github.com/VictoriaMetrics/fastcache v1.5.7/go.mod h1:ptDBkNMQI4RtmVo8VS/XwRY6RoTu1dAWCbrk+6WsEM8=
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-20190718012654-fb15b899a751 h1:JYp7IbQjafoB+tBA3gMyHYHrpOtNuDiK/uB5uXxq5wM=
@@ -24,11 +22,6 @@ github.com/beorn7/perks v1.0.0 h1:HWo1m869IqiPhD389kmkxeTalrjNbbJTC8LXupb+sl0=
github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8=
github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM=
github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw=
github.com/cespare/xxhash v1.1.0 h1:a6HrQnmkObjyL+Gs60czilIUGqrzKutQD6XZog3p+ko=
github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc=
github.com/cespare/xxhash/v2 v2.0.1-0.20190104013014-3767db7a7e18/go.mod h1:HD5P3vAIAh+Y2GAxg0PrPN1P8WkepXGpjbUPDHJqqKM=
github.com/cespare/xxhash/v2 v2.1.0 h1:yTUvW7Vhb89inJ+8irsUqiWjh8iT6sQPZiQzI6ReGkA=
github.com/cespare/xxhash/v2 v2.1.0/go.mod h1:dgIUBU3pDso/gPgZ1osOZ0iQf77oPR28Tjxl5dIMyVM=
github.com/cespare/xxhash/v2 v2.1.1 h1:6MnRN8NT7+YBpUIWxHtefFZOKTAPgGjpQSxqLNn0+qY=
github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
@@ -47,16 +40,18 @@ github.com/golang/protobuf v1.3.1 h1:YF8+flBXS5eO826T4nzqPrxfhQThhXl0YzfuUPu4SBg
github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
github.com/golang/protobuf v1.3.2 h1:6nsPYzhq5kReh6QImI3k5qWzO4PEbvbIW2cwSfR/6xs=
github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
github.com/golang/protobuf v1.3.3 h1:gyjaxf+svBWX08ZjK86iN9geUJF0H6gp2IRKX6Nf6/I=
github.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw=
github.com/golang/snappy v0.0.1 h1:Qgr9rKW7uDUkrbSmQeiDsGa8SjGyCOGtuasMWwvp2P4=
github.com/golang/snappy v0.0.1/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
github.com/google/go-cmp v0.3.0 h1:crn/baboCvb5fXaQ0IJ1SGTsTVrWpDsCWC8EGETZijY=
github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
github.com/google/go-cmp v0.3.1 h1:Xye71clBPdm5HgqGwUkwhbynsUJZhDbS20FvLhQ2izg=
github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
github.com/google/go-cmp v0.4.0 h1:xsAVV57WRhGj6kEIi8ReJzQlHHqcBYCElAvkovg3B/4=
github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI=
github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU=
github.com/json-iterator/go v1.1.7/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
github.com/json-iterator/go v1.1.9/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w=
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
@@ -81,33 +76,29 @@ github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZb
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw=
github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5FsnadC4Ky3P0J6CfImo=
github.com/prometheus/client_golang v1.2.1 h1:JnMpQc6ppsNgw9QPAGF6Dod479itz7lvlsMzzNayLOI=
github.com/prometheus/client_golang v1.2.1/go.mod h1:XMU6Z2MjaRKVu/dC1qupJI9SiNkDYzz3xecMgSW/F+U=
github.com/prometheus/client_golang v1.4.0 h1:YVIb/fVcOTMSqtqZWSKnHpSLBxu8DKgxq8z6RuBZwqI=
github.com/prometheus/client_golang v1.4.0/go.mod h1:e9GMxYsXl05ICDXkRhurwBS4Q3OK1iX/F2sw+iXX5zU=
github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910 h1:idejC8f05m9MGOsuEi1ATq9shN03HrxNkD/luQvxCv8=
github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo=
github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90 h1:S/YWwWx/RA8rT8tKFRuGUZhuA90OyIBpPCXkcbwU8DE=
github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4 h1:gQz4mCbXsO+nc9n1hCxHcGA3Zx3Eo+UHZoInFGUIXNM=
github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
github.com/prometheus/client_model v0.2.0 h1:uq5h0d+GuxiXLJLNABMgp2qUWDPiLvgCzz2dUR+/W/M=
github.com/prometheus/client_model v0.2.0/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/common v0.7.0 h1:L+1lyG48J1zAQXA3RBX/nG/B3gjlHq0zTt2tlbJLyCY=
github.com/prometheus/common v0.7.0/go.mod h1:DjGbpBbp5NYNiECxcL/VnbXCCaQpKd3tt26CguLLsqA=
github.com/prometheus/common v0.9.1 h1:KOMtN28tlbam3/7ZKEYKHhKoJZYYj3gMH4uc62x7X7U=
github.com/prometheus/common v0.9.1/go.mod h1:yhUN8i9wzaXS3w1O07YhxHEBxD+W35wd8bs7vj7HSQ4=
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.2 h1:6LJUbpNm42llc4HRCuvApCSWB/WfhuNo9K98Q9sNGfs=
github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA=
github.com/prometheus/procfs v0.0.5 h1:3+auTFlqw+ZaQYJARz6ArODtkaIwtvBTx3N2NehQlL8=
github.com/prometheus/procfs v0.0.5/go.mod h1:4A/X28fw3Fc593LaREMrKMqOKvUAntwMDaekg4FpcdQ=
github.com/prometheus/procfs v0.0.7 h1:RS5GAlMbnkWkhs4+bPocMTmGjYkuCY5djjqEDdXOhcQ=
github.com/prometheus/procfs v0.0.7/go.mod h1:7Qr8sr6344vo1JqZ6HhLceV9o3AJ1Ff+GxbHq6oeK9A=
github.com/prometheus/procfs v0.0.8 h1:+fpWZdT24pJBiqJdAwYBjPSk+5YmQzYNPYzQsdzLkt8=
github.com/prometheus/procfs v0.0.8/go.mod h1:7Qr8sr6344vo1JqZ6HhLceV9o3AJ1Ff+GxbHq6oeK9A=
github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo=
github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE=
github.com/smira/go-statsd v1.3.1 h1:JalGiHNdK7GqVAPpg7j0Kwp2jZrz/fCg/B4ZuNuBY2w=
github.com/smira/go-statsd v1.3.1/go.mod h1:1srXJ9/pbnN04G8f4F1jUzsGOnwkPKXciyqpewGlkC4=
github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA=
github.com/spaolacci/murmur3 v1.0.1-0.20190317074736-539464a789e9/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=
@@ -118,6 +109,8 @@ github.com/stretchr/testify v1.4.0 h1:2E4SXV/wtOkTonXsotYi4li6zVWxYlZuYNCXe9XRJy
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
go.uber.org/atomic v1.5.0 h1:OI5t8sDa1Or+q8AeE+yKeB/SDYioSHAgcVljj9JIETY=
go.uber.org/atomic v1.5.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ=
go.uber.org/atomic v1.5.1 h1:rsqfU5vBkVknbhUGbAUwQKR2H4ItV8tjJ+6kJX4cxHM=
go.uber.org/atomic v1.5.1/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ=
go.uber.org/multierr v1.3.0/go.mod h1:VgVr7evmIr6uPjLBxg28wmKNXyqE9akIJ5XnfpiKl+4=
go.uber.org/multierr v1.4.0 h1:f3WCSC2KzAcBXGATIxAB1E2XuCpNU255wNKZ505qi3E=
go.uber.org/multierr v1.4.0/go.mod h1:VgVr7evmIr6uPjLBxg28wmKNXyqE9akIJ5XnfpiKl+4=
@@ -129,18 +122,23 @@ golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnf
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2 h1:VklqNMn3ovrHsnt90PveolxSbWFaJdECFbxSq0Mqo2M=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20191117063200-497ca9f6d64f h1:kz4KIr+xcPUsI3VMoqWfPMvtnJ6MGfiVwsWSVzphMO4=
golang.org/x/crypto v0.0.0-20191117063200-497ca9f6d64f/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20200128174031-69ecbb4d6d5d h1:9FCpayM9Egr1baVnV1SX0H87m+XB0B8S0hAMi99X/3U=
golang.org/x/crypto v0.0.0-20200128174031-69ecbb4d6d5d/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/lint v0.0.0-20190930215403-16217165b5de h1:5hukYrvBGR8/eNkX5mdUezrA6JiaEZDtJb9Ei+1LlBs=
golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
golang.org/x/lint v0.0.0-20200130185559-910be7a94367 h1:0IiAsCRByjO2QjX7ZPkw5oU9x+n1YqRL802rjC0c3Aw=
golang.org/x/lint v0.0.0-20200130185559-910be7a94367/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY=
golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc=
golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee h1:WG0RUwxtNT4qqaXX3DPA8zHFNm/D9xaBpxzHt1WcA/E=
golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg=
golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190613194153-d28f0bde5980/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20191119073136-fc4aabc6c914 h1:MlY3mEfbnWGmUi4rtHOtNnnnN4UJRGSyLPx+DXA5Sq4=
golang.org/x/net v0.0.0-20191119073136-fc4aabc6c914/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20200202094626-16171245cfb2 h1:CCH4IOTTfewWjGOlSp+zGcjutRKlBEZQ6wTn8ozI/nI=
golang.org/x/net v0.0.0-20200202094626-16171245cfb2/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=
@@ -151,28 +149,36 @@ golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5h
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191010194322-b09406accb47 h1:/XfQ9z7ib8eEJX2hdgFTZJ/ntt0swNk5oYBziWeTCvY=
golang.org/x/sys v0.0.0-20191010194322-b09406accb47/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191119060738-e882bf8e40c2 h1:wAW1U21MfVN0sUipAD8952TBjGXMRHFKQugDlQ9RwwE=
golang.org/x/sys v0.0.0-20191119060738-e882bf8e40c2/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200122134326-e047566fdf82/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200202164722-d101bd2416d5 h1:LfCXLvNmTYH9kEmVgqbnsWfruoXZIrh4YBgqVHtDvw0=
golang.org/x/sys v0.0.0-20200202164722-d101bd2416d5/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
golang.org/x/tools v0.0.0-20191029041327-9cc4af7d6b2c/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20191029190741-b9c20aec41a5 h1:hKsoRgsbwY1NafxrwTs+k64bikrLBkAgPir1TNCj3Zs=
golang.org/x/tools v0.0.0-20191029190741-b9c20aec41a5/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20191118222007-07fc4c7f2b98 h1:tZwpOHmF1OEL9wJGSgBALnhFg/8VKjQTtctCX51GLNI=
golang.org/x/tools v0.0.0-20191118222007-07fc4c7f2b98/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20200130002326-2f3ba24bd6e7/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
golang.org/x/tools v0.0.0-20200204074204-1cc6d1ef6c74 h1:KW20qMcLRWuIgjdCpHFJbVZA7zsDKtFXPNcm7/eI5ZA=
golang.org/x/tools v0.0.0-20200204074204-1cc6d1ef6c74/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543 h1:E7g+9GITq07hpfrRu66IVDexMakfv52eLZ2CXBWiKr4=
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
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/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY=
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 h1:YR8cESwS4TdDjEe65xsg0ogRM/Nc3DYOhEAlW+xobZo=
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI=
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.2 h1:ZCJp+EgiOT7lHqUV2J862kp8Qj64Jo6az82+3Td9dZw=
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.2.5 h1:ymVxjfMaHvXD8RqPRmzHHsB3VvucivSkIAvJFDI5O3c=
gopkg.in/yaml.v2 v2.2.5/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
honnef.co/go/tools v0.0.1-2019.2.3 h1:3JgtbtFHMiCmsznwGVTUWbgGov+pVqnlf1dEJTNAXeM=
honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg=
+9
View File
@@ -4,6 +4,7 @@ import (
"fmt"
"math/rand"
"sync"
"time"
"go.uber.org/zap"
@@ -13,6 +14,8 @@ import (
"github.com/9seconds/mtg/protocol"
)
const connectionTTL = time.Hour
type connection struct {
conn conntypes.PacketReadWriteCloser
proxyConns map[string]*ProxyConn
@@ -31,6 +34,9 @@ type connection struct {
func (c *connection) run() {
defer c.Close()
ttl := time.NewTimer(connectionTTL)
defer ttl.Stop()
for {
select {
case <-c.channelDone:
@@ -39,6 +45,9 @@ func (c *connection) run() {
}
return
case <-ttl.C:
c.logger.Debugw("Closing connection by TTL")
c.Close()
case resp := <-c.channelRead:
if channel, ok := c.proxyConns[string(resp.ConnID[:])]; ok {
if resp.Type == rpc.ProxyResponseTypeCloseExt {
+4 -2
View File
@@ -30,8 +30,7 @@ func (p *Proxy) Serve(listener net.Listener) {
case <-doneChan:
return
default:
p.Logger.Errorw("Cannot allocate incoming connection", "error", err)
continue
p.Logger.Fatalw("Cannot allocate incoming connection", "error", err)
}
}
@@ -42,6 +41,7 @@ func (p *Proxy) Serve(listener net.Listener) {
func (p *Proxy) accept(conn net.Conn) {
defer func() {
conn.Close()
if err := recover(); err != nil {
stats.Stats.Crash()
p.Logger.Errorw("Crash of accept handler", "error", err)
@@ -69,7 +69,9 @@ func (p *Proxy) accept(conn net.Conn) {
clientConn, err := clientProtocol.Handshake(clientConn)
if err != nil {
stats.Stats.AuthenticationFailed()
logger.Warnw("Cannot perform client handshake", "error", err)
return
}
+22 -12
View File
@@ -11,48 +11,58 @@
# export MTG_IMAGENAME="nineseconds/mtg:latest"
# curl -sfL --compressed https://raw.githubusercontent.com/9seconds/mtg/master/run.sh | bash
set -eu -o pipefail
set -eu
export XDG_CONFIG_HOME="${XDG_CONFIG_HOME:-$HOME/.config}"
export MTG_CONFIG="${MTG_CONFIG:-$XDG_CONFIG_HOME/mtg}"
if ! [ -x "$(command -v docker)" ]; then
echo 'Error: docker is not installed.' >&2
exit 1
fi
id -Gn "$USER" | grep -qw 'docker' > /dev/null
if [ $? -eq 0 ] || [ "$(id -u)" -eq '0' ]; then
DOCKER_CMD="$(command -v docker)"
else
DOCKER_CMD="sudo $(command -v docker)"
fi
mkdir -p "$MTG_CONFIG" || true
MTG_SECRET="$MTG_CONFIG/secret"
MTG_ENV="$MTG_CONFIG/env"
if [ ! -f "$MTG_ENV" ]; then
MTG_IMAGENAME="${MTG_IMAGENAME:-nineseconds/mtg:latest}"
MTG_IMAGENAME="${MTG_IMAGENAME:-nineseconds/mtg:stable}"
MTG_PORT="${MTG_PORT:-3128}"
MTG_CONTAINER="${MTG_CONTAINER:-mtg}"
echo "MTG_IMAGENAME=${MTG_IMAGENAME}" > "$MTG_ENV"
echo "MTG_PORT=${MTG_PORT}" >> "$MTG_ENV"
echo "MTG_CONTAINER=${MTG_CONTAINER}" >> "$MTG_ENV"
echo "MTG_IMAGENAME=$MTG_IMAGENAME" > "$MTG_ENV"
echo "MTG_PORT=$MTG_PORT" >> "$MTG_ENV"
echo "MTG_CONTAINER=$MTG_CONTAINER" >> "$MTG_ENV"
fi
set -a
source "$MTG_ENV"
set +a
docker pull "$MTG_IMAGENAME"
$DOCKER_CMD pull "$MTG_IMAGENAME" > /dev/null
if [ ! -f "$MTG_SECRET" ]; then
docker run \
$DOCKER_CMD run \
--rm \
"$MTG_IMAGENAME" \
generate-secret tls -c "$(openssl rand -hex 16).com" \
> "$MTG_SECRET"
fi
echo
echo "Proxy secret is $(cat "$MTG_SECRET"). Port is $MTG_PORT."
echo
docker ps --filter "Name=$MTG_CONTAINER" -aq | xargs -r docker rm -fv
docker run \
$DOCKER_CMD ps --filter "Name=$MTG_CONTAINER" -aq | xargs -r $DOCKER_CMD rm -fv > /dev/null
$DOCKER_CMD run \
-d \
--restart=unless-stopped \
--name "$MTG_CONTAINER" \
--ulimit nofile=51200:51200 \
-p "$MTG_PORT:3128" \
"$MTG_IMAGENAME" run "$(cat "$MTG_SECRET")"
"$MTG_IMAGENAME" run "$(cat "$MTG_SECRET")" > /dev/null
+10
View File
@@ -38,6 +38,14 @@ type ReplayDetectedInterface interface {
ReplayDetected()
}
type AuthenticationFailedInterface interface {
AuthenticationFailed()
}
type CloakedRequestInterface interface {
CloakedRequest()
}
type Interface interface {
IngressTrafficInterface
EgressTrafficInterface
@@ -47,4 +55,6 @@ type Interface interface {
TelegramDisconnectedInterface
CrashInterface
ReplayDetectedInterface
AuthenticationFailedInterface
CloakedRequestInterface
}
+12
View File
@@ -55,3 +55,15 @@ func (m multiStats) ReplayDetected() {
go m[i].ReplayDetected()
}
}
func (m multiStats) AuthenticationFailed() {
for i := range m {
go m[i].AuthenticationFailed()
}
}
func (m multiStats) CloakedRequest() {
for i := range m {
go m[i].CloakedRequest()
}
}
+27 -5
View File
@@ -13,11 +13,13 @@ import (
)
type statsPrometheus struct {
connections *prometheus.GaugeVec
telegramConnections *prometheus.GaugeVec
traffic *prometheus.GaugeVec
crashes prometheus.Counter
replayAttacks prometheus.Counter
connections *prometheus.GaugeVec
telegramConnections *prometheus.GaugeVec
traffic *prometheus.GaugeVec
crashes prometheus.Counter
replayAttacks prometheus.Counter
authenticationFailed prometheus.Counter
cloakedRequests prometheus.Counter
}
func (s *statsPrometheus) IngressTraffic(traffic int) {
@@ -87,6 +89,14 @@ func (s *statsPrometheus) ReplayDetected() {
s.replayAttacks.Inc()
}
func (s *statsPrometheus) AuthenticationFailed() {
s.authenticationFailed.Inc()
}
func (s *statsPrometheus) CloakedRequest() {
s.cloakedRequests.Inc()
}
func newStatsPrometheus(mux *http.ServeMux) Interface {
registry := prometheus.NewPedanticRegistry()
@@ -116,6 +126,16 @@ func newStatsPrometheus(mux *http.ServeMux) Interface {
Name: "replay_attacks",
Help: "How many replay attacks were prevented.",
}),
authenticationFailed: prometheus.NewCounter(prometheus.CounterOpts{
Namespace: config.C.StatsNamespace,
Name: "authentication_failed",
Help: "How many authentication failed events we've seen.",
}),
cloakedRequests: prometheus.NewCounter(prometheus.CounterOpts{
Namespace: config.C.StatsNamespace,
Name: "cloaked_requests",
Help: "How many requests were proxified during cloaking.",
}),
}
registry.MustRegister(instance.connections)
@@ -123,6 +143,8 @@ func newStatsPrometheus(mux *http.ServeMux) Interface {
registry.MustRegister(instance.traffic)
registry.MustRegister(instance.crashes)
registry.MustRegister(instance.replayAttacks)
registry.MustRegister(instance.authenticationFailed)
registry.MustRegister(instance.cloakedRequests)
handler := promhttp.HandlerFor(registry, promhttp.HandlerOpts{})
mux.Handle("/", handler)
+8
View File
@@ -137,6 +137,14 @@ func (s *statsStatsd) ReplayDetected() {
s.gauge("replay_attacks", 1)
}
func (s *statsStatsd) AuthenticationFailed() {
s.gauge("authentication_failed", 1)
}
func (s *statsStatsd) CloakedRequest() {
s.gauge("cloaked_requests", 1)
}
func (s *statsStatsd) gauge(metric string, value int64, tags ...*statsStatsdTag) {
key, tagList := s.prepareVals(metric, tags)
s.initGauge(metric, key, tagList)
+24 -14
View File
@@ -1,10 +1,12 @@
package telegram
import (
"fmt"
"errors"
"math/rand"
"net"
"go.uber.org/zap"
"github.com/9seconds/mtg/conntypes"
"github.com/9seconds/mtg/utils"
"github.com/9seconds/mtg/wrappers/stream"
@@ -12,10 +14,11 @@ import (
type baseTelegram struct {
dialer net.Dialer
logger *zap.SugaredLogger
secret []byte
v4DefaultDC conntypes.DC
V6DefaultDC conntypes.DC
v6DefaultDC conntypes.DC
v4Addresses map[conntypes.DC][]string
v6Addresses map[conntypes.DC][]string
}
@@ -26,25 +29,32 @@ func (b *baseTelegram) Secret() []byte {
func (b *baseTelegram) dial(dc conntypes.DC,
protocol conntypes.ConnectionProtocol) (conntypes.StreamReadWriteCloser, error) {
addr := ""
addresses := make([]string, 0, 2)
switch protocol {
case conntypes.ConnectionProtocolIPv4:
addr = b.chooseAddress(b.v4Addresses, dc, b.v4DefaultDC)
default:
addr = b.chooseAddress(b.v6Addresses, dc, b.V6DefaultDC)
if protocol&conntypes.ConnectionProtocolIPv6 != 0 {
addresses = append(addresses, b.chooseAddress(b.v6Addresses, dc, b.v6DefaultDC))
}
conn, err := b.dialer.Dial("tcp", addr)
if err != nil {
return nil, fmt.Errorf("dial has failed: %w", err)
if protocol&conntypes.ConnectionProtocolIPv4 != 0 {
addresses = append(addresses, b.chooseAddress(b.v4Addresses, dc, b.v4DefaultDC))
}
if err := utils.InitTCP(conn); err != nil {
return nil, fmt.Errorf("cannot initialize tcp socket: %w", err)
for _, addr := range addresses {
conn, err := b.dialer.Dial("tcp", addr)
if err != nil {
b.logger.Infow("Cannot dial to Telegram", "address", addr, "error", err)
continue
}
if err := utils.InitTCP(conn); err != nil {
b.logger.Infow("Cannot initialize TCP socket", "address", addr, "error", err)
continue
}
return stream.NewTelegramConn(dc, conn), nil
}
return stream.NewTelegramConn(dc, conn), nil
return nil, errors.New("cannot dial to the chosen DC")
}
func (b *baseTelegram) chooseAddress(addresses map[conntypes.DC][]string,
+1 -1
View File
@@ -37,5 +37,5 @@ func (d *directTelegram) Dial(dc conntypes.DC,
dc = conntypes.DCDefaultIdx
}
return d.baseTelegram.dial(dc-1, protocol)
return d.baseTelegram.dial(dc-1, conntypes.ConnectionProtocolAny)
}
+7 -1
View File
@@ -4,6 +4,8 @@ import (
"net"
"sync"
"time"
"go.uber.org/zap"
)
const telegramDialTimeout = 10 * time.Second
@@ -17,11 +19,14 @@ var (
func Init() {
initOnce.Do(func() {
logger := zap.S().Named("telegram")
Direct = &directTelegram{
baseTelegram: baseTelegram{
dialer: net.Dialer{Timeout: telegramDialTimeout},
logger: logger.Named("direct"),
v4DefaultDC: directV4DefaultIdx,
V6DefaultDC: directV6DefaultIdx,
v6DefaultDC: directV6DefaultIdx,
v4Addresses: directV4Addresses,
v6Addresses: directV6Addresses,
},
@@ -30,6 +35,7 @@ func Init() {
tg := &middleTelegram{
baseTelegram: baseTelegram{
dialer: net.Dialer{Timeout: telegramDialTimeout},
logger: logger.Named("middle"),
},
}
if err := tg.update(); err != nil {
+1 -1
View File
@@ -45,7 +45,7 @@ func (m *middleTelegram) update() error {
m.mutex.Lock()
m.secret = secret
m.v4DefaultDC = v4DefaultDC
m.V6DefaultDC = v6DefaultDC
m.v6DefaultDC = v6DefaultDC
m.v4Addresses = v4Addresses
m.v6Addresses = v6Addresses
m.mutex.Unlock()
+48
View File
@@ -0,0 +1,48 @@
package rwc
import (
"context"
"io"
)
type wrapperPing struct {
parent io.ReadWriteCloser
ctx context.Context
channelPing chan<- struct{}
}
func (w *wrapperPing) Read(p []byte) (int, error) {
n, err := w.parent.Read(p)
if err == nil {
select {
case <-w.ctx.Done():
case w.channelPing <- struct{}{}:
}
}
return n, err
}
func (w *wrapperPing) Write(p []byte) (int, error) {
n, err := w.parent.Write(p)
if err == nil {
select {
case <-w.ctx.Done():
case w.channelPing <- struct{}{}:
}
}
return n, err
}
func (w *wrapperPing) Close() error {
return w.parent.Close()
}
func NewPing(ctx context.Context, parent io.ReadWriteCloser, channelPing chan<- struct{}) io.ReadWriteCloser {
return &wrapperPing{
parent: parent,
ctx: ctx,
channelPing: channelPing,
}
}