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_list.go 1.5KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970
  1. package hub
  2. import (
  3. "fmt"
  4. "sort"
  5. "github.com/9seconds/mtg/config"
  6. )
  7. type connectionList struct {
  8. connections []*connection
  9. }
  10. func (c *connectionList) Get(conn *ProxyConn) (*connection, error) {
  11. if len(c.connections) > 0 {
  12. c.gc()
  13. }
  14. if len(c.connections) > 0 && c.connections[0].Len() < config.C.MultiplexPerConnection {
  15. if err := c.connections[0].Attach(conn); err == nil {
  16. return c.connections[0], nil
  17. }
  18. }
  19. newConn, err := newConnection(conn.req)
  20. if err != nil {
  21. return nil, fmt.Errorf("cannot allocate a new connection: %w", err)
  22. }
  23. if err = newConn.Attach(conn); err != nil {
  24. newConn.Close()
  25. return nil, fmt.Errorf("cannot attach to the newly created connection: %w", err)
  26. }
  27. c.connections = append(c.connections, newConn)
  28. lastIndex := len(c.connections) - 1
  29. c.connections[0], c.connections[lastIndex] = c.connections[lastIndex], c.connections[0]
  30. return newConn, nil
  31. }
  32. func (c *connectionList) gc() {
  33. prevLen := len(c.connections)
  34. for i := len(c.connections) - 1; i >= 0; i-- {
  35. lastIndex := len(c.connections) - 1
  36. if c.connections[i].Done() {
  37. c.connections[i].Close()
  38. if len(c.connections)-1 == i {
  39. c.connections = c.connections[:lastIndex]
  40. } else {
  41. c.connections[i], c.connections[lastIndex] = c.connections[lastIndex], c.connections[i]
  42. }
  43. }
  44. }
  45. if prevLen != len(c.connections) {
  46. c.sort()
  47. }
  48. }
  49. func (c *connectionList) sort() {
  50. if len(c.connections) > 1 {
  51. sort.Slice(c.connections, func(i, j int) bool {
  52. return c.connections[i].Len() < c.connections[j].Len()
  53. })
  54. }
  55. }