From 9a44cf9ff8a933cdcc556cb7b3a9f4d66b990de7 Mon Sep 17 00:00:00 2001 From: Juliusz Chroboczek Date: Tue, 2 Feb 2021 22:32:16 +0100 Subject: [PATCH] Avoid infinite loop in CreateOffer If the local description keeps getting changed, or in case of a but in Pion, CreateOffer never terminates, which could cause client software to hang. Set an arbitrary bound on the number of iterations. --- peerconnection.go | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/peerconnection.go b/peerconnection.go index f8c0d153e91..ca845fc576b 100644 --- a/peerconnection.go +++ b/peerconnection.go @@ -6,6 +6,7 @@ import ( "crypto/ecdsa" "crypto/elliptic" "crypto/rand" + "errors" "fmt" "io" "strconv" @@ -576,6 +577,8 @@ func (pc *PeerConnection) hasLocalDescriptionChanged(desc *SessionDescription) b return false } +var errExcessiveRetries = errors.New("excessive retries in CreateOffer") + // CreateOffer starts the PeerConnection and generates the localDescription // https://w3c.github.io/webrtc-pc/#dom-rtcpeerconnection-createoffer func (pc *PeerConnection) CreateOffer(options *OfferOptions) (SessionDescription, error) { //nolint:gocognit @@ -603,6 +606,7 @@ func (pc *PeerConnection) CreateOffer(options *OfferOptions) (SessionDescription // audio RTCRtpTransceiver was added to connection, but while performing the in-parallel // steps to create an offer, a video RTCRtpTransceiver was added, requiring additional // inspection of video system resources. + count := 0 for { // We cache current transceivers to ensure they aren't // mutated during offer generation. We later check if they have @@ -673,6 +677,10 @@ func (pc *PeerConnection) CreateOffer(options *OfferOptions) (SessionDescription if isPlanB || !pc.hasLocalDescriptionChanged(&offer) { break } + count++ + if count >= 128 { + return SessionDescription{}, errExcessiveRetries + } } pc.lastOffer = offer.SDP