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

abridged.go 2.9KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121
  1. package wrappers
  2. import (
  3. "bytes"
  4. "encoding/binary"
  5. "io"
  6. "net"
  7. "github.com/juju/errors"
  8. "github.com/9seconds/mtg/mtproto"
  9. "github.com/9seconds/mtg/wrappers"
  10. )
  11. type uint24 [3]byte
  12. const (
  13. abridgedSmallPacketLength = 0x7f
  14. abridgedQuickAckLength = 0x80
  15. abridgedLargePacketLength = 16777216 // 256 ^ 3
  16. )
  17. type AbridgedReadWriteCloserWithAddr struct {
  18. wrappers.BufferedReader
  19. conn wrappers.ReadWriteCloserWithAddr
  20. opts *mtproto.ConnectionOpts
  21. }
  22. func (a *AbridgedReadWriteCloserWithAddr) Read(p []byte) (int, error) {
  23. return a.BufferedRead(p, func() error {
  24. var msgLength uint8
  25. if err := binary.Read(a.conn, binary.LittleEndian, &msgLength); err != nil {
  26. return errors.Annotate(err, "Cannot read message length")
  27. }
  28. a.opts.QuickAck = false
  29. if msgLength >= abridgedQuickAckLength {
  30. a.opts.QuickAck = true
  31. msgLength -= 0x80
  32. }
  33. msgLength32 := uint32(msgLength)
  34. if msgLength == abridgedSmallPacketLength {
  35. buf := &bytes.Buffer{}
  36. buf.Grow(3)
  37. if _, err := io.CopyN(buf, a.conn, 3); err != nil {
  38. return errors.Annotate(err, "Cannot read correct message length")
  39. }
  40. number := uint24{}
  41. copy(number[:], buf.Bytes())
  42. msgLength32 = fromUint24(number)
  43. }
  44. msgLength32 *= 4
  45. if _, err := io.CopyN(a.Buffer, a.conn, int64(msgLength32)); err != nil {
  46. return errors.Annotate(err, "Cannot read message")
  47. }
  48. return nil
  49. })
  50. }
  51. func (a *AbridgedReadWriteCloserWithAddr) Write(p []byte) (int, error) {
  52. if len(p)%4 != 0 {
  53. return 0, errors.Errorf("Incorrect packet length %d", len(p))
  54. }
  55. if a.opts.SimpleAck {
  56. return a.conn.Write(reverseBytes(p))
  57. }
  58. packetLength := len(p) / 4
  59. switch {
  60. case packetLength < abridgedSmallPacketLength:
  61. newData := append([]byte{byte(packetLength)}, p...)
  62. return a.conn.Write(newData)
  63. case packetLength < abridgedLargePacketLength:
  64. length24 := toUint24(uint32(packetLength))
  65. buf := &bytes.Buffer{}
  66. buf.Grow(1 + 3 + len(p))
  67. buf.WriteByte(byte(abridgedSmallPacketLength))
  68. buf.Write(length24[:])
  69. buf.Write(p)
  70. return a.conn.Write(buf.Bytes())
  71. default:
  72. return 0, errors.Errorf("Packet is too big %d", len(p))
  73. }
  74. }
  75. func (a *AbridgedReadWriteCloserWithAddr) Close() error {
  76. return a.conn.Close()
  77. }
  78. func (a *AbridgedReadWriteCloserWithAddr) LocalAddr() *net.TCPAddr {
  79. return a.conn.LocalAddr()
  80. }
  81. func (a *AbridgedReadWriteCloserWithAddr) RemoteAddr() *net.TCPAddr {
  82. return a.conn.RemoteAddr()
  83. }
  84. func toUint24(number uint32) uint24 {
  85. return uint24{byte(number), byte(number >> 8), byte(number >> 16)}
  86. }
  87. func fromUint24(number uint24) uint32 {
  88. return uint32(number[0]) + (uint32(number[1]) << 8) + (uint32(number[2]) << 16)
  89. }
  90. func NewAbridgedRWC(conn wrappers.ReadWriteCloserWithAddr, connOpts *mtproto.ConnectionOpts) wrappers.ReadWriteCloserWithAddr {
  91. return &AbridgedReadWriteCloserWithAddr{
  92. BufferedReader: wrappers.NewBufferedReader(),
  93. conn: conn,
  94. opts: connOpts,
  95. }
  96. }