mirror of
https://github.com/pion/webrtc.git
synced 2025-10-25 00:00:30 +08:00
117 lines
4.4 KiB
Go
117 lines
4.4 KiB
Go
package sctp
|
|
|
|
import (
|
|
"encoding/binary"
|
|
|
|
"github.com/pkg/errors"
|
|
)
|
|
|
|
/*
|
|
InitCommon represents an SCTP Chunk body of type INIT and INIT ACK
|
|
|
|
0 1 2 3
|
|
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
|
|
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
|
| Type = 1 | Chunk Flags | Chunk Length |
|
|
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
|
| Initiate Tag |
|
|
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
|
| Advertised Receiver Window Credit (a_rwnd) |
|
|
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
|
| Number of Outbound Streams | Number of Inbound Streams |
|
|
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
|
| Initial TSN |
|
|
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
|
| |
|
|
| Optional/Variable-Length Parameters |
|
|
| |
|
|
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
|
|
|
The INIT chunk contains the following parameters. Unless otherwise
|
|
noted, each parameter MUST only be included once in the INIT chunk.
|
|
|
|
Fixed Parameters Status
|
|
----------------------------------------------
|
|
Initiate Tag Mandatory
|
|
Advertised Receiver Window Credit Mandatory
|
|
Number of Outbound Streams Mandatory
|
|
Number of Inbound Streams Mandatory
|
|
Initial TSN Mandatory
|
|
*/
|
|
|
|
type InitCommon struct {
|
|
initiateTag uint32
|
|
advertisedReceiverWindowCredit uint32
|
|
numOutboundStreams uint16
|
|
numInboundStreams uint16
|
|
initialTSN uint32
|
|
params []Param
|
|
}
|
|
|
|
const (
|
|
initChunkMinLength = 16
|
|
initOptionalVarHeaderLength = 4
|
|
)
|
|
|
|
func getParamPadding(len uint16, multiple uint16) uint16 {
|
|
return (multiple - (len % multiple)) % multiple
|
|
}
|
|
|
|
// Unmarshal populates a Init Chunk from a byte slice
|
|
func (i *InitCommon) Unmarshal(raw []byte) error {
|
|
|
|
i.initiateTag = binary.BigEndian.Uint32(raw[0:])
|
|
i.advertisedReceiverWindowCredit = binary.BigEndian.Uint32(raw[4:])
|
|
i.numOutboundStreams = binary.BigEndian.Uint16(raw[8:])
|
|
i.numInboundStreams = binary.BigEndian.Uint16(raw[10:])
|
|
i.initialTSN = binary.BigEndian.Uint32(raw[12:])
|
|
|
|
// https://tools.ietf.org/html/rfc4960#section-3.2.1
|
|
//
|
|
// Chunk values of SCTP control chunks consist of a chunk-type-specific
|
|
// header of required fields, followed by zero or more parameters. The
|
|
// optional and variable-length parameters contained in a chunk are
|
|
// defined in a Type-Length-Value format as shown below.
|
|
//
|
|
// 0 1 2 3
|
|
// 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
|
|
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
|
// | Parameter Type | Parameter Length |
|
|
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
|
// | |
|
|
// | Parameter Value |
|
|
// | |
|
|
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
|
|
|
offset := initChunkMinLength
|
|
remaining := len(raw) - offset
|
|
for remaining > 0 {
|
|
if remaining > initOptionalVarHeaderLength {
|
|
paramType := ParamType(binary.BigEndian.Uint16(raw[offset:]))
|
|
p, err := BuildParam(paramType, raw[offset:])
|
|
if err != nil {
|
|
return errors.Wrap(err, "Failed unmarshalling param in Init Chunk")
|
|
}
|
|
i.params = append(i.params, p)
|
|
offset += int(p.Length())
|
|
remaining -= int(p.Length())
|
|
} else {
|
|
break
|
|
}
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
// Marshal generates raw data from a Init struct
|
|
func (i *InitCommon) Marshal() ([]byte, error) {
|
|
out := make([]byte, initChunkMinLength)
|
|
binary.BigEndian.PutUint32(out[0:], i.initiateTag)
|
|
binary.BigEndian.PutUint32(out[4:], i.advertisedReceiverWindowCredit)
|
|
binary.BigEndian.PutUint16(out[8:], i.numOutboundStreams)
|
|
binary.BigEndian.PutUint16(out[10:], i.numInboundStreams)
|
|
binary.BigEndian.PutUint32(out[12:], i.initialTSN)
|
|
|
|
return out, nil
|
|
}
|