Skip to content

Commit

Permalink
Preserve ICE candidate Extensions
Browse files Browse the repository at this point in the history
Ensure that ICE candidates are retained when parsed and stringified,
and converted to ICE.candidate.
  • Loading branch information
JoeTurki committed Jan 31, 2025
1 parent 7c3b128 commit bacd6b7
Show file tree
Hide file tree
Showing 2 changed files with 35 additions and 5 deletions.
23 changes: 18 additions & 5 deletions icecandidate.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ type ICECandidate struct {
TCPType string `json:"tcpType"`
SDPMid string `json:"sdpMid"`
SDPMLineIndex uint16 `json:"sdpMLineIndex"`
extensions []ice.CandidateExtension
}

// Conversion for package ice.
Expand Down Expand Up @@ -67,6 +68,7 @@ func newICECandidateFromICE(candidate ice.Candidate, sdpMid string, sdpMLineInde
TCPType: candidate.TCPType().String(),
SDPMid: sdpMid,
SDPMLineIndex: sdpMLineIndex,
extensions: candidate.Extensions(),
}

if candidate.RelatedAddress() != nil {
Expand All @@ -77,7 +79,7 @@ func newICECandidateFromICE(candidate ice.Candidate, sdpMid string, sdpMLineInde
return newCandidate, nil
}

func (c ICECandidate) toICE() (ice.Candidate, error) {
func (c ICECandidate) toICE() (cand ice.Candidate, err error) {
candidateID := c.statsID
switch c.Typ {
case ICECandidateTypeHost:
Expand All @@ -92,7 +94,7 @@ func (c ICECandidate) toICE() (ice.Candidate, error) {
Priority: c.Priority,
}

return ice.NewCandidateHost(&config)
cand, err = ice.NewCandidateHost(&config)
case ICECandidateTypeSrflx:
config := ice.CandidateServerReflexiveConfig{
CandidateID: candidateID,
Expand All @@ -106,7 +108,7 @@ func (c ICECandidate) toICE() (ice.Candidate, error) {
RelPort: int(c.RelatedPort),
}

return ice.NewCandidateServerReflexive(&config)
cand, err = ice.NewCandidateServerReflexive(&config)
case ICECandidateTypePrflx:
config := ice.CandidatePeerReflexiveConfig{
CandidateID: candidateID,
Expand All @@ -120,7 +122,7 @@ func (c ICECandidate) toICE() (ice.Candidate, error) {
RelPort: int(c.RelatedPort),
}

return ice.NewCandidatePeerReflexive(&config)
cand, err = ice.NewCandidatePeerReflexive(&config)
case ICECandidateTypeRelay:
config := ice.CandidateRelayConfig{
CandidateID: candidateID,
Expand All @@ -134,10 +136,21 @@ func (c ICECandidate) toICE() (ice.Candidate, error) {
RelPort: int(c.RelatedPort),
}

return ice.NewCandidateRelay(&config)
cand, err = ice.NewCandidateRelay(&config)

Check warning on line 139 in icecandidate.go

View check run for this annotation

Codecov / codecov/patch

icecandidate.go#L139

Added line #L139 was not covered by tests
default:
return nil, fmt.Errorf("%w: %s", errICECandidateTypeUnknown, c.Typ)
}

if cand != nil && err == nil {
for i := range c.extensions {
err = cand.AddExtension(c.extensions[i])
if err != nil {
return nil, err
}

Check warning on line 149 in icecandidate.go

View check run for this annotation

Codecov / codecov/patch

icecandidate.go#L148-L149

Added lines #L148 - L149 were not covered by tests
}
}

return cand, err
}

func convertTypeFromICE(t ice.CandidateType) (ICECandidateType, error) {
Expand Down
17 changes: 17 additions & 0 deletions icecandidate_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -248,3 +248,20 @@ func TestICECandidateSDPMid_ToJSON(t *testing.T) {
assert.Equal(t, candidate.SDPMid, "0")
assert.Equal(t, candidate.SDPMLineIndex, uint16(1))
}

func TestICECandidateExtensions_ToJSON(t *testing.T) {
cand := "2637185494 1 udp 2121932543 192.168.1.4 50723 typ host generation 1 ufrag Jzd0 network-id 1"
candidate, err := ice.UnmarshalCandidate(cand)
assert.NoError(t, err)

sdpMid := "1"
sdpMLineIndex := uint16(2)

iceCandidate, err := newICECandidateFromICE(candidate, sdpMid, sdpMLineIndex)
assert.NoError(t, err)

candidateInit := iceCandidate.ToJSON()

assert.Equal(t, sdpMLineIndex, *candidateInit.SDPMLineIndex)
assert.Equal(t, "candidate:"+cand, candidateInit.Candidate)
}

0 comments on commit bacd6b7

Please sign in to comment.