package peer /* type mockIfWriter struct { Written [][]byte } func (w *mockIfWriter) Write(b []byte) (int, error) { w.Written = append(w.Written, bytes.Clone(b)) return len(b), nil } type mockEncryptedPacket struct { Packet []byte Route *peerRoute } type mockEncryptedPacketSender struct { Sent []mockEncryptedPacket } func (m *mockEncryptedPacketSender) SendEncryptedDataPacket(pkt []byte, route *peerRoute) { m.Sent = append(m.Sent, mockEncryptedPacket{ Packet: bytes.Clone(pkt), Route: route, }) } type mockControlMsgHandler struct { Messages []any } func (m *mockControlMsgHandler) HandleControlMsg(pkt any) { m.Messages = append(m.Messages, pkt) } type udpPipe struct { packets chan []byte } func newUDPPipe() *udpPipe { return &udpPipe{make(chan []byte, 1024)} } func (p *udpPipe) WriteToUDPAddrPort(b []byte, addr netip.AddrPort) (int, error) { p.packets <- bytes.Clone(b) return len(b), nil } func (p *udpPipe) ReadFromUDPAddrPort(b []byte) (n int, addr netip.AddrPort, err error) { packet := <-p.packets copy(b, packet) return len(packet), netip.AddrPort{}, nil } type connReaderTestHarness struct { Pipe *udpPipe R *connReader WRemote *connWriter WRelayRemote *connWriter Remote *peerRoute RelayRemote *peerRoute IFace *mockIfWriter Sender *mockEncryptedPacketSender Super *mockControlMsgHandler } // Peer 2 is indirect, peer 3 is direct. func newConnReadeTestHarness() (h connReaderTestHarness) { pipe := newUDPPipe() routes := [256]*atomic.Pointer[peerRoute]{} for i := range routes { routes[i] = &atomic.Pointer[peerRoute]{} routes[i].Store(&peerRoute{}) } local, remote, relayLocal, relayRemote := testConnWriter_getTestRoutes() routes[2].Store(local) routes[3].Store(relayLocal) h.Pipe = pipe h.WRemote = newConnWriter(pipe, 2) h.WRelayRemote = newConnWriter(pipe, 3) h.Remote = remote h.RelayRemote = relayRemote h.IFace = &mockIfWriter{} h.Sender = &mockEncryptedPacketSender{} h.Super = &mockControlMsgHandler{} h.R = newConnReader( pipe, h.IFace, h.Sender, h.Super, 1, routes) return h } // Testing that we can receive a control packet. func TestConnReader_handleControlPacket(t *testing.T) { h := newConnReadeTestHarness() pkt := synPacket{TraceID: 1234} h.WRemote.SendControlPacket(pkt, h.Remote) h.R.handleNextPacket() if len(h.Super.Messages) != 1 { t.Fatal(h.Super.Messages) } msg := h.Super.Messages[0].(controlMsg[synPacket]) if !reflect.DeepEqual(pkt, msg.Packet) { t.Fatal(msg.Packet) } } // Testing that a short packet is ignored. func TestConnReader_handleNextPacket_short(t *testing.T) { h := newConnReadeTestHarness() h.Pipe.WriteToUDPAddrPort([]byte{1, 2, 3}, netip.AddrPort{}) h.R.handleNextPacket() if len(h.Super.Messages) != 0 { t.Fatal(h.Super.Messages) } } // Testing that a packet with an unexpected stream ID is ignored. func TestConnReader_handleNextPacket_unknownStreamID(t *testing.T) { h := newConnReadeTestHarness() pkt := synPacket{TraceID: 1234} encrypted := h.WRemote.encryptControlPacket(pkt, h.Remote) var header header header.Parse(encrypted) header.StreamID = 100 header.Marshal(encrypted) h.WRemote.writeTo(encrypted, netip.AddrPort{}) h.R.handleNextPacket() if len(h.Super.Messages) != 0 { t.Fatal(h.Super.Messages) } } // Testing that control packet without matching control cipher is ignored. func TestConnReader_handleControlPacket_noCipher(t *testing.T) { h := newConnReadeTestHarness() pkt := synPacket{TraceID: 1234} encrypted := h.WRemote.encryptControlPacket(pkt, h.Remote) var header header header.Parse(encrypted) header.SourceIP = 10 header.Marshal(encrypted) h.WRemote.writeTo(encrypted, netip.AddrPort{}) h.R.handleNextPacket() if len(h.Super.Messages) != 0 { t.Fatal(h.Super.Messages) } } // Testing that control packet with incrrect destination IP is ignored. func TestConnReader_handleControlPacket_incorrectDest(t *testing.T) { h := newConnReadeTestHarness() pkt := synPacket{TraceID: 1234} encrypted := h.WRemote.encryptControlPacket(pkt, h.Remote) var header header header.Parse(encrypted) header.DestIP++ header.Marshal(encrypted) h.WRemote.writeTo(encrypted, netip.AddrPort{}) h.R.handleNextPacket() if len(h.Super.Messages) != 0 { t.Fatal(h.Super.Messages) } } // Testing that modified control packet is ignored. func TestConnReader_handleControlPacket_modified(t *testing.T) { h := newConnReadeTestHarness() pkt := synPacket{TraceID: 1234} encrypted := h.WRemote.encryptControlPacket(pkt, h.Remote) encrypted[len(encrypted)-1]++ h.WRemote.writeTo(encrypted, netip.AddrPort{}) h.R.handleNextPacket() if len(h.Super.Messages) != 0 { t.Fatal(h.Super.Messages) } } type emptyPacket struct{} func (p emptyPacket) Marshal(buf []byte) []byte { return buf[:0] } // Testing that an empty control packet is ignored. func TestConnReader_handleControlPacket_empty(t *testing.T) { h := newConnReadeTestHarness() pkt := emptyPacket{} encrypted := h.WRemote.encryptControlPacket(pkt, h.Remote) h.WRemote.writeTo(encrypted, netip.AddrPort{}) h.R.handleNextPacket() if len(h.Super.Messages) != 0 { t.Fatal(h.Super.Messages) } } // Testing that a duplicate control packet is ignored. func TestConnReader_handleControlPacket_duplicate(t *testing.T) { h := newConnReadeTestHarness() pkt := synPacket{TraceID: 1234} log.Printf("%d", h.WRemote.counters[1]) h.WRemote.SendControlPacket(pkt, h.Remote) log.Printf("%d", h.WRemote.counters[1]) // Rewind the counter. h.WRemote.counters[1] = h.WRemote.counters[1] - 1 log.Printf("%d", h.WRemote.counters[1]) h.WRemote.SendControlPacket(pkt, h.Remote) h.R.handleNextPacket() h.R.handleNextPacket() if len(h.Super.Messages) != 1 { t.Fatal(h.Super.Messages) } msg := h.Super.Messages[0].(controlMsg[synPacket]) if !reflect.DeepEqual(pkt, msg.Packet) { t.Fatal(msg.Packet) } } type invalidPacket struct { } func (p invalidPacket) Marshal(b []byte) []byte { out := b[:256] clear(out) return out } // Testing that an invalid control packet is ignored (fails to parse). func TestConnReader_handleControlPacket_cantParse(t *testing.T) { h := newConnReadeTestHarness() pkt := invalidPacket{} encrypted := h.WRemote.encryptControlPacket(pkt, h.Remote) h.WRemote.writeTo(encrypted, netip.AddrPort{}) h.R.handleNextPacket() if len(h.Super.Messages) != 0 { t.Fatal(h.Super.Messages) } } // Testing that we can receive a data packet. func TestConnReader_handleDataPacket(t *testing.T) { h := newConnReadeTestHarness() pkt := make([]byte, 1024) rand.Read(pkt) h.WRemote.SendDataPacket(pkt, h.Remote) h.R.handleNextPacket() if len(h.IFace.Written) != 1 { t.Fatal(h.IFace.Written) } if !bytes.Equal(pkt, h.IFace.Written[0]) { t.Fatal(h.IFace.Written) } } // Testing that data packet is ignored if route isn't up. func TestConnReader_handleDataPacket_routeDown(t *testing.T) { h := newConnReadeTestHarness() pkt := make([]byte, 1024) rand.Read(pkt) h.WRemote.SendDataPacket(pkt, h.Remote) route := h.R.routes[2].Load() route.Up = false h.R.handleNextPacket() if len(h.IFace.Written) != 0 { t.Fatal(h.IFace.Written) } } */ // Testing that a duplicate data packet is ignored. // Testing that we send a relayed data packet. // Testing that a relayed data packet is ignored if destination isn't up.