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
Vous ne pouvez pas sélectionner plus de 25 sujets Les noms de sujets doivent commencer par une lettre ou un nombre, peuvent contenir des tirets ('-') et peuvent comporter jusqu'à 35 caractères.

config.go 5.4KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234
  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. OptionTypeCloakPort
  46. OptionTypeAntiReplayMaxSize
  47. OptionTypeAntiReplayEvictionTime
  48. OptionTypeSecret
  49. OptionTypeAdtag
  50. )
  51. type Config struct {
  52. Bind *net.TCPAddr `json:"bind"`
  53. PublicIPv4 *net.TCPAddr `json:"public_ipv4"`
  54. PublicIPv6 *net.TCPAddr `json:"public_ipv6"`
  55. StatsBind *net.TCPAddr `json:"stats_bind"`
  56. StatsdAddr *net.TCPAddr `json:"stats_addr"`
  57. StatsNamespace string `json:"stats_namespace"`
  58. StatsdNetwork string `json:"statsd_network"`
  59. CloakHost string `json:"cloak_host"`
  60. StatsdTags map[string]string `json:"statsd_tags"`
  61. WriteBuffer int `json:"write_buffer"`
  62. ReadBuffer int `json:"read_buffer"`
  63. CloakPort int `json:"cloak_port"`
  64. AntiReplayMaxSize int `json:"anti_replay_max_size"`
  65. AntiReplayEvictionTime time.Duration `json:"anti_replay_eviction_time"`
  66. Debug bool `json:"debug"`
  67. Verbose bool `json:"verbose"`
  68. StatsdTagsFormat statsd.TagFormat `json:"statsd_tags_format"`
  69. SecretMode SecretMode `json:"secret_mode"`
  70. Secret []byte `json:"secret"`
  71. AdTag []byte `json:"adtag"`
  72. }
  73. type Opt struct {
  74. Option OptionType
  75. Value interface{}
  76. }
  77. var C = Config{}
  78. func Init(options ...Opt) error { // nolint: gocyclo, funlen
  79. for _, opt := range options {
  80. switch opt.Option {
  81. case OptionTypeDebug:
  82. C.Debug = opt.Value.(bool)
  83. case OptionTypeVerbose:
  84. C.Verbose = opt.Value.(bool)
  85. case OptionTypeBind:
  86. C.Bind = opt.Value.(*net.TCPAddr)
  87. case OptionTypePublicIPv4:
  88. C.PublicIPv4 = opt.Value.(*net.TCPAddr)
  89. if C.PublicIPv4 == nil {
  90. C.PublicIPv4 = &net.TCPAddr{}
  91. }
  92. case OptionTypePublicIPv6:
  93. C.PublicIPv6 = opt.Value.(*net.TCPAddr)
  94. if C.PublicIPv6 == nil {
  95. C.PublicIPv6 = &net.TCPAddr{}
  96. }
  97. case OptionTypeStatsBind:
  98. C.StatsBind = opt.Value.(*net.TCPAddr)
  99. case OptionTypeStatsNamespace:
  100. C.StatsNamespace = opt.Value.(string)
  101. case OptionTypeStatsdAddress:
  102. C.StatsdAddr = opt.Value.(*net.TCPAddr)
  103. case OptionTypeStatsdNetwork:
  104. value := opt.Value.(string)
  105. switch value {
  106. case "udp", "tcp":
  107. C.StatsdNetwork = value
  108. default:
  109. return fmt.Errorf("unknown statsd network %v", value)
  110. }
  111. case OptionTypeStatsdTagsFormat:
  112. value := opt.Value.(string)
  113. switch value {
  114. case "datadog":
  115. C.StatsdTagsFormat = statsd.Datadog
  116. case "influxdb":
  117. C.StatsdTagsFormat = statsd.InfluxDB
  118. default:
  119. return fmt.Errorf("incorrect statsd tag %s", value)
  120. }
  121. case OptionTypeStatsdTags:
  122. C.StatsdTags = opt.Value.(map[string]string)
  123. case OptionTypeWriteBufferSize:
  124. C.WriteBuffer = int(opt.Value.(units.Base2Bytes))
  125. case OptionTypeReadBufferSize:
  126. C.ReadBuffer = int(opt.Value.(units.Base2Bytes))
  127. case OptionTypeCloakPort:
  128. C.CloakPort = int(opt.Value.(uint16))
  129. case OptionTypeAntiReplayMaxSize:
  130. C.AntiReplayMaxSize = opt.Value.(int)
  131. case OptionTypeAntiReplayEvictionTime:
  132. C.AntiReplayEvictionTime = opt.Value.(time.Duration)
  133. case OptionTypeSecret:
  134. C.Secret = opt.Value.([]byte)
  135. case OptionTypeAdtag:
  136. C.AdTag = opt.Value.([]byte)
  137. default:
  138. return fmt.Errorf("unknown tag %v", opt.Option)
  139. }
  140. }
  141. switch {
  142. case len(C.Secret) == 1+SimpleSecretLength && bytes.HasPrefix(C.Secret, []byte{0xdd}):
  143. C.SecretMode = SecretModeSecured
  144. C.Secret = bytes.TrimPrefix(C.Secret, []byte{0xdd})
  145. case len(C.Secret) == SimpleSecretLength:
  146. C.SecretMode = SecretModeSimple
  147. case bytes.HasPrefix(C.Secret, []byte{0xee}):
  148. C.SecretMode = SecretModeTLS
  149. secret := bytes.TrimPrefix(C.Secret, []byte{0xee})
  150. C.Secret = secret[:SimpleSecretLength]
  151. C.CloakHost = string(secret[SimpleSecretLength:])
  152. default:
  153. return errors.New("incorrect secret")
  154. }
  155. return nil
  156. }
  157. func InitPublicAddress(ctx context.Context) error {
  158. if C.PublicIPv4.Port == 0 {
  159. C.PublicIPv4.Port = C.Bind.Port
  160. }
  161. if C.PublicIPv6.Port == 0 {
  162. C.PublicIPv6.Port = C.Bind.Port
  163. }
  164. foundAddress := C.PublicIPv4.IP != nil || C.PublicIPv6.IP != nil
  165. if C.PublicIPv4.IP == nil {
  166. ip, err := getGlobalIPv4(ctx)
  167. if err != nil {
  168. zap.S().Warnw("Cannot resolve public address", "error", err)
  169. } else {
  170. C.PublicIPv4.IP = ip
  171. foundAddress = true
  172. }
  173. }
  174. if C.PublicIPv6.IP == nil {
  175. ip, err := getGlobalIPv6(ctx)
  176. if err != nil {
  177. zap.S().Warnw("Cannot resolve public address", "error", err)
  178. } else {
  179. C.PublicIPv6.IP = ip
  180. foundAddress = true
  181. }
  182. }
  183. if !foundAddress {
  184. return errors.New("cannot resolve any public address")
  185. }
  186. return nil
  187. }
  188. func Printable() interface{} {
  189. data, err := json.Marshal(C)
  190. if err != nil {
  191. panic(err)
  192. }
  193. rv := map[string]interface{}{}
  194. if err := json.Unmarshal(data, &rv); err != nil {
  195. panic(err)
  196. }
  197. return rv
  198. }