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 30, 2025
1 parent 47bde05 commit 1f7e2dd
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)
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])

Check failure on line 146 in icecandidate.go

View workflow job for this annotation

GitHub Actions / lint / Go

cand.AddExtension undefined (type ice.Candidate has no field or method AddExtension)) (typecheck)

Check failure on line 146 in icecandidate.go

View workflow job for this annotation

GitHub Actions / lint / Go

cand.AddExtension undefined (type ice.Candidate has no field or method AddExtension)) (typecheck)

Check failure on line 146 in icecandidate.go

View workflow job for this annotation

GitHub Actions / lint / Go

cand.AddExtension undefined (type ice.Candidate has no field or method AddExtension)) (typecheck)

Check failure on line 146 in icecandidate.go

View workflow job for this annotation

GitHub Actions / lint / Go

cand.AddExtension undefined (type ice.Candidate has no field or method AddExtension) (typecheck)

Check failure on line 146 in icecandidate.go

View workflow job for this annotation

GitHub Actions / test (1.22) / Go 1.22

cand.AddExtension undefined (type ice.Candidate has no field or method AddExtension)

Check failure on line 146 in icecandidate.go

View workflow job for this annotation

GitHub Actions / test (1.22) / Go 1.22

cand.AddExtension undefined (type ice.Candidate has no field or method AddExtension)

Check failure on line 146 in icecandidate.go

View workflow job for this annotation

GitHub Actions / test (1.23) / Go 1.23

cand.AddExtension undefined (type ice.Candidate has no field or method AddExtension)

Check failure on line 146 in icecandidate.go

View workflow job for this annotation

GitHub Actions / test (1.23) / Go 1.23

cand.AddExtension undefined (type ice.Candidate has no field or method AddExtension)
if err != nil {
return nil, err
}
}
}

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 1f7e2dd

Please sign in to comment.