Highly-opinionated (ex-bullshit-free) MTPROTO proxy for Telegram. If you use v1.0 or upgrade broke you proxy, please read the chapter Version 2
Du kannst nicht mehr als 25 Themen auswählen Themen müssen mit entweder einem Buchstaben oder einer Ziffer beginnen. Sie können Bindestriche („-“) enthalten und bis zu 35 Zeichen lang sein.

config.go 5.3KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181
  1. package config
  2. import (
  3. "bytes"
  4. "encoding/json"
  5. "fmt"
  6. "net"
  7. "net/url"
  8. "github.com/dolonet/mtg-multi/mtglib"
  9. )
  10. type Optional struct {
  11. Enabled TypeBool `json:"enabled"`
  12. }
  13. type ListConfig struct {
  14. Optional
  15. DownloadConcurrency TypeConcurrency `json:"downloadConcurrency"`
  16. URLs []TypeBlocklistURI `json:"urls"`
  17. UpdateEach TypeDuration `json:"updateEach"`
  18. }
  19. type Config struct {
  20. Debug TypeBool `json:"debug"`
  21. AllowFallbackOnUnknownDC TypeBool `json:"allowFallbackOnUnknownDc"`
  22. Secret mtglib.Secret `json:"secret"`
  23. Secrets map[string]mtglib.Secret `json:"secrets"`
  24. BindTo TypeHostPort `json:"bindTo"`
  25. ProxyProtocolListener TypeBool `json:"proxyProtocolListener"`
  26. PreferIP TypePreferIP `json:"preferIp"`
  27. AutoUpdate TypeBool `json:"autoUpdate"`
  28. DomainFrontingPort TypePort `json:"domainFrontingPort"`
  29. DomainFrontingIP TypeIP `json:"domainFrontingIp"`
  30. DomainFrontingProxyProtocol TypeBool `json:"domainFrontingProxyProtocol"`
  31. TolerateTimeSkewness TypeDuration `json:"tolerateTimeSkewness"`
  32. Concurrency TypeConcurrency `json:"concurrency"`
  33. PublicIPv4 TypeIP `json:"publicIpv4"`
  34. PublicIPv6 TypeIP `json:"publicIpv6"`
  35. DomainFronting struct {
  36. IP TypeIP `json:"ip"`
  37. Port TypePort `json:"port"`
  38. ProxyProtocol TypeBool `json:"proxyProtocol"`
  39. } `json:"domainFronting"`
  40. Defense struct {
  41. AntiReplay struct {
  42. Optional
  43. MaxSize TypeBytes `json:"maxSize"`
  44. ErrorRate TypeErrorRate `json:"errorRate"`
  45. } `json:"antiReplay"`
  46. Blocklist ListConfig `json:"blocklist"`
  47. Allowlist ListConfig `json:"allowlist"`
  48. Doppelganger struct {
  49. URLs []TypeHttpsURL `json:"urls"`
  50. Repeats TypeConcurrency `json:"repeats_per_raid"`
  51. UpdateEach TypeDuration `json:"raid_each"`
  52. DRS TypeBool `json:"drs"`
  53. } `json:"doppelganger"`
  54. } `json:"defense"`
  55. Network struct {
  56. Timeout struct {
  57. TCP TypeDuration `json:"tcp"`
  58. HTTP TypeDuration `json:"http"`
  59. Idle TypeDuration `json:"idle"`
  60. Handshake TypeDuration `json:"handshake"`
  61. } `json:"timeout"`
  62. KeepAlive struct {
  63. Disabled TypeBool `json:"disabled"`
  64. Idle TypeDuration `json:"idle"`
  65. Interval TypeDuration `json:"interval"`
  66. Count TypeConcurrency `json:"count"`
  67. } `json:"keepAlive"`
  68. DOHIP TypeIP `json:"dohIp"`
  69. DNS TypeDNSURI `json:"dns"`
  70. Proxies []TypeProxyURL `json:"proxies"`
  71. } `json:"network"`
  72. APIBindTo TypeHostPort `json:"apiBindTo"`
  73. Throttle struct {
  74. MaxConnections TypeConcurrency `json:"maxConnections"`
  75. CheckInterval TypeDuration `json:"checkInterval"`
  76. } `json:"throttle"`
  77. Stats struct {
  78. StatsD struct {
  79. Optional
  80. Address TypeHostPort `json:"address"`
  81. MetricPrefix TypeMetricPrefix `json:"metricPrefix"`
  82. TagFormat TypeStatsdTagFormat `json:"tagFormat"`
  83. } `json:"statsd"`
  84. Prometheus struct {
  85. Optional
  86. BindTo TypeHostPort `json:"bindTo"`
  87. HTTPPath TypeHTTPPath `json:"httpPath"`
  88. MetricPrefix TypeMetricPrefix `json:"metricPrefix"`
  89. } `json:"prometheus"`
  90. } `json:"stats"`
  91. }
  92. func (c *Config) GetConcurrency(defaultValue uint) uint {
  93. if concurrency := c.Concurrency.Get(0); concurrency != 0 {
  94. return concurrency
  95. }
  96. return c.Concurrency.Get(defaultValue)
  97. }
  98. func (c *Config) GetDNS() *url.URL {
  99. var dohURL *url.URL
  100. if dohIP := c.Network.DOHIP.Get(nil); dohIP != nil {
  101. dohURL, _ = url.Parse("https://" + dohIP.String())
  102. }
  103. return c.Network.DNS.Get(dohURL)
  104. }
  105. func (c *Config) GetDomainFrontingPort(defaultValue uint) uint {
  106. if port := c.DomainFronting.Port.Get(0); port != 0 {
  107. return port
  108. }
  109. return c.DomainFrontingPort.Get(defaultValue)
  110. }
  111. func (c *Config) GetDomainFrontingIP(defaultValue net.IP) string {
  112. if ip := c.DomainFronting.IP.Get(nil); ip != nil {
  113. return ip.String()
  114. }
  115. if ip := c.DomainFrontingIP.Get(defaultValue); ip != nil {
  116. return ip.String()
  117. }
  118. return ""
  119. }
  120. func (c *Config) GetDomainFrontingProxyProtocol(defaultValue bool) bool {
  121. return c.DomainFronting.ProxyProtocol.Get(false) || c.DomainFrontingProxyProtocol.Get(defaultValue)
  122. }
  123. func (c *Config) Validate() error {
  124. if len(c.Secrets) == 0 {
  125. if !c.Secret.Valid() {
  126. return fmt.Errorf("invalid secret %s", c.Secret.String())
  127. }
  128. } else {
  129. for name, s := range c.Secrets {
  130. if !s.Valid() {
  131. return fmt.Errorf("invalid secret %q: %s", name, s.String())
  132. }
  133. }
  134. }
  135. if c.BindTo.Get("") == "" {
  136. return fmt.Errorf("incorrect bind-to parameter %s", c.BindTo.String())
  137. }
  138. return nil
  139. }
  140. // GetSecrets returns all secrets as a map. If the new [secrets] section is used,
  141. // returns that map. Otherwise, wraps the single Secret as {"default": Secret}.
  142. func (c *Config) GetSecrets() map[string]mtglib.Secret {
  143. if len(c.Secrets) > 0 {
  144. return c.Secrets
  145. }
  146. return map[string]mtglib.Secret{"default": c.Secret}
  147. }
  148. func (c *Config) String() string {
  149. buf := &bytes.Buffer{}
  150. encoder := json.NewEncoder(buf)
  151. encoder.SetEscapeHTML(false)
  152. if err := encoder.Encode(c); err != nil {
  153. panic(err)
  154. }
  155. return buf.String()
  156. }