diff options
Diffstat (limited to 'vendor/git.torproject.org/pluggable-transports/snowflake.git/common/util/util.go')
-rw-r--r-- | vendor/git.torproject.org/pluggable-transports/snowflake.git/common/util/util.go | 99 |
1 files changed, 99 insertions, 0 deletions
diff --git a/vendor/git.torproject.org/pluggable-transports/snowflake.git/common/util/util.go b/vendor/git.torproject.org/pluggable-transports/snowflake.git/common/util/util.go new file mode 100644 index 0000000..00f7302 --- /dev/null +++ b/vendor/git.torproject.org/pluggable-transports/snowflake.git/common/util/util.go @@ -0,0 +1,99 @@ +package util + +import ( + "encoding/json" + "errors" + "net" + + "github.com/pion/ice/v2" + "github.com/pion/sdp/v3" + "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() { + c, err := ice.UnmarshalCandidate(a.Value) + if err == nil && c.Type() == ice.CandidateTypeHost { + ip := net.ParseIP(c.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) +} |