chunk_heartbeat.go 2.7 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283
  1. package sctp
  2. import (
  3. "errors"
  4. "fmt"
  5. )
  6. /*
  7. chunkHeartbeat represents an SCTP Chunk of type HEARTBEAT
  8. An endpoint should send this chunk to its peer endpoint to probe the
  9. reachability of a particular destination transport address defined in
  10. the present association.
  11. The parameter field contains the Heartbeat Information, which is a
  12. variable-length opaque data structure understood only by the sender.
  13. 0 1 2 3
  14. 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
  15. +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  16. | Type = 4 | Chunk Flags | Heartbeat Length |
  17. +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  18. | |
  19. | Heartbeat Information TLV (Variable-Length) |
  20. | |
  21. +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  22. Defined as a variable-length parameter using the format described
  23. in Section 3.2.1, i.e.:
  24. Variable Parameters Status Type Value
  25. -------------------------------------------------------------
  26. heartbeat Info Mandatory 1
  27. */
  28. type chunkHeartbeat struct {
  29. chunkHeader
  30. params []param
  31. }
  32. var (
  33. errChunkTypeNotHeartbeat = errors.New("ChunkType is not of type HEARTBEAT")
  34. errHeartbeatNotLongEnoughInfo = errors.New("heartbeat is not long enough to contain Heartbeat Info")
  35. errParseParamTypeFailed = errors.New("failed to parse param type")
  36. errHeartbeatParam = errors.New("heartbeat should only have HEARTBEAT param")
  37. errHeartbeatChunkUnmarshal = errors.New("failed unmarshalling param in Heartbeat Chunk")
  38. )
  39. func (h *chunkHeartbeat) unmarshal(raw []byte) error {
  40. if err := h.chunkHeader.unmarshal(raw); err != nil {
  41. return err
  42. } else if h.typ != ctHeartbeat {
  43. return fmt.Errorf("%w: actually is %s", errChunkTypeNotHeartbeat, h.typ.String())
  44. }
  45. if len(raw) <= chunkHeaderSize {
  46. return fmt.Errorf("%w: %d", errHeartbeatNotLongEnoughInfo, len(raw))
  47. }
  48. pType, err := parseParamType(raw[chunkHeaderSize:])
  49. if err != nil {
  50. return fmt.Errorf("%w: %v", errParseParamTypeFailed, err)
  51. }
  52. if pType != heartbeatInfo {
  53. return fmt.Errorf("%w: instead have %s", errHeartbeatParam, pType.String())
  54. }
  55. p, err := buildParam(pType, raw[chunkHeaderSize:])
  56. if err != nil {
  57. return fmt.Errorf("%w: %v", errHeartbeatChunkUnmarshal, err)
  58. }
  59. h.params = append(h.params, p)
  60. return nil
  61. }
  62. func (h *chunkHeartbeat) Marshal() ([]byte, error) {
  63. return nil, errUnimplemented
  64. }
  65. func (h *chunkHeartbeat) check() (abort bool, err error) {
  66. return false, nil
  67. }