chunk_shutdown.go 1.6 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768
  1. package sctp
  2. import (
  3. "encoding/binary"
  4. "errors"
  5. "fmt"
  6. )
  7. /*
  8. chunkShutdown represents an SCTP Chunk of type chunkShutdown
  9. 0 1 2 3
  10. 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
  11. +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  12. | Type = 7 | Chunk Flags | Length = 8 |
  13. +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  14. | Cumulative TSN Ack |
  15. +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  16. */
  17. type chunkShutdown struct {
  18. chunkHeader
  19. cumulativeTSNAck uint32
  20. }
  21. const (
  22. cumulativeTSNAckLength = 4
  23. )
  24. var (
  25. errInvalidChunkSize = errors.New("invalid chunk size")
  26. errChunkTypeNotShutdown = errors.New("ChunkType is not of type SHUTDOWN")
  27. )
  28. func (c *chunkShutdown) unmarshal(raw []byte) error {
  29. if err := c.chunkHeader.unmarshal(raw); err != nil {
  30. return err
  31. }
  32. if c.typ != ctShutdown {
  33. return fmt.Errorf("%w: actually is %s", errChunkTypeNotShutdown, c.typ.String())
  34. }
  35. if len(c.raw) != cumulativeTSNAckLength {
  36. return errInvalidChunkSize
  37. }
  38. c.cumulativeTSNAck = binary.BigEndian.Uint32(c.raw[0:])
  39. return nil
  40. }
  41. func (c *chunkShutdown) marshal() ([]byte, error) {
  42. out := make([]byte, cumulativeTSNAckLength)
  43. binary.BigEndian.PutUint32(out[0:], c.cumulativeTSNAck)
  44. c.typ = ctShutdown
  45. c.raw = out
  46. return c.chunkHeader.marshal()
  47. }
  48. func (c *chunkShutdown) check() (abort bool, err error) {
  49. return false, nil
  50. }
  51. // String makes chunkShutdown printable
  52. func (c *chunkShutdown) String() string {
  53. return c.chunkHeader.String()
  54. }