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

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566
  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. return fmt.Errorf("cannot send packet: %w", err)
  29. }
  30. return nil
  31. }
  32. func (h *hub) getHub(req *protocol.TelegramRequest) *connectionHub {
  33. keyBuilder := strings.Builder{}
  34. binary.Write(&keyBuilder, binary.LittleEndian, int16(req.ClientProtocol.DC()))
  35. keyBuilder.WriteRune('_')
  36. binary.Write(&keyBuilder, binary.LittleEndian, uint8(req.ClientProtocol.ConnectionProtocol()))
  37. key := keyBuilder.String()
  38. h.mutex.RLock()
  39. rv, ok := h.subs[key]
  40. h.mutex.RUnlock()
  41. if !ok {
  42. h.mutex.Lock()
  43. defer h.mutex.Unlock()
  44. rv, ok = h.subs[key]
  45. if !ok {
  46. rv = newConnectionHub(h.logger.With(
  47. "dc", req.ClientProtocol.DC(),
  48. "protocol", req.ClientProtocol.ConnectionProtocol(),
  49. ))
  50. h.subs[key] = rv
  51. }
  52. }
  53. return rv
  54. }