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 kan inte välja fler än 25 ämnen Ämnen måste starta med en bokstav eller siffra, kan innehålla bindestreck ('-') och vara max 35 tecken långa.

config.go 5.8KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258
  1. package config
  2. import (
  3. "bytes"
  4. "encoding/json"
  5. "net"
  6. "strconv"
  7. "time"
  8. "github.com/juju/errors"
  9. "go.uber.org/zap"
  10. statsd "gopkg.in/alexcesaro/statsd.v2"
  11. )
  12. type SecretMode uint8
  13. func (s SecretMode) String() string {
  14. switch s {
  15. case SecretModeSimple:
  16. return "simple"
  17. case SecretModeSecured:
  18. return "secured"
  19. }
  20. return "tls"
  21. }
  22. const (
  23. SecretModeSimple SecretMode = iota
  24. SecretModeSecured
  25. SecretModeTLS
  26. )
  27. const SimpleSecretLength = 16
  28. type OptionType uint8
  29. const (
  30. OptionTypeDebug OptionType = iota
  31. OptionTypeVerbose
  32. OptionTypeBindIP
  33. OptionTypeBindPort
  34. OptionTypePublicIPv4
  35. OptionTypePublicIPv4Port
  36. OptionTypePublicIPv6
  37. OptionTypePublicIPv6Port
  38. OptionTypeStatsIP
  39. OptionTypeStatsPort
  40. OptionTypeStatsdIP
  41. OptionTypeStatsdPort
  42. OptionTypeStatsdNetwork
  43. OptionTypeStatsdPrefix
  44. OptionTypeStatsdTagsFormat
  45. OptionTypeStatsdTags
  46. OptionTypePrometheusPrefix
  47. OptionTypeWriteBufferSize
  48. OptionTypeReadBufferSize
  49. OptionTypeAntiReplayMaxSize
  50. OptionTypeAntiReplayEvictionTime
  51. OptionTypeSecret
  52. OptionTypeAdtag
  53. )
  54. type BufferSize struct {
  55. Read int `json:"read"`
  56. Write int `json:"write"`
  57. }
  58. type AntiReplay struct {
  59. MaxSize int `json:"max_size"`
  60. EvictionTime time.Duration `json:"duration"`
  61. }
  62. type Stats struct {
  63. Prefix string `json:"prefix"`
  64. }
  65. type StatsdStats struct {
  66. Stats
  67. Addr Addr `json:"addr"`
  68. Tags map[string]string `json:"tags"`
  69. TagsFormat statsd.TagFormat `json:"format"`
  70. }
  71. type PrometheusStats struct {
  72. Stats
  73. }
  74. type Addr struct {
  75. IP net.IP `json:"ip"`
  76. Port int `json:"port"`
  77. net string
  78. }
  79. func (a Addr) Network() string {
  80. if a.net == "" {
  81. return "tcp"
  82. }
  83. return a.net
  84. }
  85. func (a Addr) String() string {
  86. return net.JoinHostPort(a.IP.String(), strconv.Itoa(a.Port))
  87. }
  88. func (a Addr) MarshalJSON() ([]byte, error) {
  89. data := map[string]string{
  90. "network": a.Network(),
  91. "addr": a.String(),
  92. }
  93. return json.Marshal(data)
  94. }
  95. type Config struct {
  96. BufferSize BufferSize `json:"buffer_size"`
  97. AntiReplay AntiReplay `json:"anti_replay"`
  98. ListenAddr Addr `json:"listen_addr"`
  99. PublicIPv4Addr Addr `json:"public_ipv4_addr"`
  100. PublicIPv6Addr Addr `json:"public_ipv6_addr"`
  101. StatsAddr Addr `json:"stats_addr"`
  102. StatsdStats StatsdStats `json:"stats_statsd"`
  103. PrometheusStats PrometheusStats `json:"stats_prometheus"`
  104. Debug bool `json:"debug"`
  105. Verbose bool `json:"verbose"`
  106. SecretMode SecretMode `json:"secret_mode"`
  107. Secret []byte `json:"secret"`
  108. AdTag []byte `json:"adtag"`
  109. }
  110. func (c Config) String() string {
  111. data, _ := json.Marshal(c)
  112. return string(data)
  113. }
  114. type ConfigOpt struct {
  115. Option OptionType
  116. Value interface{}
  117. }
  118. var C = Config{}
  119. func Init(options ...ConfigOpt) error { // nolint: gocyclo
  120. for _, opt := range options {
  121. switch opt.Option {
  122. case OptionTypeDebug:
  123. C.Debug = opt.Value.(bool)
  124. case OptionTypeVerbose:
  125. C.Verbose = opt.Value.(bool)
  126. case OptionTypeBindIP:
  127. C.ListenAddr.IP = opt.Value.(net.IP)
  128. case OptionTypeBindPort:
  129. C.ListenAddr.Port = int(opt.Value.(uint16))
  130. case OptionTypePublicIPv4:
  131. C.PublicIPv4Addr.IP = opt.Value.(net.IP)
  132. case OptionTypePublicIPv4Port:
  133. C.PublicIPv4Addr.Port = int(opt.Value.(uint16))
  134. case OptionTypePublicIPv6:
  135. C.PublicIPv6Addr.IP = opt.Value.(net.IP)
  136. case OptionTypePublicIPv6Port:
  137. C.PublicIPv6Addr.Port = int(opt.Value.(uint16))
  138. case OptionTypeStatsIP:
  139. C.StatsAddr.IP = opt.Value.(net.IP)
  140. case OptionTypeStatsPort:
  141. C.StatsAddr.Port = int(opt.Value.(uint16))
  142. case OptionTypeStatsdIP:
  143. C.StatsdStats.Addr.IP = opt.Value.(net.IP)
  144. case OptionTypeStatsdPort:
  145. C.StatsdStats.Addr.Port = int(opt.Value.(uint16))
  146. case OptionTypeStatsdNetwork:
  147. C.StatsdStats.Addr.net = opt.Value.(string)
  148. case OptionTypeStatsdPrefix:
  149. C.StatsdStats.Prefix = opt.Value.(string)
  150. case OptionTypeStatsdTagsFormat:
  151. value := opt.Value.(string)
  152. switch value {
  153. case "datadog":
  154. C.StatsdStats.TagsFormat = statsd.Datadog
  155. case "influxdb":
  156. C.StatsdStats.TagsFormat = statsd.InfluxDB
  157. default:
  158. return errors.Errorf("Incorrect statsd tag %s", value)
  159. }
  160. case OptionTypeStatsdTags:
  161. C.StatsdStats.Tags = opt.Value.(map[string]string)
  162. case OptionTypePrometheusPrefix:
  163. C.PrometheusStats.Prefix = opt.Value.(string)
  164. case OptionTypeWriteBufferSize:
  165. C.BufferSize.Write = int(opt.Value.(uint32))
  166. case OptionTypeReadBufferSize:
  167. C.BufferSize.Read = int(opt.Value.(uint32))
  168. case OptionTypeAntiReplayMaxSize:
  169. C.AntiReplay.MaxSize = opt.Value.(int)
  170. case OptionTypeAntiReplayEvictionTime:
  171. C.AntiReplay.EvictionTime = opt.Value.(time.Duration)
  172. case OptionTypeSecret:
  173. C.Secret = opt.Value.([]byte)
  174. case OptionTypeAdtag:
  175. C.AdTag = opt.Value.([]byte)
  176. default:
  177. return errors.Errorf("Unknown tag %v", opt.Option)
  178. }
  179. }
  180. switch {
  181. case len(C.Secret) == 1+SimpleSecretLength && bytes.HasPrefix(C.Secret, []byte{0xdd}):
  182. C.SecretMode = SecretModeSecured
  183. C.Secret = bytes.TrimPrefix(C.Secret, []byte{0xdd})
  184. case len(C.Secret) == SimpleSecretLength:
  185. C.SecretMode = SecretModeSimple
  186. default:
  187. return errors.New("Incorrect secret")
  188. }
  189. return nil
  190. }
  191. func InitPublicAddress() error {
  192. if C.PublicIPv4Addr.Port == 0 {
  193. C.PublicIPv4Addr.Port = C.ListenAddr.Port
  194. }
  195. if C.PublicIPv6Addr.Port == 0 {
  196. C.PublicIPv6Addr.Port = C.ListenAddr.Port
  197. }
  198. foundAddress := C.PublicIPv4Addr.IP != nil || C.PublicIPv6Addr.IP != nil
  199. if C.PublicIPv4Addr.IP == nil {
  200. ip, err := getGlobalIPv4()
  201. if err != nil {
  202. zap.S().Warnw("Cannot resolve public address", "error", err)
  203. } else {
  204. C.PublicIPv4Addr.IP = ip
  205. foundAddress = true
  206. }
  207. }
  208. if C.PublicIPv6Addr.IP == nil {
  209. ip, err := getGlobalIPv6()
  210. if err != nil {
  211. zap.S().Warnw("Cannot resolve public address", "error", err)
  212. } else {
  213. C.PublicIPv6Addr.IP = ip
  214. foundAddress = true
  215. }
  216. }
  217. if !foundAddress {
  218. return errors.New("Cannot resolve any public address")
  219. }
  220. return nil
  221. }