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 символов.

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