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
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

config.go 5.2KB

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. default:
  148. return errors.New("incorrect secret")
  149. }
  150. return nil
  151. }
  152. func InitPublicAddress(ctx context.Context) error {
  153. if C.PublicIPv4.Port == 0 {
  154. C.PublicIPv4.Port = C.Bind.Port
  155. }
  156. if C.PublicIPv6.Port == 0 {
  157. C.PublicIPv6.Port = C.Bind.Port
  158. }
  159. foundAddress := C.PublicIPv4.IP != nil || C.PublicIPv6.IP != nil
  160. if C.PublicIPv4.IP == nil {
  161. ip, err := getGlobalIPv4(ctx)
  162. if err != nil {
  163. zap.S().Warnw("Cannot resolve public address", "error", err)
  164. } else {
  165. C.PublicIPv4.IP = ip
  166. foundAddress = true
  167. }
  168. }
  169. if C.PublicIPv6.IP == nil {
  170. ip, err := getGlobalIPv6(ctx)
  171. if err != nil {
  172. zap.S().Warnw("Cannot resolve public address", "error", err)
  173. } else {
  174. C.PublicIPv6.IP = ip
  175. foundAddress = true
  176. }
  177. }
  178. if !foundAddress {
  179. return errors.New("cannot resolve any public address")
  180. }
  181. return nil
  182. }
  183. func Printable() interface{} {
  184. data, err := json.Marshal(C)
  185. if err != nil {
  186. panic(err)
  187. }
  188. rv := map[string]interface{}{}
  189. if err := json.Unmarshal(data, &rv); err != nil {
  190. panic(err)
  191. }
  192. rrv, err := json.Marshal(rv)
  193. if err != nil {
  194. panic(err)
  195. }
  196. return rrv
  197. }