reader.go 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122
  1. package io // import "github.com/v2ray/v2ray-core/common/io"
  2. import (
  3. "io"
  4. "github.com/v2ray/v2ray-core/common/alloc"
  5. "github.com/v2ray/v2ray-core/common/crypto"
  6. "github.com/v2ray/v2ray-core/common/serial"
  7. "github.com/v2ray/v2ray-core/transport"
  8. )
  9. // ReadFrom reads from a reader and put all content to a buffer.
  10. // If buffer is nil, ReadFrom creates a new normal buffer.
  11. func ReadFrom(reader io.Reader, buffer *alloc.Buffer) (*alloc.Buffer, error) {
  12. if buffer == nil {
  13. buffer = alloc.NewBuffer()
  14. }
  15. nBytes, err := reader.Read(buffer.Value)
  16. buffer.Slice(0, nBytes)
  17. return buffer, err
  18. }
  19. type Reader interface {
  20. Read() (*alloc.Buffer, error)
  21. }
  22. type AdaptiveReader struct {
  23. reader io.Reader
  24. allocate func() *alloc.Buffer
  25. isLarge bool
  26. }
  27. func NewAdaptiveReader(reader io.Reader) *AdaptiveReader {
  28. return &AdaptiveReader{
  29. reader: reader,
  30. allocate: alloc.NewBuffer,
  31. isLarge: false,
  32. }
  33. }
  34. func (this *AdaptiveReader) Read() (*alloc.Buffer, error) {
  35. buffer, err := ReadFrom(this.reader, this.allocate())
  36. if buffer.IsFull() && !this.isLarge {
  37. this.allocate = alloc.NewLargeBuffer
  38. this.isLarge = true
  39. } else if !buffer.IsFull() {
  40. this.allocate = alloc.NewBuffer
  41. this.isLarge = false
  42. }
  43. if err != nil {
  44. alloc.Release(buffer)
  45. return nil, err
  46. }
  47. return buffer, nil
  48. }
  49. type ChunkReader struct {
  50. reader io.Reader
  51. }
  52. func NewChunkReader(reader io.Reader) *ChunkReader {
  53. return &ChunkReader{
  54. reader: reader,
  55. }
  56. }
  57. func (this *ChunkReader) Read() (*alloc.Buffer, error) {
  58. buffer := alloc.NewLargeBuffer()
  59. if _, err := io.ReadFull(this.reader, buffer.Value[:2]); err != nil {
  60. alloc.Release(buffer)
  61. return nil, err
  62. }
  63. length := serial.BytesLiteral(buffer.Value[:2]).Uint16Value()
  64. if _, err := io.ReadFull(this.reader, buffer.Value[:length]); err != nil {
  65. alloc.Release(buffer)
  66. return nil, err
  67. }
  68. buffer.Slice(0, int(length))
  69. return buffer, nil
  70. }
  71. type AuthenticationReader struct {
  72. reader Reader
  73. authenticator crypto.Authenticator
  74. authBeforePayload bool
  75. }
  76. func NewAuthenticationReader(reader io.Reader, auth crypto.Authenticator, authBeforePayload bool) *AuthenticationReader {
  77. return &AuthenticationReader{
  78. reader: NewChunkReader(reader),
  79. authenticator: auth,
  80. authBeforePayload: authBeforePayload,
  81. }
  82. }
  83. func (this *AuthenticationReader) Read() (*alloc.Buffer, error) {
  84. buffer, err := this.reader.Read()
  85. if err != nil {
  86. alloc.Release(buffer)
  87. return nil, err
  88. }
  89. authSize := this.authenticator.AuthSize()
  90. var authBytes, payloadBytes []byte
  91. if this.authBeforePayload {
  92. authBytes = buffer.Value[:authSize]
  93. payloadBytes = buffer.Value[authSize:]
  94. } else {
  95. payloadBytes = buffer.Value[:authSize]
  96. authBytes = buffer.Value[authSize:]
  97. }
  98. actualAuthBytes := this.authenticator.Authenticate(nil, payloadBytes)
  99. if !serial.BytesLiteral(authBytes).Equals(serial.BytesLiteral(actualAuthBytes)) {
  100. alloc.Release(buffer)
  101. return nil, transport.CorruptedPacket
  102. }
  103. buffer.Value = payloadBytes
  104. return buffer, nil
  105. }