mirror of
https://github.com/pion/webrtc.git
synced 2025-10-28 01:31:33 +08:00
Add init ack sending, added cookie state
This commit is contained in:
committed by
Sean DuBois
parent
04f049fb4c
commit
0e43088e58
@@ -213,10 +213,11 @@ func (p *Port) networkLoop(remoteKey []byte, tlscfg *dtls.TLSCfg, b BufferTransp
|
|||||||
p.sctpAssocations[in.srcAddr.String()] = sctp.NewAssocation(func(pkt *sctp.Packet) {
|
p.sctpAssocations[in.srcAddr.String()] = sctp.NewAssocation(func(pkt *sctp.Packet) {
|
||||||
raw, err := pkt.Marshal()
|
raw, err := pkt.Marshal()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Println(errors.Wrap(err, "Failed to Unmarshal SCTP packet"))
|
fmt.Println(errors.Wrap(err, "Failed to Marshal SCTP packet"))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
fmt.Println(raw)
|
fmt.Printf("Out: %v\n", raw)
|
||||||
|
d.Send(raw)
|
||||||
}, func(data []byte) {
|
}, func(data []byte) {
|
||||||
fmt.Printf("Handle data %v \n", data)
|
fmt.Printf("Handle data %v \n", data)
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -210,8 +210,9 @@ func (a *Association) handleInit(p *Packet, i *Init) (*Packet, error) {
|
|||||||
initAck.initiateTag = a.myVerificationTag
|
initAck.initiateTag = a.myVerificationTag
|
||||||
initAck.advertisedReceiverWindowCredit = a.myRreceiverWindowCredit
|
initAck.advertisedReceiverWindowCredit = a.myRreceiverWindowCredit
|
||||||
|
|
||||||
//initAck.params = append(initAck.params, )
|
initAck.params = []Param{NewRandomStateCookie(), NewEmptySupportedExtensions()}
|
||||||
outbound.Chunks = []Chunk{}
|
|
||||||
|
outbound.Chunks = []Chunk{initAck}
|
||||||
|
|
||||||
return outbound, nil
|
return outbound, nil
|
||||||
|
|
||||||
|
|||||||
@@ -57,6 +57,7 @@ func (i *InitAck) Marshal() ([]byte, error) {
|
|||||||
return nil, errors.Wrap(err, "Failed marshalling INIT common data")
|
return nil, errors.Wrap(err, "Failed marshalling INIT common data")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
i.ChunkHeader.typ = INITACK
|
||||||
chunkHeader, err := i.ChunkHeader.Marshal(len(initShared))
|
chunkHeader, err := i.ChunkHeader.Marshal(len(initShared))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, errors.Wrap(err, "Failed marshalling InitAck Chunk Header")
|
return nil, errors.Wrap(err, "Failed marshalling InitAck Chunk Header")
|
||||||
|
|||||||
@@ -111,6 +111,13 @@ func (i *InitCommon) Marshal() ([]byte, error) {
|
|||||||
binary.BigEndian.PutUint16(out[8:], i.numOutboundStreams)
|
binary.BigEndian.PutUint16(out[8:], i.numOutboundStreams)
|
||||||
binary.BigEndian.PutUint16(out[10:], i.numInboundStreams)
|
binary.BigEndian.PutUint16(out[10:], i.numInboundStreams)
|
||||||
binary.BigEndian.PutUint32(out[12:], i.initialTSN)
|
binary.BigEndian.PutUint32(out[12:], i.initialTSN)
|
||||||
|
for _, p := range i.params {
|
||||||
|
pp, err := p.Marshal()
|
||||||
|
if err != nil {
|
||||||
|
return nil, errors.Wrap(err, "Unable to marshal parameter for INIT/INITACK")
|
||||||
|
}
|
||||||
|
out = append(out, pp...)
|
||||||
|
}
|
||||||
|
|
||||||
return out, nil
|
return out, nil
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ package sctp
|
|||||||
import (
|
import (
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
|
"fmt"
|
||||||
"github.com/pkg/errors"
|
"github.com/pkg/errors"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -37,3 +38,68 @@ func TestInitChunk(t *testing.T) {
|
|||||||
t.Error(errors.Errorf("Unmarshal passed for SCTP packet, but got incorrect initialTSN exp: %d act: %d", 3899461680, i.initialTSN))
|
t.Error(errors.Errorf("Unmarshal passed for SCTP packet, but got incorrect initialTSN exp: %d act: %d", 3899461680, i.initialTSN))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestInitAck(t *testing.T) {
|
||||||
|
pkt := &Packet{}
|
||||||
|
rawPkt := []byte{0x13, 0x88, 0x13, 0x88, 0xce, 0x15, 0x79, 0xa2, 0x96, 0x19, 0xe8, 0xb2, 0x02, 0x00, 0x00, 0x1c, 0xeb, 0x81, 0x4e, 0x01, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x08, 0x00, 0x50, 0xdf, 0x90, 0xd9, 0x00, 0x07, 0x00, 0x08, 0x94, 0x06, 0x2f, 0x93}
|
||||||
|
err := pkt.Unmarshal(rawPkt)
|
||||||
|
if err != nil {
|
||||||
|
t.Error(errors.Wrap(err, "Unmarshal failed, has chunk"))
|
||||||
|
}
|
||||||
|
|
||||||
|
i, ok := pkt.Chunks[0].(*InitAck)
|
||||||
|
if !ok {
|
||||||
|
t.Error("Failed to cast Chunk -> Init")
|
||||||
|
}
|
||||||
|
|
||||||
|
fmt.Printf("Init ack: %v\n", i)
|
||||||
|
if err != nil {
|
||||||
|
t.Error(errors.Wrap(err, "Unmarshal init Chunk failed"))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
func TestInitMarshalUnmarshal(t *testing.T) {
|
||||||
|
p := &Packet{}
|
||||||
|
p.DestinationPort = 1
|
||||||
|
p.SourcePort = 1
|
||||||
|
p.VerificationTag = 123
|
||||||
|
|
||||||
|
initAck := &InitAck{}
|
||||||
|
|
||||||
|
initAck.initialTSN = 123
|
||||||
|
initAck.numOutboundStreams = 1
|
||||||
|
initAck.numInboundStreams = 1
|
||||||
|
initAck.initiateTag = 123
|
||||||
|
initAck.advertisedReceiverWindowCredit = 1024
|
||||||
|
initAck.params = []Param{NewRandomStateCookie()}
|
||||||
|
|
||||||
|
p.Chunks = []Chunk{initAck}
|
||||||
|
rawPkt, err := p.Marshal()
|
||||||
|
if err != nil {
|
||||||
|
t.Error(errors.Wrap(err, "Failed to marshal packet"))
|
||||||
|
}
|
||||||
|
|
||||||
|
pkt := &Packet{}
|
||||||
|
err = pkt.Unmarshal(rawPkt)
|
||||||
|
if err != nil {
|
||||||
|
t.Error(errors.Wrap(err, "Unmarshal failed, has chunk"))
|
||||||
|
}
|
||||||
|
|
||||||
|
i, ok := pkt.Chunks[0].(*InitAck)
|
||||||
|
if !ok {
|
||||||
|
t.Error("Failed to cast Chunk -> InitAck")
|
||||||
|
}
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
t.Error(errors.Wrap(err, "Unmarshal init ack Chunk failed"))
|
||||||
|
} else if i.initiateTag != 123 {
|
||||||
|
t.Error(errors.Errorf("Unmarshal passed for SCTP packet, but got incorrect initiate tag exp: %d act: %d", 123, i.initiateTag))
|
||||||
|
} else if i.advertisedReceiverWindowCredit != 1024 {
|
||||||
|
t.Error(errors.Errorf("Unmarshal passed for SCTP packet, but got incorrect advertisedReceiverWindowCredit exp: %d act: %d", 1024, i.advertisedReceiverWindowCredit))
|
||||||
|
} else if i.numOutboundStreams != 1 {
|
||||||
|
t.Error(errors.Errorf("Unmarshal passed for SCTP packet, but got incorrect numOutboundStreams tag exp: %d act: %d", 1, i.numOutboundStreams))
|
||||||
|
} else if i.numInboundStreams != 1 {
|
||||||
|
t.Error(errors.Errorf("Unmarshal passed for SCTP packet, but got incorrect numInboundStreams exp: %d act: %d", 1, i.numInboundStreams))
|
||||||
|
} else if i.initialTSN != 123 {
|
||||||
|
t.Error(errors.Errorf("Unmarshal passed for SCTP packet, but got incorrect initialTSN exp: %d act: %d", 123, i.initialTSN))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -75,6 +75,8 @@ func (p *Packet) Unmarshal(raw []byte) error {
|
|||||||
switch ChunkType(raw[offset]) {
|
switch ChunkType(raw[offset]) {
|
||||||
case INIT:
|
case INIT:
|
||||||
c = &Init{}
|
c = &Init{}
|
||||||
|
case INITACK:
|
||||||
|
c = &InitAck{}
|
||||||
default:
|
default:
|
||||||
return errors.Errorf("Failed to unmarshal, contains unknown chunk type %s", ChunkType(raw[offset]).String())
|
return errors.Errorf("Failed to unmarshal, contains unknown chunk type %s", ChunkType(raw[offset]).String())
|
||||||
}
|
}
|
||||||
@@ -82,6 +84,7 @@ func (p *Packet) Unmarshal(raw []byte) error {
|
|||||||
if err := c.Unmarshal(raw[offset:]); err != nil {
|
if err := c.Unmarshal(raw[offset:]); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
p.Chunks = append(p.Chunks, c)
|
p.Chunks = append(p.Chunks, c)
|
||||||
chunkValuePadding := c.valueLength() % 4
|
chunkValuePadding := c.valueLength() % 4
|
||||||
offset += chunkHeaderSize + c.valueLength() + chunkValuePadding
|
offset += chunkHeaderSize + c.valueLength() + chunkValuePadding
|
||||||
@@ -113,7 +116,7 @@ func (p *Packet) Marshal() ([]byte, error) {
|
|||||||
raw = append(raw, chunkRaw...)
|
raw = append(raw, chunkRaw...)
|
||||||
}
|
}
|
||||||
|
|
||||||
paddingNeeded := len(raw) % 4
|
paddingNeeded := getPadding(len(raw), 4)
|
||||||
if paddingNeeded != 0 {
|
if paddingNeeded != 0 {
|
||||||
raw = append(raw, make([]byte, paddingNeeded)...)
|
raw = append(raw, make([]byte, paddingNeeded)...)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ type ParamType uint16
|
|||||||
|
|
||||||
// Param interface
|
// Param interface
|
||||||
type Param interface {
|
type Param interface {
|
||||||
|
Marshal() ([]byte, error)
|
||||||
Length() int
|
Length() int
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -26,6 +27,8 @@ func BuildParam(t ParamType, rawParam []byte) (Param, error) {
|
|||||||
return (&ParamRequestedHMACAlgorithm{}).Unmarshal(rawParam)
|
return (&ParamRequestedHMACAlgorithm{}).Unmarshal(rawParam)
|
||||||
case ChunkList:
|
case ChunkList:
|
||||||
return (&ParamChunkList{}).Unmarshal(rawParam)
|
return (&ParamChunkList{}).Unmarshal(rawParam)
|
||||||
|
case StateCookie:
|
||||||
|
return (&ParamStateCookie{}).Unmarshal(rawParam)
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil, errors.Errorf("Unhandled ParamType %v", t)
|
return nil, errors.Errorf("Unhandled ParamType %v", t)
|
||||||
|
|||||||
34
internal/sctp/param_state_cookie.go
Normal file
34
internal/sctp/param_state_cookie.go
Normal file
@@ -0,0 +1,34 @@
|
|||||||
|
package sctp
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding/binary"
|
||||||
|
"math/rand"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
type ParamStateCookie struct {
|
||||||
|
ParamHeader
|
||||||
|
Cookie []byte
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewRandomStateCookie() *ParamStateCookie {
|
||||||
|
rs := rand.NewSource(time.Now().UnixNano())
|
||||||
|
r := rand.New(rs)
|
||||||
|
randCookie := make([]byte, 4)
|
||||||
|
binary.BigEndian.PutUint32(randCookie, r.Uint32())
|
||||||
|
s := &ParamStateCookie{
|
||||||
|
Cookie: randCookie,
|
||||||
|
}
|
||||||
|
|
||||||
|
return s
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *ParamStateCookie) Marshal() ([]byte, error) {
|
||||||
|
return s.ParamHeader.Marshal(StateCookie, s.Cookie)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *ParamStateCookie) Unmarshal(raw []byte) (Param, error) {
|
||||||
|
s.ParamHeader.Unmarshal(raw)
|
||||||
|
s.Cookie = s.raw
|
||||||
|
return s, nil
|
||||||
|
}
|
||||||
@@ -1,9 +1,5 @@
|
|||||||
package sctp
|
package sctp
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
)
|
|
||||||
|
|
||||||
func chunkTypeIntersect(l, r []ChunkType) (c []ChunkType) {
|
func chunkTypeIntersect(l, r []ChunkType) (c []ChunkType) {
|
||||||
m := make(map[ChunkType]bool)
|
m := make(map[ChunkType]bool)
|
||||||
|
|
||||||
@@ -19,9 +15,12 @@ func chunkTypeIntersect(l, r []ChunkType) (c []ChunkType) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func NewEmptySupportedExtensions() *ParamSupportedExtensions {
|
||||||
|
return &ParamSupportedExtensions{}
|
||||||
|
}
|
||||||
|
|
||||||
type ParamSupportedExtensions struct {
|
type ParamSupportedExtensions struct {
|
||||||
ParamHeader
|
ParamHeader
|
||||||
Raw []byte
|
|
||||||
ChunkTypes []ChunkType
|
ChunkTypes []ChunkType
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -40,7 +39,6 @@ func (s *ParamSupportedExtensions) Unmarshal(raw []byte) (Param, error) {
|
|||||||
for t := range s.raw {
|
for t := range s.raw {
|
||||||
s.ChunkTypes = append(s.ChunkTypes, ChunkType(t))
|
s.ChunkTypes = append(s.ChunkTypes, ChunkType(t))
|
||||||
}
|
}
|
||||||
fmt.Print(s.ChunkTypes)
|
|
||||||
|
|
||||||
return s, nil
|
return s, nil
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user