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.

connection_hub.go 1.7KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384
  1. package hub
  2. import "time"
  3. const hubGCEvery = time.Minute
  4. type connectionHub struct {
  5. sockets map[connectionID]*connection
  6. brokenSocketsChan chan connectionID
  7. connectionRequestsChan chan *connectionHubRequest
  8. returnConnectionsChan chan *connection
  9. }
  10. func (h *connectionHub) run() {
  11. gcTicker := time.NewTicker(hubGCEvery)
  12. defer gcTicker.Stop()
  13. for {
  14. select {
  15. case <-gcTicker.C:
  16. h.runGC()
  17. case id := <-h.brokenSocketsChan:
  18. h.runBrokenConnection(id)
  19. case request := <-h.connectionRequestsChan:
  20. h.runConnectionRequest(request)
  21. case conn := <-h.returnConnectionsChan:
  22. h.runReturnConnection(conn)
  23. }
  24. }
  25. }
  26. func (h *connectionHub) runBrokenConnection(id connectionID) {
  27. delete(h.sockets, id)
  28. }
  29. func (h *connectionHub) runGC() {
  30. for key, conn := range h.sockets {
  31. closing, pending := conn.Stats()
  32. switch {
  33. case closing:
  34. delete(h.sockets, key)
  35. case pending == 0:
  36. conn.Close()
  37. delete(h.sockets, key)
  38. return
  39. }
  40. }
  41. }
  42. func (h *connectionHub) runConnectionRequest(req *connectionHubRequest) {
  43. for key, conn := range h.sockets {
  44. closing, _ := conn.Stats()
  45. delete(h.sockets, key)
  46. if !closing {
  47. req.responseChan <- conn
  48. return
  49. }
  50. }
  51. newConn, err := newConnection(h, req.req)
  52. if err != nil {
  53. close(req.responseChan)
  54. return
  55. }
  56. req.responseChan <- newConn
  57. }
  58. func (h *connectionHub) runReturnConnection(conn *connection) {
  59. h.sockets[conn.id] = conn
  60. }
  61. func newConnectionHub() *connectionHub {
  62. return &connectionHub{
  63. sockets: map[connectionID]*connection{},
  64. brokenSocketsChan: make(chan connectionID, 1),
  65. connectionRequestsChan: make(chan *connectionHubRequest),
  66. returnConnectionsChan: make(chan *connection, 1),
  67. }
  68. }