241 lines
5.6 KiB
Go
241 lines
5.6 KiB
Go
package peer
|
|
|
|
import (
|
|
"bytes"
|
|
"net/netip"
|
|
"testing"
|
|
)
|
|
|
|
// ----------------------------------------------------------------------------
|
|
|
|
type testUDPPacket struct {
|
|
Addr netip.AddrPort
|
|
Data []byte
|
|
}
|
|
|
|
type testUDPAddrPortWriter struct {
|
|
written []testUDPPacket
|
|
}
|
|
|
|
func (w *testUDPAddrPortWriter) WriteToUDPAddrPort(b []byte, addr netip.AddrPort) (int, error) {
|
|
w.written = append(w.written, testUDPPacket{
|
|
Addr: addr,
|
|
Data: bytes.Clone(b),
|
|
})
|
|
return len(b), nil
|
|
}
|
|
|
|
func (w *testUDPAddrPortWriter) Written() []testUDPPacket {
|
|
out := w.written
|
|
w.written = []testUDPPacket{}
|
|
return out
|
|
}
|
|
|
|
// ----------------------------------------------------------------------------
|
|
|
|
type testPacket string
|
|
|
|
func (p testPacket) Marshal(b []byte) []byte {
|
|
b = b[:len(p)]
|
|
copy(b, []byte(p))
|
|
return b
|
|
}
|
|
|
|
// ----------------------------------------------------------------------------
|
|
|
|
func testConnWriter_getTestRoutes() (local, remote, relayLocal, relayRemote *RemotePeer) {
|
|
localKeys := generateKeys()
|
|
remoteKeys := generateKeys()
|
|
|
|
local = NewRemotePeer(2)
|
|
local.Up = true
|
|
local.Relay = false
|
|
local.PubSignKey = remoteKeys.PubSignKey
|
|
local.ControlCipher = newControlCipher(localKeys.PrivKey, remoteKeys.PubKey)
|
|
local.DataCipher = newDataCipher()
|
|
local.DirectAddr = netip.AddrPortFrom(netip.AddrFrom4([4]byte{1, 1, 1, 2}), 100)
|
|
|
|
remote = NewRemotePeer(1)
|
|
remote.Up = true
|
|
remote.Relay = false
|
|
remote.PubSignKey = localKeys.PubSignKey
|
|
remote.ControlCipher = newControlCipher(remoteKeys.PrivKey, localKeys.PubKey)
|
|
remote.DataCipher = local.DataCipher
|
|
remote.DirectAddr = netip.AddrPortFrom(netip.AddrFrom4([4]byte{1, 1, 1, 1}), 100)
|
|
|
|
rLocalKeys := generateKeys()
|
|
rRemoteKeys := generateKeys()
|
|
|
|
relayLocal = NewRemotePeer(3)
|
|
relayLocal.Up = true
|
|
relayLocal.Relay = true
|
|
relayLocal.Direct = true
|
|
relayLocal.PubSignKey = rRemoteKeys.PubSignKey
|
|
relayLocal.ControlCipher = newControlCipher(rLocalKeys.PrivKey, rRemoteKeys.PubKey)
|
|
relayLocal.DataCipher = newDataCipher()
|
|
relayLocal.DirectAddr = netip.AddrPortFrom(netip.AddrFrom4([4]byte{1, 1, 1, 3}), 100)
|
|
|
|
relayRemote = NewRemotePeer(1)
|
|
relayRemote.Up = true
|
|
relayRemote.Relay = false
|
|
relayRemote.Direct = true
|
|
relayRemote.PubSignKey = rLocalKeys.PubSignKey
|
|
relayRemote.ControlCipher = newControlCipher(rRemoteKeys.PrivKey, rLocalKeys.PubKey)
|
|
relayRemote.DataCipher = relayLocal.DataCipher
|
|
relayRemote.DirectAddr = netip.AddrPortFrom(netip.AddrFrom4([4]byte{1, 1, 1, 1}), 100)
|
|
|
|
return
|
|
}
|
|
|
|
// ----------------------------------------------------------------------------
|
|
|
|
// Testing if we can send a control packet directly to the remote route.
|
|
func TestConnWriter_SendControlPacket_direct(t *testing.T) {
|
|
route, rRoute, _, _ := testConnWriter_getTestRoutes()
|
|
route.Direct = true
|
|
|
|
writer := &testUDPAddrPortWriter{}
|
|
w := newConnWriter(writer, rRoute.IP)
|
|
in := testPacket("hello world!")
|
|
|
|
w.SendControlPacket(in, route)
|
|
out := writer.Written()
|
|
if len(out) != 1 {
|
|
t.Fatal(out)
|
|
}
|
|
|
|
if out[0].Addr != route.DirectAddr {
|
|
t.Fatal(out[0])
|
|
}
|
|
|
|
dec, ok := rRoute.ControlCipher.Decrypt(out[0].Data, make([]byte, 1024))
|
|
if !ok {
|
|
t.Fatal(ok)
|
|
}
|
|
if string(dec) != string(in) {
|
|
t.Fatal(dec)
|
|
}
|
|
}
|
|
|
|
// Testing if we can relay a packet via an intermediary.
|
|
func TestConnWriter_RelayControlPacket_relay(t *testing.T) {
|
|
route, rRoute, relay, rRelay := testConnWriter_getTestRoutes()
|
|
|
|
writer := &testUDPAddrPortWriter{}
|
|
w := newConnWriter(writer, rRoute.IP)
|
|
in := testPacket("hello world!")
|
|
|
|
w.RelayControlPacket(in, route, relay)
|
|
|
|
out := writer.Written()
|
|
if len(out) != 1 {
|
|
t.Fatal(out)
|
|
}
|
|
|
|
if out[0].Addr != relay.DirectAddr {
|
|
t.Fatal(out[0])
|
|
}
|
|
|
|
dec, ok := rRelay.DataCipher.Decrypt(out[0].Data, make([]byte, 1024))
|
|
if !ok {
|
|
t.Fatal(ok)
|
|
}
|
|
|
|
dec2, ok := rRoute.ControlCipher.Decrypt(dec, make([]byte, 1024))
|
|
if !ok {
|
|
t.Fatal(ok)
|
|
}
|
|
|
|
if string(dec2) != string(in) {
|
|
t.Fatal(dec2)
|
|
}
|
|
}
|
|
|
|
// Testing that we can send a data packet directly to a remote route.
|
|
func TestConnWriter_SendDataPacket_direct(t *testing.T) {
|
|
route, rRoute, _, _ := testConnWriter_getTestRoutes()
|
|
route.Direct = true
|
|
|
|
writer := &testUDPAddrPortWriter{}
|
|
w := newConnWriter(writer, rRoute.IP)
|
|
|
|
in := []byte("hello world!")
|
|
w.SendDataPacket(in, route)
|
|
|
|
out := writer.Written()
|
|
if len(out) != 1 {
|
|
t.Fatal(out)
|
|
}
|
|
|
|
if out[0].Addr != route.DirectAddr {
|
|
t.Fatal(out[0])
|
|
}
|
|
|
|
dec, ok := rRoute.DataCipher.Decrypt(out[0].Data, make([]byte, 1024))
|
|
if !ok {
|
|
t.Fatal(ok)
|
|
}
|
|
|
|
if !bytes.Equal(dec, in) {
|
|
t.Fatal(dec)
|
|
}
|
|
}
|
|
|
|
// Testing that we can relay a data packet via a relay.
|
|
func TestConnWriter_RelayDataPacket_relay(t *testing.T) {
|
|
route, rRoute, relay, rRelay := testConnWriter_getTestRoutes()
|
|
|
|
writer := &testUDPAddrPortWriter{}
|
|
w := newConnWriter(writer, rRoute.IP)
|
|
in := []byte("Hello world!")
|
|
|
|
w.RelayDataPacket(in, route, relay)
|
|
|
|
out := writer.Written()
|
|
if len(out) != 1 {
|
|
t.Fatal(out)
|
|
}
|
|
|
|
if out[0].Addr != relay.DirectAddr {
|
|
t.Fatal(out[0])
|
|
}
|
|
|
|
dec, ok := rRelay.DataCipher.Decrypt(out[0].Data, make([]byte, 1024))
|
|
if !ok {
|
|
t.Fatal(ok)
|
|
}
|
|
|
|
dec2, ok := rRoute.DataCipher.Decrypt(dec, make([]byte, 1024))
|
|
if !ok {
|
|
t.Fatal(ok)
|
|
}
|
|
|
|
if !bytes.Equal(dec2, in) {
|
|
t.Fatal(dec2)
|
|
}
|
|
}
|
|
|
|
// Testing that we can send an already encrypted packet.
|
|
func TestConnWriter_SendEncryptedDataPacket(t *testing.T) {
|
|
route, rRoute, _, _ := testConnWriter_getTestRoutes()
|
|
|
|
writer := &testUDPAddrPortWriter{}
|
|
w := newConnWriter(writer, rRoute.IP)
|
|
in := []byte("Hello world!")
|
|
|
|
w.SendEncryptedDataPacket(in, route)
|
|
|
|
out := writer.Written()
|
|
if len(out) != 1 {
|
|
t.Fatal(out)
|
|
}
|
|
|
|
if out[0].Addr != route.DirectAddr {
|
|
t.Fatal(out[0])
|
|
}
|
|
|
|
if !bytes.Equal(out[0].Data, in) {
|
|
t.Fatal(out[0])
|
|
}
|
|
}
|