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
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

middle.go 1.9KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576
  1. package proxy
  2. import (
  3. "context"
  4. "io"
  5. "net"
  6. "sync"
  7. "github.com/juju/errors"
  8. "github.com/9seconds/mtg/client"
  9. "github.com/9seconds/mtg/config"
  10. "github.com/9seconds/mtg/mtproto"
  11. "github.com/9seconds/mtg/telegram"
  12. "github.com/9seconds/mtg/wrappers"
  13. )
  14. func NewProxyMiddle(conf *config.Config) *Proxy {
  15. tg := telegram.NewMiddleTelegram(conf)
  16. return &Proxy{
  17. conf: conf,
  18. acceptCallback: func(ctx context.Context, cancel context.CancelFunc, clientSocket net.Conn,
  19. connID string, wait *sync.WaitGroup, conf *config.Config) (io.Closer, io.Closer, error) {
  20. client, opts, err := client.MiddleInit(ctx, cancel, clientSocket, connID, conf)
  21. if err != nil {
  22. return nil, nil, errors.Annotate(err, "Cannot initialize client connection")
  23. }
  24. server, err := middleTelegramStream(ctx, cancel, opts, connID, tg)
  25. if err != nil {
  26. return client, nil, errors.Annotate(err, "Cannot initialize telegram connection")
  27. }
  28. wait.Add(2)
  29. go middlePipe(client, server, wait, &opts.ReadHacks)
  30. go middlePipe(server, client, wait, &opts.WriteHacks)
  31. return client, server, nil
  32. },
  33. }
  34. }
  35. func middleTelegramStream(ctx context.Context, cancel context.CancelFunc, opts *mtproto.ConnectionOpts,
  36. connID string, tg *telegram.MiddleTelegram) (wrappers.WrapPacketReadWriteCloser, error) {
  37. streamConn, err := tg.Dial(connID, opts)
  38. if err != nil {
  39. return nil, errors.Annotate(err, "Cannot dial to Telegram")
  40. }
  41. streamConn = wrappers.NewCtx(ctx, cancel, streamConn)
  42. packetConn, err := tg.Init(opts, streamConn)
  43. if err != nil {
  44. return nil, errors.Annotate(err, "Cannot handshake telegram")
  45. }
  46. return packetConn, nil
  47. }
  48. func middlePipe(src wrappers.WrapPacketReader, dst wrappers.WrapPacketWriter, wait *sync.WaitGroup, hacks *mtproto.Hacks) {
  49. defer wait.Done()
  50. for {
  51. hacks.SimpleAck = false
  52. hacks.QuickAck = false
  53. packet, err := src.Read()
  54. if err != nil {
  55. return
  56. }
  57. if _, err = dst.Write(packet); err != nil {
  58. return
  59. }
  60. }
  61. }