mirror of
https://gitlab.torproject.org/tpo/anti-censorship/pluggable-transports/snowflake.git
synced 2025-10-13 20:11:19 -04:00
Extract remote address from ICE candidates
Parse the received ICE candidates as well as the Connection Data field for a non-local IP address to pass to the bridge. This fixes bug #33157.
This commit is contained in:
parent
8467c01e9e
commit
d7aa9b8356
2 changed files with 157 additions and 16 deletions
|
@ -24,6 +24,7 @@ import (
|
|||
"git.torproject.org/pluggable-transports/snowflake.git/common/util"
|
||||
"git.torproject.org/pluggable-transports/snowflake.git/common/websocketconn"
|
||||
"github.com/gorilla/websocket"
|
||||
"github.com/pion/sdp/v2"
|
||||
"github.com/pion/webrtc/v2"
|
||||
)
|
||||
|
||||
|
@ -65,15 +66,47 @@ var remoteIPPatterns = []*regexp.Regexp{
|
|||
regexp.MustCompile(`(?m)^c=IN IP6 ([0-9A-Fa-f:.]+)(?:\/\d+)?(:? |\r?\n)`),
|
||||
}
|
||||
|
||||
// https://tools.ietf.org/html/rfc4566#section-5.7
|
||||
func remoteIPFromSDP(sdp string) net.IP {
|
||||
for _, pattern := range remoteIPPatterns {
|
||||
m := pattern.FindStringSubmatch(sdp)
|
||||
if m != nil {
|
||||
// Ignore parsing errors, ParseIP returns nil.
|
||||
return net.ParseIP(m[1])
|
||||
// Checks whether an IP address is a remote address for the client
|
||||
func isRemoteAddress(ip net.IP) bool {
|
||||
return !(util.IsLocal(ip) || ip.IsUnspecified() || ip.IsLoopback())
|
||||
}
|
||||
|
||||
func remoteIPFromSDP(str string) net.IP {
|
||||
// Look for remote IP in "a=candidate" attribute fields
|
||||
// https://tools.ietf.org/html/rfc5245#section-15.1
|
||||
var desc sdp.SessionDescription
|
||||
err := desc.Unmarshal([]byte(str))
|
||||
if err != nil {
|
||||
log.Println("Error parsing SDP: ", err.Error())
|
||||
return nil
|
||||
}
|
||||
for _, m := range desc.MediaDescriptions {
|
||||
for _, a := range m.Attributes {
|
||||
if a.IsICECandidate() {
|
||||
ice, err := a.ToICECandidate()
|
||||
if err == nil {
|
||||
ip := net.ParseIP(ice.Address)
|
||||
if ip != nil && isRemoteAddress(ip) {
|
||||
return ip
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// Finally look for remote IP in "c=" Connection Data field
|
||||
// https://tools.ietf.org/html/rfc4566#section-5.7
|
||||
for _, pattern := range remoteIPPatterns {
|
||||
m := pattern.FindStringSubmatch(str)
|
||||
if m != nil {
|
||||
// Ignore parsing errors, ParseIP returns nil.
|
||||
ip := net.ParseIP(m[1])
|
||||
if ip != nil && isRemoteAddress(ip) {
|
||||
return ip
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue