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

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172
  1. package hub
  2. import (
  3. "encoding/binary"
  4. "fmt"
  5. "strings"
  6. "sync"
  7. "go.uber.org/zap"
  8. "github.com/9seconds/mtg/conntypes"
  9. "github.com/9seconds/mtg/protocol"
  10. )
  11. type hub struct {
  12. logger *zap.SugaredLogger
  13. subs map[string]*connectionHub
  14. mutex sync.RWMutex
  15. }
  16. func (h *hub) Write(packet conntypes.Packet, req *protocol.TelegramRequest) error {
  17. sub := h.getHub(req)
  18. connections := make(chan *connection)
  19. sub.channelConnectionRequests <- &connectionHubRequest{
  20. request: req,
  21. response: connections,
  22. }
  23. conn, ok := <-connections
  24. if !ok {
  25. return ErrCannotCreateConnection
  26. }
  27. if err := conn.write(packet); err != nil {
  28. conn.shutdown()
  29. return fmt.Errorf("cannot send packet: %w", err)
  30. }
  31. sub.channelReturnConnections <- conn
  32. return nil
  33. }
  34. func (h *hub) getHub(req *protocol.TelegramRequest) *connectionHub {
  35. keyBuilder := strings.Builder{}
  36. binary.Write(&keyBuilder, binary.LittleEndian, int16(req.ClientProtocol.DC()))
  37. keyBuilder.WriteRune('_')
  38. binary.Write(&keyBuilder, binary.LittleEndian, uint8(req.ClientProtocol.ConnectionProtocol()))
  39. key := keyBuilder.String()
  40. h.mutex.RLock()
  41. rv, ok := h.subs[key]
  42. h.mutex.RUnlock()
  43. if !ok {
  44. h.mutex.Lock()
  45. defer h.mutex.Unlock()
  46. rv, ok = h.subs[key]
  47. if !ok {
  48. h.logger.Debugw("Create new connection hub",
  49. "dc", req.ClientProtocol.DC(),
  50. "protocol", req.ClientProtocol.ConnectionProtocol())
  51. rv = newConnectionHub(h.logger.With(
  52. "dc", req.ClientProtocol.DC(),
  53. "protocol", req.ClientProtocol.ConnectionProtocol(),
  54. ))
  55. h.subs[key] = rv
  56. }
  57. }
  58. return rv
  59. }