blob: 04927afc7118ffb41b1d8eb22c9c4b8d21b866d2 [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{
31 PublicKey: n.privKey.Public(),
32 DiscoKey: n.e.DiscoKey(),
33 DiscoEndpoint: n.e.DiscoEndpoint(),
34 IPPort: netaddr.IPPort{
35 IP: netaddr.IPv4(127, 0, 0, 1),
36 Port: localPort,
37 },
38 VPNIP: netaddr.MustParseIP(ip),
39 }
40 return
41}
42
43func (n *node) addPeer(x types.Node) {
44 n.peers = append(n.peers, x)
45}
46
47func (n *node) configure() error {
48 return n.e.Configure(&types.NetworkMap{n.node, n.peers})
49}
50
51func (n *node) ping(ip string, ch chan<- *ipnstate.PingResult) {
52 n.e.Ping(netaddr.MustParseIP(ip), func(p *ipnstate.PingResult) {
53 ch <- p
54 })
55}
56
57func TestTwoPeers(t *testing.T) {
58 var a, b *node
59 var err error
60 if a, err = newNode("10.0.0.1", 1234); err != nil {
61 t.Fatal(err)
62 }
63 if b, err = newNode("10.0.0.2", 1235); err != nil {
64 t.Fatal(err)
65 }
66 a.addPeer(b.node)
67 b.addPeer(a.node)
68 if err := a.configure(); err != nil {
69 t.Fatal(err)
70 }
71 if err := b.configure(); err != nil {
72 t.Fatal(err)
73 }
74 ping := make(chan *ipnstate.PingResult, 0)
75 a.ping("10.0.0.2", ping)
76 b.ping("10.0.0.1", ping)
77 for i := 0; i < 2; i++ {
78 p := <-ping
79 if p.Err != "" {
80 t.Error(p.Err)
81 }
82 log.Printf("Ping received: %+v\n", p)
83 }
84}
85
86func TestTenPeers(t *testing.T) {
87 n := 10
88 nodes := make([]*node, n)
89 ping := make(chan *ipnstate.PingResult, 0)
90 for i := 0; i < n; i++ {
91 ip := fmt.Sprintf("10.0.0.%d", i+1)
92 localPort := uint16(i + 4321)
93 var err error
94 if nodes[i], err = newNode(ip, localPort); err != nil {
95 t.Fatal(err)
96 }
97 for j := 0; j < i; j++ {
98 nodes[i].addPeer(nodes[j].node)
99 nodes[j].addPeer(nodes[i].node)
100 }
101 }
102 for i := 0; i < n; i++ {
103 if err := nodes[i].configure(); err != nil {
104 t.Fatal(err)
105 }
106 for j := 0; j < i; j++ {
107 nodes[i].ping(nodes[j].ip.String(), ping)
108 nodes[j].ping(nodes[i].ip.String(), ping)
109 }
110
111 }
112 for i := 0; i < n*(n-1); i++ {
113 p := <-ping
114 if p.Err != "" {
115 t.Error(p.Err)
giolekvad12813b2021-05-01 19:58:44 +0400116 } else {
117 log.Printf("Ping received: %+v\n", p)
giolekva3c0e1822021-03-15 00:08:44 +0400118 }
giolekva3c0e1822021-03-15 00:08:44 +0400119 }
120}