quorate/services/oci-l4-relay-guest/cmd/smtp-evidence/conntrack_test.go

63 lines
2.4 KiB
Go
Raw Normal View History

package main
import (
"net/netip"
"testing"
"time"
"github.com/ti-mo/conntrack"
)
func TestConntrackRecordRequiresDeclaredPortAndReplyTarget(t *testing.T) {
flow := acceptedFlow()
record, ok := conntrackRecordForFlow(&flow, []conntrackService{{
Name: "web",
Ports: []uint16{80, 443},
TargetAddress: netip.MustParseAddr("10.104.40.127"),
}})
if !ok {
t.Fatal("accepted relay flow was not classified")
}
if record.Service != "web" || record.Original.SourceAddress != "198.18.0.1" || record.Reply.SourceAddress != "10.104.40.127" || record.DurationMilliseconds != 1500 || record.TCPState != "time_wait" {
t.Fatalf("unexpected record %#v", record)
}
flow.TupleReply.IP.SourceAddress = netip.MustParseAddr("203.0.113.10")
if _, ok := conntrackRecordForFlow(&flow, []conntrackService{{Name: "web", Ports: []uint16{443}, TargetAddress: netip.MustParseAddr("10.104.40.127")}}); ok {
t.Fatal("outbound connection was classified as accepted relay traffic")
}
}
func TestConntrackSamplingIsDeterministic(t *testing.T) {
flow := acceptedFlow()
first := sampleConntrackFlow(&flow, 10)
for attempt := 0; attempt < 100; attempt++ {
if sampleConntrackFlow(&flow, 10) != first {
t.Fatal("sampling decision changed for an unchanged tuple")
}
}
}
func TestTokenBucketBoundsBurstAndRefills(t *testing.T) {
now := time.Date(2026, 7, 31, 0, 0, 0, 0, time.UTC)
bucket := newTokenBucket(1, 2, now)
if !bucket.allow(now) || !bucket.allow(now) || bucket.allow(now) {
t.Fatal("initial burst was not bounded")
}
if !bucket.allow(now.Add(time.Second)) || bucket.allow(now.Add(time.Second)) {
t.Fatal("sustained rate was not bounded")
}
}
func acceptedFlow() conntrack.Flow {
startedAt := time.Date(2026, 7, 31, 0, 0, 0, 0, time.UTC)
flow := conntrack.NewFlow(6, 0, netip.MustParseAddr("198.18.0.1"), netip.MustParseAddr("10.49.127.43"), 50000, 443, 60, 0)
flow.TupleReply.IP.SourceAddress = netip.MustParseAddr("10.104.40.127")
flow.TupleReply.IP.DestinationAddress = netip.MustParseAddr("198.18.0.1")
flow.TupleReply.Proto.SourcePort = 443
flow.TupleReply.Proto.DestinationPort = 50000
flow.Timestamp = conntrack.Timestamp{Start: startedAt, Stop: startedAt.Add(1500 * time.Millisecond)}
flow.CountersOrig = conntrack.Counter{Packets: 3, Bytes: 180}
flow.CountersReply = conntrack.Counter{Direction: true, Packets: 4, Bytes: 240}
flow.ProtoInfo.TCP = &conntrack.ProtoInfoTCP{State: 7}
return flow
}