reader.go 2.6 KB

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