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

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178
  1. package config
  2. import (
  3. "encoding/hex"
  4. "fmt"
  5. "net"
  6. "strconv"
  7. "strings"
  8. "github.com/juju/errors"
  9. )
  10. // Buffer sizes define internal socket buffer sizes.
  11. const (
  12. BufferWriteSize = 32 * 1024
  13. BufferReadSize = 32 * 1024
  14. )
  15. // Config represents common configuration of mtg.
  16. type Config struct {
  17. Debug bool
  18. Verbose bool
  19. SecureMode bool
  20. BindPort uint16
  21. PublicIPv4Port uint16
  22. PublicIPv6Port uint16
  23. StatsPort uint16
  24. BindIP net.IP
  25. PublicIPv4 net.IP
  26. PublicIPv6 net.IP
  27. StatsIP net.IP
  28. Secret []byte
  29. AdTag []byte
  30. }
  31. // URLs contains links to the proxy (tg://, t.me) and their QR codes.
  32. type URLs struct {
  33. TG string `json:"tg_url"`
  34. TMe string `json:"tme_url"`
  35. TGQRCode string `json:"tg_qrcode"`
  36. TMeQRCode string `json:"tme_qrcode"`
  37. }
  38. // IPURLs contains links to both ipv4 and ipv6 of the proxy.
  39. type IPURLs struct {
  40. IPv4 URLs `json:"ipv4"`
  41. IPv6 URLs `json:"ipv6"`
  42. BotSecret string `json:"secret_for_mtproxybot"`
  43. }
  44. // BindAddr returns connection for this server to bind to.
  45. func (c *Config) BindAddr() string {
  46. return getAddr(c.BindIP, c.BindPort)
  47. }
  48. // StatAddr returns connection string to the stats API.
  49. func (c *Config) StatAddr() string {
  50. return getAddr(c.StatsIP, c.StatsPort)
  51. }
  52. // UseMiddleProxy defines if this proxy has to connect middle proxies
  53. // which supports promoted channels or directly access Telegram.
  54. func (c *Config) UseMiddleProxy() bool {
  55. return len(c.AdTag) > 0
  56. }
  57. // BotSecretString returns secret string which should work with MTProxybot.
  58. func (c *Config) BotSecretString() string {
  59. return hex.EncodeToString(c.Secret)
  60. }
  61. // SecretString returns a secret in a form entered on the start of the
  62. // application.
  63. func (c *Config) SecretString() string {
  64. secret := c.BotSecretString()
  65. if c.SecureMode {
  66. return "dd" + secret
  67. }
  68. return secret
  69. }
  70. // GetURLs returns configured IPURLs instance with links to this server.
  71. func (c *Config) GetURLs() IPURLs {
  72. urls := IPURLs{}
  73. secret := c.SecretString()
  74. if c.PublicIPv4 != nil {
  75. urls.IPv4 = getURLs(c.PublicIPv4, c.PublicIPv4Port, secret)
  76. }
  77. if c.PublicIPv6 != nil {
  78. urls.IPv6 = getURLs(c.PublicIPv6, c.PublicIPv6Port, secret)
  79. }
  80. urls.BotSecret = c.BotSecretString()
  81. return urls
  82. }
  83. func getAddr(host fmt.Stringer, port uint16) string {
  84. return net.JoinHostPort(host.String(), strconv.Itoa(int(port)))
  85. }
  86. // NewConfig returns new configuration. If required, it manages and
  87. // fetches data from external sources. Parameters passed to this
  88. // function, should come from command line arguments.
  89. func NewConfig(debug, verbose bool, // nolint: gocyclo
  90. bindIP net.IP, bindPort uint16,
  91. publicIPv4 net.IP, PublicIPv4Port uint16,
  92. publicIPv6 net.IP, publicIPv6Port uint16,
  93. statsIP net.IP, statsPort uint16,
  94. secret, adtag string) (*Config, error) {
  95. secureMode := false
  96. if strings.HasPrefix(secret, "dd") && len(secret) == 34 {
  97. secureMode = true
  98. secret = strings.TrimPrefix(secret, "dd")
  99. } else if len(secret) != 32 {
  100. return nil, errors.New("Telegram demands secret of length 32")
  101. }
  102. secretBytes, err := hex.DecodeString(secret)
  103. if err != nil {
  104. return nil, errors.Annotate(err, "Cannot create config")
  105. }
  106. var adTagBytes []byte
  107. if len(adtag) != 0 {
  108. adTagBytes, err = hex.DecodeString(adtag)
  109. if err != nil {
  110. return nil, errors.Annotate(err, "Cannot create config")
  111. }
  112. }
  113. if publicIPv4 == nil {
  114. publicIPv4, err = getGlobalIPv4()
  115. if err != nil {
  116. publicIPv4 = nil
  117. } else if publicIPv4.To4() == nil {
  118. return nil, errors.Errorf("IP %s is not IPv4", publicIPv4.String())
  119. }
  120. }
  121. if PublicIPv4Port == 0 {
  122. PublicIPv4Port = bindPort
  123. }
  124. if publicIPv6 == nil {
  125. publicIPv6, err = getGlobalIPv6()
  126. if err != nil {
  127. publicIPv6 = nil
  128. } else if publicIPv6.To4() != nil {
  129. return nil, errors.Errorf("IP %s is not IPv6", publicIPv6.String())
  130. }
  131. }
  132. if publicIPv6Port == 0 {
  133. publicIPv6Port = bindPort
  134. }
  135. if statsIP == nil {
  136. statsIP = publicIPv4
  137. }
  138. conf := &Config{
  139. Debug: debug,
  140. Verbose: verbose,
  141. BindIP: bindIP,
  142. BindPort: bindPort,
  143. PublicIPv4: publicIPv4,
  144. PublicIPv4Port: PublicIPv4Port,
  145. PublicIPv6: publicIPv6,
  146. PublicIPv6Port: publicIPv6Port,
  147. StatsIP: statsIP,
  148. StatsPort: statsPort,
  149. Secret: secretBytes,
  150. AdTag: adTagBytes,
  151. SecureMode: secureMode,
  152. }
  153. return conf, nil
  154. }