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) {
|
||||
raw, err := pkt.Marshal()
|
||||
if err != nil {
|
||||
fmt.Println(errors.Wrap(err, "Failed to Unmarshal SCTP packet"))
|
||||
fmt.Println(errors.Wrap(err, "Failed to Marshal SCTP packet"))
|
||||
return
|
||||
}
|
||||
fmt.Println(raw)
|
||||
fmt.Printf("Out: %v\n", raw)
|
||||
d.Send(raw)
|
||||
}, func(data []byte) {
|
||||
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.advertisedReceiverWindowCredit = a.myRreceiverWindowCredit
|
||||
|
||||
//initAck.params = append(initAck.params, )
|
||||
outbound.Chunks = []Chunk{}
|
||||
initAck.params = []Param{NewRandomStateCookie(), NewEmptySupportedExtensions()}
|
||||
|
||||
outbound.Chunks = []Chunk{initAck}
|
||||
|
||||
return outbound, nil
|
||||
|
||||
|
||||
@@ -57,6 +57,7 @@ func (i *InitAck) Marshal() ([]byte, error) {
|
||||
return nil, errors.Wrap(err, "Failed marshalling INIT common data")
|
||||
}
|
||||
|
||||
i.ChunkHeader.typ = INITACK
|
||||
chunkHeader, err := i.ChunkHeader.Marshal(len(initShared))
|
||||
if err != nil {
|
||||
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[10:], i.numInboundStreams)
|
||||
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
|
||||
}
|
||||
|
||||
@@ -3,6 +3,7 @@ package sctp
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"fmt"
|
||||
"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))
|
||||
}
|
||||
}
|
||||
|
||||
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]) {
|
||||
case INIT:
|
||||
c = &Init{}
|
||||
case INITACK:
|
||||
c = &InitAck{}
|
||||
default:
|
||||
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 {
|
||||
return err
|
||||
}
|
||||
|
||||
p.Chunks = append(p.Chunks, c)
|
||||
chunkValuePadding := c.valueLength() % 4
|
||||
offset += chunkHeaderSize + c.valueLength() + chunkValuePadding
|
||||
@@ -113,7 +116,7 @@ func (p *Packet) Marshal() ([]byte, error) {
|
||||
raw = append(raw, chunkRaw...)
|
||||
}
|
||||
|
||||
paddingNeeded := len(raw) % 4
|
||||
paddingNeeded := getPadding(len(raw), 4)
|
||||
if paddingNeeded != 0 {
|
||||
raw = append(raw, make([]byte, paddingNeeded)...)
|
||||
}
|
||||
|
||||
@@ -10,6 +10,7 @@ type ParamType uint16
|
||||
|
||||
// Param interface
|
||||
type Param interface {
|
||||
Marshal() ([]byte, error)
|
||||
Length() int
|
||||
}
|
||||
|
||||
@@ -26,6 +27,8 @@ func BuildParam(t ParamType, rawParam []byte) (Param, error) {
|
||||
return (&ParamRequestedHMACAlgorithm{}).Unmarshal(rawParam)
|
||||
case ChunkList:
|
||||
return (&ParamChunkList{}).Unmarshal(rawParam)
|
||||
case StateCookie:
|
||||
return (&ParamStateCookie{}).Unmarshal(rawParam)
|
||||
}
|
||||
|
||||
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
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
)
|
||||
|
||||
func chunkTypeIntersect(l, r []ChunkType) (c []ChunkType) {
|
||||
m := make(map[ChunkType]bool)
|
||||
|
||||
@@ -19,9 +15,12 @@ func chunkTypeIntersect(l, r []ChunkType) (c []ChunkType) {
|
||||
return
|
||||
}
|
||||
|
||||
func NewEmptySupportedExtensions() *ParamSupportedExtensions {
|
||||
return &ParamSupportedExtensions{}
|
||||
}
|
||||
|
||||
type ParamSupportedExtensions struct {
|
||||
ParamHeader
|
||||
Raw []byte
|
||||
ChunkTypes []ChunkType
|
||||
}
|
||||
|
||||
@@ -40,7 +39,6 @@ func (s *ParamSupportedExtensions) Unmarshal(raw []byte) (Param, error) {
|
||||
for t := range s.raw {
|
||||
s.ChunkTypes = append(s.ChunkTypes, ChunkType(t))
|
||||
}
|
||||
fmt.Print(s.ChunkTypes)
|
||||
|
||||
return s, nil
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user