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.8KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121
  1. package wrappers
  2. import (
  3. "bytes"
  4. "io"
  5. "net"
  6. "github.com/juju/errors"
  7. "github.com/9seconds/mtg/mtproto"
  8. "github.com/9seconds/mtg/wrappers"
  9. )
  10. type uint24 [3]byte
  11. const (
  12. abridgedSmallPacketLength = 0x7f
  13. abridgedQuickAckLength = 0x80
  14. abridgedLargePacketLength = 16777216 // 256 ^ 3
  15. )
  16. type AbridgedReadWriteCloserWithAddr struct {
  17. wrappers.BufferedReader
  18. conn wrappers.ReadWriteCloserWithAddr
  19. opts *mtproto.ConnectionOpts
  20. }
  21. func (a *AbridgedReadWriteCloserWithAddr) Read(p []byte) (int, error) {
  22. return a.BufferedRead(p, func() error {
  23. buf := &bytes.Buffer{}
  24. buf.Grow(3)
  25. if _, err := io.CopyN(buf, a.conn, 1); err != nil {
  26. return errors.Annotate(err, "Cannot read message length")
  27. }
  28. msgLength := uint8(buf.Bytes()[0])
  29. buf.Reset()
  30. a.opts.QuickAck = false
  31. if msgLength >= abridgedQuickAckLength {
  32. a.opts.QuickAck = true
  33. msgLength -= 0x80
  34. }
  35. msgLength32 := uint32(msgLength)
  36. if msgLength == abridgedSmallPacketLength {
  37. if _, err := io.CopyN(buf, a.conn, 3); err != nil {
  38. return errors.Annotate(err, "Cannot read the 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. }