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文字以内のものにしてください。

proxy.go 1.5KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273
  1. package proxy
  2. import (
  3. "context"
  4. "io"
  5. "net"
  6. "sync"
  7. "github.com/juju/errors"
  8. uuid "github.com/satori/go.uuid"
  9. "go.uber.org/zap"
  10. "github.com/9seconds/mtg/config"
  11. )
  12. type proxyAcceptCallback func(context.Context, context.CancelFunc, net.Conn, string, *sync.WaitGroup, *config.Config) (io.Closer, io.Closer, error)
  13. type Proxy struct {
  14. conf *config.Config
  15. acceptCallback proxyAcceptCallback
  16. }
  17. func (p *Proxy) Serve() error {
  18. lsock, err := net.Listen("tcp", p.conf.BindAddr())
  19. if err != nil {
  20. return errors.Annotate(err, "Cannot create listen socket")
  21. }
  22. for {
  23. if conn, err := lsock.Accept(); err != nil {
  24. zap.S().Errorw("Cannot allocate incoming connection", "error", err)
  25. } else {
  26. go p.accept(conn)
  27. }
  28. }
  29. }
  30. func (p *Proxy) accept(conn net.Conn) {
  31. connID := uuid.NewV4().String()
  32. log := zap.S().With("connection_id", connID)
  33. defer func() {
  34. conn.Close()
  35. if err := recover(); err != nil {
  36. log.Errorw("Crash of accept handler", "error", err)
  37. }
  38. }()
  39. log.Infow("Client connected", "addr", conn.RemoteAddr())
  40. ctx, cancel := context.WithCancel(context.Background())
  41. wait := &sync.WaitGroup{}
  42. client, server, err := p.acceptCallback(ctx, cancel, conn, connID, wait, p.conf)
  43. defer func() {
  44. if client != nil {
  45. client.Close()
  46. }
  47. if server != nil {
  48. server.Close()
  49. }
  50. }()
  51. if err != nil {
  52. log.Errorw("Cannot initialize connection", "error", err)
  53. cancel()
  54. }
  55. <-ctx.Done()
  56. wait.Wait()
  57. log.Infow("Client disconnected", "addr", conn.RemoteAddr())
  58. }