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

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263
  1. package config
  2. import (
  3. "bytes"
  4. "context"
  5. "encoding/json"
  6. "errors"
  7. "fmt"
  8. "net"
  9. "github.com/alecthomas/units"
  10. statsd "github.com/smira/go-statsd"
  11. "go.uber.org/zap"
  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. type PreferIP uint8
  29. const (
  30. PreferIPv4 PreferIP = iota
  31. PreferIPv6
  32. )
  33. const SimpleSecretLength = 16
  34. type OptionType uint8
  35. const (
  36. OptionTypeDebug OptionType = iota
  37. OptionTypeVerbose
  38. OptionTypePreferIP
  39. OptionTypeBind
  40. OptionTypePublicIPv4
  41. OptionTypePublicIPv6
  42. OptionTypeStatsBind
  43. OptionTypeStatsNamespace
  44. OptionTypeStatsdAddress
  45. OptionTypeStatsdTagsFormat
  46. OptionTypeStatsdTags
  47. OptionTypeWriteBufferSize
  48. OptionTypeReadBufferSize
  49. OptionTypeCloakPort
  50. OptionTypeAntiReplayMaxSize
  51. OptionTypeMultiplexPerConnection
  52. OptionTypeNTPServers
  53. OptionTypeSecret
  54. OptionTypeAdtag
  55. )
  56. type Config struct {
  57. Bind *net.TCPAddr `json:"bind"`
  58. PublicIPv4 *net.TCPAddr `json:"public_ipv4"`
  59. PublicIPv6 *net.TCPAddr `json:"public_ipv6"`
  60. StatsBind *net.TCPAddr `json:"stats_bind"`
  61. StatsdAddr *net.TCPAddr `json:"stats_addr"`
  62. StatsdTagsFormat *statsd.TagFormat `json:"statsd_tags_format"`
  63. StatsNamespace string `json:"stats_namespace"`
  64. CloakHost string `json:"cloak_host"`
  65. StatsdTags map[string]string `json:"statsd_tags"`
  66. WriteBuffer int `json:"write_buffer"`
  67. ReadBuffer int `json:"read_buffer"`
  68. CloakPort int `json:"cloak_port"`
  69. AntiReplayMaxSize int `json:"anti_replay_max_size"`
  70. MultiplexPerConnection int `json:"multiplex_per_connection"`
  71. Debug bool `json:"debug"`
  72. Verbose bool `json:"verbose"`
  73. SecretMode SecretMode `json:"secret_mode"`
  74. PreferIP PreferIP `json:"prefer_ip"`
  75. NTPServers []string `json:"ntp_servers"`
  76. Secret []byte `json:"secret"`
  77. AdTag []byte `json:"adtag"`
  78. }
  79. type Opt struct {
  80. Option OptionType
  81. Value interface{}
  82. }
  83. var C = Config{}
  84. func Init(options ...Opt) error { // nolint: gocyclo, funlen
  85. for _, opt := range options {
  86. switch opt.Option {
  87. case OptionTypeDebug:
  88. C.Debug = opt.Value.(bool)
  89. case OptionTypeVerbose:
  90. C.Verbose = opt.Value.(bool)
  91. case OptionTypePreferIP:
  92. value := opt.Value.(string)
  93. switch value {
  94. case "ipv4":
  95. C.PreferIP = PreferIPv4
  96. case "ipv6":
  97. C.PreferIP = PreferIPv6
  98. default:
  99. return fmt.Errorf("incorrect direct IP mode %s", value)
  100. }
  101. case OptionTypeBind:
  102. C.Bind = opt.Value.(*net.TCPAddr)
  103. case OptionTypePublicIPv4:
  104. C.PublicIPv4 = opt.Value.(*net.TCPAddr)
  105. if C.PublicIPv4 == nil {
  106. C.PublicIPv4 = &net.TCPAddr{}
  107. }
  108. case OptionTypePublicIPv6:
  109. C.PublicIPv6 = opt.Value.(*net.TCPAddr)
  110. if C.PublicIPv6 == nil {
  111. C.PublicIPv6 = &net.TCPAddr{}
  112. }
  113. case OptionTypeStatsBind:
  114. C.StatsBind = opt.Value.(*net.TCPAddr)
  115. case OptionTypeStatsNamespace:
  116. C.StatsNamespace = opt.Value.(string)
  117. case OptionTypeStatsdAddress:
  118. C.StatsdAddr = opt.Value.(*net.TCPAddr)
  119. case OptionTypeStatsdTagsFormat:
  120. value := opt.Value.(string)
  121. switch value {
  122. case "datadog":
  123. C.StatsdTagsFormat = statsd.TagFormatDatadog
  124. case "influxdb":
  125. C.StatsdTagsFormat = statsd.TagFormatInfluxDB
  126. default:
  127. return fmt.Errorf("incorrect statsd tag %s", value)
  128. }
  129. case OptionTypeStatsdTags:
  130. C.StatsdTags = opt.Value.(map[string]string)
  131. case OptionTypeWriteBufferSize:
  132. C.WriteBuffer = int(opt.Value.(units.Base2Bytes))
  133. case OptionTypeReadBufferSize:
  134. C.ReadBuffer = int(opt.Value.(units.Base2Bytes))
  135. case OptionTypeCloakPort:
  136. C.CloakPort = int(opt.Value.(uint16))
  137. case OptionTypeAntiReplayMaxSize:
  138. C.AntiReplayMaxSize = int(opt.Value.(units.Base2Bytes))
  139. case OptionTypeMultiplexPerConnection:
  140. C.MultiplexPerConnection = int(opt.Value.(uint))
  141. case OptionTypeNTPServers:
  142. C.NTPServers = opt.Value.([]string)
  143. if len(C.NTPServers) == 0 {
  144. return errors.New("ntp server list is empty")
  145. }
  146. case OptionTypeSecret:
  147. C.Secret = opt.Value.([]byte)
  148. case OptionTypeAdtag:
  149. C.AdTag = opt.Value.([]byte)
  150. default:
  151. return fmt.Errorf("unknown tag %v", opt.Option)
  152. }
  153. }
  154. switch {
  155. case len(C.Secret) == 1+SimpleSecretLength && bytes.HasPrefix(C.Secret, []byte{0xdd}):
  156. C.SecretMode = SecretModeSecured
  157. C.Secret = bytes.TrimPrefix(C.Secret, []byte{0xdd})
  158. case len(C.Secret) > SimpleSecretLength && bytes.HasPrefix(C.Secret, []byte{0xee}):
  159. C.SecretMode = SecretModeTLS
  160. secret := bytes.TrimPrefix(C.Secret, []byte{0xee})
  161. C.Secret = secret[:SimpleSecretLength]
  162. C.CloakHost = string(secret[SimpleSecretLength:])
  163. case len(C.Secret) == SimpleSecretLength:
  164. C.SecretMode = SecretModeSimple
  165. default:
  166. return errors.New("incorrect secret")
  167. }
  168. if C.MultiplexPerConnection == 0 {
  169. return errors.New("cannot use 0 clients per connection for multiplexing")
  170. }
  171. if C.CloakHost != "" {
  172. if _, err := net.LookupHost(C.CloakHost); err != nil {
  173. zap.S().Warnw("Cannot resolve address of host", "hostname", C.CloakHost, "error", err)
  174. }
  175. }
  176. return nil
  177. }
  178. func InitPublicAddress(ctx context.Context) error {
  179. if C.PublicIPv4.Port == 0 {
  180. C.PublicIPv4.Port = C.Bind.Port
  181. }
  182. if C.PublicIPv6.Port == 0 {
  183. C.PublicIPv6.Port = C.Bind.Port
  184. }
  185. foundAddress := C.PublicIPv4.IP != nil || C.PublicIPv6.IP != nil
  186. if C.PublicIPv4.IP == nil {
  187. ip, err := getGlobalIPv4(ctx)
  188. if err != nil {
  189. zap.S().Warnw("Cannot resolve public address", "error", err)
  190. } else {
  191. C.PublicIPv4.IP = ip
  192. foundAddress = true
  193. }
  194. }
  195. if C.PublicIPv6.IP == nil {
  196. ip, err := getGlobalIPv6(ctx)
  197. if err != nil {
  198. zap.S().Warnw("Cannot resolve public address", "error", err)
  199. } else {
  200. C.PublicIPv6.IP = ip
  201. foundAddress = true
  202. }
  203. }
  204. if !foundAddress {
  205. return errors.New("cannot resolve any public address")
  206. }
  207. return nil
  208. }
  209. func Printable() interface{} {
  210. data, err := json.Marshal(C)
  211. if err != nil {
  212. panic(err)
  213. }
  214. rv := map[string]interface{}{}
  215. if err := json.Unmarshal(data, &rv); err != nil {
  216. panic(err)
  217. }
  218. return rv
  219. }