diff --git a/cmd/bitmaskcfg/cmd/locations_best.go b/cmd/bitmaskcfg/cmd/locations_best.go index 48fa120b121e6053ccea4d681e4c6400abd11be5..792937ccc4dfc8f290d24465fc990d943f7956f8 100644 --- a/cmd/bitmaskcfg/cmd/locations_best.go +++ b/cmd/bitmaskcfg/cmd/locations_best.go @@ -22,7 +22,12 @@ to us.`, Run: func(cmd *cobra.Command, args []string) { log.Info().Msg("Picking best location...") candidates := getGatewayForEachLocation() - best := pickBest(candidates) + best, err := pickBest(candidates) + if err != nil { + log.Fatal(). + Err(err). + Msg("Could not pick best location") + } for l, ipaddr := range candidates { if best == ipaddr { fmt.Printf("Best: %s (%s)\n", l, best) @@ -65,12 +70,15 @@ func getGatewayForEachLocation() map[string]string { } // pickBest will select the best endpoint by the lower latency. -func pickBest(candidates map[string]string) string { +func pickBest(candidates map[string]string) (string, error) { endpoints := []string{} for _, ipaddr := range candidates { endpoints = append(endpoints, string(ipaddr)) } - best := latency.PickBestEndpointByLatency(endpoints) - return best + best, err := latency.PickBestEndpointByLatency(endpoints) + if err != nil { + return "", err + } + return best, nil } diff --git a/pkg/latency/icmp.go b/pkg/latency/icmp.go index 249320b0ad8de6e3c7bc93df65e8b77c500c085c..8169e5130308c6ab423fe31acce43e3b4e24fed0 100644 --- a/pkg/latency/icmp.go +++ b/pkg/latency/icmp.go @@ -1,7 +1,7 @@ package latency import ( - "fmt" + "errors" "sort" "sync" "time" @@ -13,30 +13,31 @@ import ( // PickBestEndpointByLatency will send a brief ICMP ping train to all // the passed endpoints, and return the one with the lesser latency. -func PickBestEndpointByLatency(endpoints []string) string { +func PickBestEndpointByLatency(endpoints []string) (string, error) { ch := make(chan pingResult, len(endpoints)) pingAllTargets(ch, endpoints) var pr []pingResult for r := range ch { - log.Debug().Msg(fmt.Sprintf("%s: min: %d, loss:%.2f", r.ip, r.stats.MinRtt.Milliseconds(), r.stats.PacketLoss)) + log.Debug().Msgf("%s: min: %d, loss:%.2f", r.ip, r.stats.MinRtt.Milliseconds(), r.stats.PacketLoss) pr = append(pr, r) } - best := pickBest(pr) - return best.ip + best, err := pickBest(pr) + return best.ip, err } func doPing(wg *sync.WaitGroup, ch chan pingResult, ip string) { defer wg.Done() - pinger, err := ping.NewPinger(ip) - if err != nil { - return - } + pinger := ping.New(ip) pinger.Interval = time.Millisecond * 200 pinger.Count = 10 pinger.Timeout = time.Second * 4 - err = pinger.Run() + err := pinger.Run() if err != nil { + log.Warn(). + Err(err). + Str("ip", ip). + Msg("Could not ping host") return } ch <- pingResult{ip, pinger.Statistics()} @@ -57,9 +58,9 @@ func pingAllTargets(ch chan pingResult, targets []string) { close(ch) } -func pickBest(pr []pingResult) pingResult { +func pickBest(pr []pingResult) (pingResult, error) { st := pr[:] - log.Debug().Msg(fmt.Sprintf("results: %d", len(st))) + log.Debug().Msgf("results: %d", len(st)) var noloss []pingResult for _, val := range st { @@ -72,10 +73,14 @@ func pickBest(pr []pingResult) pingResult { if len(noloss) != 0 { st = noloss } - log.Debug().Msg(fmt.Sprintf("no-loss: %d", len(st))) + log.Debug().Msgf("no-loss: %d", len(st)) sort.Slice(st, func(i, j int) bool { return st[i].stats.MinRtt < st[j].stats.MinRtt }) - return st[0] + + if len(st) == 0 { + return pingResult{}, errors.New("Could not pick best result. Ping results are empty") + } + return st[0], nil }