package sctp
import (
"encoding/binary"
"errors"
"fmt"
"time"
)
type chunkPayloadData struct {
chunkHeader
unordered bool
beginningFragment bool
endingFragment bool
immediateSack bool
tsn uint32
streamIdentifier uint16
streamSequenceNumber uint16
payloadType PayloadProtocolIdentifier
userData []byte
acked bool
missIndicator uint32
since time .Time
nSent uint32
_abandoned bool
_allInflight bool
retransmit bool
head *chunkPayloadData
}
const (
payloadDataEndingFragmentBitmask = 1
payloadDataBeginingFragmentBitmask = 2
payloadDataUnorderedBitmask = 4
payloadDataImmediateSACK = 8
payloadDataHeaderSize = 12
)
type PayloadProtocolIdentifier uint32
const (
PayloadTypeUnknown PayloadProtocolIdentifier = 0
PayloadTypeWebRTCDCEP PayloadProtocolIdentifier = 50
PayloadTypeWebRTCString PayloadProtocolIdentifier = 51
PayloadTypeWebRTCBinary PayloadProtocolIdentifier = 53
PayloadTypeWebRTCStringEmpty PayloadProtocolIdentifier = 56
PayloadTypeWebRTCBinaryEmpty PayloadProtocolIdentifier = 57
)
var (
ErrChunkPayloadSmall = errors .New ("packet is smaller than the header size" )
)
func (p PayloadProtocolIdentifier ) String () string {
switch p {
case PayloadTypeWebRTCDCEP :
return "WebRTC DCEP"
case PayloadTypeWebRTCString :
return "WebRTC String"
case PayloadTypeWebRTCBinary :
return "WebRTC Binary"
case PayloadTypeWebRTCStringEmpty :
return "WebRTC String (Empty)"
case PayloadTypeWebRTCBinaryEmpty :
return "WebRTC Binary (Empty)"
default :
return fmt .Sprintf ("Unknown Payload Protocol Identifier: %d" , p )
}
}
func (p *chunkPayloadData ) unmarshal (raw []byte ) error {
if err := p .chunkHeader .unmarshal (raw ); err != nil {
return err
}
p .immediateSack = p .flags &payloadDataImmediateSACK != 0
p .unordered = p .flags &payloadDataUnorderedBitmask != 0
p .beginningFragment = p .flags &payloadDataBeginingFragmentBitmask != 0
p .endingFragment = p .flags &payloadDataEndingFragmentBitmask != 0
if len (p .raw ) < payloadDataHeaderSize {
return ErrChunkPayloadSmall
}
p .tsn = binary .BigEndian .Uint32 (p .raw [0 :])
p .streamIdentifier = binary .BigEndian .Uint16 (p .raw [4 :])
p .streamSequenceNumber = binary .BigEndian .Uint16 (p .raw [6 :])
p .payloadType = PayloadProtocolIdentifier (binary .BigEndian .Uint32 (p .raw [8 :]))
p .userData = p .raw [payloadDataHeaderSize :]
return nil
}
func (p *chunkPayloadData ) marshal () ([]byte , error ) {
payRaw := make ([]byte , payloadDataHeaderSize +len (p .userData ))
binary .BigEndian .PutUint32 (payRaw [0 :], p .tsn )
binary .BigEndian .PutUint16 (payRaw [4 :], p .streamIdentifier )
binary .BigEndian .PutUint16 (payRaw [6 :], p .streamSequenceNumber )
binary .BigEndian .PutUint32 (payRaw [8 :], uint32 (p .payloadType ))
copy (payRaw [payloadDataHeaderSize :], p .userData )
flags := uint8 (0 )
if p .endingFragment {
flags = 1
}
if p .beginningFragment {
flags |= 1 << 1
}
if p .unordered {
flags |= 1 << 2
}
if p .immediateSack {
flags |= 1 << 3
}
p .chunkHeader .flags = flags
p .chunkHeader .typ = ctPayloadData
p .chunkHeader .raw = payRaw
return p .chunkHeader .marshal ()
}
func (p *chunkPayloadData ) check () (abort bool , err error ) {
return false , nil
}
func (p *chunkPayloadData ) String () string {
return fmt .Sprintf ("%s\n%d" , p .chunkHeader , p .tsn )
}
func (p *chunkPayloadData ) abandoned () bool {
if p .head != nil {
return p .head ._abandoned && p .head ._allInflight
}
return p ._abandoned && p ._allInflight
}
func (p *chunkPayloadData ) setAbandoned (abandoned bool ) {
if p .head != nil {
p .head ._abandoned = abandoned
return
}
p ._abandoned = abandoned
}
func (p *chunkPayloadData ) setAllInflight () {
if p .endingFragment {
if p .head != nil {
p .head ._allInflight = true
} else {
p ._allInflight = true
}
}
}
func (p *chunkPayloadData ) isFragmented () bool {
return !(p .head == nil && p .beginningFragment && p .endingFragment )
}
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 .