mirror of
https://github.com/ScuroNeko/mtg.git
synced 2026-08-31 20:54:02 +03:00
FILE / ScuroNeko/mtg
mtglib/proxy_opts.go
Исходный файл и его история в репозитории.
Domain fronting relay (for non-Telegram traffic) had no idle timeout, causing worker pool exhaustion under traffic spikes. The ProxyOpts.IdleTimeout field existed but was never wired into the proxy. Now domain fronting connections are wrapped with per-read/write deadlines reset to the configured idle timeout (default 1m), so stale or slowloris-style connections are reaped promptly. Fixes #378
230 lines
6.4 KiB
Go
230 lines
6.4 KiB
Go
package mtglib
|
|
|
|
import "time"
|
|
|
|
// ProxyOpts is a structure with settings to mtg proxy.
|
|
//
|
|
// This is not required per se, but this is to shorten function signature and
|
|
// give an ability to conveniently provide default values.
|
|
type ProxyOpts struct {
|
|
// Secret defines a secret which should be used by a proxy.
|
|
//
|
|
// This is a mandatory setting.
|
|
Secret Secret
|
|
|
|
// Network defines a network instance which should be used for all network
|
|
// communications made by proxies.
|
|
//
|
|
// This is a mandatory setting.
|
|
Network Network
|
|
|
|
// AntiReplayCache defines an instance of antireplay cache.
|
|
//
|
|
// This is a mandatory setting.
|
|
AntiReplayCache AntiReplayCache
|
|
|
|
// IPBlocklist defines an instance of IP blocklist.
|
|
//
|
|
// This is a mandatory setting.
|
|
IPBlocklist IPBlocklist
|
|
|
|
// IPAllowlist defines a whitelist of IPs to allow to use proxy.
|
|
//
|
|
// This is an optional setting, ignored by default (no restrictions).
|
|
IPAllowlist IPBlocklist
|
|
|
|
// EventStream defines an instance of event stream.
|
|
//
|
|
// This ia a mandatory setting.
|
|
EventStream EventStream
|
|
|
|
// Logger defines an instance of the logger.
|
|
//
|
|
// This is a mandatory setting.
|
|
Logger Logger
|
|
|
|
// BufferSize is a size of the copy buffer in bytes.
|
|
//
|
|
// Please remember that we multiply this number in 2, because when we relay
|
|
// between proxies, we have to create 2 intermediate buffers: to and from.
|
|
//
|
|
// This is an optional setting.
|
|
//
|
|
// Deprecated: this setting is no longer makes any effect.
|
|
BufferSize uint
|
|
|
|
// Concurrency is a size of the worker pool for connection management.
|
|
//
|
|
// If we have more connections than this number, they are going to be
|
|
// rejected.
|
|
//
|
|
// This is an optional setting.
|
|
Concurrency uint
|
|
|
|
// IdleTimeout is a timeout for relay when we have to break a stream.
|
|
//
|
|
// This is a timeout for any activity. So, if we have any message which will
|
|
// pass to either direction, a timer is reset. If we have no any reads or
|
|
// writes for this timeout, a connection will be aborted.
|
|
//
|
|
// This is an optional setting.
|
|
IdleTimeout time.Duration
|
|
|
|
// TolerateTimeSkewness is a time boundary that defines a time range where
|
|
// faketls timestamp is acceptable.
|
|
//
|
|
// This means that if if you got a timestamp X, now is Y, then if |X-Y| <
|
|
// TolerateTimeSkewness, then you accept a packet.
|
|
//
|
|
// This is an optional setting.
|
|
TolerateTimeSkewness time.Duration
|
|
|
|
// PreferIP defines an IP connectivity preference. Valid values are:
|
|
// 'prefer-ipv4', 'prefer-ipv6', 'only-ipv4', 'only-ipv6'.
|
|
//
|
|
// This is an optional setting.
|
|
PreferIP string
|
|
|
|
// AutoUpdate defines if it is required to auto update proxy list from
|
|
// Telegram instead of relying on a hardcoded list.
|
|
//
|
|
// This is an optional setting.
|
|
AutoUpdate bool
|
|
|
|
// DomainFrontingPort is a port we use to connect to a fronting domain.
|
|
//
|
|
// This is required because secret does not specify a port. It specifies a
|
|
// hostname only.
|
|
//
|
|
// This is an optional setting.
|
|
DomainFrontingPort uint
|
|
|
|
// DomainFrontingIP is an IP address to use when connecting to the fronting
|
|
// domain instead of resolving the hostname from the secret via DNS.
|
|
//
|
|
// This is useful when DNS resolution of the fronting host is blocked.
|
|
// The hostname from the secret is still used for SNI in the TLS handshake.
|
|
//
|
|
// This is an optional setting.
|
|
DomainFrontingIP string
|
|
|
|
// DomainFrontingProxyProtocol is used if communication between upstream
|
|
// endpoint and mtg supports proxy protocol. This is useful in case
|
|
// if mtg is also placed behind load balancer, and this will make
|
|
// fronting webserver to know about real IP addresses
|
|
//
|
|
// This is an optional setting.
|
|
DomainFrontingProxyProtocol bool
|
|
|
|
// 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 DCs of
|
|
// Telegram.
|
|
//
|
|
// This is required if you use mtglib as an integration library for your
|
|
// Telegram-related projects.
|
|
//
|
|
// This is an optional setting.
|
|
//
|
|
// OBSOLETE and DEPRECATED. Ignored.
|
|
UseTestDCs bool
|
|
|
|
// DCOverrides defines a set of IP addresses that should be used
|
|
// with a higher priority to those that are calculated somehow by mtg.
|
|
//
|
|
// OBSOLETE and DEPRECATED. Ignored.
|
|
DCOverrides map[int][]string
|
|
|
|
// DoppelGangerURLs is a list of URLs that should be crawled by
|
|
// mtg to calculate parameters for statistical distribution of a
|
|
// traffic for fronting domains. If nothing is given, then predefined
|
|
// statistics is going to be used.
|
|
DoppelGangerURLs []string
|
|
|
|
// DoppelGangerPerRaid defines how many time each URL from
|
|
// DoppelGangerURLs list should be crawled per raid. We recommend to
|
|
// have this number ~10.
|
|
DoppelGangerPerRaid uint
|
|
|
|
// DoppelGangerEach defines a time period between each raid. We recommend
|
|
// to use hours here.
|
|
DoppelGangerEach time.Duration
|
|
|
|
// DoppelGangerDRS defines if TLS Dynamic Record Sizing is active.
|
|
DoppelGangerDRS bool
|
|
|
|
}
|
|
|
|
func (p ProxyOpts) valid() error {
|
|
switch {
|
|
case p.Network == nil:
|
|
return ErrNetworkIsNotDefined
|
|
case p.AntiReplayCache == nil:
|
|
return ErrAntiReplayCacheIsNotDefined
|
|
case p.IPBlocklist == nil:
|
|
return ErrIPBlocklistIsNotDefined
|
|
case p.IPAllowlist == nil:
|
|
return ErrIPAllowlistIsNotDefined
|
|
case p.EventStream == nil:
|
|
return ErrEventStreamIsNotDefined
|
|
case p.Logger == nil:
|
|
return ErrLoggerIsNotDefined
|
|
case !p.Secret.Valid():
|
|
return ErrSecretInvalid
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
func (p ProxyOpts) getConcurrency() int {
|
|
if p.Concurrency == 0 {
|
|
return DefaultConcurrency
|
|
}
|
|
|
|
return int(p.Concurrency)
|
|
}
|
|
|
|
func (p ProxyOpts) getDomainFrontingPort() int {
|
|
if p.DomainFrontingPort == 0 {
|
|
return DefaultDomainFrontingPort
|
|
}
|
|
|
|
return int(p.DomainFrontingPort)
|
|
}
|
|
|
|
func (p ProxyOpts) getTolerateTimeSkewness() time.Duration {
|
|
if p.TolerateTimeSkewness == 0 {
|
|
return DefaultTolerateTimeSkewness
|
|
}
|
|
|
|
return p.TolerateTimeSkewness
|
|
}
|
|
|
|
func (p ProxyOpts) getPreferIP() string {
|
|
if p.PreferIP == "" {
|
|
return DefaultPreferIP
|
|
}
|
|
|
|
return p.PreferIP
|
|
}
|
|
|
|
func (p ProxyOpts) getIdleTimeout() time.Duration {
|
|
if p.IdleTimeout == 0 {
|
|
return DefaultIdleTimeout
|
|
}
|
|
|
|
return p.IdleTimeout
|
|
}
|
|
|
|
func (p ProxyOpts) getLogger(name string) Logger {
|
|
return p.Logger.Named(name)
|
|
}
|