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

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