mirror of
https://github.com/netbirdio/ice.git
synced 2026-05-22 17:10:58 -07:00
Add Marshal and Unmarshal to Candidate Base
Move string representation of candidates into pion/ice from pion/webrtc
This commit is contained in:
committed by
Sean DuBois
parent
8a5a37d711
commit
166df5842e
@@ -57,6 +57,7 @@ Check out the **[contributing wiki](https://github.com/pion/webrtc/wiki/Contribu
|
||||
* [Jerko Steiner](https://github.com/jeremija)
|
||||
* [Sidney San Martín](https://github.com/s4y)
|
||||
* [JooYoung Lim](https://github.com/DevRockstarZ)
|
||||
* [Kory Miller](https://github.com/korymiller1489)
|
||||
|
||||
### License
|
||||
MIT License - see [LICENSE](LICENSE) for full text
|
||||
|
||||
@@ -33,6 +33,8 @@ type Candidate interface {
|
||||
|
||||
Equal(other Candidate) bool
|
||||
|
||||
Marshal() string
|
||||
|
||||
addr() net.Addr
|
||||
agent() *Agent
|
||||
context() context.Context
|
||||
|
||||
@@ -4,6 +4,8 @@ import (
|
||||
"context"
|
||||
"fmt"
|
||||
"net"
|
||||
"strconv"
|
||||
"strings"
|
||||
"sync/atomic"
|
||||
"time"
|
||||
|
||||
@@ -357,3 +359,97 @@ func (c *candidateBase) agent() *Agent {
|
||||
func (c *candidateBase) context() context.Context {
|
||||
return c
|
||||
}
|
||||
|
||||
// Marshal returns the string representation of the ICECandidate
|
||||
func (c candidateBase) Marshal() string {
|
||||
val := fmt.Sprintf("%s %d %s %d %s %d typ %s",
|
||||
c.ID(),
|
||||
c.Component(),
|
||||
c.NetworkType().NetworkShort(),
|
||||
c.Priority(),
|
||||
c.Address(),
|
||||
c.Port(),
|
||||
c.Type())
|
||||
|
||||
if c.RelatedAddress() != nil {
|
||||
val = fmt.Sprintf("%s raddr %s rport %d",
|
||||
val,
|
||||
c.RelatedAddress().Address,
|
||||
c.RelatedAddress().Port)
|
||||
}
|
||||
|
||||
return val
|
||||
}
|
||||
|
||||
// UnmarshalCandidate creates a Candidate from its string representation
|
||||
func UnmarshalCandidate(raw string) (Candidate, error) {
|
||||
split := strings.Fields(raw)
|
||||
if len(split) < 8 {
|
||||
return nil, fmt.Errorf("attribute not long enough to be ICE candidate (%d)", len(split))
|
||||
}
|
||||
|
||||
// Foundation
|
||||
foundation := split[0]
|
||||
|
||||
// Component
|
||||
rawComponent, err := strconv.ParseUint(split[1], 10, 16)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("could not parse component: %v", err)
|
||||
}
|
||||
component := uint16(rawComponent)
|
||||
|
||||
// Protocol
|
||||
protocol := split[2]
|
||||
|
||||
// Priority
|
||||
if _, err = strconv.ParseUint(split[3], 10, 32); err != nil {
|
||||
return nil, fmt.Errorf("could not parse priority: %v", err)
|
||||
}
|
||||
|
||||
// Address
|
||||
address := split[4]
|
||||
|
||||
// Port
|
||||
rawPort, err := strconv.ParseUint(split[5], 10, 16)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("could not parse port: %v", err)
|
||||
}
|
||||
port := int(rawPort)
|
||||
typ := split[7]
|
||||
|
||||
relatedAddress := ""
|
||||
relatedPort := 0
|
||||
if len(split) > 8 {
|
||||
split = split[8:]
|
||||
|
||||
if split[0] == "raddr" {
|
||||
if len(split) < 4 {
|
||||
return nil, fmt.Errorf("could not parse related addresses: incorrect length")
|
||||
}
|
||||
|
||||
// RelatedAddress
|
||||
relatedAddress = split[1]
|
||||
|
||||
// RelatedPort
|
||||
rawRelatedPort, err := strconv.ParseUint(split[3], 10, 16)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("could not parse port: %v", err)
|
||||
}
|
||||
relatedPort = int(rawRelatedPort)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
switch typ {
|
||||
case "host":
|
||||
return NewCandidateHost(&CandidateHostConfig{foundation, protocol, address, port, uint16(component), TCPTypePassive})
|
||||
case "srflx":
|
||||
return NewCandidateServerReflexive(&CandidateServerReflexiveConfig{foundation, protocol, address, port, uint16(component), relatedAddress, relatedPort})
|
||||
case "prflx":
|
||||
return NewCandidatePeerReflexive(&CandidatePeerReflexiveConfig{foundation, protocol, address, port, uint16(component), relatedAddress, relatedPort})
|
||||
case "relay":
|
||||
return NewCandidateRelay(&CandidateRelayConfig{foundation, protocol, address, port, uint16(component), relatedAddress, relatedPort, nil})
|
||||
}
|
||||
|
||||
return nil, fmt.Errorf("Unknown candidate typ(%s)", typ)
|
||||
}
|
||||
|
||||
@@ -136,3 +136,80 @@ func TestCandidateLastReceived(t *testing.T) {
|
||||
candidate.setLastReceived(now)
|
||||
assert.Equal(t, candidate.LastReceived(), now)
|
||||
}
|
||||
|
||||
func TestCandidateMarshal(t *testing.T) {
|
||||
for _, test := range []struct {
|
||||
candidate Candidate
|
||||
marshaled string
|
||||
expectError bool
|
||||
}{
|
||||
{&CandidateHost{
|
||||
candidateBase{
|
||||
networkType: NetworkTypeUDP6,
|
||||
candidateType: CandidateTypeHost,
|
||||
address: "fcd9:e3b8:12ce:9fc5:74a5:c6bb:d8b:e08a",
|
||||
port: 53987,
|
||||
},
|
||||
"",
|
||||
},
|
||||
"1938809241 1 udp 2130706431 fcd9:e3b8:12ce:9fc5:74a5:c6bb:d8b:e08a 53987 typ host",
|
||||
false,
|
||||
},
|
||||
{&CandidateHost{
|
||||
candidateBase{
|
||||
networkType: NetworkTypeUDP4,
|
||||
candidateType: CandidateTypeHost,
|
||||
address: "10.0.75.1",
|
||||
port: 53634,
|
||||
},
|
||||
"",
|
||||
},
|
||||
"1986380506 1 udp 2130706431 10.0.75.1 53634 typ host",
|
||||
false,
|
||||
},
|
||||
{&CandidateServerReflexive{
|
||||
candidateBase{
|
||||
networkType: NetworkTypeUDP4,
|
||||
candidateType: CandidateTypeServerReflexive,
|
||||
address: "191.228.238.68",
|
||||
port: 53991,
|
||||
relatedAddress: &CandidateRelatedAddress{"192.168.0.274", 53991},
|
||||
},
|
||||
},
|
||||
"4207374051 1 udp 1694498815 191.228.238.68 53991 typ srflx raddr 192.168.0.274 rport 53991",
|
||||
false,
|
||||
},
|
||||
{&CandidateRelay{
|
||||
candidateBase{
|
||||
networkType: NetworkTypeUDP4,
|
||||
candidateType: CandidateTypeRelay,
|
||||
address: "50.0.0.1",
|
||||
port: 5000,
|
||||
relatedAddress: &CandidateRelatedAddress{"192.168.0.1", 5001},
|
||||
},
|
||||
nil,
|
||||
},
|
||||
"4207374051 1 udp 16777215 50.0.0.1 5000 typ relay raddr 192.168.0.1 rport 5001",
|
||||
false,
|
||||
},
|
||||
|
||||
// Invalid candidates
|
||||
{nil, "", true},
|
||||
{nil, "1938809241", true},
|
||||
{nil, "1986380506 99999999 udp 2122063615 10.0.75.1 53634 typ host generation 0 network-id 2", true},
|
||||
{nil, "1986380506 1 udp 99999999999 10.0.75.1 53634 typ host", true},
|
||||
{nil, "4207374051 1 udp 1685790463 191.228.238.68 99999999 typ srflx raddr 192.168.0.278 rport 53991 generation 0 network-id 3", true},
|
||||
{nil, "4207374051 1 udp 1685790463 191.228.238.68 53991 typ srflx raddr", true},
|
||||
{nil, "4207374051 1 udp 1685790463 191.228.238.68 53991 typ srflx raddr 192.168.0.278 rport 99999999 generation 0 network-id 3", true},
|
||||
} {
|
||||
actualCandidate, err := UnmarshalCandidate(test.marshaled)
|
||||
if test.expectError {
|
||||
assert.Error(t, err)
|
||||
return
|
||||
}
|
||||
|
||||
assert.NoError(t, err)
|
||||
assert.True(t, test.candidate.Equal(actualCandidate))
|
||||
assert.Equal(t, test.marshaled, actualCandidate.Marshal())
|
||||
}
|
||||
}
|
||||
|
||||
@@ -12,9 +12,7 @@ github.com/pion/randutil v0.1.0 h1:CFG1UdESneORglEsnimhUjf33Rwjubwj6xfiOXBa3mA=
|
||||
github.com/pion/randutil v0.1.0/go.mod h1:XcJrSMMbbMRhASFVOlj/5hQial/Y8oH/HVo7TBZq+j8=
|
||||
github.com/pion/stun v0.3.5 h1:uLUCBCkQby4S1cf6CGuR9QrVOKcvUwFeemaC865QHDg=
|
||||
github.com/pion/stun v0.3.5/go.mod h1:gDMim+47EeEtfWogA37n6qXZS88L5V6LqFcf+DZA2UA=
|
||||
github.com/pion/transport v0.8.10 h1:lTiobMEw2PG6BH/mgIVqTV2mBp/mPT+IJLaN8ZxgdHk=
|
||||
github.com/pion/transport v0.8.10/go.mod h1:tBmha/UCjpum5hqTWhfAEs3CO4/tHSg0MYRhSzR+CZ8=
|
||||
github.com/pion/transport v0.10.0 h1:9M12BSneJm6ggGhJyWpDveFOstJsTiQjkLf4M44rm80=
|
||||
github.com/pion/transport v0.10.0/go.mod h1:BnHnUipd0rZQyTVB2SBGojFHT9CBt5C5TcsJSQGkvSE=
|
||||
github.com/pion/transport v0.10.1 h1:2W+yJT+0mOQ160ThZYUx5Zp2skzshiNgxrNE9GUfhJM=
|
||||
github.com/pion/transport v0.10.1/go.mod h1:PBis1stIILMiis0PewDw91WJeLJkyIMcEk+DwKOzf4A=
|
||||
@@ -24,11 +22,8 @@ github.com/pion/udp v0.1.0 h1:uGxQsNyrqG3GLINv36Ff60covYmfrLoxzwnCsIYspXI=
|
||||
github.com/pion/udp v0.1.0/go.mod h1:BPELIjbwE9PRbd/zxI/KYBnbo7B6+oA6YuEaNE8lths=
|
||||
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||
github.com/stretchr/objx v0.1.0 h1:4G4v2dO3VZwixGIRoQ5Lfboy6nUhCyYzaqnIAPPhYs4=
|
||||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
github.com/stretchr/testify v1.4.0 h1:2E4SXV/wtOkTonXsotYi4li6zVWxYlZuYNCXe9XRJyk=
|
||||
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
|
||||
github.com/stretchr/testify v1.5.1 h1:nOGnQDM7FYENwehXlg/kFVnos3rEvtKTjRvOWSzb6H4=
|
||||
github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA=
|
||||
github.com/stretchr/testify v1.6.1 h1:hDPOHmpOpP40lSULcqw7IrRb/u7w6RpDC9399XyoNd0=
|
||||
github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||
@@ -38,13 +33,10 @@ golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPh
|
||||
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||
golang.org/x/net v0.0.0-20191126235420-ef20fe5d7933/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20200625001655-4c5254603344 h1:vGXIOMxbNfDTk/aXCmfdLgkrSV+Z2tcbze+pEc3v5W4=
|
||||
golang.org/x/net v0.0.0-20200625001655-4c5254603344/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
|
||||
golang.org/x/net v0.0.0-20200822124328-c89045814202 h1:VvcQYSHwXgi7W+TpUR6A9g6Up98WAHf3f/ulnJ62IyA=
|
||||
golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
|
||||
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a h1:1BGLXjeY4akVXGgbC9HugT3Jv3hCI0z56oJR5vAMgBU=
|
||||
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20190412213103-97732733099d h1:+R4KGOnez64A81RvjARKc4UT5/tI9ujCIVX+P5KiHuI=
|
||||
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd h1:xhmwyvizuTgC2qz7ZlMluP20uW+C3Rm0FD/WLDX8884=
|
||||
golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
@@ -53,7 +45,6 @@ golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543 h1:E7g+9GITq07hpfrRu66IV
|
||||
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/yaml.v2 v2.2.2 h1:ZCJp+EgiOT7lHqUV2J862kp8Qj64Jo6az82+3Td9dZw=
|
||||
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo=
|
||||
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
|
||||
Reference in New Issue
Block a user