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

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495
  1. package doppel
  2. import (
  3. "bytes"
  4. "context"
  5. "sync"
  6. "github.com/9seconds/mtg/v2/essentials"
  7. "github.com/9seconds/mtg/v2/mtglib/internal/tls"
  8. )
  9. type Conn struct {
  10. essentials.Conn
  11. p *connPayload
  12. }
  13. type connPayload struct {
  14. ctx context.Context
  15. ctxCancel context.CancelCauseFunc
  16. clock Clock
  17. wg sync.WaitGroup
  18. writeLock sync.Mutex
  19. writeStream bytes.Buffer
  20. }
  21. func (c Conn) Write(p []byte) (int, error) {
  22. c.p.writeLock.Lock()
  23. c.p.writeStream.Write(p)
  24. c.p.writeLock.Unlock()
  25. return len(p), context.Cause(c.p.ctx)
  26. }
  27. func (c Conn) Start() {
  28. c.p.wg.Go(func() {
  29. c.start()
  30. })
  31. }
  32. func (c Conn) start() {
  33. buf := [tls.MaxRecordSize]byte{}
  34. for {
  35. select {
  36. case <-c.p.ctx.Done():
  37. return
  38. case <-c.p.clock.tick:
  39. }
  40. c.p.writeLock.Lock()
  41. n, err := c.p.writeStream.Read(buf[:c.p.clock.stats.Size()])
  42. c.p.writeLock.Unlock()
  43. if n == 0 || err != nil {
  44. continue
  45. }
  46. if err := tls.WriteRecord(c.Conn, buf[:n]); err != nil {
  47. c.p.ctxCancel(err)
  48. return
  49. }
  50. }
  51. }
  52. func (c Conn) Stop() {
  53. c.p.ctxCancel(nil)
  54. c.p.wg.Wait()
  55. }
  56. func NewConn(ctx context.Context, conn essentials.Conn, stats *Stats) Conn {
  57. ctx, cancel := context.WithCancelCause(ctx)
  58. rv := Conn{
  59. Conn: conn,
  60. p: &connPayload{
  61. ctx: ctx,
  62. ctxCancel: cancel,
  63. clock: Clock{
  64. stats: stats,
  65. tick: make(chan struct{}),
  66. },
  67. },
  68. }
  69. rv.p.writeStream.Grow(tls.DefaultBufferSize)
  70. rv.p.wg.Go(func() {
  71. rv.p.clock.Start(ctx)
  72. })
  73. rv.p.wg.Go(func() {
  74. rv.start()
  75. })
  76. return rv
  77. }