const.go 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157
  1. package yamux
  2. import (
  3. "encoding/binary"
  4. "fmt"
  5. )
  6. var (
  7. // ErrInvalidVersion means we received a frame with an
  8. // invalid version
  9. ErrInvalidVersion = fmt.Errorf("invalid protocol version")
  10. // ErrInvalidMsgType means we received a frame with an
  11. // invalid message type
  12. ErrInvalidMsgType = fmt.Errorf("invalid msg type")
  13. // ErrSessionShutdown is used if there is a shutdown during
  14. // an operation
  15. ErrSessionShutdown = fmt.Errorf("session shutdown")
  16. // ErrStreamsExhausted is returned if we have no more
  17. // stream ids to issue
  18. ErrStreamsExhausted = fmt.Errorf("streams exhausted")
  19. // ErrDuplicateStream is used if a duplicate stream is
  20. // opened inbound
  21. ErrDuplicateStream = fmt.Errorf("duplicate stream initiated")
  22. // ErrReceiveWindowExceeded indicates the window was exceeded
  23. ErrRecvWindowExceeded = fmt.Errorf("recv window exceeded")
  24. // ErrTimeout is used when we reach an IO deadline
  25. ErrTimeout = fmt.Errorf("i/o deadline reached")
  26. // ErrStreamClosed is returned when using a closed stream
  27. ErrStreamClosed = fmt.Errorf("stream closed")
  28. // ErrUnexpectedFlag is set when we get an unexpected flag
  29. ErrUnexpectedFlag = fmt.Errorf("unexpected flag")
  30. // ErrRemoteGoAway is used when we get a go away from the other side
  31. ErrRemoteGoAway = fmt.Errorf("remote end is not accepting connections")
  32. // ErrConnectionReset is sent if a stream is reset. This can happen
  33. // if the backlog is exceeded, or if there was a remote GoAway.
  34. ErrConnectionReset = fmt.Errorf("connection reset")
  35. // ErrConnectionWriteTimeout indicates that we hit the "safety valve"
  36. // timeout writing to the underlying stream connection.
  37. ErrConnectionWriteTimeout = fmt.Errorf("connection write timeout")
  38. // ErrKeepAliveTimeout is sent if a missed keepalive caused the stream close
  39. ErrKeepAliveTimeout = fmt.Errorf("keepalive timeout")
  40. )
  41. const (
  42. // protoVersion is the only version we support
  43. protoVersion uint8 = 0
  44. )
  45. const (
  46. // Data is used for data frames. They are followed
  47. // by length bytes worth of payload.
  48. typeData uint8 = iota
  49. // WindowUpdate is used to change the window of
  50. // a given stream. The length indicates the delta
  51. // update to the window.
  52. typeWindowUpdate
  53. // Ping is sent as a keep-alive or to measure
  54. // the RTT. The StreamID and Length value are echoed
  55. // back in the response.
  56. typePing
  57. // GoAway is sent to terminate a session. The StreamID
  58. // should be 0 and the length is an error code.
  59. typeGoAway
  60. )
  61. const (
  62. // SYN is sent to signal a new stream. May
  63. // be sent with a data payload
  64. flagSYN uint16 = 1 << iota
  65. // ACK is sent to acknowledge a new stream. May
  66. // be sent with a data payload
  67. flagACK
  68. // FIN is sent to half-close the given stream.
  69. // May be sent with a data payload.
  70. flagFIN
  71. // RST is used to hard close a given stream.
  72. flagRST
  73. )
  74. const (
  75. // initialStreamWindow is the initial stream window size
  76. initialStreamWindow uint32 = 256 * 1024
  77. )
  78. const (
  79. // goAwayNormal is sent on a normal termination
  80. goAwayNormal uint32 = iota
  81. // goAwayProtoErr sent on a protocol error
  82. goAwayProtoErr
  83. // goAwayInternalErr sent on an internal error
  84. goAwayInternalErr
  85. )
  86. const (
  87. sizeOfVersion = 1
  88. sizeOfType = 1
  89. sizeOfFlags = 2
  90. sizeOfStreamID = 4
  91. sizeOfLength = 4
  92. headerSize = sizeOfVersion + sizeOfType + sizeOfFlags +
  93. sizeOfStreamID + sizeOfLength
  94. )
  95. type header []byte
  96. func (h header) Version() uint8 {
  97. return h[0]
  98. }
  99. func (h header) MsgType() uint8 {
  100. return h[1]
  101. }
  102. func (h header) Flags() uint16 {
  103. return binary.BigEndian.Uint16(h[2:4])
  104. }
  105. func (h header) StreamID() uint32 {
  106. return binary.BigEndian.Uint32(h[4:8])
  107. }
  108. func (h header) Length() uint32 {
  109. return binary.BigEndian.Uint32(h[8:12])
  110. }
  111. func (h header) String() string {
  112. return fmt.Sprintf("Vsn:%d Type:%d Flags:%d StreamID:%d Length:%d",
  113. h.Version(), h.MsgType(), h.Flags(), h.StreamID(), h.Length())
  114. }
  115. func (h header) encode(msgType uint8, flags uint16, streamID uint32, length uint32) {
  116. h[0] = protoVersion
  117. h[1] = msgType
  118. binary.BigEndian.PutUint16(h[2:4], flags)
  119. binary.BigEndian.PutUint32(h[4:8], streamID)
  120. binary.BigEndian.PutUint32(h[8:12], length)
  121. }