From 4d781c851df53fe8b6fd96b3ccd63164de7ee492 Mon Sep 17 00:00:00 2001 From: sirzooro Date: Sat, 6 Jul 2024 14:52:09 +0200 Subject: [PATCH] Remove IPv6 ZoneID from ICE candidates (#704) Link-local IPv6 addresses may have ZoneID attached at the end. It has local meaning only and should not be send to other parties. This change removes ZoneID from generated candidate string, and ignores ZoneID when received candidate is parsed. --- candidate_base.go | 11 +++++++++-- candidate_test.go | 39 ++++++++++++++++++++++++++++++++++++++- 2 files changed, 47 insertions(+), 3 deletions(-) diff --git a/candidate_base.go b/candidate_base.go index 63199406..f7259852 100644 --- a/candidate_base.go +++ b/candidate_base.go @@ -447,6 +447,13 @@ func (c *candidateBase) copy() (Candidate, error) { return UnmarshalCandidate(c.Marshal()) } +func removeZoneIDFromAddress(addr string) string { + if i := strings.Index(addr, "%"); i != -1 { + return addr[:i] + } + return addr +} + // Marshal returns the string representation of the ICECandidate func (c *candidateBase) Marshal() string { val := c.Foundation() @@ -459,7 +466,7 @@ func (c *candidateBase) Marshal() string { c.Component(), c.NetworkType().NetworkShort(), c.Priority(), - c.Address(), + removeZoneIDFromAddress(c.Address()), c.Port(), c.Type()) @@ -509,7 +516,7 @@ func UnmarshalCandidate(raw string) (Candidate, error) { priority := uint32(priorityRaw) // Address - address := split[4] + address := removeZoneIDFromAddress(split[4]) // Port rawPort, err := strconv.ParseUint(split[5], 10, 16) diff --git a/candidate_test.go b/candidate_test.go index 9fb7ebc5..64b4e3be 100644 --- a/candidate_test.go +++ b/candidate_test.go @@ -391,7 +391,7 @@ func TestCandidateMarshal(t *testing.T) { assert.NoError(t, err) - assert.True(t, test.candidate.Equal(actualCandidate)) + assert.Truef(t, test.candidate.Equal(actualCandidate), "%s != %s", test.candidate.String(), actualCandidate.String()) assert.Equal(t, test.marshaled, actualCandidate.Marshal()) } } @@ -435,3 +435,40 @@ func TestCandidateWriteTo(t *testing.T) { _, err = c1.writeTo([]byte("test"), c2) assert.Error(t, err, "writing to closed conn") } + +func TestMarshalUnmarshalCandidateWithZoneID(t *testing.T) { + candidateWithZoneID := &CandidateHost{ + candidateBase{ + networkType: NetworkTypeUDP6, + candidateType: CandidateTypeHost, + address: "fcd9:e3b8:12ce:9fc5:74a5:c6bb:d8b:e08a%Local Connection", + port: 53987, + priorityOverride: 500, + foundationOverride: "750", + }, + "", + } + candidateStr := "750 0 udp 500 fcd9:e3b8:12ce:9fc5:74a5:c6bb:d8b:e08a 53987 typ host" + require.Equal(t, candidateStr, candidateWithZoneID.Marshal()) + + candidate := &CandidateHost{ + candidateBase{ + networkType: NetworkTypeUDP6, + candidateType: CandidateTypeHost, + address: "fcd9:e3b8:12ce:9fc5:74a5:c6bb:d8b:e08a", + port: 53987, + priorityOverride: 500, + foundationOverride: "750", + }, + "", + } + candidateWithZoneIDStr := "750 0 udp 500 fcd9:e3b8:12ce:9fc5:74a5:c6bb:d8b:e08a%eth0 53987 typ host" + candidate2, err := UnmarshalCandidate(candidateWithZoneIDStr) + require.NoError(t, err) + require.Truef(t, candidate.Equal(candidate2), "%s != %s", candidate.String(), candidate2.String()) + + candidateWithZoneIDStr2 := "750 0 udp 500 fcd9:e3b8:12ce:9fc5:74a5:c6bb:d8b:e08a%eth0%eth1 53987 typ host" + candidate2, err = UnmarshalCandidate(candidateWithZoneIDStr2) + require.NoError(t, err) + require.Truef(t, candidate.Equal(candidate2), "%s != %s", candidate.String(), candidate2.String()) +}