Cleanup gather code

Simplify tests and use assert where possible. Move all generic code out
of gather.go into util.go

Relates to #118
This commit is contained in:
Sean DuBois
2020-02-23 22:05:13 -08:00
parent aa3fe7c6a3
commit 11318ea39f
3 changed files with 70 additions and 96 deletions
-56
View File
@@ -7,7 +7,6 @@ import (
"sync"
"time"
"github.com/pion/stun"
"github.com/pion/transport/vnet"
"github.com/pion/turn/v2"
)
@@ -470,58 +469,3 @@ func (a *Agent) gatherCandidatesRelay(urls []*URL) error {
return nil
}
// 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.PacketConn, 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(
func(p []byte) (int, error) {
n, _, errr := conn.ReadFrom(p)
return n, errr
},
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
}
+13 -40
View File
@@ -14,47 +14,28 @@ import (
func TestListenUDP(t *testing.T) {
a, err := NewAgent(&AgentConfig{})
if err != nil {
t.Fatalf("Failed to create agent: %s", err)
}
assert.NoError(t, err)
localIPs, err := a.localInterfaces([]NetworkType{NetworkTypeUDP4})
if len(localIPs) == 0 {
t.Fatal("localInterfaces found no interfaces, unable to test")
} else if err != nil {
t.Fatal(err)
}
assert.NotEqual(t, len(localIPs), 0, "localInterfaces found no interfaces, unable to test")
assert.NoError(t, err)
ip := localIPs[0]
conn, err := a.listenUDP(0, 0, udp, &net.UDPAddr{IP: ip, Port: 0})
if err != nil {
t.Fatalf("listenUDP error with no port restriction %v", err)
} else if conn == nil {
t.Fatalf("listenUDP error with no port restriction return a nil conn")
}
assert.NoError(t, err, "listenUDP error with no port restriction")
assert.NotNil(t, conn, "listenUDP error with no port restriction return a nil conn")
_, err = a.listenUDP(4999, 5000, udp, &net.UDPAddr{IP: ip, Port: 0})
if err == nil {
t.Fatal("listenUDP with invalid port range did not fail")
}
if err != ErrPort {
t.Fatal("listenUDP with invalid port range did not return ErrPort")
}
assert.Equal(t, err, ErrPort, "listenUDP with invalid port range did not return ErrPort")
conn, err = a.listenUDP(5000, 5000, udp, &net.UDPAddr{IP: ip, Port: 0})
if err != nil {
t.Fatalf("listenUDP error with no port restriction %v", err)
} else if conn == nil {
t.Fatalf("listenUDP error with no port restriction return a nil conn")
}
assert.NoError(t, err, "listenUDP error with no port restriction")
assert.NotNil(t, conn, "listenUDP error with no port restriction return a nil conn")
_, port, err := net.SplitHostPort(conn.LocalAddr().String())
if err != nil {
t.Fatal(err)
} else if port != "5000" {
t.Fatalf("listenUDP with port restriction of 5000 listened on incorrect port (%s)", port)
}
assert.NoError(t, err)
assert.Equal(t, port, "5000", "listenUDP with port restriction of 5000 listened on incorrect port")
portMin := 5100
portMax := 5109
@@ -63,11 +44,8 @@ func TestListenUDP(t *testing.T) {
portRange := make([]int, 0, total)
for i := 0; i < total; i++ {
conn, err = a.listenUDP(portMax, portMin, udp, &net.UDPAddr{IP: ip, Port: 0})
if err != nil {
t.Fatalf("listenUDP error with no port restriction %v", err)
} else if conn == nil {
t.Fatalf("listenUDP error with no port restriction return a nil conn")
}
assert.NoError(t, err, "listenUDP error with no port restriction")
assert.NotNil(t, conn, "listenUDP error with no port restriction return a nil conn")
_, port, err = net.SplitHostPort(conn.LocalAddr().String())
if err != nil {
@@ -88,12 +66,7 @@ func TestListenUDP(t *testing.T) {
t.Fatalf("listenUDP with port restriction [%d, %d], got:%v, want:%v", portMin, portMax, result, portRange)
}
_, err = a.listenUDP(portMax, portMin, udp, &net.UDPAddr{IP: ip, Port: 0})
if err == nil {
t.Fatalf("listenUDP with port restriction [%d, %d], should return error", portMin, portMax)
}
if err != ErrPort {
t.Fatalf("listenUDP with port restriction [%d, %d], did not return ErrPort", portMin, portMax)
}
assert.Equal(t, err, ErrPort, "listenUDP with port restriction [%d, %d], did not return ErrPort", portMin, portMax)
assert.NoError(t, a.Close())
}
+57
View File
@@ -6,6 +6,8 @@ import (
"net"
"sync/atomic"
"time"
"github.com/pion/stun"
)
type atomicError struct{ v atomic.Value }
@@ -87,3 +89,58 @@ func generateRandString(prefix, sufix string) (string, error) {
return fmt.Sprintf("%s%X-%X-%X-%X-%X%s", prefix, b[0:4], b[4:6], b[6:8], b[8:10], b[10:], sufix), nil
}
// 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.PacketConn, 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(
func(p []byte) (int, error) {
n, _, errr := conn.ReadFrom(p)
return n, errr
},
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
}