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
Вы не можете выбрать более 25 тем Темы должны начинаться с буквы или цифры, могут содержать дефисы(-) и должны содержать не более 35 символов.

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224
  1. package config
  2. import (
  3. "bytes"
  4. "context"
  5. "encoding/json"
  6. "errors"
  7. "fmt"
  8. "net"
  9. "time"
  10. "github.com/alecthomas/units"
  11. "go.uber.org/zap"
  12. statsd "gopkg.in/alexcesaro/statsd.v2"
  13. )
  14. type SecretMode uint8
  15. func (s SecretMode) String() string {
  16. switch s {
  17. case SecretModeSimple:
  18. return "simple"
  19. case SecretModeSecured:
  20. return "secured"
  21. }
  22. return "tls"
  23. }
  24. const (
  25. SecretModeSimple SecretMode = iota
  26. SecretModeSecured
  27. SecretModeTLS
  28. )
  29. const SimpleSecretLength = 16
  30. type OptionType uint8
  31. const (
  32. OptionTypeDebug OptionType = iota
  33. OptionTypeVerbose
  34. OptionTypeBind
  35. OptionTypePublicIPv4
  36. OptionTypePublicIPv6
  37. OptionTypeStatsBind
  38. OptionTypeStatsNamespace
  39. OptionTypeStatsdAddress
  40. OptionTypeStatsdNetwork
  41. OptionTypeStatsdTagsFormat
  42. OptionTypeStatsdTags
  43. OptionTypeWriteBufferSize
  44. OptionTypeReadBufferSize
  45. OptionTypeAntiReplayMaxSize
  46. OptionTypeAntiReplayEvictionTime
  47. OptionTypeSecret
  48. OptionTypeAdtag
  49. )
  50. type Config struct {
  51. Bind *net.TCPAddr `json:"bind"`
  52. PublicIPv4 *net.TCPAddr `json:"public_ipv4"`
  53. PublicIPv6 *net.TCPAddr `json:"public_ipv6"`
  54. StatsBind *net.TCPAddr `json:"stats_bind"`
  55. StatsdAddr *net.TCPAddr `json:"stats_addr"`
  56. StatsNamespace string `json:"stats_namespace"`
  57. StatsdNetwork string `json:"statsd_network"`
  58. StatsdTags map[string]string `json:"statsd_tags"`
  59. WriteBuffer int `json:"write_buffer"`
  60. ReadBuffer int `json:"read_buffer"`
  61. AntiReplayMaxSize int `json:"anti_replay_max_size"`
  62. AntiReplayEvictionTime time.Duration `json:"anti_replay_eviction_time"`
  63. Debug bool `json:"debug"`
  64. Verbose bool `json:"verbose"`
  65. StatsdTagsFormat statsd.TagFormat `json:"statsd_tags_format"`
  66. SecretMode SecretMode `json:"secret_mode"`
  67. Secret []byte `json:"secret"`
  68. AdTag []byte `json:"adtag"`
  69. }
  70. type Opt struct {
  71. Option OptionType
  72. Value interface{}
  73. }
  74. var C = Config{}
  75. func Init(options ...Opt) error { // nolint: gocyclo, funlen
  76. for _, opt := range options {
  77. switch opt.Option {
  78. case OptionTypeDebug:
  79. C.Debug = opt.Value.(bool)
  80. case OptionTypeVerbose:
  81. C.Verbose = opt.Value.(bool)
  82. case OptionTypeBind:
  83. C.Bind = opt.Value.(*net.TCPAddr)
  84. case OptionTypePublicIPv4:
  85. C.PublicIPv4 = opt.Value.(*net.TCPAddr)
  86. if C.PublicIPv4 == nil {
  87. C.PublicIPv4 = &net.TCPAddr{}
  88. }
  89. case OptionTypePublicIPv6:
  90. C.PublicIPv6 = opt.Value.(*net.TCPAddr)
  91. if C.PublicIPv6 == nil {
  92. C.PublicIPv6 = &net.TCPAddr{}
  93. }
  94. case OptionTypeStatsBind:
  95. C.StatsBind = opt.Value.(*net.TCPAddr)
  96. case OptionTypeStatsNamespace:
  97. C.StatsNamespace = opt.Value.(string)
  98. case OptionTypeStatsdAddress:
  99. C.StatsdAddr = opt.Value.(*net.TCPAddr)
  100. case OptionTypeStatsdNetwork:
  101. value := opt.Value.(string)
  102. switch value {
  103. case "udp", "tcp":
  104. C.StatsdNetwork = value
  105. default:
  106. return fmt.Errorf("unknown statsd network %v", value)
  107. }
  108. case OptionTypeStatsdTagsFormat:
  109. value := opt.Value.(string)
  110. switch value {
  111. case "datadog":
  112. C.StatsdTagsFormat = statsd.Datadog
  113. case "influxdb":
  114. C.StatsdTagsFormat = statsd.InfluxDB
  115. default:
  116. return fmt.Errorf("Incorrect statsd tag %s", value)
  117. }
  118. case OptionTypeStatsdTags:
  119. C.StatsdTags = opt.Value.(map[string]string)
  120. case OptionTypeWriteBufferSize:
  121. C.WriteBuffer = int(opt.Value.(units.Base2Bytes))
  122. case OptionTypeReadBufferSize:
  123. C.ReadBuffer = int(opt.Value.(units.Base2Bytes))
  124. case OptionTypeAntiReplayMaxSize:
  125. C.AntiReplayMaxSize = opt.Value.(int)
  126. case OptionTypeAntiReplayEvictionTime:
  127. C.AntiReplayEvictionTime = opt.Value.(time.Duration)
  128. case OptionTypeSecret:
  129. C.Secret = opt.Value.([]byte)
  130. case OptionTypeAdtag:
  131. C.AdTag = opt.Value.([]byte)
  132. default:
  133. return fmt.Errorf("Unknown tag %v", opt.Option)
  134. }
  135. }
  136. switch {
  137. case len(C.Secret) == 1+SimpleSecretLength && bytes.HasPrefix(C.Secret, []byte{0xdd}):
  138. C.SecretMode = SecretModeSecured
  139. C.Secret = bytes.TrimPrefix(C.Secret, []byte{0xdd})
  140. case len(C.Secret) == SimpleSecretLength:
  141. C.SecretMode = SecretModeSimple
  142. default:
  143. return errors.New("Incorrect secret")
  144. }
  145. return nil
  146. }
  147. func InitPublicAddress(ctx context.Context) error {
  148. if C.PublicIPv4.Port == 0 {
  149. C.PublicIPv4.Port = C.Bind.Port
  150. }
  151. if C.PublicIPv6.Port == 0 {
  152. C.PublicIPv6.Port = C.Bind.Port
  153. }
  154. foundAddress := C.PublicIPv4.IP != nil || C.PublicIPv6.IP != nil
  155. if C.PublicIPv4.IP == nil {
  156. ip, err := getGlobalIPv4(ctx)
  157. if err != nil {
  158. zap.S().Warnw("Cannot resolve public address", "error", err)
  159. } else {
  160. C.PublicIPv4.IP = ip
  161. foundAddress = true
  162. }
  163. }
  164. if C.PublicIPv6.IP == nil {
  165. ip, err := getGlobalIPv6(ctx)
  166. if err != nil {
  167. zap.S().Warnw("Cannot resolve public address", "error", err)
  168. } else {
  169. C.PublicIPv6.IP = ip
  170. foundAddress = true
  171. }
  172. }
  173. if !foundAddress {
  174. return errors.New("Cannot resolve any public address")
  175. }
  176. return nil
  177. }
  178. func Printable() interface{} {
  179. data, err := json.Marshal(C)
  180. if err != nil {
  181. panic(err)
  182. }
  183. rv := map[string]interface{}{}
  184. if err := json.Unmarshal(data, &rv); err != nil {
  185. panic(err)
  186. }
  187. rrv, err := json.Marshal(rv)
  188. if err != nil {
  189. panic(err)
  190. }
  191. return rrv
  192. }