Skip to content

Commit

Permalink
Fix rollover estimation after SetROC
Browse files Browse the repository at this point in the history
SRTP context estimated the wrong ROC when the sequence number is
overflown during burst packet loss, and SetROC gives the correct ROC.
  • Loading branch information
at-wat committed Feb 9, 2023
1 parent e966eef commit 1bdeef2
Show file tree
Hide file tree
Showing 2 changed files with 77 additions and 1 deletion.
3 changes: 2 additions & 1 deletion context.go
Original file line number Diff line number Diff line change
Expand Up @@ -201,7 +201,8 @@ func (c *Context) ROC(ssrc uint32) (uint32, bool) {
// SetROC sets SRTP rollover counter value of specified SSRC.
func (c *Context) SetROC(ssrc uint32, roc uint32) {
s := c.getSRTPSSRCState(ssrc)
s.index = uint64(roc)<<16 | (s.index & (seqNumMax - 1))
s.index = uint64(roc) << 16
s.rolloverHasProcessed = false
}

// Index returns SRTCP index value of specified SSRC.
Expand Down
75 changes: 75 additions & 0 deletions srtp_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -774,3 +774,78 @@ func TestRTPMaxPackets(t *testing.T) {
})
}
}

func TestRTPBurstLossWithSetROC(t *testing.T) {
profiles := map[string]ProtectionProfile{
"CTR": profileCTR,
"GCM": profileGCM,
}
for name, profile := range profiles {
profile := profile
t.Run(name, func(t *testing.T) {
assert := assert.New(t)

encryptContext, err := buildTestContext(profile)
if err != nil {
t.Fatal(err)
}

type packetWithROC struct {
pkt rtp.Packet
enc []byte
raw []byte

roc uint32
}

var pkts []*packetWithROC
encryptContext.SetROC(1, 3)
for i := 0x8C00; i < 0x20400; i += 0x100 {
p := &packetWithROC{
pkt: rtp.Packet{
Payload: []byte{
byte(i >> 16),
byte(i >> 8),
byte(i),
},
Header: rtp.Header{
Marker: true,
SSRC: 1,
SequenceNumber: uint16(i),
},
},
}
b, errMarshal := p.pkt.Marshal()
if errMarshal != nil {
t.Fatal(errMarshal)
}
p.raw = b
enc, errEnc := encryptContext.EncryptRTP(nil, b, nil)
if errEnc != nil {
t.Fatal(errEnc)
}
p.roc, _ = encryptContext.ROC(1)
if 0x9000 < i && i < 0x20100 {
continue
}
p.enc = enc
pkts = append(pkts, p)
}

decryptContext, err := buildTestContext(profile)
if err != nil {
t.Fatal(err)
}

for _, p := range pkts {
decryptContext.SetROC(1, p.roc)
pkt, err := decryptContext.DecryptRTP(nil, p.enc, nil)
if err != nil {
t.Errorf("roc=%d, seq=%d: %v", p.roc, p.pkt.SequenceNumber, err)
continue
}
assert.Equal(p.raw, pkt)
}
})
}
}

0 comments on commit 1bdeef2

Please sign in to comment.