Skip to content

Commit

Permalink
Fixes SDP session id
Browse files Browse the repository at this point in the history
SDP session id should stay unchanged for subsequent offers/answers
  • Loading branch information
zyxar committed Apr 14, 2021
1 parent a0b3117 commit fb4b582
Show file tree
Hide file tree
Showing 4 changed files with 75 additions and 3 deletions.
2 changes: 1 addition & 1 deletion fmtp.go
Expand Up @@ -21,7 +21,7 @@ func parseFmtp(line string) fmtp {
return f
}

// fmtpConsist checks that two FTMP parameters are not inconsistent.
// fmtpConsist checks that two FMTP parameters are not inconsistent.
func fmtpConsist(a, b fmtp) bool {
for k, v := range a {
if vb, ok := b[k]; ok && !strings.EqualFold(vb, v) {
Expand Down
4 changes: 4 additions & 0 deletions peerconnection.go
Expand Up @@ -31,6 +31,8 @@ type PeerConnection struct {
statsID string
mu sync.RWMutex

sdpOrigin sdp.Origin

// ops is an operations queue which will ensure the enqueued actions are
// executed in order. It is used for asynchronously, but serially processing
// remote and local descriptions
Expand Down Expand Up @@ -672,6 +674,7 @@ func (pc *PeerConnection) CreateOffer(options *OfferOptions) (SessionDescription
return SessionDescription{}, err
}

updateSDPOrigin(&pc.sdpOrigin, d)
sdpBytes, err := d.Marshal()
if err != nil {
return SessionDescription{}, err
Expand Down Expand Up @@ -809,6 +812,7 @@ func (pc *PeerConnection) CreateAnswer(options *AnswerOptions) (SessionDescripti
return SessionDescription{}, err
}

updateSDPOrigin(&pc.sdpOrigin, d)
sdpBytes, err := d.Marshal()
if err != nil {
return SessionDescription{}, err
Expand Down
47 changes: 47 additions & 0 deletions peerconnection_go_test.go
Expand Up @@ -1350,3 +1350,50 @@ func TestPeerConnection_TransceiverDirection(t *testing.T) {
})
}
}

func TestPeerConnection_SessionID(t *testing.T) {
defer test.TimeOut(time.Second * 10).Stop()
defer test.CheckRoutines(t)()

pcOffer, pcAnswer, err := newPair()
assert.NoError(t, err)
var offerSessionID uint64
var offerSessionVersion uint64
var answerSessionID uint64
var answerSessionVersion uint64
for i := 0; i < 10; i++ {
assert.NoError(t, signalPair(pcOffer, pcAnswer))
offer := pcOffer.LocalDescription().parsed
sessionID := offer.Origin.SessionID
sessionVersion := offer.Origin.SessionVersion
if offerSessionID == 0 {
offerSessionID = sessionID
offerSessionVersion = sessionVersion
} else {
if offerSessionID != sessionID {
t.Errorf("offer[%v] session id mismatch: expected=%v, got=%v", i, offerSessionID, sessionID)
}
if offerSessionVersion+1 != sessionVersion {
t.Errorf("offer[%v] session version mismatch: expected=%v, got=%v", i, offerSessionVersion+1, sessionVersion)
}
offerSessionVersion++
}

answer := pcAnswer.LocalDescription().parsed
sessionID = answer.Origin.SessionID
sessionVersion = answer.Origin.SessionVersion
if answerSessionID == 0 {
answerSessionID = sessionID
answerSessionVersion = sessionVersion
} else {
if answerSessionID != sessionID {
t.Errorf("answer[%v] session id mismatch: expected=%v, got=%v", i, answerSessionID, sessionID)
}
if answerSessionVersion+1 != sessionVersion {
t.Errorf("answer[%v] session version mismatch: expected=%v, got=%v", i, answerSessionVersion+1, sessionVersion)
}
answerSessionVersion++
}
}
closePairNow(t, pcOffer, pcAnswer)
}
25 changes: 23 additions & 2 deletions sdp.go
Expand Up @@ -8,6 +8,7 @@ import (
"regexp"
"strconv"
"strings"
"sync/atomic"

"github.com/pion/ice/v2"
"github.com/pion/logging"
Expand Down Expand Up @@ -271,8 +272,9 @@ func populateLocalCandidates(sessionDescription *SessionDescription, i *ICEGathe
}

return &SessionDescription{
SDP: string(sdp),
Type: sessionDescription.Type,
SDP: string(sdp),
Type: sessionDescription.Type,
parsed: parsed,
}
}

Expand Down Expand Up @@ -641,3 +643,22 @@ func rtpExtensionsFromMediaDescription(m *sdp.MediaDescription) (map[string]int,

return out, nil
}

// updateSDPOrigin saves sdp.Origin in PeerConnection when creating 1st local SDP;
// for subsequent calling, it updates Origin for SessionDescription from saved one
// and increments session version by one.
// https://tools.ietf.org/html/draft-ietf-rtcweb-jsep-25#section-5.2.2
// https://tools.ietf.org/html/draft-ietf-rtcweb-jsep-25#section-5.3.2
func updateSDPOrigin(origin *sdp.Origin, d *sdp.SessionDescription) {
if atomic.CompareAndSwapUint64(&origin.SessionVersion, 0, d.Origin.SessionVersion) { // store
atomic.StoreUint64(&origin.SessionID, d.Origin.SessionID)
} else { // load
for { // awaiting for saving session id
d.Origin.SessionID = atomic.LoadUint64(&origin.SessionID)
if d.Origin.SessionID != 0 {
break
}
}
d.Origin.SessionVersion = atomic.AddUint64(&origin.SessionVersion, 1)
}
}

0 comments on commit fb4b582

Please sign in to comment.