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 6.9KB

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