package udp import ( "encoding/binary" "testing" "git.difuse.io/Difuse/Mellaris/analyzer" ) func makeWireGuardPacket(msgType byte, body []byte) []byte { buf := make([]byte, 1+3+len(body)) buf[0] = msgType copy(buf[4:], body) return buf } func TestWireGuardUDPStream_Feed_HandshakeInitiation(t *testing.T) { s := newWireGuardUDPStream(nil) body := make([]byte, wireguardSizeHandshakeInitiation-4) binary.LittleEndian.PutUint32(body[0:4], 0x01020304) u, done := s.Feed(false, makeWireGuardPacket(wireguardTypeHandshakeInitiation, body)) if u == nil { t.Fatal("Feed returned nil update") } if done { t.Error("should not be done") } if u.Type != analyzer.PropUpdateReplace { t.Errorf("Type = %d, want PropUpdateReplace", u.Type) } initMap, ok := u.M["handshake_initiation"].(analyzer.PropMap) if !ok { t.Fatal("handshake_initiation missing") } if idx := initMap["sender_index"].(uint32); idx != 0x01020304 { t.Errorf("sender_index = %d, want %d", idx, 0x01020304) } } func TestWireGuardUDPStream_Feed_HandshakeResponse(t *testing.T) { s := newWireGuardUDPStream(nil) body := make([]byte, wireguardSizeHandshakeResponse-4) binary.LittleEndian.PutUint32(body[0:4], 0x01020304) binary.LittleEndian.PutUint32(body[4:8], 0x05060708) u, _ := s.Feed(false, makeWireGuardPacket(wireguardTypeHandshakeResponse, body)) if u == nil { t.Fatal("Feed returned nil update") } respMap, ok := u.M["handshake_response"].(analyzer.PropMap) if !ok { t.Fatal("handshake_response missing") } if idx := respMap["sender_index"].(uint32); idx != 0x01020304 { t.Errorf("sender_index = %d", idx) } if idx := respMap["receiver_index"].(uint32); idx != 0x05060708 { t.Errorf("receiver_index = %d", idx) } } func TestWireGuardUDPStream_Feed_PacketData(t *testing.T) { s := newWireGuardUDPStream(nil) body := make([]byte, wireguardMinSizePacketData-4) binary.LittleEndian.PutUint32(body[0:4], 0x0a0b0c0d) binary.LittleEndian.PutUint64(body[4:12], 42) u, _ := s.Feed(false, makeWireGuardPacket(wireguardTypeData, body)) if u == nil { t.Fatal("Feed returned nil update") } dataMap, ok := u.M["packet_data"].(analyzer.PropMap) if !ok { t.Fatal("packet_data missing") } if idx := dataMap["receiver_index"].(uint32); idx != 0x0a0b0c0d { t.Errorf("receiver_index = %d", idx) } if ctr := dataMap["counter"].(uint64); ctr != 42 { t.Errorf("counter = %d", ctr) } } func TestWireGuardUDPStream_Feed_CookieReply(t *testing.T) { s := newWireGuardUDPStream(nil) body := make([]byte, wireguardSizePacketCookieReply-4) binary.LittleEndian.PutUint32(body[0:4], 0x11111111) u, _ := s.Feed(false, makeWireGuardPacket(wireguardTypeCookieReply, body)) if u == nil { t.Fatal("Feed returned nil update") } crMap, ok := u.M["packet_cookie_reply"].(analyzer.PropMap) if !ok { t.Fatal("packet_cookie_reply missing") } if idx := crMap["receiver_index"].(uint32); idx != 0x11111111 { t.Errorf("receiver_index = %d", idx) } } func TestWireGuardUDPStream_Feed_InvalidLength(t *testing.T) { s := newWireGuardUDPStream(nil) u, done := s.Feed(false, []byte{wireguardTypeHandshakeInitiation, 0, 0, 0, 0x01}) if u == nil || !done { u, done = s.Feed(false, []byte{wireguardTypeHandshakeInitiation, 0, 0, 0, 0x01}) } if u == nil || !done { u, _ = s.Feed(false, []byte{wireguardTypeHandshakeInitiation, 0, 0, 0, 0x01}) } u, done = s.Feed(false, []byte{wireguardTypeHandshakeInitiation, 0, 0, 0, 0x01}) if u != nil || !done { t.Error("should return done after 4 invalid packets") } } func TestWireGuardUDPStream_Feed_TooShort(t *testing.T) { s := newWireGuardUDPStream(nil) u, _ := s.Feed(false, []byte{1, 0, 0}) if u != nil { t.Error("should return nil for too-short packet") } } func TestWireGuardUDPStream_Feed_NonZeroReserved(t *testing.T) { s := newWireGuardUDPStream(nil) u, _ := s.Feed(false, []byte{wireguardTypeHandshakeInitiation, 0, 0, 1, 0, 0, 0, 0}) if u != nil { t.Error("should return nil when reserved bytes are non-zero") } } func TestWireGuardUDPStream_Feed_HandshakeInitiation_WrongSize(t *testing.T) { s := newWireGuardUDPStream(nil) body := make([]byte, wireguardSizeHandshakeInitiation-4+1) binary.LittleEndian.PutUint32(body[0:4], 1) u, _ := s.Feed(false, makeWireGuardPacket(wireguardTypeHandshakeInitiation, body)) if u != nil { t.Error("should return nil for wrong init size") } } func TestWireGuardUDPStream_Close(t *testing.T) { s := newWireGuardUDPStream(nil) u := s.Close(false) if u != nil { t.Error("Close() should return nil") } } func TestWireGuardUDPStream_PutSenderIndex_MatchReceiverIndex(t *testing.T) { s := newWireGuardUDPStream(nil) s.putSenderIndex(false, 0xdeadbeef) if !s.matchReceiverIndex(true, 0xdeadbeef) { t.Error("should match reverse direction") } if s.matchReceiverIndex(false, 0xdeadbeef) { t.Error("should not match same direction") } if s.matchReceiverIndex(true, 0x12345678) { t.Error("should not match wrong index") } } func TestWireGuardUDPStream_RememberedIndexRing(t *testing.T) { s := newWireGuardUDPStream(nil) for i := uint32(0); i < wireguardRememberedIndexCount+2; i++ { s.putSenderIndex(false, i) } if s.matchReceiverIndex(true, 0) { t.Error("index 0 should have been evicted from ring") } if !s.matchReceiverIndex(true, uint32(wireguardRememberedIndexCount+1)) { t.Error("latest index should still be in ring") } } func TestWireGuardAnalyzer_Name(t *testing.T) { a := &WireGuardAnalyzer{} if a.Name() != "wireguard" { t.Errorf("Name() = %q, want wireguard", a.Name()) } }