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

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152
  1. package server
  2. import (
  3. "context"
  4. "io"
  5. "net"
  6. "strconv"
  7. "sync"
  8. "github.com/9seconds/mtg/obfuscated2"
  9. "github.com/juju/errors"
  10. uuid "github.com/satori/go.uuid"
  11. "go.uber.org/zap"
  12. )
  13. const bufferSize = 4096
  14. type Server struct {
  15. ip net.IP
  16. port int
  17. secret []byte
  18. logger *zap.SugaredLogger
  19. lsock net.Listener
  20. ctx context.Context
  21. }
  22. func (s *Server) Serve() error {
  23. lsock, err := net.Listen("tcp", s.Addr())
  24. if err != nil {
  25. return errors.Annotate(err, "Cannot create listen socket")
  26. }
  27. for {
  28. if conn, err := lsock.Accept(); err != nil {
  29. s.logger.Warn("Cannot allocate incoming connection", "error", err)
  30. } else {
  31. go s.accept(conn)
  32. }
  33. }
  34. return nil
  35. }
  36. func (s *Server) Addr() string {
  37. return net.JoinHostPort(s.ip.String(), strconv.Itoa(s.port))
  38. }
  39. func (s *Server) accept(conn net.Conn) {
  40. defer conn.Close()
  41. ctx, cancel := context.WithCancel(context.Background())
  42. socketID := s.makeSocketID()
  43. s.logger.Debugw("Client connected",
  44. "secret", s.secret,
  45. "addr", conn.RemoteAddr().String(),
  46. "socketid", socketID,
  47. )
  48. clientConn, dc, err := s.getClientStream(conn, ctx, cancel, socketID)
  49. if err != nil {
  50. s.logger.Warnw("Cannot initialize client connection",
  51. "secret", s.secret,
  52. "addr", conn.RemoteAddr().String(),
  53. "socketid", socketID,
  54. "error", err,
  55. )
  56. return
  57. }
  58. defer clientConn.Close()
  59. tgConn, err := s.getTelegramStream(dc, ctx, cancel, socketID)
  60. if err != nil {
  61. s.logger.Warnw("Cannot initialize Telegram connection",
  62. "socketid", socketID,
  63. "error", err,
  64. )
  65. return
  66. }
  67. defer tgConn.Close()
  68. wait := &sync.WaitGroup{}
  69. wait.Add(2)
  70. go s.pipe(wait, clientConn, tgConn)
  71. go s.pipe(wait, tgConn, clientConn)
  72. <-ctx.Done()
  73. wait.Wait()
  74. s.logger.Debugw("Client disconnected",
  75. "secret", s.secret,
  76. "addr", conn.RemoteAddr().String(),
  77. "socketid", socketID,
  78. )
  79. }
  80. func (s *Server) makeSocketID() string {
  81. return uuid.NewV4().String()
  82. }
  83. func (s *Server) getClientStream(conn net.Conn, ctx context.Context, cancel context.CancelFunc, socketID string) (io.ReadWriteCloser, int16, error) {
  84. frame, err := obfuscated2.ExtractFrame(conn)
  85. if err != nil {
  86. return nil, 0, errors.Annotate(err, "Cannot create client stream")
  87. }
  88. obfs2, dc, err := obfuscated2.ParseObfuscated2ClientFrame(s.secret, frame)
  89. if err != nil {
  90. return nil, 0, errors.Annotate(err, "Cannot create client stream")
  91. }
  92. wConn := newLogReadWriteCloser(conn, s.logger, socketID, "client")
  93. wConn = newCipherReadWriteCloser(conn, obfs2)
  94. wConn = newCtxReadWriteCloser(wConn, ctx, cancel)
  95. return wConn, dc, nil
  96. }
  97. func (s *Server) getTelegramStream(dc int16, ctx context.Context, cancel context.CancelFunc, socketID string) (io.ReadWriteCloser, error) {
  98. socket, err := dialToTelegram(dc)
  99. if err != nil {
  100. return nil, errors.Annotate(err, "Cannot dial")
  101. }
  102. obfs2, frame := obfuscated2.MakeTelegramObfuscated2Frame()
  103. if n, err := socket.Write(frame); err != nil || n != len(frame) {
  104. return nil, errors.Annotate(err, "Cannot write hadnshake frame")
  105. }
  106. wConn := newLogReadWriteCloser(socket, s.logger, socketID, "telegram")
  107. wConn = newCipherReadWriteCloser(wConn, obfs2)
  108. wConn = newCtxReadWriteCloser(wConn, ctx, cancel)
  109. return wConn, nil
  110. }
  111. func (s *Server) pipe(wait *sync.WaitGroup, reader io.Reader, writer io.Writer) {
  112. defer wait.Done()
  113. buf := make([]byte, bufferSize)
  114. io.CopyBuffer(writer, reader, buf)
  115. }
  116. func NewServer(ip net.IP, port int, secret []byte, logger *zap.SugaredLogger) *Server {
  117. return &Server{
  118. ip: ip,
  119. port: port,
  120. secret: secret,
  121. ctx: context.Background(),
  122. logger: logger,
  123. }
  124. }