Merge pull request #216 from 9seconds/configure-fallback-dc

Add configuration option allow-fallback-on-unknown-dc
This commit is contained in:
Sergey Arkhipov
2021-10-04 15:09:47 +03:00
committed by GitHub
7 changed files with 66 additions and 36 deletions
+13
View File
@@ -56,6 +56,19 @@ domain-fronting-port = 443
# time range of this parameter. # time range of this parameter.
tolerate-time-skewness = "5s" tolerate-time-skewness = "5s"
# Telegram has a concept of DC. You can think about DC as a number of a cluster
# with a certain purpose. Some clusters serve media, some - messages, some rule
# channels and so on. But sometimes unknown DC number is requested by client.
# It could be a bug or some global reconfiguration of the Telegram.
#
# By default, proxy rejects such requests. But it is also possible to fallback
# this request to any DC. Telegram works in a way that any DC is able to serve
# any request but sacrificing a latency.
#
# If this setting is disabled (default), mtg will reject a connection.
# Otherwise, chose a new DC.
allow-fallback-on-unknown-dc = false
# network defines different network-related settings # network defines different network-related settings
[network] [network]
# please be aware that mtg needs to do some external requests. For # please be aware that mtg needs to do some external requests. For
+2
View File
@@ -184,6 +184,8 @@ func runProxy(conf *config.Config, version string) error {
BufferSize: conf.TCPBuffer.Get(mtglib.DefaultBufferSize), BufferSize: conf.TCPBuffer.Get(mtglib.DefaultBufferSize),
DomainFrontingPort: conf.DomainFrontingPort.Get(mtglib.DefaultDomainFrontingPort), DomainFrontingPort: conf.DomainFrontingPort.Get(mtglib.DefaultDomainFrontingPort),
PreferIP: conf.PreferIP.Get(mtglib.DefaultPreferIP), PreferIP: conf.PreferIP.Get(mtglib.DefaultPreferIP),
AllowFallbackOnUnknownDC: conf.AllowFallbackOnUnknownDC.Get(false),
} }
proxy, err := mtglib.NewProxy(opts) proxy, err := mtglib.NewProxy(opts)
+1
View File
@@ -71,6 +71,7 @@ func (s *SimpleRun) Run(cli *CLI, version string) error { // nolint: cyclop
} }
conf.Debug.Value = s.Debug conf.Debug.Value = s.Debug
conf.AllowFallbackOnUnknownDC.Value = true
conf.Defense.AntiReplay.Enabled.Value = true conf.Defense.AntiReplay.Enabled.Value = true
if err := conf.Validate(); err != nil { if err := conf.Validate(); err != nil {
+10 -9
View File
@@ -9,15 +9,16 @@ import (
) )
type Config struct { type Config struct {
Debug TypeBool `json:"debug"` Debug TypeBool `json:"debug"`
Secret mtglib.Secret `json:"secret"` AllowFallbackOnUnknownDC TypeBool `json:"allowFallbackOnUnknownDc"`
BindTo TypeHostPort `json:"bindTo"` Secret mtglib.Secret `json:"secret"`
TCPBuffer TypeBytes `json:"tcpBuffer"` BindTo TypeHostPort `json:"bindTo"`
PreferIP TypePreferIP `json:"preferIp"` TCPBuffer TypeBytes `json:"tcpBuffer"`
DomainFrontingPort TypePort `json:"domainFrontingPort"` PreferIP TypePreferIP `json:"preferIp"`
TolerateTimeSkewness TypeDuration `json:"tolerateTimeSkewness"` DomainFrontingPort TypePort `json:"domainFrontingPort"`
Concurrency TypeConcurrency `json:"concurrency"` TolerateTimeSkewness TypeDuration `json:"tolerateTimeSkewness"`
Defense struct { Concurrency TypeConcurrency `json:"concurrency"`
Defense struct {
AntiReplay struct { AntiReplay struct {
Enabled TypeBool `json:"enabled"` Enabled TypeBool `json:"enabled"`
MaxSize TypeBytes `json:"maxSize"` MaxSize TypeBytes `json:"maxSize"`
+10 -9
View File
@@ -9,15 +9,16 @@ import (
) )
type tomlConfig struct { type tomlConfig struct {
Debug bool `toml:"debug" json:"debug,omitempty"` Debug bool `toml:"debug" json:"debug,omitempty"`
Secret string `toml:"secret" json:"secret"` AllowFallbackOnUnknownDC bool `toml:"allow-fallback-on-unknown-dc" json:"allowFallbackOnUnknownDc,omitempty"`
BindTo string `toml:"bind-to" json:"bindTo"` Secret string `toml:"secret" json:"secret"`
TCPBuffer string `toml:"tcp-buffer" json:"tcpBuffer,omitempty"` BindTo string `toml:"bind-to" json:"bindTo"`
PreferIP string `toml:"prefer-ip" json:"preferIp,omitempty"` TCPBuffer string `toml:"tcp-buffer" json:"tcpBuffer,omitempty"`
DomainFrontingPort uint `toml:"domain-fronting-port" json:"domainFrontingPort,omitempty"` PreferIP string `toml:"prefer-ip" json:"preferIp,omitempty"`
TolerateTimeSkewness string `toml:"tolerate-time-skewness" json:"tolerateTimeSkewness,omitempty"` DomainFrontingPort uint `toml:"domain-fronting-port" json:"domainFrontingPort,omitempty"`
Concurrency uint `toml:"concurrency" json:"concurrency,omitempty"` TolerateTimeSkewness string `toml:"tolerate-time-skewness" json:"tolerateTimeSkewness,omitempty"`
Defense struct { Concurrency uint `toml:"concurrency" json:"concurrency,omitempty"`
Defense struct {
AntiReplay struct { AntiReplay struct {
Enabled bool `toml:"enabled" json:"enabled,omitempty"` Enabled bool `toml:"enabled" json:"enabled,omitempty"`
MaxSize string `toml:"max-size" json:"maxSize,omitempty"` MaxSize string `toml:"max-size" json:"maxSize,omitempty"`
+20 -18
View File
@@ -23,11 +23,12 @@ type Proxy struct {
ctxCancel context.CancelFunc ctxCancel context.CancelFunc
streamWaitGroup sync.WaitGroup streamWaitGroup sync.WaitGroup
tolerateTimeSkewness time.Duration allowFallbackOnUnknownDC bool
bufferSize int tolerateTimeSkewness time.Duration
domainFrontingPort int bufferSize int
workerPool *ants.PoolWithFunc domainFrontingPort int
telegram *telegram.Telegram workerPool *ants.PoolWithFunc
telegram *telegram.Telegram
secret Secret secret Secret
network Network network Network
@@ -209,7 +210,7 @@ func (p *Proxy) doObfuscated2Handshake(ctx *streamContext) error {
func (p *Proxy) doTelegramCall(ctx *streamContext) error { func (p *Proxy) doTelegramCall(ctx *streamContext) error {
dc := ctx.dc dc := ctx.dc
if !p.telegram.IsKnownDC(dc) { if p.allowFallbackOnUnknownDC && !p.telegram.IsKnownDC(dc) {
dc = p.telegram.GetFallbackDC() dc = p.telegram.GetFallbackDC()
ctx.logger = ctx.logger.BindInt("fallback_dc", dc) ctx.logger = ctx.logger.BindInt("fallback_dc", dc)
@@ -285,18 +286,19 @@ func NewProxy(opts ProxyOpts) (*Proxy, error) {
ctx, cancel := context.WithCancel(context.Background()) ctx, cancel := context.WithCancel(context.Background())
proxy := &Proxy{ proxy := &Proxy{
ctx: ctx, ctx: ctx,
ctxCancel: cancel, ctxCancel: cancel,
secret: opts.Secret, secret: opts.Secret,
network: opts.Network, network: opts.Network,
antiReplayCache: opts.AntiReplayCache, antiReplayCache: opts.AntiReplayCache,
ipBlocklist: opts.IPBlocklist, ipBlocklist: opts.IPBlocklist,
eventStream: opts.EventStream, eventStream: opts.EventStream,
logger: opts.getLogger("proxy"), logger: opts.getLogger("proxy"),
domainFrontingPort: opts.getDomainFrontingPort(), domainFrontingPort: opts.getDomainFrontingPort(),
tolerateTimeSkewness: opts.getTolerateTimeSkewness(), tolerateTimeSkewness: opts.getTolerateTimeSkewness(),
bufferSize: opts.getBufferSize(), bufferSize: opts.getBufferSize(),
telegram: tg, allowFallbackOnUnknownDC: opts.AllowFallbackOnUnknownDC,
telegram: tg,
} }
pool, err := ants.NewPoolWithFunc(opts.getConcurrency(), pool, err := ants.NewPoolWithFunc(opts.getConcurrency(),
+10
View File
@@ -90,6 +90,16 @@ type ProxyOpts struct {
// This is an optional setting. // This is an optional setting.
DomainFrontingPort uint DomainFrontingPort uint
// AllowFallbackOnUnknownDC defines how proxy behaves if unknown DC was
// requested. If this setting is set to false, then such connection
// will be rejected. Otherwise, proxy will chose any DC.
//
// Telegram is designed in a way that any DC can serve any request,
// the problem is a latency.
//
// This is an optional setting.
AllowFallbackOnUnknownDC bool
// UseTestDCs defines if we have to connect to production or to staging // UseTestDCs defines if we have to connect to production or to staging
// DCs of Telegram. // DCs of Telegram.
// //