package aerotun import ( "fmt" "net" "reflect" "strings" "testing" ) func TestDefaultRoutePreservesUnderlayAndRollsBack(t *testing.T) { for _, fail := range []bool{false, true} { t.Run(fmt.Sprint(fail), func(t *testing.T) { var calls []string r := routeManager{run: func(a ...string) ([]byte, error) { cmd := strings.Join(a, " ") calls = append(calls, cmd) if strings.Contains(cmd, "route get") { return []byte(`[{"dev":"eth0","gateway":"192.0.2.1"}]`), nil } if strings.Contains(cmd, "show exact") { return []byte(`[]`), nil } if fail && strings.Contains(cmd, "add 128.") { return nil, fmt.Errorf("route conflict") } return nil, nil }} err := r.install("aerotun0", net.ParseIP("203.0.113.10")) if (err != nil) != fail { t.Fatalf("unexpected result: %v", err) } if !fail { r.cleanup() } want := []string{"-j -4 route get 203.0.113.10", "-j -4 route show exact 203.0.113.10/32", "-4 route add 203.0.113.10/32 via 192.0.2.1 dev eth0", "-4 route add 0.0.0.0/1 dev aerotun0", "-4 route add 128.0.0.0/1 dev aerotun0"} if !fail { want = append(want, "-4 route del 128.0.0.0/1 dev aerotun0") } want = append(want, "-4 route del 0.0.0.0/1 dev aerotun0", "-4 route del 203.0.113.10/32 via 192.0.2.1 dev eth0") if !reflect.DeepEqual(calls, want) { t.Fatalf("route operations:\n%v\nwant:\n%v", calls, want) } }) } } func TestValidateConfig(t *testing.T) { base := TunnelInstance{Name: "aerotun0", Mode: "client", LocalAddress: "10.99.0.1/24", PeerAddress: "10.99.0.2/24", RemoteEndpoint: "192.0.2.1:51830", PSK: testPSK} if err := validateConfig(&base); err != nil { t.Fatal(err) } for _, mutate := range []func(*TunnelInstance){func(c *TunnelInstance) { c.Name = "lo"; c.Mode = "invalid" }, func(c *TunnelInstance) { c.PSK = "short" }, func(c *TunnelInstance) { c.MTU = 65535 }, func(c *TunnelInstance) { c.RemoteEndpoint = "" }, func(c *TunnelInstance) { c.LocalAddress = "bad" }, func(c *TunnelInstance) { c.PeerAddress = c.LocalAddress }, func(c *TunnelInstance) { c.Mode = "server"; c.DefaultRoute = true }} { c := base mutate(&c) if err := validateConfig(&c); err == nil { t.Fatalf("invalid config accepted: %+v", c) } } } func TestDefaultRouteLeavesExistingEndpointRoute(t *testing.T) { var changes []string r := routeManager{run: func(a ...string) ([]byte, error) { cmd := strings.Join(a, " ") if strings.Contains(cmd, "route get") { return []byte(`[{"dev":"eth0","gateway":"192.0.2.1"}]`), nil } if strings.Contains(cmd, "show exact") { return []byte(`[{"dst":"203.0.113.10/32","dev":"eth0"}]`), nil } changes = append(changes, cmd) return nil, nil }} if err := r.install("aerotun0", net.ParseIP("203.0.113.10")); err != nil { t.Fatal(err) } r.cleanup() for _, cmd := range changes { if strings.Contains(cmd, "203.0.113.10") { t.Fatalf("modified pre-existing endpoint route: %s", cmd) } } if len(changes) != 4 { t.Fatalf("expected two additions and two deletions: %v", changes) } }