snowflake/common/util/util.go
Cecylia Bocovich 83c01565ef Update webrtc library to v3.0.0
This update required two main changes to how we use the library. First,
we had to make sure we created the datachannel on the offering peer side
before creating the offer. Second, we had to make sure we wait for the
gathering of all candidates to complete since trickle-ice is enabled by
default. See the release notes for more details:
https://github.com/pion/webrtc/wiki/Release-WebRTC@v3.0.0.
2021-01-12 10:37:26 -05:00

98 lines
2.5 KiB
Go

package util
import (
"encoding/json"
"errors"
"net"
"github.com/pion/sdp/v2"
"github.com/pion/webrtc/v3"
)
func SerializeSessionDescription(desc *webrtc.SessionDescription) (string, error) {
bytes, err := json.Marshal(*desc)
if err != nil {
return "", err
}
return string(bytes), nil
}
func DeserializeSessionDescription(msg string) (*webrtc.SessionDescription, error) {
var parsed map[string]interface{}
err := json.Unmarshal([]byte(msg), &parsed)
if err != nil {
return nil, err
}
if _, ok := parsed["type"]; !ok {
return nil, errors.New("cannot deserialize SessionDescription without type field")
}
if _, ok := parsed["sdp"]; !ok {
return nil, errors.New("cannot deserialize SessionDescription without sdp field")
}
var stype webrtc.SDPType
switch parsed["type"].(string) {
default:
return nil, errors.New("Unknown SDP type")
case "offer":
stype = webrtc.SDPTypeOffer
case "pranswer":
stype = webrtc.SDPTypePranswer
case "answer":
stype = webrtc.SDPTypeAnswer
case "rollback":
stype = webrtc.SDPTypeRollback
}
return &webrtc.SessionDescription{
Type: stype,
SDP: parsed["sdp"].(string),
}, nil
}
// Stolen from https://github.com/golang/go/pull/30278
func IsLocal(ip net.IP) bool {
if ip4 := ip.To4(); ip4 != nil {
// Local IPv4 addresses are defined in https://tools.ietf.org/html/rfc1918
return ip4[0] == 10 ||
(ip4[0] == 172 && ip4[1]&0xf0 == 16) ||
(ip4[0] == 192 && ip4[1] == 168) ||
// Carrier-Grade NAT as per https://tools.ietf.org/htm/rfc6598
(ip4[0] == 100 && ip4[1]&0xc0 == 64) ||
// Dynamic Configuration as per https://tools.ietf.org/htm/rfc3927
(ip4[0] == 169 && ip4[1] == 254)
}
// Local IPv6 addresses are defined in https://tools.ietf.org/html/rfc4193
return len(ip) == net.IPv6len && ip[0]&0xfe == 0xfc
}
// Removes local LAN address ICE candidates
func StripLocalAddresses(str string) string {
var desc sdp.SessionDescription
err := desc.Unmarshal([]byte(str))
if err != nil {
return str
}
for _, m := range desc.MediaDescriptions {
attrs := make([]sdp.Attribute, 0)
for _, a := range m.Attributes {
if a.IsICECandidate() {
ice, err := a.ToICECandidate()
if err == nil && ice.Typ == "host" {
ip := net.ParseIP(ice.Address)
if ip != nil && (IsLocal(ip) || ip.IsUnspecified() || ip.IsLoopback()) {
/* no append in this case */
continue
}
}
}
attrs = append(attrs, a)
}
m.Attributes = attrs
}
bts, err := desc.Marshal()
if err != nil {
return str
}
return string(bts)
}