reader.go 2.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116
  1. package io
  2. import (
  3. "hash"
  4. "hash/fnv"
  5. "io"
  6. "v2ray.com/core/common/alloc"
  7. "v2ray.com/core/common/errors"
  8. "v2ray.com/core/common/serial"
  9. )
  10. // Private: Visible for testing.
  11. type Validator struct {
  12. actualAuth hash.Hash32
  13. expectedAuth uint32
  14. }
  15. func NewValidator(expectedAuth uint32) *Validator {
  16. return &Validator{
  17. actualAuth: fnv.New32a(),
  18. expectedAuth: expectedAuth,
  19. }
  20. }
  21. func (v *Validator) Consume(b []byte) {
  22. v.actualAuth.Write(b)
  23. }
  24. func (v *Validator) Validate() bool {
  25. return v.actualAuth.Sum32() == v.expectedAuth
  26. }
  27. type AuthChunkReader struct {
  28. reader io.Reader
  29. last *alloc.Buffer
  30. chunkLength int
  31. validator *Validator
  32. }
  33. func NewAuthChunkReader(reader io.Reader) *AuthChunkReader {
  34. return &AuthChunkReader{
  35. reader: reader,
  36. chunkLength: -1,
  37. }
  38. }
  39. func (v *AuthChunkReader) Read() (*alloc.Buffer, error) {
  40. var buffer *alloc.Buffer
  41. if v.last != nil {
  42. buffer = v.last
  43. v.last = nil
  44. } else {
  45. buffer = alloc.NewBuffer().Clear()
  46. }
  47. if v.chunkLength == -1 {
  48. for buffer.Len() < 6 {
  49. _, err := buffer.FillFrom(v.reader)
  50. if err != nil {
  51. buffer.Release()
  52. return nil, io.ErrUnexpectedEOF
  53. }
  54. }
  55. length := serial.BytesToUint16(buffer.Value[:2])
  56. v.chunkLength = int(length) - 4
  57. v.validator = NewValidator(serial.BytesToUint32(buffer.Value[2:6]))
  58. buffer.SliceFrom(6)
  59. if buffer.Len() < v.chunkLength && v.chunkLength <= 2048 {
  60. _, err := buffer.FillFrom(v.reader)
  61. if err != nil {
  62. buffer.Release()
  63. return nil, io.ErrUnexpectedEOF
  64. }
  65. }
  66. } else if buffer.Len() < v.chunkLength {
  67. _, err := buffer.FillFrom(v.reader)
  68. if err != nil {
  69. buffer.Release()
  70. return nil, io.ErrUnexpectedEOF
  71. }
  72. }
  73. if v.chunkLength == 0 {
  74. buffer.Release()
  75. return nil, io.EOF
  76. }
  77. if buffer.Len() < v.chunkLength {
  78. v.validator.Consume(buffer.Value)
  79. v.chunkLength -= buffer.Len()
  80. } else {
  81. v.validator.Consume(buffer.Value[:v.chunkLength])
  82. if !v.validator.Validate() {
  83. buffer.Release()
  84. return nil, errors.New("VMess|AuthChunkReader: Invalid auth.")
  85. }
  86. leftLength := buffer.Len() - v.chunkLength
  87. if leftLength > 0 {
  88. v.last = alloc.NewBuffer().Clear()
  89. v.last.Append(buffer.Value[v.chunkLength:])
  90. buffer.Slice(0, v.chunkLength)
  91. }
  92. v.chunkLength = -1
  93. v.validator = nil
  94. }
  95. return buffer, nil
  96. }
  97. func (v *AuthChunkReader) Release() {
  98. v.reader = nil
  99. v.last.Release()
  100. v.last = nil
  101. v.validator = nil
  102. }