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
Du kannst nicht mehr als 25 Themen auswählen Themen müssen mit entweder einem Buchstaben oder einer Ziffer beginnen. Sie können Bindestriche („-“) enthalten und bis zu 35 Zeichen lang sein.

proxy.go 2.3KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100
  1. package proxy
  2. import (
  3. "context"
  4. "net"
  5. "github.com/9seconds/mtg/config"
  6. "github.com/9seconds/mtg/conntypes"
  7. "github.com/9seconds/mtg/protocol"
  8. "github.com/9seconds/mtg/stats"
  9. "github.com/9seconds/mtg/utils"
  10. "github.com/9seconds/mtg/wrappers/stream"
  11. "go.uber.org/zap"
  12. )
  13. type Proxy struct {
  14. Logger *zap.SugaredLogger
  15. Context context.Context
  16. ClientProtocolMaker protocol.ClientProtocolMaker
  17. }
  18. func (p *Proxy) Serve(listener net.Listener) {
  19. doneChan := p.Context.Done()
  20. for {
  21. conn, err := listener.Accept()
  22. if err != nil {
  23. select {
  24. case <-doneChan:
  25. return
  26. default:
  27. p.Logger.Fatalw("Cannot allocate incoming connection", "error", err)
  28. }
  29. }
  30. go p.accept(conn)
  31. }
  32. }
  33. func (p *Proxy) accept(conn net.Conn) {
  34. defer func() {
  35. conn.Close()
  36. if err := recover(); err != nil {
  37. stats.Stats.Crash()
  38. p.Logger.Errorw("Crash of accept handler", "error", err)
  39. }
  40. }()
  41. connID := conntypes.NewConnID()
  42. logger := p.Logger.With("connection_id", connID)
  43. if err := utils.InitTCP(conn, config.C.ClientReadBuffer(), config.C.ClientWriteBuffer()); err != nil {
  44. logger.Errorw("Cannot initialize client TCP connection", "error", err)
  45. return
  46. }
  47. ctx, cancel := context.WithCancel(p.Context)
  48. defer cancel()
  49. clientConn := stream.NewClientConn(conn, connID)
  50. clientConn = stream.NewCtx(ctx, cancel, clientConn)
  51. clientConn = stream.NewTimeout(clientConn)
  52. defer clientConn.Close()
  53. clientProtocol := p.ClientProtocolMaker()
  54. clientConn, err := clientProtocol.Handshake(clientConn)
  55. if err != nil {
  56. stats.Stats.AuthenticationFailed()
  57. logger.Warnw("Cannot perform client handshake", "error", err)
  58. return
  59. }
  60. stats.Stats.ClientConnected(clientProtocol.ConnectionType(), clientConn.RemoteAddr())
  61. defer stats.Stats.ClientDisconnected(clientProtocol.ConnectionType(), clientConn.RemoteAddr())
  62. logger.Infow("Client connected", "addr", conn.RemoteAddr())
  63. req := &protocol.TelegramRequest{
  64. Logger: logger,
  65. ClientConn: clientConn,
  66. ConnID: connID,
  67. Ctx: ctx,
  68. Cancel: cancel,
  69. ClientProtocol: clientProtocol,
  70. }
  71. err = nil
  72. if config.C.MiddleProxyMode() {
  73. middleConnection(req)
  74. } else {
  75. err = directConnection(req)
  76. }
  77. logger.Infow("Client disconnected", "error", err, "addr", conn.RemoteAddr())
  78. }