Files
2026-08-20 17:53:55 +02:00

78 lines
2.5 KiB
Go

package udp
import (
"net"
"testing"
"time"
)
// The relay exists so a second application can be fed the same WSJT-X stream,
// and the ONE thing it must get right is that the bytes are unchanged. The
// relays in the field prepend an origin header ("127.0.0.1:2237|") — which is
// why stripForwarderHeader had to be written on the receiving side — so a
// header here would inflict on the next program the fault we had to survive.
func TestRelayForwardsVerbatim(t *testing.T) {
dst, err := net.ListenUDP("udp", &net.UDPAddr{IP: net.IPv4(127, 0, 0, 1), Port: 0})
if err != nil {
t.Fatal(err)
}
defer dst.Close()
port := dst.LocalAddr().(*net.UDPAddr).Port
m := &Manager{outbound: []Config{{
ID: 1, Name: "relay", ServiceType: ServiceWSJTRelay,
DestinationIP: "127.0.0.1", Port: port,
}}}
// A packet with bytes that no parser here understands, on purpose: the relay
// must not care what it is carrying.
sent := []byte{0xad, 0xbc, 0xcb, 0xda, 0x00, 0x00, 0x00, 0x63, 0xde, 0xad, 0xbe, 0xef}
m.RelayInbound(sent, 2237)
buf := make([]byte, 1024)
_ = dst.SetReadDeadline(time.Now().Add(2 * time.Second))
n, _, err := dst.ReadFromUDP(buf)
if err != nil {
t.Fatalf("nothing relayed: %v", err)
}
if got := buf[:n]; string(got) != string(sent) {
t.Errorf("relayed % X, want % X — the bytes must go out unchanged", got, sent)
}
}
// A relay aimed at one of OpsLog's OWN listening ports would come straight back
// in, be relayed again, and saturate the loopback within seconds. The row is
// skipped instead.
func TestRelayRefusesToFeedItself(t *testing.T) {
own, err := net.ListenUDP("udp", &net.UDPAddr{IP: net.IPv4(127, 0, 0, 1), Port: 0})
if err != nil {
t.Fatal(err)
}
defer own.Close()
port := own.LocalAddr().(*net.UDPAddr).Port
m := &Manager{
inbound: map[int64]*Server{
7: {cfg: Config{ID: 7, Port: port, ServiceType: ServiceWSJT}},
},
outbound: []Config{{
ID: 1, Name: "loop", ServiceType: ServiceWSJTRelay,
DestinationIP: "127.0.0.1", Port: port,
}},
}
m.RelayInbound([]byte{1, 2, 3, 4}, 2237)
buf := make([]byte, 64)
_ = own.SetReadDeadline(time.Now().Add(300 * time.Millisecond))
if n, _, err := own.ReadFromUDP(buf); err == nil {
t.Fatalf("relayed %d bytes back into our own listener — that is the loop", n)
}
}
// No relay rows configured must cost nothing and send nothing.
func TestRelayWithNoRowsIsSilent(t *testing.T) {
m := &Manager{}
m.RelayInbound([]byte{1, 2, 3}, 2237) // must not panic
m.RelayInbound(nil, 2237)
}