| 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{ |
| 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 | |
| 43 | func (n *node) addPeer(x types.Node) { |
| 44 | n.peers = append(n.peers, x) |
| 45 | } |
| 46 | |
| 47 | func (n *node) configure() error { |
| 48 | return n.e.Configure(&types.NetworkMap{n.node, n.peers}) |
| 49 | } |
| 50 | |
| 51 | func (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 | |
| 57 | func 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 | |
| 86 | func 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) |
| 116 | } |
| 117 | log.Printf("Ping received: %+v\n", p) |
| 118 | } |
| 119 | } |