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
Du kannst nicht mehr als 25 Themen auswählen Themen müssen mit entweder einem Buchstaben oder einer Ziffer beginnen. Sie können Bindestriche („-“) enthalten und bis zu 35 Zeichen lang sein.

proxy_conn.go 1.6KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879
  1. package hub
  2. import (
  3. "sync"
  4. "time"
  5. "github.com/9seconds/mtg/conntypes"
  6. "github.com/9seconds/mtg/mtproto/rpc"
  7. "github.com/9seconds/mtg/protocol"
  8. )
  9. const (
  10. proxyConnWriteTimeout = 2 * time.Minute
  11. proxyConnReadTimeout = 2 * time.Minute
  12. proxyConnBackpressureAfter = 10
  13. )
  14. type ProxyConn struct {
  15. closeOnce sync.Once
  16. req *protocol.TelegramRequest
  17. channelResponse chan *rpc.ProxyResponse
  18. channelClosed chan<- conntypes.ConnID
  19. channelWrite chan<- conntypes.Packet
  20. channelDone chan struct{}
  21. }
  22. func (p *ProxyConn) Read() (*rpc.ProxyResponse, error) {
  23. timer := time.NewTimer(proxyConnReadTimeout)
  24. defer timer.Stop()
  25. select {
  26. case <-timer.C:
  27. return nil, ErrTimeout
  28. case <-p.channelDone:
  29. return nil, ErrClosed
  30. case packet := <-p.channelResponse:
  31. return packet, nil
  32. }
  33. }
  34. func (p *ProxyConn) Write(packet conntypes.Packet) error {
  35. timer := time.NewTimer(proxyConnWriteTimeout)
  36. defer timer.Stop()
  37. select {
  38. case <-timer.C:
  39. return ErrTimeout
  40. case <-p.channelDone:
  41. return ErrClosed
  42. case p.channelWrite <- packet:
  43. return nil
  44. }
  45. }
  46. func (p *ProxyConn) put(response *rpc.ProxyResponse) {
  47. select {
  48. case <-p.channelDone:
  49. case p.channelResponse <- response:
  50. }
  51. }
  52. func (p *ProxyConn) Close() {
  53. p.closeOnce.Do(func() {
  54. close(p.channelDone)
  55. go func() {
  56. p.channelClosed <- p.req.ConnID
  57. }()
  58. })
  59. }
  60. func newProxyConn(req *protocol.TelegramRequest, channelClosed chan<- conntypes.ConnID) *ProxyConn {
  61. return &ProxyConn{
  62. channelResponse: make(chan *rpc.ProxyResponse, proxyConnBackpressureAfter),
  63. channelDone: make(chan struct{}),
  64. channelClosed: channelClosed,
  65. req: req,
  66. }
  67. }