param_outgoing_reset_request.go 3.8 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788
  1. package sctp
  2. import (
  3. "encoding/binary"
  4. "errors"
  5. )
  6. const (
  7. paramOutgoingResetRequestStreamIdentifiersOffset = 12
  8. )
  9. // This parameter is used by the sender to request the reset of some or
  10. // all outgoing streams.
  11. // 0 1 2 3
  12. // 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
  13. // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  14. // | Parameter Type = 13 | Parameter Length = 16 + 2 * N |
  15. // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  16. // | Re-configuration Request Sequence Number |
  17. // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  18. // | Re-configuration Response Sequence Number |
  19. // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  20. // | Sender's Last Assigned TSN |
  21. // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  22. // | Stream Number 1 (optional) | Stream Number 2 (optional) |
  23. // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  24. // / ...... /
  25. // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  26. // | Stream Number N-1 (optional) | Stream Number N (optional) |
  27. // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  28. type paramOutgoingResetRequest struct {
  29. paramHeader
  30. // reconfigRequestSequenceNumber is used to identify the request. It is a monotonically
  31. // increasing number that is initialized to the same value as the
  32. // initial TSN. It is increased by 1 whenever sending a new Re-
  33. // configuration Request Parameter.
  34. reconfigRequestSequenceNumber uint32
  35. // When this Outgoing SSN Reset Request Parameter is sent in response
  36. // to an Incoming SSN Reset Request Parameter, this parameter is also
  37. // an implicit response to the incoming request. This field then
  38. // holds the Re-configuration Request Sequence Number of the incoming
  39. // request. In other cases, it holds the next expected
  40. // Re-configuration Request Sequence Number minus 1.
  41. reconfigResponseSequenceNumber uint32
  42. // This value holds the next TSN minus 1 -- in other words, the last
  43. // TSN that this sender assigned.
  44. senderLastTSN uint32
  45. // This optional field, if included, is used to indicate specific
  46. // streams that are to be reset. If no streams are listed, then all
  47. // streams are to be reset.
  48. streamIdentifiers []uint16
  49. }
  50. var errSSNResetRequestParamTooShort = errors.New("outgoing SSN reset request parameter too short")
  51. func (r *paramOutgoingResetRequest) marshal() ([]byte, error) {
  52. r.typ = outSSNResetReq
  53. r.raw = make([]byte, paramOutgoingResetRequestStreamIdentifiersOffset+2*len(r.streamIdentifiers))
  54. binary.BigEndian.PutUint32(r.raw, r.reconfigRequestSequenceNumber)
  55. binary.BigEndian.PutUint32(r.raw[4:], r.reconfigResponseSequenceNumber)
  56. binary.BigEndian.PutUint32(r.raw[8:], r.senderLastTSN)
  57. for i, sID := range r.streamIdentifiers {
  58. binary.BigEndian.PutUint16(r.raw[paramOutgoingResetRequestStreamIdentifiersOffset+2*i:], sID)
  59. }
  60. return r.paramHeader.marshal()
  61. }
  62. func (r *paramOutgoingResetRequest) unmarshal(raw []byte) (param, error) {
  63. err := r.paramHeader.unmarshal(raw)
  64. if err != nil {
  65. return nil, err
  66. }
  67. if len(r.raw) < paramOutgoingResetRequestStreamIdentifiersOffset {
  68. return nil, errSSNResetRequestParamTooShort
  69. }
  70. r.reconfigRequestSequenceNumber = binary.BigEndian.Uint32(r.raw)
  71. r.reconfigResponseSequenceNumber = binary.BigEndian.Uint32(r.raw[4:])
  72. r.senderLastTSN = binary.BigEndian.Uint32(r.raw[8:])
  73. lim := (len(r.raw) - paramOutgoingResetRequestStreamIdentifiersOffset) / 2
  74. r.streamIdentifiers = make([]uint16, lim)
  75. for i := 0; i < lim; i++ {
  76. r.streamIdentifiers[i] = binary.BigEndian.Uint16(r.raw[paramOutgoingResetRequestStreamIdentifiersOffset+2*i:])
  77. }
  78. return r, nil
  79. }