blob: 02fdc19a47c80e9b6afe01ee6410bb6a9c488835 [file] [log] [blame]
giolekva3c0e1822021-03-15 00:08:44 +04001package engine
2
3import (
4 "fmt"
5 "log"
6 "testing"
7
8 "github.com/giolekva/pcloud/core/vpn/types"
9
10 "inet.af/netaddr"
11 "tailscale.com/ipn/ipnstate"
12)
13
14type node struct {
15 ip netaddr.IP
16 privKey types.PrivateKey
17 node types.Node
18 peers []types.Node
19 e Engine
20}
21
22func newNode(ip string, localPort uint16) (n *node, err error) {
23 n = &node{
24 ip: netaddr.MustParseIP(ip),
25 privKey: types.NewPrivateKey(),
26 }
27 if n.e, err = NewFakeWireguardEngine(localPort, n.privKey); err != nil {
28 return
29 }
30 n.node = types.Node{
giolekva2a088e22021-08-01 14:20:25 +040031 PublicKey: n.privKey.Public(),
32 DiscoKey: n.e.DiscoKey(),
33 IPPort: netaddr.IPPortFrom(
34 netaddr.IPv4(127, 0, 0, 1),
35 localPort,
36 ),
giolekva3c0e1822021-03-15 00:08:44 +040037 VPNIP: netaddr.MustParseIP(ip),
38 }
39 return
40}
41
42func (n *node) addPeer(x types.Node) {
43 n.peers = append(n.peers, x)
44}
45
46func (n *node) configure() error {
47 return n.e.Configure(&types.NetworkMap{n.node, n.peers})
48}
49
50func (n *node) ping(ip string, ch chan<- *ipnstate.PingResult) {
51 n.e.Ping(netaddr.MustParseIP(ip), func(p *ipnstate.PingResult) {
52 ch <- p
53 })
54}
55
56func TestTwoPeers(t *testing.T) {
57 var a, b *node
58 var err error
59 if a, err = newNode("10.0.0.1", 1234); err != nil {
60 t.Fatal(err)
61 }
62 if b, err = newNode("10.0.0.2", 1235); err != nil {
63 t.Fatal(err)
64 }
65 a.addPeer(b.node)
66 b.addPeer(a.node)
67 if err := a.configure(); err != nil {
68 t.Fatal(err)
69 }
70 if err := b.configure(); err != nil {
71 t.Fatal(err)
72 }
73 ping := make(chan *ipnstate.PingResult, 0)
74 a.ping("10.0.0.2", ping)
75 b.ping("10.0.0.1", ping)
76 for i := 0; i < 2; i++ {
77 p := <-ping
78 if p.Err != "" {
79 t.Error(p.Err)
80 }
81 log.Printf("Ping received: %+v\n", p)
82 }
83}
84
85func TestTenPeers(t *testing.T) {
86 n := 10
87 nodes := make([]*node, n)
88 ping := make(chan *ipnstate.PingResult, 0)
89 for i := 0; i < n; i++ {
90 ip := fmt.Sprintf("10.0.0.%d", i+1)
91 localPort := uint16(i + 4321)
92 var err error
93 if nodes[i], err = newNode(ip, localPort); err != nil {
94 t.Fatal(err)
95 }
96 for j := 0; j < i; j++ {
97 nodes[i].addPeer(nodes[j].node)
98 nodes[j].addPeer(nodes[i].node)
99 }
100 }
101 for i := 0; i < n; i++ {
102 if err := nodes[i].configure(); err != nil {
103 t.Fatal(err)
104 }
105 for j := 0; j < i; j++ {
106 nodes[i].ping(nodes[j].ip.String(), ping)
107 nodes[j].ping(nodes[i].ip.String(), ping)
108 }
109
110 }
111 for i := 0; i < n*(n-1); i++ {
112 p := <-ping
113 if p.Err != "" {
114 t.Error(p.Err)
giolekvad12813b2021-05-01 19:58:44 +0400115 } else {
116 log.Printf("Ping received: %+v\n", p)
giolekva3c0e1822021-03-15 00:08:44 +0400117 }
giolekva3c0e1822021-03-15 00:08:44 +0400118 }
119}