chunk_shutdown.go 1.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869
  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. // Shutdown chunk errors
  25. var (
  26. ErrInvalidChunkSize = errors.New("invalid chunk size")
  27. ErrChunkTypeNotShutdown = errors.New("ChunkType is not of type SHUTDOWN")
  28. )
  29. func (c *chunkShutdown) unmarshal(raw []byte) error {
  30. if err := c.chunkHeader.unmarshal(raw); err != nil {
  31. return err
  32. }
  33. if c.typ != ctShutdown {
  34. return fmt.Errorf("%w: actually is %s", ErrChunkTypeNotShutdown, c.typ.String())
  35. }
  36. if len(c.raw) != cumulativeTSNAckLength {
  37. return ErrInvalidChunkSize
  38. }
  39. c.cumulativeTSNAck = binary.BigEndian.Uint32(c.raw[0:])
  40. return nil
  41. }
  42. func (c *chunkShutdown) marshal() ([]byte, error) {
  43. out := make([]byte, cumulativeTSNAckLength)
  44. binary.BigEndian.PutUint32(out[0:], c.cumulativeTSNAck)
  45. c.typ = ctShutdown
  46. c.raw = out
  47. return c.chunkHeader.marshal()
  48. }
  49. func (c *chunkShutdown) check() (abort bool, err error) {
  50. return false, nil
  51. }
  52. // String makes chunkShutdown printable
  53. func (c *chunkShutdown) String() string {
  54. return c.chunkHeader.String()
  55. }