frame-reader.go 2.2 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798
  1. // Read a generic "framed" packet consisting of a header and a
  2. // This is used for both TLS Records and TLS Handshake Messages
  3. package mint
  4. type framing interface {
  5. headerLen() int
  6. defaultReadLen() int
  7. frameLen(hdr []byte) (int, error)
  8. }
  9. const (
  10. kFrameReaderHdr = 0
  11. kFrameReaderBody = 1
  12. )
  13. type frameNextAction func(f *frameReader) error
  14. type frameReader struct {
  15. details framing
  16. state uint8
  17. header []byte
  18. body []byte
  19. working []byte
  20. writeOffset int
  21. remainder []byte
  22. }
  23. func newFrameReader(d framing) *frameReader {
  24. hdr := make([]byte, d.headerLen())
  25. return &frameReader{
  26. d,
  27. kFrameReaderHdr,
  28. hdr,
  29. nil,
  30. hdr,
  31. 0,
  32. nil,
  33. }
  34. }
  35. func dup(a []byte) []byte {
  36. r := make([]byte, len(a))
  37. copy(r, a)
  38. return r
  39. }
  40. func (f *frameReader) needed() int {
  41. tmp := (len(f.working) - f.writeOffset) - len(f.remainder)
  42. if tmp < 0 {
  43. return 0
  44. }
  45. return tmp
  46. }
  47. func (f *frameReader) addChunk(in []byte) {
  48. // Append to the buffer.
  49. logf(logTypeFrameReader, "Appending %v", len(in))
  50. f.remainder = append(f.remainder, in...)
  51. }
  52. func (f *frameReader) process() (hdr []byte, body []byte, err error) {
  53. for f.needed() == 0 {
  54. logf(logTypeFrameReader, "%v bytes needed for next block", len(f.working)-f.writeOffset)
  55. // Fill out our working block
  56. copied := copy(f.working[f.writeOffset:], f.remainder)
  57. f.remainder = f.remainder[copied:]
  58. f.writeOffset += copied
  59. if f.writeOffset < len(f.working) {
  60. logf(logTypeVerbose, "Read would have blocked 1")
  61. return nil, nil, AlertWouldBlock
  62. }
  63. // Reset the write offset, because we are now full.
  64. f.writeOffset = 0
  65. // We have read a full frame
  66. if f.state == kFrameReaderBody {
  67. logf(logTypeFrameReader, "Returning frame hdr=%#x len=%d buffered=%d", f.header, len(f.body), len(f.remainder))
  68. f.state = kFrameReaderHdr
  69. f.working = f.header
  70. return dup(f.header), dup(f.body), nil
  71. }
  72. // We have read the header
  73. bodyLen, err := f.details.frameLen(f.header)
  74. if err != nil {
  75. return nil, nil, err
  76. }
  77. logf(logTypeFrameReader, "Processed header, body len = %v", bodyLen)
  78. f.body = make([]byte, bodyLen)
  79. f.working = f.body
  80. f.writeOffset = 0
  81. f.state = kFrameReaderBody
  82. }
  83. logf(logTypeVerbose, "Read would have blocked 2")
  84. return nil, nil, AlertWouldBlock
  85. }