package main import ( "flag" "fmt" "io" "net/http" "os" "os/exec" "os/signal" "strings" "syscall" "time" "github.com/nats-io/nats-server/v2/server" ) func runServer(args []string) { fs := flag.NewFlagSet("server", flag.ExitOnError) conf := fs.String("conf", "", "config file") fs.Parse(args) opts, err := server.ProcessConfigFile(*conf) if err != nil { fmt.Println("config:", err) os.Exit(1) } opts.NoSigs = true opts.Debug = os.Getenv("Q8DEBUG") != "" s, err := server.NewServer(opts) if err != nil { fmt.Println("server:", err) os.Exit(1) } s.ConfigureLogger() go s.Start() if !s.ReadyForConnections(30 * time.Second) { fmt.Println("not ready") os.Exit(1) } fmt.Println("ready", server.VERSION) ch := make(chan os.Signal, 1) signal.Notify(ch, syscall.SIGINT, syscall.SIGTERM) <-ch s.Shutdown() } // runAgent is a switch for machine C: it drops every packet to and from the peer, and takes the rule away again. func runAgent(args []string) { fs := flag.NewFlagSet("agent", flag.ExitOnError) peer := fs.String("peer", "", "address to cut off") fs.Parse(args) nft := func(script string) string { cmd := exec.Command("nft", "-f", "-") cmd.Stdin = strings.NewReader(script) out, err := cmd.CombinedOutput() if err != nil { return fmt.Sprintf("error: %v: %s", err, out) } return "ok" } http.HandleFunc("/block", func(w http.ResponseWriter, r *http.Request) { nft("delete table inet q8cut\n") // ignore: it may not exist io.WriteString(w, nft(fmt.Sprintf(`add table inet q8cut add chain inet q8cut in { type filter hook input priority -10; policy accept; } add chain inet q8cut out { type filter hook output priority -10; policy accept; } add rule inet q8cut in ip saddr %s drop add rule inet q8cut out ip daddr %s drop `, *peer, *peer))) }) http.HandleFunc("/unblock", func(w http.ResponseWriter, r *http.Request) { io.WriteString(w, nft("delete table inet q8cut\n")) }) fmt.Println("agent listening on :9099 for peer", *peer) fmt.Println(http.ListenAndServe(":9099", nil)) } func runWait(args []string) { fs := flag.NewFlagSet("wait", flag.ExitOnError) url := fs.String("url", "", "url") secs := fs.Int("s", 60, "seconds") fs.Parse(args) end := time.Now().Add(time.Duration(*secs) * time.Second) for time.Now().Before(end) { if r, err := http.Get(*url); err == nil { r.Body.Close() if r.StatusCode == 200 { fmt.Println("up") return } } time.Sleep(500 * time.Millisecond) } fmt.Println("timeout") os.Exit(1) }