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.

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