Files

91 lines
2.2 KiB
Go

package udpserver
import (
"bytes"
"context"
"net"
"testing"
"time"
"github.com/pion/dtls/v3"
"github.com/samosvalishe/free-turn-proxy/internal/logx"
"github.com/samosvalishe/free-turn-proxy/internal/transport/dtlsdial"
)
func echoBackend(t *testing.T) string {
t.Helper()
pc, err := (&net.ListenConfig{}).ListenPacket(t.Context(), "udp", "127.0.0.1:0")
if err != nil {
t.Fatal(err)
}
t.Cleanup(func() { _ = pc.Close() })
go func() {
buf := make([]byte, 64<<10)
for {
n, addr, err := pc.ReadFrom(buf)
if err != nil {
return
}
_, _ = pc.WriteTo(buf[:n], addr)
}
}()
return pc.LocalAddr().String()
}
func dtlsPair(t *testing.T, ctx context.Context, backend string) net.Conn {
t.Helper()
cert, err := dtlsdial.GenerateSelfSignedCert()
if err != nil {
t.Fatal(err)
}
ln, err := dtls.ListenWithOptions("udp", &net.UDPAddr{IP: net.IPv4(127, 0, 0, 1)}, dtls.WithCertificates(cert))
if err != nil {
t.Fatal(err)
}
t.Cleanup(func() { _ = ln.Close() })
go func() {
conn, aerr := ln.Accept()
if aerr != nil {
return
}
Handle(ctx, logx.Nop(), conn, backend)
}()
pc, err := (&net.ListenConfig{}).ListenPacket(ctx, "udp", "127.0.0.1:0")
if err != nil {
t.Fatal(err)
}
serverAddr, ok := ln.Addr().(*net.UDPAddr)
if !ok {
t.Fatalf("listener addr %T", ln.Addr())
}
dialer := &dtlsdial.Dialer{HandshakeTimeout: 5 * time.Second}
conn, err := dialer.Dial(ctx, pc, serverAddr)
if err != nil {
t.Fatal(err)
}
t.Cleanup(func() { _ = conn.Close() })
return conn
}
// Датаграмма в пределах клиентского буфера 2048 проходит сервер в обе стороны целиком.
func TestHandleRelaysLargeDatagram(t *testing.T) {
ctx, cancel := context.WithTimeout(t.Context(), 10*time.Second)
defer cancel()
conn := dtlsPair(t, ctx, echoBackend(t))
for _, size := range []int{1200, 1800, 2048} {
payload := bytes.Repeat([]byte{0x5a}, size)
if _, err := conn.Write(payload); err != nil {
t.Fatalf("size %d: write: %v", size, err)
}
_ = conn.SetReadDeadline(time.Now().Add(2 * time.Second))
buf := make([]byte, 4096)
n, err := conn.Read(buf)
if err != nil || !bytes.Equal(buf[:n], payload) {
t.Fatalf("size %d: echo n=%d err=%v", size, n, err)
}
}
}