From 7b33f85353a2080145c9fdbbb8cb83bbf28e65d2 Mon Sep 17 00:00:00 2001 From: Aleksandr Razumov Date: Tue, 21 May 2019 13:14:54 +0300 Subject: [PATCH] Merge GetMappedAddressUDP The GetMappedAddressUDP function was moved from stun v0.2.2, adapted to gortc API and slightly simplified. --- gather.go | 57 ++++++++++++++++++++++++++++++++++++++++++++++++++++--- go.mod | 1 - go.sum | 4 ---- 3 files changed, 54 insertions(+), 8 deletions(-) diff --git a/gather.go b/gather.go index 92a5f46..8db9078 100644 --- a/gather.go +++ b/gather.go @@ -5,8 +5,7 @@ import ( "net" "time" - // TODO(ar): Merge - "github.com/pion/stun" + "github.com/gortc/stun" ) func localInterfaces(networkTypes []NetworkType) (ips []net.IP) { @@ -138,7 +137,7 @@ func gatherCandidatesReflective(a *Agent, urls []*URL, networkTypes []NetworkTyp continue } - xoraddr, err := stun.GetMappedAddressUDP(conn, serverAddr, time.Second*5) + xoraddr, err := getXORMappedAddr(conn, serverAddr, time.Second*5) if err != nil { a.log.Warnf("could not get server reflexive address %s %s: %v\n", network, url, err) continue @@ -170,3 +169,55 @@ func gatherCandidatesReflective(a *Agent, urls []*URL, networkTypes []NetworkTyp } } } + +// getXORMappedAddr initiates a stun requests to serverAddr using conn, reads the response and returns +// the XORMappedAddress returned by the stun server. +// +// Adapted from stun v0.2. +func getXORMappedAddr(conn *net.UDPConn, serverAddr net.Addr, deadline time.Duration) (*stun.XORMappedAddress, error) { + if deadline > 0 { + if err := conn.SetReadDeadline(time.Now().Add(deadline)); err != nil { + return nil, err + } + } + defer func() { + if deadline > 0 { + _ = conn.SetReadDeadline(time.Time{}) + } + }() + resp, err := stunRequest( + conn.Read, + func(b []byte) (int, error) { + return conn.WriteTo(b, serverAddr) + }, + ) + if err != nil { + return nil, err + } + var addr stun.XORMappedAddress + if err = addr.GetFrom(resp); err != nil { + return nil, fmt.Errorf("failed to get XOR-MAPPED-ADDRESS response: %v", err) + } + return &addr, nil +} + +func stunRequest(read func([]byte) (int, error), write func([]byte) (int, error)) (*stun.Message, error) { + req, err := stun.Build(stun.BindingRequest, stun.TransactionID) + if err != nil { + return nil, err + } + if _, err = write(req.Raw); err != nil { + return nil, err + } + const maxMessageSize = 1280 + bs := make([]byte, maxMessageSize) + n, err := read(bs) + if err != nil { + return nil, err + } + res := &stun.Message{Raw: bs[:n]} + if err := res.Decode(); err != nil { + return nil, err + } + return res, nil +} diff --git a/go.mod b/go.mod index 885180f..6829160 100644 --- a/go.mod +++ b/go.mod @@ -5,7 +5,6 @@ go 1.12 require ( github.com/gortc/stun v1.19.0 github.com/pion/logging v0.2.1 - github.com/pion/stun v0.2.2 github.com/pion/transport v0.7.0 github.com/stretchr/testify v1.3.0 ) diff --git a/go.sum b/go.sum index 804a8fd..82803d5 100644 --- a/go.sum +++ b/go.sum @@ -4,12 +4,8 @@ github.com/gortc/stun v1.19.0 h1:6qy7zGGk0tdMOdEzK7hLeAVZEHllJC8+OOBpPAyjY1c= github.com/gortc/stun v1.19.0/go.mod h1:dZ0O/fYCkg9Z0Pvl6WDpNhRFTAU0X1CPOsJiZqn6EHo= github.com/pion/logging v0.2.1 h1:LwASkBKZ+2ysGJ+jLv1E/9H1ge0k1nTfi1X+5zirkDk= github.com/pion/logging v0.2.1/go.mod h1:k0/tDVsRCX2Mb2ZEmTqNa7CWsQPc+YYCB7Q+5pahoms= -github.com/pion/stun v0.2.2 h1:0IJCwJFOdEmHzz4oxl9SBGLlJbnNbF+0h6XSOmuE034= -github.com/pion/stun v0.2.2/go.mod h1:TChCNKgwnFiFG/c9K+zqEdd6pO6tlODb9yN1W/zVfsE= github.com/pion/transport v0.7.0 h1:EsXN8TglHMlKZMo4ZGqwK6QgXBu0WYg7wfGMWIXsS+w= github.com/pion/transport v0.7.0/go.mod h1:iWZ07doqOosSLMhZ+FXUTq+TamDoXSllxpbGcfkCmbE= -github.com/pkg/errors v0.8.1 h1:iURUrRGxPUNPdy5/HRSm+Yj6okJ6UtLINN0Q9M4+h3I= -github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= 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/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=