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文字以内のものにしてください。

config.go 5.8KB

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