package peer import ( "bytes" "crypto/rand" mrand "math/rand" "net/netip" "sync/atomic" ) // A test peer. type P struct { cryptoKeys RT *atomic.Pointer[RoutingTable] Conn *TestUDPConn IFace *TestIFace ConnWriter *ConnWriter ConnReader *ConnReader IFReader *IFReader Super *Supervisor } func NewPeerForTesting(n *TestNetwork, ip byte, addr netip.AddrPort) P { p := P{ cryptoKeys: generateKeys(), RT: &atomic.Pointer[RoutingTable]{}, IFace: NewTestIFace(), } rt := NewRoutingTable(ip, addr) p.RT.Store(&rt) p.Conn = n.NewUDPConn(addr) p.ConnWriter = NewConnWriter(p.Conn.WriteToUDPAddrPort, p.RT) p.IFReader = NewIFReader(p.IFace, p.ConnWriter) /* p.ConnReader = NewConnReader( p.Conn.ReadFromUDPAddrPort, p.IFace, p.ConnWriter.Forward, p.Super.HandleControlMsg, p.RT) */ return p } func ConnectPeers(p1, p2 *P) { rt1 := p1.RT.Load() rt2 := p2.RT.Load() ip1 := rt1.LocalIP ip2 := rt2.LocalIP rt1.Peers[ip2].Up = true rt1.Peers[ip2].Direct = true rt1.Peers[ip2].Relay = true rt1.Peers[ip2].DirectAddr = rt2.LocalAddr rt1.Peers[ip2].PubSignKey = p2.PubSignKey rt1.Peers[ip2].ControlCipher = newControlCipher(p1.PrivKey, p2.PubKey) rt1.Peers[ip2].DataCipher = newDataCipher() rt2.Peers[ip1].Up = true rt2.Peers[ip1].Direct = true rt2.Peers[ip1].Relay = true rt2.Peers[ip1].DirectAddr = rt1.LocalAddr rt2.Peers[ip1].PubSignKey = p1.PubSignKey rt2.Peers[ip1].ControlCipher = newControlCipher(p2.PrivKey, p1.PubKey) rt2.Peers[ip1].DataCipher = rt1.Peers[ip2].DataCipher } func NewPeersForTesting() (p1, p2, p3 P) { n := NewTestNetwork() p1 = NewPeerForTesting( n, 1, netip.AddrPortFrom(netip.AddrFrom4([4]byte{1, 1, 1, 1}), 100)) p2 = NewPeerForTesting( n, 2, netip.AddrPortFrom(netip.AddrFrom4([4]byte{1, 1, 1, 2}), 200)) p3 = NewPeerForTesting( n, 3, netip.AddrPortFrom(netip.AddrFrom4([4]byte{1, 1, 1, 3}), 300)) ConnectPeers(&p1, &p2) ConnectPeers(&p1, &p3) ConnectPeers(&p2, &p3) return } func RandPacket() []byte { n := mrand.Intn(1200) b := make([]byte, n) rand.Read(b) return b } func ModifyPacket(in []byte) []byte { x := make([]byte, 1) for { rand.Read(x) out := bytes.Clone(in) idx := mrand.Intn(len(out)) if out[idx] != x[0] { out[idx] = x[0] return out } } } // ---------------------------------------------------------------------------- type UnknownControlPacket struct { TraceID uint64 } func (p UnknownControlPacket) Marshal(buf []byte) []byte { return newBinWriter(buf).Byte(255).Uint64(p.TraceID).Build() }