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文字以内のものにしてください。

faketls.go 3.1KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149
  1. package stream
  2. import (
  3. "bytes"
  4. "encoding/binary"
  5. "errors"
  6. "fmt"
  7. "io"
  8. "net"
  9. "time"
  10. "go.uber.org/zap"
  11. "github.com/9seconds/mtg/conntypes"
  12. )
  13. var (
  14. errFakeTLSTimeout = errors.New("timeout")
  15. fakeTLSWritePrefix = []byte{0x17, 0x03, 0x03}
  16. )
  17. const (
  18. faketlsMaxChunkSize = 16384 + 24
  19. faketlsRecordTypeApplicationData = 0x17
  20. faketlsRecordTypeCCS = 0x14
  21. )
  22. type wrapperFakeTLS struct {
  23. bufferedReader
  24. parent conntypes.StreamReadWriteCloser
  25. }
  26. func (w *wrapperFakeTLS) Write(p []byte) (int, error) {
  27. return w.write(p, func(b []byte) (int, error) {
  28. return w.parent.Write(b)
  29. })
  30. }
  31. func (w *wrapperFakeTLS) WriteTimeout(p []byte, timeout time.Duration) (int, error) {
  32. startTime := time.Now()
  33. return w.write(p, func(b []byte) (int, error) {
  34. elapsed := time.Since(startTime)
  35. if elapsed > timeout {
  36. return w.parent.WriteTimeout(b, timeout-elapsed)
  37. }
  38. return 0, errFakeTLSTimeout
  39. })
  40. }
  41. func (w *wrapperFakeTLS) write(p []byte, writeFunc func([]byte) (int, error)) (int, error) {
  42. sum := 0
  43. size := [2]byte{}
  44. for len(p) > 0 {
  45. chunkSize := faketlsMaxChunkSize
  46. if chunkSize > len(p) {
  47. chunkSize = len(p)
  48. }
  49. if _, err := writeFunc(fakeTLSWritePrefix); err != nil {
  50. return sum, err
  51. }
  52. binary.BigEndian.PutUint16(size[:], uint16(chunkSize))
  53. if _, err := writeFunc(size[:]); err != nil {
  54. return sum, err
  55. }
  56. n, err := writeFunc(p[:chunkSize])
  57. sum += n
  58. if err != nil {
  59. return sum, err
  60. }
  61. p = p[chunkSize:]
  62. }
  63. return sum, nil
  64. }
  65. func (w *wrapperFakeTLS) Conn() net.Conn {
  66. return w.parent.Conn()
  67. }
  68. func (w *wrapperFakeTLS) Logger() *zap.SugaredLogger {
  69. return w.parent.Logger().Named("faketls")
  70. }
  71. func (w *wrapperFakeTLS) LocalAddr() *net.TCPAddr {
  72. return w.parent.LocalAddr()
  73. }
  74. func (w *wrapperFakeTLS) RemoteAddr() *net.TCPAddr {
  75. return w.parent.RemoteAddr()
  76. }
  77. func (w *wrapperFakeTLS) Close() error {
  78. return w.parent.Close()
  79. }
  80. func NewFakeTLS(socket conntypes.StreamReadWriteCloser) conntypes.StreamReadWriteCloser {
  81. faketls := &wrapperFakeTLS{
  82. parent: socket,
  83. }
  84. faketls.readFunc = func() ([]byte, error) {
  85. data := &bytes.Buffer{}
  86. buf := [2]byte{}
  87. recordType := byte(faketlsRecordTypeCCS)
  88. for recordType == faketlsRecordTypeCCS {
  89. if _, err := io.ReadFull(faketls.parent, buf[:1]); err != nil {
  90. return nil, fmt.Errorf("cannot read record type: %w", err)
  91. }
  92. switch buf[0] {
  93. case faketlsRecordTypeCCS, faketlsRecordTypeApplicationData:
  94. recordType = buf[0]
  95. default:
  96. return nil, fmt.Errorf("incorrect record type %v", buf[0])
  97. }
  98. if _, err := io.ReadFull(faketls.parent, buf[:]); err != nil {
  99. return nil, fmt.Errorf("cannot read version: %w", err)
  100. }
  101. if !bytes.Equal(buf[:], []byte{0x03, 0x03}) {
  102. return nil, fmt.Errorf("unknown tls version %v", buf)
  103. }
  104. if _, err := io.ReadFull(faketls.parent, buf[:]); err != nil {
  105. return nil, fmt.Errorf("cannot read data length: %w", err)
  106. }
  107. dataLength := binary.BigEndian.Uint16(buf[:])
  108. if _, err := io.CopyN(data, faketls.parent, int64(dataLength)); err != nil {
  109. return nil, fmt.Errorf("cannot copy frame data: %w", err)
  110. }
  111. }
  112. return data.Bytes(), nil
  113. }
  114. return faketls
  115. }