package peer import ( "bytes" "net" "reflect" "sync/atomic" "testing" ) // Test that we parse IPv4 packets correctly. func TestIFReader_parsePacket_ipv4(t *testing.T) { r := newIFReader(nil, [256]*atomic.Pointer[RemotePeer]{}, nil, nil) pkt := make([]byte, 1234) pkt[0] = 4 << 4 pkt[19] = 128 if ip, ok := r.parsePacket(pkt); !ok || ip != 128 { t.Fatal(ip, ok) } } // Test that we parse IPv6 packets correctly. func TestIFReader_parsePacket_ipv6(t *testing.T) { r := newIFReader(nil, [256]*atomic.Pointer[RemotePeer]{}, nil, nil) pkt := make([]byte, 1234) pkt[0] = 6 << 4 pkt[39] = 42 if ip, ok := r.parsePacket(pkt); !ok || ip != 42 { t.Fatal(ip, ok) } } // Test that empty packets work as expected. func TestIFReader_parsePacket_emptyPacket(t *testing.T) { r := newIFReader(nil, [256]*atomic.Pointer[RemotePeer]{}, nil, nil) pkt := make([]byte, 0) if ip, ok := r.parsePacket(pkt); ok { t.Fatal(ip, ok) } } // Test that invalid IP versions fail. func TestIFReader_parsePacket_invalidIPVersion(t *testing.T) { r := newIFReader(nil, [256]*atomic.Pointer[RemotePeer]{}, nil, nil) for i := byte(1); i < 16; i++ { if i == 4 || i == 6 { continue } pkt := make([]byte, 1234) pkt[0] = i << 4 if ip, ok := r.parsePacket(pkt); ok { t.Fatal(i, ip, ok) } } } // Test that short IPv4 packets fail. func TestIFReader_parsePacket_shortIPv4(t *testing.T) { r := newIFReader(nil, [256]*atomic.Pointer[RemotePeer]{}, nil, nil) pkt := make([]byte, 19) pkt[0] = 4 << 4 if ip, ok := r.parsePacket(pkt); ok { t.Fatal(ip, ok) } } // Test that short IPv6 packets fail. func TestIFReader_parsePacket_shortIPv6(t *testing.T) { r := newIFReader(nil, [256]*atomic.Pointer[RemotePeer]{}, nil, nil) pkt := make([]byte, 39) pkt[0] = 6 << 4 if ip, ok := r.parsePacket(pkt); ok { t.Fatal(ip, ok) } } // Test that we can read a packet. func TestIFReader_readNextpacket(t *testing.T) { in, out := net.Pipe() r := newIFReader(out, [256]*atomic.Pointer[RemotePeer]{}, nil, nil) defer in.Close() defer out.Close() go in.Write([]byte("hello world!")) pkt := r.readNextPacket(make([]byte, bufferSize)) if !bytes.Equal(pkt, []byte("hello world!")) { t.Fatalf("%s", pkt) } } // ---------------------------------------------------------------------------- type sentPacket struct { Relayed bool Packet []byte Route RemotePeer Relay RemotePeer } type sendPacketTestHarness struct { Packets []sentPacket } func (h *sendPacketTestHarness) SendDataPacket(pkt []byte, route *RemotePeer) { h.Packets = append(h.Packets, sentPacket{ Packet: bytes.Clone(pkt), Route: *route, }) } func (h *sendPacketTestHarness) RelayDataPacket(pkt []byte, route, relay *RemotePeer) { h.Packets = append(h.Packets, sentPacket{ Relayed: true, Packet: bytes.Clone(pkt), Route: *route, Relay: *relay, }) } func newIFReaderForSendPacketTesting() (*ifReader, *sendPacketTestHarness) { h := &sendPacketTestHarness{} routes := [256]*atomic.Pointer[RemotePeer]{} for i := range routes { routes[i] = &atomic.Pointer[RemotePeer]{} routes[i].Store(&RemotePeer{}) } relay := &atomic.Pointer[RemotePeer]{} r := newIFReader(nil, routes, relay, h) return r, h } // Testing that we can send a packet directly. func TestIFReader_sendPacket_direct(t *testing.T) { r, h := newIFReaderForSendPacketTesting() route := r.peers[2].Load() route.Up = true route.Direct = true in := []byte("hello world") r.sendPacket(in, 2) if len(h.Packets) != 1 { t.Fatal(h.Packets) } expected := sentPacket{ Relayed: false, Packet: in, Route: *route, } if !reflect.DeepEqual(h.Packets[0], expected) { t.Fatal(h.Packets[0]) } } // Testing that we don't send a packet if route isn't up. func TestIFReader_sendPacket_directNotUp(t *testing.T) { r, h := newIFReaderForSendPacketTesting() route := r.peers[2].Load() route.Direct = true in := []byte("hello world") r.sendPacket(in, 2) if len(h.Packets) != 0 { t.Fatal(h.Packets) } } // Testing that we can send a packet via a relay. func TestIFReader_sendPacket_relayed(t *testing.T) { r, h := newIFReaderForSendPacketTesting() route := r.peers[2].Load() route.Up = true route.Direct = false relay := r.peers[3].Load() r.relay.Store(relay) relay.Up = true relay.Direct = true in := []byte("hello world") r.sendPacket(in, 2) if len(h.Packets) != 1 { t.Fatal(h.Packets) } expected := sentPacket{ Relayed: true, Packet: in, Route: *route, Relay: *relay, } if !reflect.DeepEqual(h.Packets[0], expected) { t.Fatal(h.Packets[0]) } } // Testing that we don't try to send on a nil relay IP. func TestIFReader_sendPacket_nilRealy(t *testing.T) { r, h := newIFReaderForSendPacketTesting() route := r.peers[2].Load() route.Up = true route.Direct = false in := []byte("hello world") r.sendPacket(in, 2) if len(h.Packets) != 0 { t.Fatal(h.Packets) } }