mirror of
https://github.com/pion/ice.git
synced 2025-10-05 15:37:07 +08:00
108 lines
2.4 KiB
Go
108 lines
2.4 KiB
Go
// +build !js
|
|
|
|
package ice
|
|
|
|
import (
|
|
"net"
|
|
"sync"
|
|
"testing"
|
|
"time"
|
|
|
|
"github.com/pion/logging"
|
|
"github.com/pion/stun"
|
|
"github.com/pion/transport/test"
|
|
"github.com/stretchr/testify/require"
|
|
)
|
|
|
|
func TestUDPMux(t *testing.T) {
|
|
report := test.CheckRoutines(t)
|
|
defer report()
|
|
|
|
loggerFactory := logging.NewDefaultLoggerFactory()
|
|
udpMux := NewUDPMuxDefault(UDPMuxParams{
|
|
Logger: loggerFactory.NewLogger("ice"),
|
|
ReadBufferSize: 20,
|
|
})
|
|
err := udpMux.Start(7686)
|
|
require.NoError(t, err)
|
|
|
|
defer func() {
|
|
_ = udpMux.Close()
|
|
}()
|
|
|
|
require.NotNil(t, udpMux.LocalAddr(), "tcpMux.LocalAddr() is nil")
|
|
require.Equal(t, ":7686", udpMux.LocalAddr().String())
|
|
|
|
wg := sync.WaitGroup{}
|
|
|
|
wg.Add(1)
|
|
go func() {
|
|
defer wg.Done()
|
|
testMuxConnection(t, udpMux, "ufrag1")
|
|
}()
|
|
wg.Add(1)
|
|
go func() {
|
|
defer wg.Done()
|
|
testMuxConnection(t, udpMux, "ufrag2")
|
|
}()
|
|
|
|
testMuxConnection(t, udpMux, "ufrag3")
|
|
wg.Wait()
|
|
|
|
require.NoError(t, udpMux.Close())
|
|
|
|
// can't create more connections
|
|
_, err = udpMux.GetConn("failufrag", "udp")
|
|
require.Error(t, err)
|
|
}
|
|
|
|
func testMuxConnection(t *testing.T, udpMux *UDPMuxDefault, ufrag string) {
|
|
pktConn, err := udpMux.GetConn(ufrag, udp)
|
|
require.NoError(t, err, "error retrieving muxed connection for ufrag")
|
|
defer func() {
|
|
_ = pktConn.Close()
|
|
}()
|
|
|
|
remoteConn, err := net.DialUDP(udp, nil, udpMux.LocalAddr().(*net.UDPAddr))
|
|
require.NoError(t, err, "error dialing test udp connection")
|
|
|
|
// initial messages are dropped
|
|
_, err = remoteConn.Write([]byte("dropped bytes"))
|
|
require.NoError(t, err)
|
|
// wait for packet to be consumed
|
|
time.Sleep(time.Millisecond)
|
|
|
|
// write out to establish connection
|
|
msg := stun.New()
|
|
msg.Type = stun.MessageType{Method: stun.MethodBinding, Class: stun.ClassRequest}
|
|
msg.Add(stun.AttrUsername, []byte(ufrag+":otherufrag"))
|
|
msg.Encode()
|
|
_, err = pktConn.WriteTo(msg.Raw, remoteConn.LocalAddr())
|
|
require.NoError(t, err)
|
|
|
|
// ensure received
|
|
buf := make([]byte, receiveMTU)
|
|
n, err := remoteConn.Read(buf)
|
|
require.NoError(t, err)
|
|
require.Equal(t, msg.Raw, buf[:n])
|
|
|
|
// write a bunch of packets from remote to ensure proper receipt
|
|
dataToSend := [][]byte{
|
|
[]byte("hello world"),
|
|
[]byte("test text"),
|
|
msg.Raw,
|
|
}
|
|
|
|
buffer := make([]byte, receiveMTU)
|
|
for _, data := range dataToSend {
|
|
_, err := remoteConn.Write(data)
|
|
require.NoError(t, err)
|
|
|
|
n, _, err := pktConn.ReadFrom(buffer)
|
|
require.NoError(t, err)
|
|
require.Equal(t, data, buffer[:n])
|
|
|
|
time.Sleep(10 * time.Millisecond)
|
|
}
|
|
}
|