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
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

config.go 4.9KB

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