package sctp
import (
"errors"
"fmt"
)
type chunkInit struct {
chunkHeader
chunkInitCommon
}
var (
ErrChunkTypeNotTypeInit = errors .New ("ChunkType is not of type INIT" )
ErrChunkValueNotLongEnough = errors .New ("chunk Value isn't long enough for mandatory parameters exp" )
ErrChunkTypeInitFlagZero = errors .New ("ChunkType of type INIT flags must be all 0" )
ErrChunkTypeInitUnmarshalFailed = errors .New ("failed to unmarshal INIT body" )
ErrChunkTypeInitMarshalFailed = errors .New ("failed marshaling INIT common data" )
ErrChunkTypeInitInitateTagZero = errors .New ("ChunkType of type INIT ACK InitiateTag must not be 0" )
ErrInitInboundStreamRequestZero = errors .New ("INIT ACK inbound stream request must be > 0" )
ErrInitOutboundStreamRequestZero = errors .New ("INIT ACK outbound stream request must be > 0" )
ErrInitAdvertisedReceiver1500 = errors .New ("INIT ACK Advertised Receiver Window Credit (a_rwnd) must be >= 1500" )
ErrInitUnknownParam = errors .New ("INIT with unknown param" )
)
func (i *chunkInit ) unmarshal (raw []byte ) error {
if err := i .chunkHeader .unmarshal (raw ); err != nil {
return err
}
if i .typ != ctInit {
return fmt .Errorf ("%w: actually is %s" , ErrChunkTypeNotTypeInit , i .typ .String ())
} else if len (i .raw ) < initChunkMinLength {
return fmt .Errorf ("%w: %d actual: %d" , ErrChunkValueNotLongEnough , initChunkMinLength , len (i .raw ))
}
if i .flags != 0 {
return ErrChunkTypeInitFlagZero
}
if err := i .chunkInitCommon .unmarshal (i .raw ); err != nil {
return fmt .Errorf ("%w: %v" , ErrChunkTypeInitUnmarshalFailed , err )
}
return nil
}
func (i *chunkInit ) marshal () ([]byte , error ) {
initShared , err := i .chunkInitCommon .marshal ()
if err != nil {
return nil , fmt .Errorf ("%w: %v" , ErrChunkTypeInitMarshalFailed , err )
}
i .chunkHeader .typ = ctInit
i .chunkHeader .raw = initShared
return i .chunkHeader .marshal ()
}
func (i *chunkInit ) check () (abort bool , err error ) {
if i .initiateTag == 0 {
return true , ErrChunkTypeInitInitateTagZero
}
if i .numInboundStreams == 0 {
return true , ErrInitInboundStreamRequestZero
}
if i .numOutboundStreams == 0 {
return true , ErrInitOutboundStreamRequestZero
}
if i .advertisedReceiverWindowCredit < 1500 {
return true , ErrInitAdvertisedReceiver1500
}
for _ , p := range i .unrecognizedParams {
if p .unrecognizedAction == paramHeaderUnrecognizedActionStop ||
p .unrecognizedAction == paramHeaderUnrecognizedActionStopAndReport {
return true , ErrInitUnknownParam
}
}
return false , nil
}
func (i *chunkInit ) String () string {
return fmt .Sprintf ("%s\n%s" , i .chunkHeader , i .chunkInitCommon )
}
The pages are generated with Golds v0.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 .