mirror of
https://github.com/hackdiaz-dev/free-turn-proxy.git
synced 2026-10-12 09:41:53 +02:00
91 lines
2.2 KiB
Go
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)
|
|
}
|
|
}
|
|
}
|