Compare commits

...

6 Commits

Author SHA1 Message Date
Bastian Doetsch
d2de3225b0 add support for selecting a country via CLI flag 2022-03-06 18:03:36 +01:00
Bastian Doetsch
130a048394 fix design after adding badge in README.md 2022-03-06 17:47:47 +01:00
Bastian Doetsch
0be7f66582 updated README.md with badge 2022-03-06 17:46:55 +01:00
Bastian Doetsch
0f014cf9f3 updated README.md with usage information 2022-03-06 17:37:44 +01:00
Bastian Doetsch
230e89e2b7 allow full json output for best server using flag -o json 2022-03-06 17:36:21 +01:00
Bastian Doetsch
20e1092604 unshallow checkout to always have access to the latest tag during release 2022-03-06 17:16:09 +01:00
3 changed files with 37 additions and 9 deletions

View File

@@ -9,6 +9,8 @@ jobs:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- uses: actions/checkout@v2 - uses: actions/checkout@v2
with:
fetch-depth: 0
- name: Set up Go - name: Set up Go
uses: actions/setup-go@v2 uses: actions/setup-go@v2

View File

@@ -1,13 +1,22 @@
# mullvad-best-server # mullvad-best-server
Determines the mullvat.net server with the lowest latency. ![Build](https://github.com/bastiandoetsch/mullvad-best-server/actions/workflows/go.yml/badge.svg)
Determines the mullvat.net wireguard server with the lowest latency.
## Installation ## Installation
Download binary from releases for your platform and unpack. Download binary from releases for your platform and unpack.
## Usage ## Usage
### Default usage
Execute `mullvad-best-server`. It outputs the code, e.g. `de05`. You can then connect to it with e.g. wireguard using the normal shell scripts. Execute `mullvad-best-server`. It outputs the code, e.g. `de05`. You can then connect to it with e.g. wireguard using the normal shell scripts.
### Extended Output
If you want the full server information, execute `mullvad-best-server -o json`. It returns the full json output of the server information.
### Specify Country
The -c flag allows to give a country code. Else de/at/ch will be used.
## Background ## Background
The program uses `https://api.mullvad.net/www/relays/wireguard/` to get the current server list, pings the ones with the right country The program uses `https://api.mullvad.net/www/relays/wireguard/` to get the current server list, pings the ones with the right country
and outputs the server with the lowest ping. and outputs the server with the lowest ping.

25
main.go
View File

@@ -2,6 +2,7 @@ package main
import ( import (
"encoding/json" "encoding/json"
"flag"
"fmt" "fmt"
"github.com/go-ping/ping" "github.com/go-ping/ping"
"github.com/rs/zerolog" "github.com/rs/zerolog"
@@ -17,26 +18,42 @@ var pings = make(map[string]time.Duration)
func main() { func main() {
zerolog.SetGlobalLevel(zerolog.InfoLevel) zerolog.SetGlobalLevel(zerolog.InfoLevel)
var outputFlag = flag.String("o", "short", "Output format. 'json' outputs server json")
var countryFlag = flag.String("c", "ch", "Server country code, e.g. ch for Switzerland")
flag.Parse()
servers := getServers() servers := getServers()
bestIndex := selectBestServerIndex(servers) bestIndex := selectBestServerIndex(servers, countryFlag)
log.Debug().Interface("server", servers[bestIndex]).Msg("Best latency server found.") log.Debug().Interface("server", servers[bestIndex]).Msg("Best latency server found.")
hostname := strings.Split(servers[bestIndex].Hostname, "-")[0] hostname := strings.Split(servers[bestIndex].Hostname, "-")[0]
if *outputFlag != "json" {
fmt.Println(hostname) fmt.Println(hostname)
} else {
serverJson, err := json.Marshal(servers[bestIndex])
if err != nil {
log.Fatal().Err(err)
}
fmt.Println(string(serverJson))
}
} }
func selectBestServerIndex(servers []server) int { func selectBestServerIndex(servers []server, country *string) int {
best := servers[0].Hostname best := servers[0].Hostname
bestIndex := 0 bestIndex := -1
allowedCountries := map[string]string{} allowedCountries := map[string]string{}
if *country == "" {
allowedCountries["de"] = "1" allowedCountries["de"] = "1"
allowedCountries["ch"] = "1" allowedCountries["ch"] = "1"
allowedCountries["at"] = "1" allowedCountries["at"] = "1"
} else {
allowedCountries[*country] = "1"
}
for i, server := range servers { for i, server := range servers {
if server.Active && allowedCountries[server.CountryCode] != "" { if server.Active && allowedCountries[server.CountryCode] != "" {
duration, err := serverLatency(server) duration, err := serverLatency(server)
if err == nil { if err == nil {
pings[server.Hostname] = duration pings[server.Hostname] = duration
if best == "" || pings[best] > pings[server.Hostname] { if bestIndex == -1 || pings[best] > pings[server.Hostname] {
best = server.Hostname best = server.Hostname
bestIndex = i bestIndex = i
} }