// SPDX-FileCopyrightText: 2023 The Pion community <https://pion.ly>// SPDX-License-Identifier: MITpackage sctpimport ()/*chunkInitCommon 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 otherwisenoted, each parameter MUST only be included once in the INIT chunk.Fixed Parameters Status----------------------------------------------Initiate Tag MandatoryAdvertised Receiver Window Credit MandatoryNumber of Outbound Streams MandatoryNumber of Inbound Streams MandatoryInitial TSN Mandatory*/type chunkInitCommon struct { initiateTag uint32 advertisedReceiverWindowCredit uint32 numOutboundStreams uint16 numInboundStreams uint16 initialTSN uint32 params []param unrecognizedParams []paramHeader}const ( initChunkMinLength = 16 initOptionalVarHeaderLength = 4)// Init chunk errors.var (ErrInitChunkParseParamTypeFailed = errors.New("failed to parse param type")ErrInitAckMarshalParam = errors.New("unable to marshal parameter for INIT/INITACK"))func ( *chunkInitCommon) ( []byte) error { .initiateTag = binary.BigEndian.Uint32([0:]) .advertisedReceiverWindowCredit = binary.BigEndian.Uint32([4:]) .numOutboundStreams = binary.BigEndian.Uint16([8:]) .numInboundStreams = binary.BigEndian.Uint16([10:]) .initialTSN = binary.BigEndian.Uint32([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 | // | | // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ := initChunkMinLength := len() - for > 0 {if > initOptionalVarHeaderLength {varparamHeaderif := .unmarshal([:]); != nil {returnfmt.Errorf("%w: %v", ErrInitChunkParseParamTypeFailed, ) //nolint:errorlint } , := buildParam(.typ, [:])if != nil { .unrecognizedParams = append(.unrecognizedParams, ) } else { .params = append(.params, ) } := getPadding(.length()) += .length() + -= .length() + } else {break } }returnnil}func ( *chunkInitCommon) () ([]byte, error) { := make([]byte, initChunkMinLength)binary.BigEndian.PutUint32([0:], .initiateTag)binary.BigEndian.PutUint32([4:], .advertisedReceiverWindowCredit)binary.BigEndian.PutUint16([8:], .numOutboundStreams)binary.BigEndian.PutUint16([10:], .numInboundStreams)binary.BigEndian.PutUint32([12:], .initialTSN)for , := range .params { , := .marshal()if != nil {returnnil, fmt.Errorf("%w: %v", ErrInitAckMarshalParam, ) //nolint:errorlint } = append(, ...) //nolint:makezero // TODO: fix// Chunks (including Type, Length, and Value fields) are padded out // by the sender with all zero bytes to be a multiple of 4 bytes // long. This padding MUST NOT be more than 3 bytes in total. The // Chunk Length value does not include terminating padding of the // chunk. *However, it does include padding of any variable-length // parameter except the last parameter in the chunk.* The receiver // MUST ignore the padding.if != len(.params)-1 { = padByte(, getPadding(len())) } }return , nil}// String makes chunkInitCommon printable.func ( chunkInitCommon) () string { := `initiateTag: %d advertisedReceiverWindowCredit: %d numOutboundStreams: %d numInboundStreams: %d initialTSN: %d` := fmt.Sprintf(, .initiateTag, .advertisedReceiverWindowCredit, .numOutboundStreams, .numInboundStreams, .initialTSN, )for , := range .params { += fmt.Sprintf("Param %d:\n %s", , ) }return}
The pages are generated with Goldsv0.8.2. (GOOS=linux GOARCH=amd64)
Golds is a Go 101 project developed by Tapir Liu.
PR and bug reports are welcome and can be submitted to the issue list.
Please follow @zigo_101 (reachable from the left QR code) to get the latest news of Golds.