| giolekva | 3c0e182 | 2021-03-15 00:08:44 +0400 | [diff] [blame] | 1 | package engine |
| 2 | |
| 3 | import ( |
| 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 | |
| 14 | type node struct { |
| 15 | ip netaddr.IP |
| 16 | privKey types.PrivateKey |
| 17 | node types.Node |
| 18 | peers []types.Node |
| 19 | e Engine |
| 20 | } |
| 21 | |
| 22 | func 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{ |
| giolekva | 2a088e2 | 2021-08-01 14:20:25 +0400 | [diff] [blame] | 31 | PublicKey: n.privKey.Public(), |
| 32 | DiscoKey: n.e.DiscoKey(), |
| 33 | IPPort: netaddr.IPPortFrom( |
| 34 | netaddr.IPv4(127, 0, 0, 1), |
| 35 | localPort, |
| 36 | ), |
| giolekva | 3c0e182 | 2021-03-15 00:08:44 +0400 | [diff] [blame] | 37 | VPNIP: netaddr.MustParseIP(ip), |
| 38 | } |
| 39 | return |
| 40 | } |
| 41 | |
| 42 | func (n *node) addPeer(x types.Node) { |
| 43 | n.peers = append(n.peers, x) |
| 44 | } |
| 45 | |
| 46 | func (n *node) configure() error { |
| 47 | return n.e.Configure(&types.NetworkMap{n.node, n.peers}) |
| 48 | } |
| 49 | |
| 50 | func (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 | |
| 56 | func 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 | |
| 85 | func 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) |
| giolekva | d12813b | 2021-05-01 19:58:44 +0400 | [diff] [blame] | 115 | } else { |
| 116 | log.Printf("Ping received: %+v\n", p) |
| giolekva | 3c0e182 | 2021-03-15 00:08:44 +0400 | [diff] [blame] | 117 | } |
| giolekva | 3c0e182 | 2021-03-15 00:08:44 +0400 | [diff] [blame] | 118 | } |
| 119 | } |