-
Notifications
You must be signed in to change notification settings - Fork 1.6k
/
ice.go
85 lines (73 loc) · 2.13 KB
/
ice.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
package sdp
import (
"fmt"
"strconv"
"strings"
"github.com/pions/webrtc/pkg/ice"
)
// ICECandidateUnmarshal takes a candidate strings and returns a ice.Candidate or nil if it fails to parse
func ICECandidateUnmarshal(raw string) ice.Candidate {
split := strings.Fields(raw)
if len(split) < 8 {
fmt.Printf("Attribute not long enough to be ICE candidate (%d) %s \n", len(split), raw)
return nil
}
getValue := func(key string) string {
rtrnNext := false
for _, i := range split {
if rtrnNext {
return i
} else if i == key {
rtrnNext = true
}
}
return ""
}
port, err := strconv.Atoi(split[5])
if err != nil {
return nil
}
// TODO verify valid address
address := split[4]
switch getValue("typ") {
case "host":
return &ice.CandidateHost{
CandidateBase: ice.CandidateBase{
Protocol: ice.ProtoTypeUDP,
Address: address,
Port: port,
},
}
case "srflx":
return &ice.CandidateSrflx{
CandidateBase: ice.CandidateBase{
Protocol: ice.ProtoTypeUDP,
Address: address,
Port: port,
},
}
default:
return nil
}
}
func iceSrflxCandidateString(c *ice.CandidateSrflx, component int) string {
return fmt.Sprintf("udpcandidate %d udp %d %s %d typ srflx raddr %s rport %d generation 0",
component, c.CandidateBase.Priority(ice.SrflxCandidatePreference, uint16(component)), c.CandidateBase.Address, c.CandidateBase.Port, c.RemoteAddress, c.RemotePort)
}
func iceHostCandidateString(c *ice.CandidateHost, component int) string {
return fmt.Sprintf("udpcandidate %d udp %d %s %d typ host generation 0",
component, c.CandidateBase.Priority(ice.HostCandidatePreference, uint16(component)), c.CandidateBase.Address, c.CandidateBase.Port)
}
// ICECandidateMarshal takes a candidate and returns a string representation
func ICECandidateMarshal(c ice.Candidate) []string {
out := make([]string, 0)
switch c := c.(type) {
case *ice.CandidateSrflx:
out = append(out, iceSrflxCandidateString(c, 1))
out = append(out, iceSrflxCandidateString(c, 2))
case *ice.CandidateHost:
out = append(out, iceHostCandidateString(c, 1))
out = append(out, iceHostCandidateString(c, 2))
}
return out
}