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.

mux.go 1.6KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990
  1. package hub
  2. import (
  3. "context"
  4. "time"
  5. "github.com/9seconds/mtg/conntypes"
  6. "github.com/9seconds/mtg/protocol"
  7. )
  8. const muxGCEvery = time.Minute
  9. type muxNewRequest struct {
  10. req *protocol.TelegramRequest
  11. resp chan<- muxNewResponse
  12. }
  13. type muxNewResponse struct {
  14. conn *ProxyConn
  15. err error
  16. }
  17. type mux struct {
  18. connections connectionList
  19. clients map[string]*connection
  20. ctx context.Context
  21. channelClosed chan conntypes.ConnID
  22. channelNew chan muxNewRequest
  23. }
  24. func (m *mux) run() {
  25. gcTicker := time.NewTicker(muxGCEvery)
  26. defer gcTicker.Stop()
  27. for {
  28. select {
  29. case <-m.ctx.Done():
  30. for _, v := range m.clients {
  31. v.Close()
  32. }
  33. return
  34. case <-gcTicker.C:
  35. m.connections.gc()
  36. case req := <-m.channelNew:
  37. m.connections.gc()
  38. proxyConn := newProxyConn(req.req, m.channelClosed)
  39. conn, err := m.connections.get(proxyConn)
  40. if err == nil {
  41. m.clients[string(req.req.ConnID[:])] = conn
  42. }
  43. req.resp <- muxNewResponse{
  44. conn: proxyConn,
  45. err: err,
  46. }
  47. close(req.resp)
  48. case connID := <-m.channelClosed:
  49. if conn, ok := m.clients[string(connID[:])]; ok {
  50. conn.Detach(connID)
  51. delete(m.clients, string(connID[:]))
  52. }
  53. }
  54. }
  55. }
  56. func (m *mux) Get(req *protocol.TelegramRequest) (*ProxyConn, error) {
  57. resp := make(chan muxNewResponse)
  58. m.channelNew <- muxNewRequest{
  59. req: req,
  60. resp: resp,
  61. }
  62. rv := <-resp
  63. return rv.conn, rv.err
  64. }
  65. func newMux(ctx context.Context) *mux {
  66. m := &mux{
  67. ctx: ctx,
  68. clients: make(map[string]*connection),
  69. channelClosed: make(chan conntypes.ConnID, 1),
  70. channelNew: make(chan muxNewRequest),
  71. }
  72. go m.run()
  73. return m
  74. }