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

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091
  1. package telegram
  2. import (
  3. "errors"
  4. "math/rand"
  5. "net"
  6. "github.com/9seconds/mtg/config"
  7. "github.com/9seconds/mtg/conntypes"
  8. "github.com/9seconds/mtg/utils"
  9. "github.com/9seconds/mtg/wrappers/stream"
  10. "go.uber.org/zap"
  11. )
  12. type baseTelegram struct {
  13. dialer net.Dialer
  14. logger *zap.SugaredLogger
  15. secret []byte
  16. v4DefaultDC conntypes.DC
  17. v6DefaultDC conntypes.DC
  18. v4Addresses map[conntypes.DC][]string
  19. v6Addresses map[conntypes.DC][]string
  20. }
  21. func (b *baseTelegram) Secret() []byte {
  22. return b.secret
  23. }
  24. func (b *baseTelegram) dial(dc conntypes.DC,
  25. protocol conntypes.ConnectionProtocol) (conntypes.StreamReadWriteCloser, error) {
  26. for _, addr := range b.getAddresses(dc, protocol) {
  27. conn, err := b.dialer.Dial("tcp", addr)
  28. if err != nil {
  29. b.logger.Infow("Cannot dial to Telegram", "address", addr, "error", err)
  30. continue
  31. }
  32. if err := utils.InitTCP(conn, config.C.ProxyReadBuffer(), config.C.ProxyWriteBuffer()); err != nil {
  33. b.logger.Infow("Cannot initialize TCP socket", "address", addr, "error", err)
  34. continue
  35. }
  36. return stream.NewTelegramConn(dc, conn), nil
  37. }
  38. return nil, errors.New("cannot dial to the chosen DC")
  39. }
  40. func (b *baseTelegram) getAddresses(dc conntypes.DC, protocol conntypes.ConnectionProtocol) []string {
  41. addresses := make([]string, 0, 2)
  42. protos := []conntypes.ConnectionProtocol{
  43. conntypes.ConnectionProtocolIPv6,
  44. conntypes.ConnectionProtocolIPv4,
  45. }
  46. if config.C.PreferIP == config.PreferIPv4 {
  47. protos[0], protos[1] = protos[1], protos[0]
  48. }
  49. for _, proto := range protos {
  50. switch {
  51. case proto&protocol == 0:
  52. case proto&conntypes.ConnectionProtocolIPv6 != 0:
  53. addresses = append(addresses, b.chooseAddress(b.v6Addresses, dc, b.v6DefaultDC))
  54. case proto&conntypes.ConnectionProtocolIPv4 != 0:
  55. addresses = append(addresses, b.chooseAddress(b.v4Addresses, dc, b.v4DefaultDC))
  56. }
  57. }
  58. return addresses
  59. }
  60. func (b *baseTelegram) chooseAddress(addresses map[conntypes.DC][]string,
  61. dc, defaultDC conntypes.DC) string {
  62. addrs, ok := addresses[dc]
  63. if !ok {
  64. addrs = addresses[defaultDC]
  65. }
  66. switch {
  67. case len(addrs) == 1:
  68. return addrs[0]
  69. case len(addrs) > 1:
  70. return addrs[rand.Intn(len(addrs))] // nolint: gosec
  71. }
  72. return ""
  73. }