frame.go 1.6 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283
  1. package gfsmux // import "go.gridfinity.dev/gfsmux"
  2. import (
  3. "encoding/binary"
  4. "fmt"
  5. )
  6. const ( // cmds
  7. // protocol version 1:
  8. CmdSyn byte = iota // stream open
  9. CmdFin // stream close, a.k.a EOF mark
  10. CmdPsh // data push
  11. CmdNop // no operation
  12. // protocol version 2 extra commands
  13. // notify bytes consumed by remote peer-end
  14. cmdUPD
  15. )
  16. const (
  17. // data size of cmdUPD, format:
  18. // |4B data consumed(ACK)| 4B window size(WINDOW) |
  19. szCmdUPD = 8
  20. )
  21. const (
  22. // initial peer window guess, a slow-start
  23. initialPeerWindow = 262144
  24. )
  25. const (
  26. sizeOfVer = 1
  27. sizeOfCmd = 1
  28. sizeOfLength = 2
  29. sizeOfSid = 4
  30. HeaderSize = sizeOfVer + sizeOfCmd + sizeOfSid + sizeOfLength
  31. )
  32. // Frame defines a packet from or to be multiplexed into a single Connection
  33. type Frame struct {
  34. Ver byte
  35. Cmd byte
  36. Sid uint32
  37. Data []byte
  38. }
  39. func NewFrame(Version, Cmd byte, Sid uint32) Frame {
  40. return Frame{Ver: Version, Cmd: Cmd, Sid: Sid}
  41. }
  42. type rawHeader [HeaderSize]byte
  43. func (h rawHeader) Version() byte {
  44. return h[0]
  45. }
  46. func (h rawHeader) Cmd() byte {
  47. return h[1]
  48. }
  49. func (h rawHeader) Length() uint16 {
  50. return binary.LittleEndian.Uint16(h[2:])
  51. }
  52. func (h rawHeader) StreamID() uint32 {
  53. return binary.LittleEndian.Uint32(h[4:])
  54. }
  55. func (h rawHeader) String() string {
  56. return fmt.Sprintf("Version:%d Cmd:%d StreamID:%d Length:%d",
  57. h.Version(), h.Cmd(), h.StreamID(), h.Length())
  58. }
  59. type updHeader [szCmdUPD]byte
  60. func (h updHeader) Consumed() uint32 {
  61. return binary.LittleEndian.Uint32(h[:])
  62. }
  63. func (h updHeader) Window() uint32 {
  64. return binary.LittleEndian.Uint32(h[4:])
  65. }