chunk.go 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143
  1. package crypto
  2. import (
  3. "io"
  4. "v2ray.com/core/common"
  5. "v2ray.com/core/common/buf"
  6. "v2ray.com/core/common/serial"
  7. )
  8. // ChunkSizeDecoder is a utility class to decode size value from bytes.
  9. type ChunkSizeDecoder interface {
  10. SizeBytes() int32
  11. Decode([]byte) (uint16, error)
  12. }
  13. // ChunkSizeEncoder is a utility class to encode size value into bytes.
  14. type ChunkSizeEncoder interface {
  15. SizeBytes() int32
  16. Encode(uint16, []byte) []byte
  17. }
  18. type PaddingLengthGenerator interface {
  19. NextPaddingLen() uint16
  20. }
  21. type PlainChunkSizeParser struct{}
  22. func (PlainChunkSizeParser) SizeBytes() int32 {
  23. return 2
  24. }
  25. func (PlainChunkSizeParser) Encode(size uint16, b []byte) []byte {
  26. return serial.Uint16ToBytes(size, b)
  27. }
  28. func (PlainChunkSizeParser) Decode(b []byte) (uint16, error) {
  29. return serial.BytesToUint16(b), nil
  30. }
  31. type AEADChunkSizeParser struct {
  32. Auth *AEADAuthenticator
  33. }
  34. func (p *AEADChunkSizeParser) SizeBytes() int32 {
  35. return 2 + int32(p.Auth.Overhead())
  36. }
  37. func (p *AEADChunkSizeParser) Encode(size uint16, b []byte) []byte {
  38. b = serial.Uint16ToBytes(size-uint16(p.Auth.Overhead()), b)
  39. b, err := p.Auth.Seal(b[:0], b)
  40. common.Must(err)
  41. return b
  42. }
  43. func (p *AEADChunkSizeParser) Decode(b []byte) (uint16, error) {
  44. b, err := p.Auth.Open(b[:0], b)
  45. if err != nil {
  46. return 0, err
  47. }
  48. return serial.BytesToUint16(b) + uint16(p.Auth.Overhead()), nil
  49. }
  50. type ChunkStreamReader struct {
  51. sizeDecoder ChunkSizeDecoder
  52. reader *buf.BufferedReader
  53. buffer []byte
  54. leftOverSize int32
  55. }
  56. func NewChunkStreamReader(sizeDecoder ChunkSizeDecoder, reader io.Reader) *ChunkStreamReader {
  57. return &ChunkStreamReader{
  58. sizeDecoder: sizeDecoder,
  59. reader: &buf.BufferedReader{Reader: buf.NewReader(reader)},
  60. buffer: make([]byte, sizeDecoder.SizeBytes()),
  61. }
  62. }
  63. func (r *ChunkStreamReader) readSize() (uint16, error) {
  64. if _, err := io.ReadFull(r.reader, r.buffer); err != nil {
  65. return 0, err
  66. }
  67. return r.sizeDecoder.Decode(r.buffer)
  68. }
  69. func (r *ChunkStreamReader) ReadMultiBuffer() (buf.MultiBuffer, error) {
  70. size := r.leftOverSize
  71. if size == 0 {
  72. nextSize, err := r.readSize()
  73. if err != nil {
  74. return nil, err
  75. }
  76. if nextSize == 0 {
  77. return nil, io.EOF
  78. }
  79. size = int32(nextSize)
  80. }
  81. r.leftOverSize = size
  82. mb, err := r.reader.ReadAtMost(size)
  83. if !mb.IsEmpty() {
  84. r.leftOverSize -= mb.Len()
  85. return mb, nil
  86. }
  87. return nil, err
  88. }
  89. type ChunkStreamWriter struct {
  90. sizeEncoder ChunkSizeEncoder
  91. writer buf.Writer
  92. }
  93. func NewChunkStreamWriter(sizeEncoder ChunkSizeEncoder, writer io.Writer) *ChunkStreamWriter {
  94. return &ChunkStreamWriter{
  95. sizeEncoder: sizeEncoder,
  96. writer: buf.NewWriter(writer),
  97. }
  98. }
  99. func (w *ChunkStreamWriter) WriteMultiBuffer(mb buf.MultiBuffer) error {
  100. const sliceSize = 8192
  101. mbLen := mb.Len()
  102. mb2Write := buf.NewMultiBufferCap(mbLen/buf.Size + mbLen/sliceSize + 2)
  103. for {
  104. slice := mb.SliceBySize(sliceSize)
  105. b := buf.New()
  106. common.Must(b.Reset(func(buffer []byte) (int, error) {
  107. w.sizeEncoder.Encode(uint16(slice.Len()), buffer[:0])
  108. return int(w.sizeEncoder.SizeBytes()), nil
  109. }))
  110. mb2Write.Append(b)
  111. mb2Write.AppendMulti(slice)
  112. if mb.IsEmpty() {
  113. break
  114. }
  115. }
  116. return w.writer.WriteMultiBuffer(mb2Write)
  117. }