From 920ad8b54bab3866391b34823e8058291c17842c Mon Sep 17 00:00:00 2001 From: Quentin McGaw Date: Sun, 20 Feb 2022 02:58:16 +0000 Subject: [PATCH] chore(errors): review all errors in codebase --- cmd/gluetun/main.go | 9 +-- internal/cli/formatservers.go | 11 ++- internal/cli/update.go | 17 ++--- internal/configuration/settings/errors.go | 12 +--- internal/configuration/settings/health.go | 5 +- internal/configuration/settings/httpproxy.go | 3 +- internal/configuration/settings/openvpn.go | 18 ++--- .../settings/openvpnselection.go | 4 +- .../configuration/settings/portforward.go | 2 +- internal/configuration/settings/provider.go | 4 +- internal/configuration/settings/publicip.go | 2 +- internal/configuration/settings/server.go | 4 +- .../configuration/settings/serverselection.go | 6 +- internal/configuration/settings/settings.go | 2 +- internal/configuration/settings/vpn.go | 6 +- internal/configuration/settings/wireguard.go | 4 +- internal/configuration/sources/env/dns.go | 2 +- .../configuration/sources/env/firewall.go | 10 +-- internal/configuration/sources/env/health.go | 4 +- internal/configuration/sources/env/helpers.go | 7 +- internal/configuration/sources/env/log.go | 2 +- .../configuration/sources/env/provider.go | 4 +- internal/configuration/sources/env/vpn.go | 6 +- .../configuration/sources/files/openvpn.go | 4 +- internal/configuration/sources/files/vpn.go | 2 +- internal/configuration/sources/mux/reader.go | 4 +- internal/firewall/enable.go | 41 +++++------ internal/firewall/ip6tables.go | 7 +- internal/firewall/iptables.go | 16 ++--- internal/firewall/outboundsubnets.go | 8 +-- internal/firewall/ports.go | 8 +-- internal/firewall/vpn.go | 8 +-- internal/healthcheck/client.go | 3 +- internal/openvpn/extract/data.go | 4 +- internal/openvpn/extract/extract.go | 11 +-- internal/openvpn/extract/extract_test.go | 10 +-- internal/openvpn/parse/certificate.go | 2 +- internal/openvpn/parse/errors.go | 7 -- internal/openvpn/parse/key.go | 2 +- internal/portforward/firewall.go | 2 +- internal/provider/custom/connection.go | 3 +- internal/provider/custom/openvpnconf.go | 2 +- internal/provider/ipvanish/connection.go | 7 -- internal/provider/privado/connection.go | 8 --- .../privateinternetaccess/httpclient.go | 9 +-- .../privateinternetaccess/portforward.go | 72 +++++++------------ internal/provider/vpnunlimited/connection.go | 7 -- internal/provider/vyprvpn/connection.go | 8 --- internal/publicip/errors.go | 3 +- internal/publicip/fetch.go | 5 +- internal/publicip/info.go | 3 +- internal/routing/default.go | 8 +-- internal/routing/enable.go | 20 ++---- internal/routing/errors.go | 2 - internal/routing/inbound.go | 21 +++--- internal/routing/ip.go | 6 +- internal/routing/local.go | 9 ++- internal/routing/outbound.go | 15 ++-- internal/routing/routes.go | 19 ++--- internal/routing/rules.go | 15 ++-- internal/routing/rules_test.go | 4 +- internal/routing/vpn.go | 6 +- internal/storage/read.go | 6 +- internal/storage/sync.go | 10 +-- internal/tun/check.go | 13 ++-- internal/tun/create.go | 13 +--- internal/updater/providers/ivpn/api.go | 14 ++-- internal/updater/providers/ivpn/servers.go | 3 +- internal/updater/providers/mullvad/api.go | 3 +- internal/updater/providers/nordvpn/api.go | 5 +- internal/updater/providers/pia/api.go | 3 +- .../updater/providers/privatevpn/filename.go | 3 +- internal/updater/providers/protonvpn/api.go | 8 +-- internal/updater/providers/surfshark/api.go | 5 +- .../updater/providers/surfshark/servers.go | 6 +- internal/updater/providers/windscribe/api.go | 5 +- internal/updater/resolver/repeat.go | 3 +- internal/updater/unzip/fetch.go | 3 +- internal/version/github.go | 3 +- internal/vpn/openvpn.go | 19 ++--- internal/vpn/portforward.go | 10 +-- internal/vpn/wireguard.go | 12 +--- internal/wireguard/config.go | 10 +-- internal/wireguard/ipv6.go | 10 +-- internal/wireguard/route.go | 2 +- internal/wireguard/route_test.go | 2 +- internal/wireguard/rule.go | 4 +- internal/wireguard/rule_test.go | 4 +- 88 files changed, 254 insertions(+), 460 deletions(-) delete mode 100644 internal/openvpn/parse/errors.go diff --git a/cmd/gluetun/main.go b/cmd/gluetun/main.go index b90e74c8..db266497 100644 --- a/cmd/gluetun/main.go +++ b/cmd/gluetun/main.go @@ -56,11 +56,6 @@ var ( created = "an unknown date" ) -var ( - errSetupRouting = errors.New("cannot setup routing") - errCreateUser = errors.New("cannot create user") -) - func main() { buildInfo := models.BuildInformation{ Version: version, @@ -278,7 +273,7 @@ func _main(ctx context.Context, buildInfo models.BuildInformation, const defaultUsername = "nonrootuser" nonRootUsername, err := alpineConf.CreateUser(defaultUsername, puid) if err != nil { - return fmt.Errorf("%w: %s", errCreateUser, err) + return fmt.Errorf("cannot create user: %w", err) } if nonRootUsername != defaultUsername { logger.Info("using existing username " + nonRootUsername + " corresponding to user id " + fmt.Sprint(puid)) @@ -296,7 +291,7 @@ func _main(ctx context.Context, buildInfo models.BuildInformation, if strings.Contains(err.Error(), "operation not permitted") { logger.Warn("💡 Tip: Are you passing NET_ADMIN capability to gluetun?") } - return fmt.Errorf("%w: %s", errSetupRouting, err) + return fmt.Errorf("cannot setup routing: %w", err) } defer func() { logger.Info("routing cleanup...") diff --git a/internal/cli/formatservers.go b/internal/cli/formatservers.go index b4654403..271097b3 100644 --- a/internal/cli/formatservers.go +++ b/internal/cli/formatservers.go @@ -18,9 +18,6 @@ type ServersFormatter interface { var ( ErrFormatNotRecognized = errors.New("format is not recognized") ErrProviderUnspecified = errors.New("VPN provider to format was not specified") - ErrOpenOutputFile = errors.New("cannot open output file") - ErrWriteOutput = errors.New("cannot write to output file") - ErrCloseOutputFile = errors.New("cannot close output file") ) func (c *CLI) FormatServers(args []string) error { @@ -62,7 +59,7 @@ func (c *CLI) FormatServers(args []string) error { logger := newNoopLogger() storage, err := storage.New(logger, constants.ServersData) if err != nil { - return fmt.Errorf("%w: %s", ErrNewStorage, err) + return fmt.Errorf("cannot create servers storage: %w", err) } currentServers := storage.GetServers() @@ -115,18 +112,18 @@ func (c *CLI) FormatServers(args []string) error { output = filepath.Clean(output) file, err := os.OpenFile(output, os.O_TRUNC|os.O_WRONLY|os.O_CREATE, 0644) if err != nil { - return fmt.Errorf("%w: %s", ErrOpenOutputFile, err) + return fmt.Errorf("cannot open output file: %w", err) } _, err = fmt.Fprint(file, formatted) if err != nil { _ = file.Close() - return fmt.Errorf("%w: %s", ErrWriteOutput, err) + return fmt.Errorf("cannot write to output file: %w", err) } err = file.Close() if err != nil { - return fmt.Errorf("%w: %s", ErrCloseOutputFile, err) + return fmt.Errorf("cannot close output file: %w", err) } return nil diff --git a/internal/cli/update.go b/internal/cli/update.go index 668bb024..c1a3daad 100644 --- a/internal/cli/update.go +++ b/internal/cli/update.go @@ -20,12 +20,9 @@ import ( ) var ( - ErrModeUnspecified = errors.New("at least one of -enduser or -maintainer must be specified") - ErrDNSAddress = errors.New("DNS address is not valid") - ErrNoProviderSpecified = errors.New("no provider was specified") - ErrNewStorage = errors.New("cannot create storage") - ErrUpdateServerInformation = errors.New("cannot update server information") - ErrWriteToFile = errors.New("cannot write updated information to file") + ErrModeUnspecified = errors.New("at least one of -enduser or -maintainer must be specified") + ErrDNSAddress = errors.New("DNS address is not valid") + ErrNoProviderSpecified = errors.New("no provider was specified") ) type Updater interface { @@ -90,25 +87,25 @@ func (c *CLI) Update(ctx context.Context, args []string, logger UpdaterLogger) e storage, err := storage.New(logger, constants.ServersData) if err != nil { - return fmt.Errorf("%w: %s", ErrNewStorage, err) + return fmt.Errorf("cannot create servers storage: %w", err) } currentServers := storage.GetServers() updater := updater.New(options, httpClient, currentServers, logger) allServers, err := updater.UpdateServers(ctx) if err != nil { - return fmt.Errorf("%w: %s", ErrUpdateServerInformation, err) + return fmt.Errorf("cannot update server information: %w", err) } if endUserMode { if err := storage.FlushToFile(allServers); err != nil { - return fmt.Errorf("%w: %s", ErrWriteToFile, err) + return fmt.Errorf("cannot write updated information to file: %w", err) } } if maintainerMode { if err := writeToEmbeddedJSON(c.repoServersPath, allServers); err != nil { - return fmt.Errorf("%w: %s", ErrWriteToFile, err) + return fmt.Errorf("cannot write updated information to file: %w", err) } } diff --git a/internal/configuration/settings/errors.go b/internal/configuration/settings/errors.go index 88879d0a..968a85fa 100644 --- a/internal/configuration/settings/errors.go +++ b/internal/configuration/settings/errors.go @@ -4,19 +4,15 @@ import "errors" var ( ErrCityNotValid = errors.New("the city specified is not valid") - ErrControlServerAddress = errors.New("listening address it not valid") - ErrControlServerPort = errors.New("listening port it not valid") ErrControlServerPrivilegedPort = errors.New("cannot use privileged port without running as root") ErrCountryNotValid = errors.New("the country specified is not valid") + ErrFilepathMissing = errors.New("filepath is missing") ErrFirewallZeroPort = errors.New("cannot have a zero port to block") ErrHostnameNotValid = errors.New("the hostname specified is not valid") ErrISPNotValid = errors.New("the ISP specified is not valid") + ErrMissingValue = errors.New("missing value") ErrNameNotValid = errors.New("the server name specified is not valid") - ErrOpenVPNClientCertMissing = errors.New("client certificate is missing") - ErrOpenVPNClientCertNotValid = errors.New("client certificate is not valid") ErrOpenVPNClientKeyMissing = errors.New("client key is missing") - ErrOpenVPNClientKeyNotValid = errors.New("client key is not valid") - ErrOpenVPNConfigFile = errors.New("custom configuration file error") ErrOpenVPNCustomPortNotAllowed = errors.New("custom endpoint port is not allowed") ErrOpenVPNEncryptionPresetNotValid = errors.New("PIA encryption preset is not valid") ErrOpenVPNInterfaceNotValid = errors.New("interface name is not valid") @@ -27,8 +23,6 @@ var ( ErrOpenVPNVerbosityIsOutOfBounds = errors.New("verbosity value is out of bounds") ErrOpenVPNVersionIsNotValid = errors.New("version is not valid") ErrPortForwardingEnabled = errors.New("port forwarding cannot be enabled") - ErrPortForwardingFilepathNotValid = errors.New("port forwarding filepath given is not valid") - ErrPublicIPFilepathNotValid = errors.New("public IP address file path is not valid") ErrPublicIPPeriodTooShort = errors.New("public IP address check period is too short") ErrRegionNotValid = errors.New("the region specified is not valid") ErrServerAddressNotValid = errors.New("server listening address is not valid") @@ -44,9 +38,7 @@ var ( ErrWireguardInterfaceAddressNotSet = errors.New("interface address is not set") ErrWireguardInterfaceNotValid = errors.New("interface name is not valid") ErrWireguardPreSharedKeyNotSet = errors.New("pre-shared key is not set") - ErrWireguardPreSharedKeyNotValid = errors.New("pre-shared key is not valid") ErrWireguardPrivateKeyNotSet = errors.New("private key is not set") - ErrWireguardPrivateKeyNotValid = errors.New("private key is not valid") ErrWireguardPublicKeyNotSet = errors.New("public key is not set") ErrWireguardPublicKeyNotValid = errors.New("public key is not valid") ) diff --git a/internal/configuration/settings/health.go b/internal/configuration/settings/health.go index 65846c9a..2f4358b9 100644 --- a/internal/configuration/settings/health.go +++ b/internal/configuration/settings/health.go @@ -27,13 +27,12 @@ func (h Health) Validate() (err error) { _, err = address.Validate(h.ServerAddress, address.OptionListening(uid)) if err != nil { - return fmt.Errorf("%w: %s", - ErrServerAddressNotValid, err) + return fmt.Errorf("server listening address is not valid: %w", err) } err = h.VPN.validate() if err != nil { - return fmt.Errorf("health VPN settings validation failed: %w", err) + return fmt.Errorf("health VPN settings: %w", err) } return nil diff --git a/internal/configuration/settings/httpproxy.go b/internal/configuration/settings/httpproxy.go index 2588b81c..59adb046 100644 --- a/internal/configuration/settings/httpproxy.go +++ b/internal/configuration/settings/httpproxy.go @@ -41,8 +41,7 @@ func (h HTTPProxy) validate() (err error) { uid := os.Getuid() _, err = address.Validate(h.ListeningAddress, address.OptionListening(uid)) if err != nil { - return fmt.Errorf("%w: %s", - ErrServerAddressNotValid, h.ListeningAddress) + return fmt.Errorf("%w: %s", ErrServerAddressNotValid, h.ListeningAddress) } return nil diff --git a/internal/configuration/settings/openvpn.go b/internal/configuration/settings/openvpn.go index d5dfbf91..f940710e 100644 --- a/internal/configuration/settings/openvpn.go +++ b/internal/configuration/settings/openvpn.go @@ -93,17 +93,17 @@ func (o OpenVPN) validate(vpnProvider string) (err error) { err = validateOpenVPNConfigFilepath(isCustom, *o.ConfFile) if err != nil { - return err + return fmt.Errorf("custom configuration file: %w", err) } err = validateOpenVPNClientCertificate(vpnProvider, *o.ClientCrt) if err != nil { - return err + return fmt.Errorf("client certificate: %w", err) } err = validateOpenVPNClientKey(vpnProvider, *o.ClientKey) if err != nil { - return err + return fmt.Errorf("client key: %w", err) } const maxMSSFix = 10000 @@ -132,12 +132,12 @@ func validateOpenVPNConfigFilepath(isCustom bool, } if confFile == "" { - return fmt.Errorf("%w: no file path specified", ErrOpenVPNConfigFile) + return ErrFilepathMissing } err = helpers.FileExists(confFile) if err != nil { - return fmt.Errorf("%w: %s", ErrOpenVPNConfigFile, err) + return err } return nil @@ -150,7 +150,7 @@ func validateOpenVPNClientCertificate(vpnProvider, constants.Cyberghost, constants.VPNUnlimited: if clientCert == "" { - return ErrOpenVPNClientCertMissing + return ErrMissingValue } } @@ -160,7 +160,7 @@ func validateOpenVPNClientCertificate(vpnProvider, _, err = parse.ExtractCert([]byte(clientCert)) if err != nil { - return fmt.Errorf("%w: %s", ErrOpenVPNClientCertNotValid, err) + return err } return nil } @@ -172,7 +172,7 @@ func validateOpenVPNClientKey(vpnProvider, clientKey string) (err error) { constants.VPNUnlimited, constants.Wevpn: if clientKey == "" { - return ErrOpenVPNClientKeyMissing + return ErrMissingValue } } @@ -182,7 +182,7 @@ func validateOpenVPNClientKey(vpnProvider, clientKey string) (err error) { _, err = parse.ExtractPrivateKey([]byte(clientKey)) if err != nil { - return fmt.Errorf("%w: %s", ErrOpenVPNClientKeyNotValid, err) + return err } return nil } diff --git a/internal/configuration/settings/openvpnselection.go b/internal/configuration/settings/openvpnselection.go index af1e192c..659556f5 100644 --- a/internal/configuration/settings/openvpnselection.go +++ b/internal/configuration/settings/openvpnselection.go @@ -33,14 +33,16 @@ func (o OpenVPNSelection) validate(vpnProvider string) (err error) { if confFile := *o.ConfFile; confFile != "" { err := helpers.FileExists(confFile) if err != nil { - return fmt.Errorf("%w: %s", ErrOpenVPNConfigFile, err) + return fmt.Errorf("configuration file: %w", err) } } // Validate TCP if *o.TCP && helpers.IsOneOf(vpnProvider, + constants.Ipvanish, constants.Perfectprivacy, constants.Privado, + constants.VPNUnlimited, constants.Vyprvpn, ) { return fmt.Errorf("%w: for VPN service provider %s", diff --git a/internal/configuration/settings/portforward.go b/internal/configuration/settings/portforward.go index c1695e25..d9de6870 100644 --- a/internal/configuration/settings/portforward.go +++ b/internal/configuration/settings/portforward.go @@ -38,7 +38,7 @@ func (p PortForwarding) validate(vpnProvider string) (err error) { if *p.Filepath != "" { // optional _, err := filepath.Abs(*p.Filepath) if err != nil { - return fmt.Errorf("%w: %s", ErrPortForwardingFilepathNotValid, err) + return fmt.Errorf("filepath is not valid: %w", err) } } diff --git a/internal/configuration/settings/provider.go b/internal/configuration/settings/provider.go index ff1bf4b6..4a03d9fa 100644 --- a/internal/configuration/settings/provider.go +++ b/internal/configuration/settings/provider.go @@ -43,12 +43,12 @@ func (p *Provider) validate(vpnType string, allServers models.AllServers) (err e err = p.ServerSelection.validate(*p.Name, allServers) if err != nil { - return fmt.Errorf("server selection settings validation failed: %w", err) + return fmt.Errorf("server selection: %w", err) } err = p.PortForwarding.validate(*p.Name) if err != nil { - return fmt.Errorf("port forwarding settings validation failed: %w", err) + return fmt.Errorf("port forwarding: %w", err) } return nil diff --git a/internal/configuration/settings/publicip.go b/internal/configuration/settings/publicip.go index 0ec4af9b..10780f70 100644 --- a/internal/configuration/settings/publicip.go +++ b/internal/configuration/settings/publicip.go @@ -33,7 +33,7 @@ func (p PublicIP) validate() (err error) { if *p.IPFilepath != "" { // optional _, err := filepath.Abs(*p.IPFilepath) if err != nil { - return fmt.Errorf("%w: %s", ErrPublicIPFilepathNotValid, err) + return fmt.Errorf("filepath is not valid: %w", err) } } diff --git a/internal/configuration/settings/server.go b/internal/configuration/settings/server.go index f095ca78..ee321bfe 100644 --- a/internal/configuration/settings/server.go +++ b/internal/configuration/settings/server.go @@ -23,12 +23,12 @@ type ControlServer struct { func (c ControlServer) validate() (err error) { _, portStr, err := net.SplitHostPort(*c.Address) if err != nil { - return fmt.Errorf("%w: %s", ErrControlServerAddress, err) + return fmt.Errorf("listening address is not valid: %w", err) } port, err := strconv.Atoi(portStr) if err != nil { - return fmt.Errorf("%w: %s", ErrControlServerPort, err) + return fmt.Errorf("listening port it not valid: %w", err) } uid := os.Getuid() diff --git a/internal/configuration/settings/serverselection.go b/internal/configuration/settings/serverselection.go index b0709257..7d86d54c 100644 --- a/internal/configuration/settings/serverselection.go +++ b/internal/configuration/settings/serverselection.go @@ -116,18 +116,18 @@ func (ss *ServerSelection) validate(vpnServiceProvider string, if *ss.MultiHopOnly && vpnServiceProvider != constants.Surfshark { return fmt.Errorf("%w: for VPN service provider %s", - ErrStreamOnlyNotSupported, vpnServiceProvider) + ErrMultiHopOnlyNotSupported, vpnServiceProvider) } if ss.VPN == constants.OpenVPN { err = ss.OpenVPN.validate(vpnServiceProvider) if err != nil { - return fmt.Errorf("OpenVPN server selection settings validation failed: %w", err) + return fmt.Errorf("OpenVPN server selection settings: %w", err) } } else { err = ss.Wireguard.validate(vpnServiceProvider) if err != nil { - return fmt.Errorf("Wireguard server selection settings validation failed: %w", err) + return fmt.Errorf("Wireguard server selection settings: %w", err) } } diff --git a/internal/configuration/settings/settings.go b/internal/configuration/settings/settings.go index 04a5d49e..2b4c2939 100644 --- a/internal/configuration/settings/settings.go +++ b/internal/configuration/settings/settings.go @@ -49,7 +49,7 @@ func (s *Settings) Validate(allServers models.AllServers) (err error) { for name, validation := range nameToValidation { err = validation() if err != nil { - return fmt.Errorf("failed validating %s settings: %w", name, err) + return fmt.Errorf("%s settings: %w", name, err) } } diff --git a/internal/configuration/settings/vpn.go b/internal/configuration/settings/vpn.go index df4c7a12..10f28a8c 100644 --- a/internal/configuration/settings/vpn.go +++ b/internal/configuration/settings/vpn.go @@ -31,18 +31,18 @@ func (v *VPN) validate(allServers models.AllServers) (err error) { err = v.Provider.validate(v.Type, allServers) if err != nil { - return fmt.Errorf("provider settings validation failed: %w", err) + return fmt.Errorf("provider settings: %w", err) } if v.Type == constants.OpenVPN { err := v.OpenVPN.validate(*v.Provider.Name) if err != nil { - return fmt.Errorf("OpenVPN settings validation failed: %w", err) + return fmt.Errorf("OpenVPN settings: %w", err) } } else { err := v.Wireguard.validate(*v.Provider.Name) if err != nil { - return fmt.Errorf("Wireguard settings validation failed: %w", err) + return fmt.Errorf("Wireguard settings: %w", err) } } diff --git a/internal/configuration/settings/wireguard.go b/internal/configuration/settings/wireguard.go index 9e1cc854..5ae960b1 100644 --- a/internal/configuration/settings/wireguard.go +++ b/internal/configuration/settings/wireguard.go @@ -50,14 +50,14 @@ func (w Wireguard) validate(vpnProvider string) (err error) { } _, err = wgtypes.ParseKey(*w.PrivateKey) if err != nil { - return fmt.Errorf("%w: %s", ErrWireguardPrivateKeyNotValid, err) + return fmt.Errorf("private key is not valid: %w", err) } // Validate PreSharedKey if *w.PreSharedKey != "" { // Note: this is optional _, err = wgtypes.ParseKey(*w.PreSharedKey) if err != nil { - return fmt.Errorf("%w: %s", ErrWireguardPreSharedKeyNotValid, err) + return fmt.Errorf("pre-shared key is not valid: %w", err) } } diff --git a/internal/configuration/sources/env/dns.go b/internal/configuration/sources/env/dns.go index fc1f2eaf..d166e6c7 100644 --- a/internal/configuration/sources/env/dns.go +++ b/internal/configuration/sources/env/dns.go @@ -20,7 +20,7 @@ func (r *Reader) readDNS() (dns settings.DNS, err error) { dns.DoT, err = r.readDoT() if err != nil { - return dns, fmt.Errorf("cannot read DoT settings: %w", err) + return dns, fmt.Errorf("DoT settings: %w", err) } return dns, nil diff --git a/internal/configuration/sources/env/firewall.go b/internal/configuration/sources/env/firewall.go index 93b594d9..45eafbe7 100644 --- a/internal/configuration/sources/env/firewall.go +++ b/internal/configuration/sources/env/firewall.go @@ -55,8 +55,7 @@ func stringsToPorts(ss []string) (ports []uint16, err error) { for i, s := range ss { port, err := strconv.Atoi(s) if err != nil { - return nil, fmt.Errorf("%w: %s: %s", - ErrPortParsing, s, err) + return nil, fmt.Errorf("%w: %s: %s", ErrPortParsing, s, err) } else if port < 1 || port > 65535 { return nil, fmt.Errorf("%w: must be between 1 and 65535: %d", ErrPortValue, port) @@ -66,10 +65,6 @@ func stringsToPorts(ss []string) (ports []uint16, err error) { return ports, nil } -var ( - ErrIPNetParsing = errors.New("cannot parse IP network") -) - func stringsToIPNets(ss []string) (ipNets []net.IPNet, err error) { if len(ss) == 0 { return nil, nil @@ -78,8 +73,7 @@ func stringsToIPNets(ss []string) (ipNets []net.IPNet, err error) { for i, s := range ss { ip, ipNet, err := net.ParseCIDR(s) if err != nil { - return nil, fmt.Errorf("%w: %s: %s", - ErrIPNetParsing, s, err) + return nil, fmt.Errorf("cannot parse IP network %q: %w", s, err) } ipNet.IP = ip ipNets[i] = *ipNet diff --git a/internal/configuration/sources/env/health.go b/internal/configuration/sources/env/health.go index cfd9f579..15dee44c 100644 --- a/internal/configuration/sources/env/health.go +++ b/internal/configuration/sources/env/health.go @@ -38,9 +38,7 @@ func (r *Reader) readDurationWithRetro(envKey, retroEnvKey string) (d *time.Dura d = new(time.Duration) *d, err = time.ParseDuration(s) if err != nil { - return nil, fmt.Errorf( - "environment variable %s: %w", - envKey, err) + return nil, fmt.Errorf("environment variable %s: %w", envKey, err) } return d, nil diff --git a/internal/configuration/sources/env/helpers.go b/internal/configuration/sources/env/helpers.go index cdc32c60..f3836379 100644 --- a/internal/configuration/sources/env/helpers.go +++ b/internal/configuration/sources/env/helpers.go @@ -2,7 +2,6 @@ package env import ( "encoding/base64" - "errors" "fmt" "os" "strconv" @@ -115,13 +114,11 @@ func lowerAndSplit(csv string) (values []string) { return strings.Split(csv, ",") } -var ErrDecodeBase64 = errors.New("cannot decode base64 string") - func decodeBase64(b64String string) (decoded string, err error) { b, err := base64.StdEncoding.DecodeString(b64String) if err != nil { - return "", fmt.Errorf("%w: %s: %s", - ErrDecodeBase64, b64String, err) + return "", fmt.Errorf("cannot decode base64 string %q: %w", + b64String, err) } return string(b), nil } diff --git a/internal/configuration/sources/env/log.go b/internal/configuration/sources/env/log.go index c84175d9..1e45da4a 100644 --- a/internal/configuration/sources/env/log.go +++ b/internal/configuration/sources/env/log.go @@ -48,7 +48,7 @@ func parseLogLevel(s string) (level logging.Level, err error) { return logging.LevelError, nil default: return level, fmt.Errorf( - "%w: %s: can be one of: debug, info, warning or error", + "%w: %q is not valid and can be one of debug, info, warning or error", ErrLogLevelUnknown, s) } } diff --git a/internal/configuration/sources/env/provider.go b/internal/configuration/sources/env/provider.go index fc83950f..4c3e45c8 100644 --- a/internal/configuration/sources/env/provider.go +++ b/internal/configuration/sources/env/provider.go @@ -18,12 +18,12 @@ func (r *Reader) readProvider(vpnType string) (provider settings.Provider, err e provider.ServerSelection, err = r.readServerSelection(providerName, vpnType) if err != nil { - return provider, fmt.Errorf("cannot read server selection settings: %w", err) + return provider, fmt.Errorf("server selection: %w", err) } provider.PortForwarding, err = r.readPortForward() if err != nil { - return provider, fmt.Errorf("cannot read port forwarding settings: %w", err) + return provider, fmt.Errorf("port forwarding: %w", err) } return provider, nil diff --git a/internal/configuration/sources/env/vpn.go b/internal/configuration/sources/env/vpn.go index 11a4efde..c09ee111 100644 --- a/internal/configuration/sources/env/vpn.go +++ b/internal/configuration/sources/env/vpn.go @@ -13,17 +13,17 @@ func (r *Reader) readVPN() (vpn settings.VPN, err error) { vpn.Provider, err = r.readProvider(vpn.Type) if err != nil { - return vpn, fmt.Errorf("cannot read provider settings: %w", err) + return vpn, fmt.Errorf("VPN provider: %w", err) } vpn.OpenVPN, err = r.readOpenVPN() if err != nil { - return vpn, fmt.Errorf("cannot read OpenVPN settings: %w", err) + return vpn, fmt.Errorf("OpenVPN: %w", err) } vpn.Wireguard, err = r.readWireguard() if err != nil { - return vpn, fmt.Errorf("cannot read Wireguard settings: %w", err) + return vpn, fmt.Errorf("wireguard: %w", err) } return vpn, nil diff --git a/internal/configuration/sources/files/openvpn.go b/internal/configuration/sources/files/openvpn.go index 5064b3ea..e3183a8b 100644 --- a/internal/configuration/sources/files/openvpn.go +++ b/internal/configuration/sources/files/openvpn.go @@ -16,12 +16,12 @@ const ( func (r *Reader) readOpenVPN() (settings settings.OpenVPN, err error) { settings.ClientKey, err = ReadFromFile(OpenVPNClientKeyPath) if err != nil { - return settings, fmt.Errorf("cannot read client key: %w", err) + return settings, fmt.Errorf("client key: %w", err) } settings.ClientCrt, err = ReadFromFile(OpenVPNClientCertificatePath) if err != nil { - return settings, fmt.Errorf("cannot read client certificate: %w", err) + return settings, fmt.Errorf("client certificate: %w", err) } return settings, nil diff --git a/internal/configuration/sources/files/vpn.go b/internal/configuration/sources/files/vpn.go index 4af013c8..8e3af796 100644 --- a/internal/configuration/sources/files/vpn.go +++ b/internal/configuration/sources/files/vpn.go @@ -9,7 +9,7 @@ import ( func (r *Reader) readVPN() (vpn settings.VPN, err error) { vpn.OpenVPN, err = r.readOpenVPN() if err != nil { - return vpn, fmt.Errorf("cannot read OpenVPN settings: %w", err) + return vpn, fmt.Errorf("OpenVPN: %w", err) } return vpn, nil diff --git a/internal/configuration/sources/mux/reader.go b/internal/configuration/sources/mux/reader.go index 856464fd..f6564a95 100644 --- a/internal/configuration/sources/mux/reader.go +++ b/internal/configuration/sources/mux/reader.go @@ -26,7 +26,7 @@ func (r *Reader) Read() (settings settings.Settings, err error) { for _, source := range r.sources { settingsFromSource, err := source.Read() if err != nil { - return settings, fmt.Errorf("cannot read from source %T: %w", source, err) + return settings, fmt.Errorf("reading from source %T: %w", source, err) } settings.MergeWith(settingsFromSource) } @@ -42,7 +42,7 @@ func (r *Reader) ReadHealth() (settings settings.Health, err error) { for _, source := range r.sources { settingsFromSource, err := source.ReadHealth() if err != nil { - return settings, fmt.Errorf("cannot read from source %T: %w", source, err) + return settings, fmt.Errorf("reading from source %T: %w", source, err) } settings.MergeWith(settingsFromSource) } diff --git a/internal/firewall/enable.go b/internal/firewall/enable.go index b35efa44..ee2cb318 100644 --- a/internal/firewall/enable.go +++ b/internal/firewall/enable.go @@ -2,16 +2,9 @@ package firewall import ( "context" - "errors" "fmt" ) -var ( - ErrEnable = errors.New("failed enabling firewall") - ErrDisable = errors.New("failed disabling firewall") - ErrUserPostRules = errors.New("cannot run user post firewall rules") -) - type Enabler interface { SetEnabled(ctx context.Context, enabled bool) (err error) } @@ -32,7 +25,7 @@ func (c *Config) SetEnabled(ctx context.Context, enabled bool) (err error) { if !enabled { c.logger.Info("disabling...") if err = c.disable(ctx); err != nil { - return err + return fmt.Errorf("cannot disable firewall: %w", err) } c.enabled = false c.logger.Info("disabled successfully") @@ -42,7 +35,7 @@ func (c *Config) SetEnabled(ctx context.Context, enabled bool) (err error) { c.logger.Info("enabling...") if err := c.enable(ctx); err != nil { - return fmt.Errorf("%w: %s", ErrEnable, err) + return fmt.Errorf("cannot enable firewall: %w", err) } c.enabled = true c.logger.Info("enabled successfully") @@ -52,13 +45,13 @@ func (c *Config) SetEnabled(ctx context.Context, enabled bool) (err error) { func (c *Config) disable(ctx context.Context) (err error) { if err = c.clearAllRules(ctx); err != nil { - return fmt.Errorf("cannot disable firewall: %w", err) + return fmt.Errorf("cannot clear all rules: %w", err) } if err = c.setIPv4AllPolicies(ctx, "ACCEPT"); err != nil { - return fmt.Errorf("cannot disable firewall: %w", err) + return fmt.Errorf("cannot set ipv4 policies: %w", err) } if err = c.setIPv6AllPolicies(ctx, "ACCEPT"); err != nil { - return fmt.Errorf("cannot disable firewall: %w", err) + return fmt.Errorf("cannot set ipv6 policies: %w", err) } return nil } @@ -76,12 +69,12 @@ func (c *Config) fallbackToDisabled(ctx context.Context) { func (c *Config) enable(ctx context.Context) (err error) { touched := false if err = c.setIPv4AllPolicies(ctx, "DROP"); err != nil { - return fmt.Errorf("cannot enable firewall: %w", err) + return err } touched = true if err = c.setIPv6AllPolicies(ctx, "DROP"); err != nil { - return fmt.Errorf("cannot enable firewall: %w", err) + return err } const remove = false @@ -94,33 +87,33 @@ func (c *Config) enable(ctx context.Context) (err error) { // Loopback traffic if err = c.acceptInputThroughInterface(ctx, "lo", remove); err != nil { - return fmt.Errorf("cannot enable firewall: %w", err) + return err } if err = c.acceptOutputThroughInterface(ctx, "lo", remove); err != nil { - return fmt.Errorf("cannot enable firewall: %w", err) + return err } if err = c.acceptEstablishedRelatedTraffic(ctx, remove); err != nil { - return fmt.Errorf("cannot enable firewall: %w", err) + return err } if c.vpnConnection.IP != nil { if err = c.acceptOutputTrafficToVPN(ctx, c.defaultInterface, c.vpnConnection, remove); err != nil { - return fmt.Errorf("cannot enable firewall: %w", err) + return err } if err = c.acceptOutputThroughInterface(ctx, c.vpnIntf, remove); err != nil { - return fmt.Errorf("cannot enable firewall: %w", err) + return err } } for _, network := range c.localNetworks { if err := c.acceptOutputFromIPToSubnet(ctx, network.InterfaceName, network.IP, *network.IPNet, remove); err != nil { - return fmt.Errorf("cannot enable firewall: %w", err) + return err } } for _, subnet := range c.outboundSubnets { if err := c.acceptOutputFromIPToSubnet(ctx, c.defaultInterface, c.localIP, subnet, remove); err != nil { - return fmt.Errorf("cannot enable firewall: %w", err) + return err } } @@ -128,18 +121,18 @@ func (c *Config) enable(ctx context.Context) (err error) { // to reach Gluetun. for _, network := range c.localNetworks { if err := c.acceptInputToSubnet(ctx, network.InterfaceName, *network.IPNet, remove); err != nil { - return fmt.Errorf("cannot enable firewall: %w", err) + return err } } for port, intf := range c.allowedInputPorts { if err := c.acceptInputToPort(ctx, intf, port, remove); err != nil { - return fmt.Errorf("cannot enable firewall: %w", err) + return err } } if err := c.runUserPostRules(ctx, c.customRulesPath, remove); err != nil { - return fmt.Errorf("%w: %s", ErrUserPostRules, err) + return fmt.Errorf("cannot run user defined post firewall rules: %w", err) } return nil diff --git a/internal/firewall/ip6tables.go b/internal/firewall/ip6tables.go index ff058a60..5680b73e 100644 --- a/internal/firewall/ip6tables.go +++ b/internal/firewall/ip6tables.go @@ -11,7 +11,6 @@ import ( ) var ( - ErrIP6Tables = errors.New("failed ip6tables command") ErrIP6NotSupported = errors.New("ip6tables not supported") ) @@ -44,18 +43,18 @@ func (c *Config) runIP6tablesInstruction(ctx context.Context, instruction string flags := strings.Fields(instruction) cmd := exec.CommandContext(ctx, "ip6tables", flags...) if output, err := c.runner.Run(cmd); err != nil { - return fmt.Errorf("%w: \"ip6tables %s\": %s: %s", ErrIP6Tables, instruction, output, err) + return fmt.Errorf("command failed: \"ip6tables %s\": %s: %w", instruction, output, err) } return nil } -var errPolicyNotValid = errors.New("policy is not valid") +var ErrPolicyNotValid = errors.New("policy is not valid") func (c *Config) setIPv6AllPolicies(ctx context.Context, policy string) error { switch policy { case "ACCEPT", "DROP": default: - return fmt.Errorf("%w: %s", errPolicyNotValid, policy) + return fmt.Errorf("%w: %s", ErrPolicyNotValid, policy) } return c.runIP6tablesInstructions(ctx, []string{ "--policy INPUT " + policy, diff --git a/internal/firewall/iptables.go b/internal/firewall/iptables.go index 8fbb6baf..65c395f1 100644 --- a/internal/firewall/iptables.go +++ b/internal/firewall/iptables.go @@ -16,10 +16,7 @@ import ( var ( ErrIPTablesVersionTooShort = errors.New("iptables version string is too short") - ErrIPTables = errors.New("failed iptables command") ErrPolicyUnknown = errors.New("unknown policy") - ErrClearRules = errors.New("cannot clear all rules") - ErrSetIPtablesPolicies = errors.New("cannot set iptables policies") ErrNeedIP6Tables = errors.New("ip6tables is required, please upgrade your kernel to support it") ) @@ -79,33 +76,30 @@ func (c *Config) runIptablesInstruction(ctx context.Context, instruction string) flags := strings.Fields(instruction) cmd := exec.CommandContext(ctx, "iptables", flags...) if output, err := c.runner.Run(cmd); err != nil { - return fmt.Errorf("%w \"iptables %s\": %s: %s", ErrIPTables, instruction, output, err) + return fmt.Errorf("command failed: \"iptables %s\": %s: %w", instruction, output, err) } return nil } func (c *Config) clearAllRules(ctx context.Context) error { - if err := c.runMixedIptablesInstructions(ctx, []string{ + return c.runMixedIptablesInstructions(ctx, []string{ "--flush", // flush all chains "--delete-chain", // delete all chains - }); err != nil { - return fmt.Errorf("%w: %s", ErrClearRules, err.Error()) - } - return nil + }) } func (c *Config) setIPv4AllPolicies(ctx context.Context, policy string) error { switch policy { case "ACCEPT", "DROP": default: - return fmt.Errorf("%w: %s: %s", ErrSetIPtablesPolicies, ErrPolicyUnknown, policy) + return fmt.Errorf("%w: %s", ErrPolicyUnknown, policy) } if err := c.runIptablesInstructions(ctx, []string{ "--policy INPUT " + policy, "--policy OUTPUT " + policy, "--policy FORWARD " + policy, }); err != nil { - return fmt.Errorf("%w: %s", ErrSetIPtablesPolicies, err) + return err } return nil } diff --git a/internal/firewall/outboundsubnets.go b/internal/firewall/outboundsubnets.go index 3d8711f5..c204a5eb 100644 --- a/internal/firewall/outboundsubnets.go +++ b/internal/firewall/outboundsubnets.go @@ -23,7 +23,7 @@ func (c *Config) SetOutboundSubnets(ctx context.Context, subnets []net.IPNet) (e return nil } - c.logger.Info("setting allowed subnets through firewall...") + c.logger.Info("setting allowed subnets...") subnetsToAdd, subnetsToRemove := subnet.FindSubnetsToChange(c.outboundSubnets, subnets) if len(subnetsToAdd) == 0 && len(subnetsToRemove) == 0 { @@ -32,7 +32,7 @@ func (c *Config) SetOutboundSubnets(ctx context.Context, subnets []net.IPNet) (e c.removeOutboundSubnets(ctx, subnetsToRemove) if err := c.addOutboundSubnets(ctx, subnetsToAdd); err != nil { - return fmt.Errorf("cannot set allowed subnets through firewall: %w", err) + return fmt.Errorf("cannot set allowed outbound subnets: %w", err) } return nil @@ -42,7 +42,7 @@ func (c *Config) removeOutboundSubnets(ctx context.Context, subnets []net.IPNet) const remove = true for _, subNet := range subnets { if err := c.acceptOutputFromIPToSubnet(ctx, c.defaultInterface, c.localIP, subNet, remove); err != nil { - c.logger.Error("cannot remove outdated outbound subnet through firewall: " + err.Error()) + c.logger.Error("cannot remove outdated outbound subnet: " + err.Error()) continue } c.outboundSubnets = subnet.RemoveSubnetFromSubnets(c.outboundSubnets, subNet) @@ -53,7 +53,7 @@ func (c *Config) addOutboundSubnets(ctx context.Context, subnets []net.IPNet) er const remove = false for _, subnet := range subnets { if err := c.acceptOutputFromIPToSubnet(ctx, c.defaultInterface, c.localIP, subnet, remove); err != nil { - return fmt.Errorf("cannot add allowed subnet through firewall: %w", err) + return err } c.outboundSubnets = append(c.outboundSubnets, subnet) } diff --git a/internal/firewall/ports.go b/internal/firewall/ports.go index 7788b69c..e6b51e91 100644 --- a/internal/firewall/ports.go +++ b/internal/firewall/ports.go @@ -33,13 +33,13 @@ func (c *Config) SetAllowedPort(ctx context.Context, port uint16, intf string) ( } const remove = true if err := c.acceptInputToPort(ctx, existingIntf, port, remove); err != nil { - return fmt.Errorf("cannot remove old allowed port %d through interface %s: %w", port, existingIntf, err) + return fmt.Errorf("cannot remove old allowed port %d: %w", port, err) } } const remove = false if err := c.acceptInputToPort(ctx, intf, port, remove); err != nil { - return fmt.Errorf("cannot set allowed port %d through interface %s: %w", port, intf, err) + return fmt.Errorf("cannot allow input to port %d: %w", port, err) } c.allowedInputPorts[port] = intf @@ -60,7 +60,7 @@ func (c *Config) RemoveAllowedPort(ctx context.Context, port uint16) (err error) return nil } - c.logger.Info("removing allowed port " + strconv.Itoa(int(port)) + " through firewall...") + c.logger.Info("removing allowed port " + strconv.Itoa(int(port)) + " ...") intf, ok := c.allowedInputPorts[port] if !ok { @@ -69,7 +69,7 @@ func (c *Config) RemoveAllowedPort(ctx context.Context, port uint16) (err error) const remove = true if err := c.acceptInputToPort(ctx, intf, port, remove); err != nil { - return fmt.Errorf("cannot remove allowed port %d through interface %s: %w", port, intf, err) + return fmt.Errorf("cannot remove allowed port %d: %w", port, err) } delete(c.allowedInputPorts, port) diff --git a/internal/firewall/vpn.go b/internal/firewall/vpn.go index ab68202e..96ae1cf1 100644 --- a/internal/firewall/vpn.go +++ b/internal/firewall/vpn.go @@ -23,7 +23,7 @@ func (c *Config) SetVPNConnection(ctx context.Context, return nil } - c.logger.Info("setting VPN connection through firewall...") + c.logger.Info("allowing VPN connection...") if c.vpnConnection.Equal(connection) { return nil @@ -32,14 +32,14 @@ func (c *Config) SetVPNConnection(ctx context.Context, remove := true if c.vpnConnection.IP != nil { if err := c.acceptOutputTrafficToVPN(ctx, c.defaultInterface, c.vpnConnection, remove); err != nil { - c.logger.Error("cannot remove outdated VPN connection through firewall: " + err.Error()) + c.logger.Error("cannot remove outdated VPN connection rule: " + err.Error()) } } c.vpnConnection = models.Connection{} if c.vpnIntf != "" { if err = c.acceptOutputThroughInterface(ctx, c.vpnIntf, remove); err != nil { - c.logger.Error("cannot remove outdated VPN interface from firewall: " + err.Error()) + c.logger.Error("cannot remove outdated VPN interface rule: " + err.Error()) } } c.vpnIntf = "" @@ -47,7 +47,7 @@ func (c *Config) SetVPNConnection(ctx context.Context, remove = false if err := c.acceptOutputTrafficToVPN(ctx, c.defaultInterface, connection, remove); err != nil { - return fmt.Errorf("cannot set VPN connection through firewall: %w", err) + return fmt.Errorf("cannot allow output traffic through VPN connection: %w", err) } c.vpnConnection = connection diff --git a/internal/healthcheck/client.go b/internal/healthcheck/client.go index 76458a33..8535a552 100644 --- a/internal/healthcheck/client.go +++ b/internal/healthcheck/client.go @@ -45,5 +45,6 @@ func (c *Client) Check(ctx context.Context, url string) error { if err != nil { return err } - return fmt.Errorf("%w: %s: %s", ErrHTTPStatusNotOK, response.Status, string(b)) + return fmt.Errorf("%w: %d %s: %s", ErrHTTPStatusNotOK, + response.StatusCode, response.Status, string(b)) } diff --git a/internal/openvpn/extract/data.go b/internal/openvpn/extract/data.go index b5fcc526..63c36378 100644 --- a/internal/openvpn/extract/data.go +++ b/internal/openvpn/extract/data.go @@ -17,12 +17,12 @@ func (e *Extractor) Data(filepath string) (lines []string, connection models.Connection, err error) { lines, err = readCustomConfigLines(filepath) if err != nil { - return nil, connection, fmt.Errorf("%w: %s", ErrRead, err) + return nil, connection, fmt.Errorf("cannot read configuration file: %w", err) } connection, err = extractDataFromLines(lines) if err != nil { - return nil, connection, fmt.Errorf("%w: %s", ErrExtractConnection, err) + return nil, connection, fmt.Errorf("cannot extract connection from file: %w", err) } return lines, connection, nil diff --git a/internal/openvpn/extract/extract.go b/internal/openvpn/extract/extract.go index 19edd5f1..3855a12d 100644 --- a/internal/openvpn/extract/extract.go +++ b/internal/openvpn/extract/extract.go @@ -48,25 +48,20 @@ func extractDataFromLines(lines []string) ( return connection, nil } -var ( - errExtractProto = errors.New("failed extracting protocol from proto line") - errExtractRemote = errors.New("failed extracting from remote line") -) - func extractDataFromLine(line string) ( ip net.IP, port uint16, protocol string, err error) { switch { case strings.HasPrefix(line, "proto "): protocol, err = extractProto(line) if err != nil { - return nil, 0, "", fmt.Errorf("%w: %s", errExtractProto, err) + return nil, 0, "", fmt.Errorf("failed extracting protocol from proto line: %w", err) } return nil, 0, protocol, nil case strings.HasPrefix(line, "remote "): ip, port, protocol, err = extractRemote(line) if err != nil { - return nil, 0, "", fmt.Errorf("%w: %s", errExtractRemote, err) + return nil, 0, "", fmt.Errorf("failed extracting from remote line: %w", err) } return ip, port, protocol, nil } @@ -122,7 +117,7 @@ func extractRemote(line string) (ip net.IP, port uint16, if err != nil { return nil, 0, "", fmt.Errorf("%w: %s", errPortNotValid, line) } else if portInt < 1 || portInt > 65535 { - return nil, 0, "", fmt.Errorf("%w: not between 1 and 65535: %d", errPortNotValid, portInt) + return nil, 0, "", fmt.Errorf("%w: %d must be between 1 and 65535", errPortNotValid, portInt) } port = uint16(portInt) } diff --git a/internal/openvpn/extract/extract_test.go b/internal/openvpn/extract/extract_test.go index b5191422..1e1708f6 100644 --- a/internal/openvpn/extract/extract_test.go +++ b/internal/openvpn/extract/extract_test.go @@ -98,7 +98,7 @@ func Test_extractDataFromLine(t *testing.T) { }, "extract proto error": { line: "proto bad", - isErr: errExtractProto, + isErr: errProtocolNotSupported, }, "extract proto success": { line: "proto tcp", @@ -106,7 +106,7 @@ func Test_extractDataFromLine(t *testing.T) { }, "extract remote error": { line: "remote bad", - isErr: errExtractRemote, + isErr: errHostNotIP, }, "extract remote success": { line: "remote 1.2.3.4 1194 udp", @@ -213,15 +213,15 @@ func Test_extractRemote(t *testing.T) { }, "port is zero": { line: "remote 1.2.3.4 0", - err: errors.New("port is not valid: not between 1 and 65535: 0"), + err: errors.New("port is not valid: 0 must be between 1 and 65535"), }, "port is minus one": { line: "remote 1.2.3.4 -1", - err: errors.New("port is not valid: not between 1 and 65535: -1"), + err: errors.New("port is not valid: -1 must be between 1 and 65535"), }, "port is over 65535": { line: "remote 1.2.3.4 65536", - err: errors.New("port is not valid: not between 1 and 65535: 65536"), + err: errors.New("port is not valid: 65536 must be between 1 and 65535"), }, "IP host and port": { line: "remote 1.2.3.4 8000", diff --git a/internal/openvpn/parse/certificate.go b/internal/openvpn/parse/certificate.go index caff7e08..2a04c361 100644 --- a/internal/openvpn/parse/certificate.go +++ b/internal/openvpn/parse/certificate.go @@ -7,7 +7,7 @@ import ( func ExtractCert(b []byte) (certData string, err error) { certData, err = extractPEM(b, "CERTIFICATE") if err != nil { - return "", fmt.Errorf("%w: %s", ErrExtractPEM, err) + return "", fmt.Errorf("cannot extract PEM data: %w", err) } return certData, nil diff --git a/internal/openvpn/parse/errors.go b/internal/openvpn/parse/errors.go deleted file mode 100644 index a12edbcd..00000000 --- a/internal/openvpn/parse/errors.go +++ /dev/null @@ -1,7 +0,0 @@ -package parse - -import "errors" - -var ( - ErrExtractPEM = errors.New("cannot extract PEM data") -) diff --git a/internal/openvpn/parse/key.go b/internal/openvpn/parse/key.go index fe33e434..7fef1a53 100644 --- a/internal/openvpn/parse/key.go +++ b/internal/openvpn/parse/key.go @@ -7,7 +7,7 @@ import ( func ExtractPrivateKey(b []byte) (keyData string, err error) { keyData, err = extractPEM(b, "PRIVATE KEY") if err != nil { - return "", fmt.Errorf("%w: %s", ErrExtractPEM, err) + return "", fmt.Errorf("cannot extract PEM data: %w", err) } return keyData, nil diff --git a/internal/portforward/firewall.go b/internal/portforward/firewall.go index bf187927..42e7b54e 100644 --- a/internal/portforward/firewall.go +++ b/internal/portforward/firewall.go @@ -27,6 +27,6 @@ func (l *Loop) firewallAllowPort(ctx context.Context) { startData := l.state.GetStartData() err := l.portAllower.SetAllowedPort(ctx, port, startData.Interface) if err != nil { - l.logger.Error("cannot allow port through firewall: " + err.Error()) + l.logger.Error("cannot allow port: " + err.Error()) } } diff --git a/internal/provider/custom/connection.go b/internal/provider/custom/connection.go index d8a61ba3..770a30b8 100644 --- a/internal/provider/custom/connection.go +++ b/internal/provider/custom/connection.go @@ -13,7 +13,6 @@ import ( var ( ErrVPNTypeNotSupported = errors.New("VPN type not supported for custom provider") - ErrExtractConnection = errors.New("cannot extract connection") ) // GetConnection gets the connection from the OpenVPN configuration file. @@ -34,7 +33,7 @@ func getOpenVPNConnection(extractor extract.Interface, connection models.Connection, err error) { _, connection, err = extractor.Data(*selection.OpenVPN.ConfFile) if err != nil { - return connection, fmt.Errorf("%w: %s", ErrExtractConnection, err) + return connection, fmt.Errorf("cannot extract connection: %w", err) } connection.Port = getPort(connection.Port, selection) diff --git a/internal/provider/custom/openvpnconf.go b/internal/provider/custom/openvpnconf.go index 16fff5f0..7c0f692e 100644 --- a/internal/provider/custom/openvpnconf.go +++ b/internal/provider/custom/openvpnconf.go @@ -18,7 +18,7 @@ func (p *Provider) BuildConf(connection models.Connection, settings settings.OpenVPN) (lines []string, err error) { lines, _, err = p.extractor.Data(*settings.ConfFile) if err != nil { - return nil, fmt.Errorf("%w: %s", ErrExtractData, err) + return nil, fmt.Errorf("failed extracting information from custom configuration file: %w", err) } lines = modifyConfig(lines, connection, settings) diff --git a/internal/provider/ipvanish/connection.go b/internal/provider/ipvanish/connection.go index cf1a211d..5133c4ec 100644 --- a/internal/provider/ipvanish/connection.go +++ b/internal/provider/ipvanish/connection.go @@ -1,23 +1,16 @@ package ipvanish import ( - "errors" - "github.com/qdm12/gluetun/internal/configuration/settings" "github.com/qdm12/gluetun/internal/constants" "github.com/qdm12/gluetun/internal/models" "github.com/qdm12/gluetun/internal/provider/utils" ) -var ErrProtocolUnsupported = errors.New("network protocol is not supported") - func (i *Ipvanish) GetConnection(selection settings.ServerSelection) ( connection models.Connection, err error) { const port = 443 const protocol = constants.UDP - if *selection.OpenVPN.TCP { - return connection, ErrProtocolUnsupported - } servers, err := i.filterServers(selection) if err != nil { diff --git a/internal/provider/privado/connection.go b/internal/provider/privado/connection.go index a7a39519..b9c5c636 100644 --- a/internal/provider/privado/connection.go +++ b/internal/provider/privado/connection.go @@ -1,24 +1,16 @@ package privado import ( - "errors" - "fmt" - "github.com/qdm12/gluetun/internal/configuration/settings" "github.com/qdm12/gluetun/internal/constants" "github.com/qdm12/gluetun/internal/models" "github.com/qdm12/gluetun/internal/provider/utils" ) -var ErrProtocolUnsupported = errors.New("network protocol is not supported") - func (p *Privado) GetConnection(selection settings.ServerSelection) ( connection models.Connection, err error) { const port = 1194 const protocol = constants.UDP - if *selection.OpenVPN.TCP { - return connection, fmt.Errorf("%w: TCP for provider Privado", ErrProtocolUnsupported) - } servers, err := p.filterServers(selection) if err != nil { diff --git a/internal/provider/privateinternetaccess/httpclient.go b/internal/provider/privateinternetaccess/httpclient.go index 7d0ed512..2cbd4213 100644 --- a/internal/provider/privateinternetaccess/httpclient.go +++ b/internal/provider/privateinternetaccess/httpclient.go @@ -4,7 +4,6 @@ import ( "crypto/tls" "crypto/x509" "encoding/base64" - "errors" "fmt" "net" "net/http" @@ -13,18 +12,14 @@ import ( "github.com/qdm12/gluetun/internal/constants" ) -var ( - ErrParseCertificate = errors.New("cannot parse X509 certificate") -) - func newHTTPClient(serverName string) (client *http.Client, err error) { certificateBytes, err := base64.StdEncoding.DecodeString(constants.PiaCAStrong) if err != nil { - return nil, fmt.Errorf("%w: %s", ErrParseCertificate, err) + return nil, fmt.Errorf("cannot parse X509 certificate: %w", err) } certificate, err := x509.ParseCertificate(certificateBytes) if err != nil { - return nil, fmt.Errorf("%w: %s", ErrParseCertificate, err) + return nil, fmt.Errorf("cannot parse X509 certificate: %w", err) } //nolint:gomnd diff --git a/internal/provider/privateinternetaccess/portforward.go b/internal/provider/privateinternetaccess/portforward.go index 3fdd344c..4875c293 100644 --- a/internal/provider/privateinternetaccess/portforward.go +++ b/internal/provider/privateinternetaccess/portforward.go @@ -21,12 +21,8 @@ import ( ) var ( - ErrGatewayIPIsNil = errors.New("gateway IP address is nil") - ErrServerNameEmpty = errors.New("server name is empty") - ErrCreateHTTPClient = errors.New("cannot create custom HTTP client") - ErrReadSavedPortForwardData = errors.New("cannot read saved port forwarded data") - ErrRefreshPortForwardData = errors.New("cannot refresh port forward data") - ErrBindPort = errors.New("cannot bind port") + ErrGatewayIPIsNil = errors.New("gateway IP address is nil") + ErrServerNameEmpty = errors.New("server name is empty") ) // PortForward obtains a VPN server side port forwarded from PIA. @@ -53,12 +49,12 @@ func (p *PIA) PortForward(ctx context.Context, client *http.Client, privateIPClient, err := newHTTPClient(serverName) if err != nil { - return 0, fmt.Errorf("%w: %s", ErrCreateHTTPClient, err) + return 0, fmt.Errorf("cannot create custom HTTP client: %w", err) } data, err := readPIAPortForwardData(p.portForwardPath) if err != nil { - return 0, fmt.Errorf("%w: %s", ErrReadSavedPortForwardData, err) + return 0, fmt.Errorf("cannot read saved port forwarded data: %w", err) } dataFound := data.Port > 0 @@ -79,7 +75,7 @@ func (p *PIA) PortForward(ctx context.Context, client *http.Client, data, err = refreshPIAPortForwardData(ctx, client, privateIPClient, gateway, p.portForwardPath, p.authFilePath) if err != nil { - return 0, fmt.Errorf("%w: %s", ErrRefreshPortForwardData, err) + return 0, fmt.Errorf("cannot refresh port forward data: %w", err) } durationToExpiration = data.Expiration.Sub(p.timeNow()) } @@ -87,7 +83,7 @@ func (p *PIA) PortForward(ctx context.Context, client *http.Client, // First time binding if err := bindPort(ctx, privateIPClient, gateway, data); err != nil { - return 0, fmt.Errorf("%w: %s", ErrBindPort, err) + return 0, fmt.Errorf("cannot bind port: %w", err) } return data.Port, nil @@ -101,12 +97,12 @@ func (p *PIA) KeepPortForward(ctx context.Context, client *http.Client, port uint16, gateway net.IP, serverName string) (err error) { privateIPClient, err := newHTTPClient(serverName) if err != nil { - return fmt.Errorf("%w: %s", ErrCreateHTTPClient, err) + return fmt.Errorf("cannot create custom HTTP client: %w", err) } data, err := readPIAPortForwardData(p.portForwardPath) if err != nil { - return fmt.Errorf("%w: %s", ErrReadSavedPortForwardData, err) + return fmt.Errorf("cannot read saved port forwarded data: %w", err) } durationToExpiration := data.Expiration.Sub(p.timeNow()) @@ -128,7 +124,7 @@ func (p *PIA) KeepPortForward(ctx context.Context, client *http.Client, case <-keepAliveTimer.C: err := bindPort(ctx, privateIPClient, gateway, data) if err != nil { - return fmt.Errorf("%w: %s", ErrBindPort, err) + return fmt.Errorf("cannot bind port: %w", err) } keepAliveTimer.Reset(keepAlivePeriod) case <-expiryTimer.C: @@ -138,26 +134,20 @@ func (p *PIA) KeepPortForward(ctx context.Context, client *http.Client, } } -var ( - ErrFetchToken = errors.New("cannot fetch token") - ErrFetchPortForwarding = errors.New("cannot fetch port forwarding data") - ErrPersistPortForwarding = errors.New("cannot persist port forwarding data") -) - func refreshPIAPortForwardData(ctx context.Context, client, privateIPClient *http.Client, gateway net.IP, portForwardPath, authFilePath string) (data piaPortForwardData, err error) { data.Token, err = fetchToken(ctx, client, authFilePath) if err != nil { - return data, fmt.Errorf("%w: %s", ErrFetchToken, err) + return data, fmt.Errorf("cannot fetch token: %w", err) } data.Port, data.Signature, data.Expiration, err = fetchPortForwardData(ctx, privateIPClient, gateway, data.Token) if err != nil { - return data, fmt.Errorf("%w: %s", ErrFetchPortForwarding, err) + return data, fmt.Errorf("cannot fetch port forwarding data: %w", err) } if err := writePIAPortForwardData(portForwardPath, data); err != nil { - return data, fmt.Errorf("%w: %s", ErrPersistPortForwarding, err) + return data, fmt.Errorf("cannot persist port forwarding data: %w", err) } return data, nil @@ -242,15 +232,14 @@ func packPayload(port uint16, token string, expiration time.Time) (payload strin } var ( - errGetCredentials = errors.New("cannot get username and password") - errEmptyToken = errors.New("token received is empty") + errEmptyToken = errors.New("token received is empty") ) func fetchToken(ctx context.Context, client *http.Client, authFilePath string) (token string, err error) { username, password, err := getOpenvpnCredentials(authFilePath) if err != nil { - return "", fmt.Errorf("%w: %s", errGetCredentials, err) + return "", fmt.Errorf("cannot get username and password: %w", err) } errSubstitutions := map[string]string{ @@ -284,7 +273,7 @@ func fetchToken(ctx context.Context, client *http.Client, Token string `json:"token"` } if err := decoder.Decode(&result); err != nil { - return "", fmt.Errorf("%w: %s", ErrUnmarshalResponse, err) + return "", fmt.Errorf("cannot unmarshal response: %w", err) } if result.Token == "" { @@ -294,7 +283,6 @@ func fetchToken(ctx context.Context, client *http.Client, } var ( - errAuthFileRead = errors.New("cannot read OpenVPN authentication file") errAuthFileMalformed = errors.New("authentication file is malformed") ) @@ -302,13 +290,13 @@ func getOpenvpnCredentials(authFilePath string) ( username, password string, err error) { file, err := os.Open(authFilePath) if err != nil { - return "", "", fmt.Errorf("%w: %s", errAuthFileRead, err) + return "", "", fmt.Errorf("cannot read OpenVPN authentication file: %w", err) } authData, err := io.ReadAll(file) if err != nil { _ = file.Close() - return "", "", fmt.Errorf("%w: %s", errAuthFileRead, err) + return "", "", fmt.Errorf("authentication file is malformed: %w", err) } if err := file.Close(); err != nil { @@ -325,11 +313,6 @@ func getOpenvpnCredentials(authFilePath string) ( return username, password, nil } -var ( - errGetSignaturePayload = errors.New("cannot obtain signature payload") - errUnpackPayload = errors.New("cannot unpack payload data") -) - func fetchPortForwardData(ctx context.Context, client *http.Client, gateway net.IP, token string) ( port uint16, signature string, expiration time.Time, err error) { errSubstitutions := map[string]string{token: ""} @@ -345,13 +328,13 @@ func fetchPortForwardData(ctx context.Context, client *http.Client, gateway net. request, err := http.NewRequestWithContext(ctx, http.MethodGet, url.String(), nil) if err != nil { err = replaceInErr(err, errSubstitutions) - return 0, "", expiration, fmt.Errorf("%w: %s", errGetSignaturePayload, err) + return 0, "", expiration, fmt.Errorf("cannot obtain signature payload: %w", err) } response, err := client.Do(request) if err != nil { err = replaceInErr(err, errSubstitutions) - return 0, "", expiration, fmt.Errorf("%w: %s", errGetSignaturePayload, err) + return 0, "", expiration, fmt.Errorf("cannot obtain signature payload: %w", err) } defer response.Body.Close() @@ -366,7 +349,7 @@ func fetchPortForwardData(ctx context.Context, client *http.Client, gateway net. Signature string `json:"signature"` } if err := decoder.Decode(&data); err != nil { - return 0, "", expiration, fmt.Errorf("%w: %s", ErrUnmarshalResponse, err) + return 0, "", expiration, fmt.Errorf("cannot unmarshal response: %w", err) } if data.Status != "OK" { @@ -375,21 +358,19 @@ func fetchPortForwardData(ctx context.Context, client *http.Client, gateway net. port, _, expiration, err = unpackPayload(data.Payload) if err != nil { - return 0, "", expiration, fmt.Errorf("%w: %s", errUnpackPayload, err) + return 0, "", expiration, fmt.Errorf("cannot unpack payload data: %w", err) } return port, data.Signature, expiration, err } var ( - ErrSerializePayload = errors.New("cannot serialize payload") - ErrUnmarshalResponse = errors.New("cannot unmarshal response") - ErrBadResponse = errors.New("bad response received") + ErrBadResponse = errors.New("bad response received") ) func bindPort(ctx context.Context, client *http.Client, gateway net.IP, data piaPortForwardData) (err error) { payload, err := packPayload(data.Port, data.Token, data.Expiration) if err != nil { - return fmt.Errorf("%w: %s", ErrSerializePayload, err) + return fmt.Errorf("cannot serialize payload: %w", err) } queryParams := make(url.Values) @@ -428,7 +409,7 @@ func bindPort(ctx context.Context, client *http.Client, gateway net.IP, data pia Message string `json:"message"` } if err := decoder.Decode(&responseData); err != nil { - return fmt.Errorf("%w: from %s: %s", ErrUnmarshalResponse, url.String(), err) + return fmt.Errorf("cannot unmarshal response: from %s: %w", url.String(), err) } if responseData.Status != "OK" { @@ -464,6 +445,7 @@ func makeNOKStatusError(response *http.Response, substitutions map[string]string shortenMessage = strings.ReplaceAll(shortenMessage, " ", " ") shortenMessage = replaceInString(shortenMessage, substitutions) - return fmt.Errorf("%w: %s: %s: response received: %s", - ErrHTTPStatusCodeNotOK, url, response.Status, shortenMessage) + return fmt.Errorf("%w: %s: %d %s: response received: %s", + ErrHTTPStatusCodeNotOK, url, response.StatusCode, + response.Status, shortenMessage) } diff --git a/internal/provider/vpnunlimited/connection.go b/internal/provider/vpnunlimited/connection.go index b88258ec..1e8933cf 100644 --- a/internal/provider/vpnunlimited/connection.go +++ b/internal/provider/vpnunlimited/connection.go @@ -1,23 +1,16 @@ package vpnunlimited import ( - "errors" - "github.com/qdm12/gluetun/internal/configuration/settings" "github.com/qdm12/gluetun/internal/constants" "github.com/qdm12/gluetun/internal/models" "github.com/qdm12/gluetun/internal/provider/utils" ) -var ErrProtocolUnsupported = errors.New("network protocol is not supported") - func (p *Provider) GetConnection(selection settings.ServerSelection) ( connection models.Connection, err error) { const port = 1194 const protocol = constants.UDP - if *selection.OpenVPN.TCP { - return connection, ErrProtocolUnsupported - } servers, err := p.filterServers(selection) if err != nil { diff --git a/internal/provider/vyprvpn/connection.go b/internal/provider/vyprvpn/connection.go index 30d5361f..867642d1 100644 --- a/internal/provider/vyprvpn/connection.go +++ b/internal/provider/vyprvpn/connection.go @@ -1,24 +1,16 @@ package vyprvpn import ( - "errors" - "fmt" - "github.com/qdm12/gluetun/internal/configuration/settings" "github.com/qdm12/gluetun/internal/constants" "github.com/qdm12/gluetun/internal/models" "github.com/qdm12/gluetun/internal/provider/utils" ) -var ErrProtocolUnsupported = errors.New("network protocol is not supported") - func (v *Vyprvpn) GetConnection(selection settings.ServerSelection) ( connection models.Connection, err error) { const port = 443 const protocol = constants.UDP - if *selection.OpenVPN.TCP { - return connection, fmt.Errorf("%w: TCP for provider VyprVPN", ErrProtocolUnsupported) - } servers, err := v.filterServers(selection) if err != nil { diff --git a/internal/publicip/errors.go b/internal/publicip/errors.go index ea1ff226..2ba2f841 100644 --- a/internal/publicip/errors.go +++ b/internal/publicip/errors.go @@ -3,6 +3,5 @@ package publicip import "errors" var ( - ErrBadStatusCode = errors.New("bad HTTP status") - ErrCannotReadBody = errors.New("cannot read response body") + ErrBadStatusCode = errors.New("bad HTTP status") ) diff --git a/internal/publicip/fetch.go b/internal/publicip/fetch.go index 9b394d9b..56eda31f 100644 --- a/internal/publicip/fetch.go +++ b/internal/publicip/fetch.go @@ -56,12 +56,13 @@ func (f *Fetch) FetchPublicIP(ctx context.Context) (ip net.IP, err error) { defer response.Body.Close() if response.StatusCode != http.StatusOK { - return nil, fmt.Errorf("%w from %s: %s", ErrBadStatusCode, url, response.Status) + return nil, fmt.Errorf("%w from %s: %d %s", ErrBadStatusCode, + url, response.StatusCode, response.Status) } content, err := io.ReadAll(response.Body) if err != nil { - return nil, fmt.Errorf("%w: %s", ErrCannotReadBody, err) + return nil, fmt.Errorf("cannot ready response body: %w", err) } s := strings.ReplaceAll(string(content), "\n", "") diff --git a/internal/publicip/info.go b/internal/publicip/info.go index 78f79b48..d28e3583 100644 --- a/internal/publicip/info.go +++ b/internal/publicip/info.go @@ -38,7 +38,8 @@ func Info(ctx context.Context, client *http.Client, ip net.IP) ( //nolint:interf case http.StatusTooManyRequests: return result, fmt.Errorf("%w: %s", ErrTooManyRequests, baseURL) default: - return result, fmt.Errorf("%w: %d", ErrBadHTTPStatus, response.StatusCode) + return result, fmt.Errorf("%w: %d %s", ErrBadHTTPStatus, + response.StatusCode, response.Status) } decoder := json.NewDecoder(response.Body) diff --git a/internal/routing/default.go b/internal/routing/default.go index 8315a468..e8e2d0b6 100644 --- a/internal/routing/default.go +++ b/internal/routing/default.go @@ -19,7 +19,7 @@ type DefaultRouteGetter interface { func (r *Routing) DefaultRoute() (defaultInterface string, defaultGateway net.IP, err error) { routes, err := r.netLinker.RouteList(nil, netlink.FAMILY_ALL) if err != nil { - return "", nil, fmt.Errorf("%w: %s", ErrRoutesList, err) + return "", nil, fmt.Errorf("cannot list routes: %w", err) } for _, route := range routes { if route.Dst == nil { @@ -27,7 +27,7 @@ func (r *Routing) DefaultRoute() (defaultInterface string, defaultGateway net.IP linkIndex := route.LinkIndex link, err := r.netLinker.LinkByIndex(linkIndex) if err != nil { - return "", nil, fmt.Errorf("%w: for default route at index %d: %s", ErrLinkByIndex, linkIndex, err) + return "", nil, fmt.Errorf("cannot obtain link by index: for default route at index %d: %w", linkIndex, err) } attributes := link.Attrs() defaultInterface = attributes.Name @@ -46,7 +46,7 @@ type DefaultIPGetter interface { func (r *Routing) DefaultIP() (ip net.IP, err error) { routes, err := r.netLinker.RouteList(nil, netlink.FAMILY_ALL) if err != nil { - return nil, fmt.Errorf("%w: %s", ErrRoutesList, err) + return nil, fmt.Errorf("cannot list routes: %w", err) } defaultLinkName := "" @@ -55,7 +55,7 @@ func (r *Routing) DefaultIP() (ip net.IP, err error) { linkIndex := route.LinkIndex link, err := r.netLinker.LinkByIndex(linkIndex) if err != nil { - return nil, fmt.Errorf("%w: for default route at index %d: %s", ErrLinkByIndex, linkIndex, err) + return nil, fmt.Errorf("cannot find link by index: for default route at index %d: %w", linkIndex, err) } defaultLinkName = link.Attrs().Name } diff --git a/internal/routing/enable.go b/internal/routing/enable.go index fedc791d..c330eb9c 100644 --- a/internal/routing/enable.go +++ b/internal/routing/enable.go @@ -1,17 +1,9 @@ package routing import ( - "errors" "fmt" ) -var ( - ErrDefaultRoute = errors.New("cannot get default route") - ErrAddInboundFromDefault = errors.New("cannot add routes for inbound traffic from default IP") - ErrDelInboundFromDefault = errors.New("cannot remove routes for inbound traffic from default IP") - ErrSubnetsOutboundSet = errors.New("cannot set outbound subnets routes") -) - type Setuper interface { Setup() (err error) } @@ -19,7 +11,7 @@ type Setuper interface { func (r *Routing) Setup() (err error) { defaultInterfaceName, defaultGateway, err := r.DefaultRoute() if err != nil { - return fmt.Errorf("%w: %s", ErrDefaultRoute, err) + return fmt.Errorf("cannot get default route: %w", err) } touched := false @@ -35,14 +27,14 @@ func (r *Routing) Setup() (err error) { err = r.routeInboundFromDefault(defaultGateway, defaultInterfaceName) if err != nil { - return fmt.Errorf("%w: %s", ErrAddInboundFromDefault, err) + return fmt.Errorf("cannot add routes for inbound traffic from default IP: %w", err) } r.stateMutex.RLock() outboundSubnets := r.outboundSubnets r.stateMutex.RUnlock() if err := r.setOutboundRoutes(outboundSubnets, defaultInterfaceName, defaultGateway); err != nil { - return fmt.Errorf("%w: %s", ErrSubnetsOutboundSet, err) + return fmt.Errorf("cannot set outbound subnets routes: %w", err) } return nil @@ -55,16 +47,16 @@ type TearDowner interface { func (r *Routing) TearDown() error { defaultInterfaceName, defaultGateway, err := r.DefaultRoute() if err != nil { - return fmt.Errorf("%w: %s", ErrDefaultRoute, err) + return fmt.Errorf("cannot get default route: %w", err) } err = r.unrouteInboundFromDefault(defaultGateway, defaultInterfaceName) if err != nil { - return fmt.Errorf("%w: %s", ErrDelInboundFromDefault, err) + return fmt.Errorf("cannot remove routes for inbound traffic from default IP: %w", err) } if err := r.setOutboundRoutes(nil, defaultInterfaceName, defaultGateway); err != nil { - return fmt.Errorf("%w: %s", ErrSubnetsOutboundSet, err) + return fmt.Errorf("cannot set outbound subnets routes: %w", err) } return nil diff --git a/internal/routing/errors.go b/internal/routing/errors.go index 95cc7767..47b9b5f4 100644 --- a/internal/routing/errors.go +++ b/internal/routing/errors.go @@ -5,7 +5,5 @@ import ( ) var ( - ErrLinkByIndex = errors.New("cannot obtain link by index") ErrLinkDefaultNotFound = errors.New("default link not found") - ErrRoutesList = errors.New("cannot list routes") ) diff --git a/internal/routing/inbound.go b/internal/routing/inbound.go index 9f074286..2ce77bab 100644 --- a/internal/routing/inbound.go +++ b/internal/routing/inbound.go @@ -1,7 +1,6 @@ package routing import ( - "errors" "fmt" "net" @@ -13,19 +12,15 @@ const ( inboundPriority = 100 ) -var ( - errDefaultIP = errors.New("cannot get default IP address") -) - func (r *Routing) routeInboundFromDefault(defaultGateway net.IP, defaultInterface string) (err error) { if err := r.addRuleInboundFromDefault(inboundTable); err != nil { - return fmt.Errorf("%w: %s", errRuleAdd, err) + return fmt.Errorf("cannot add rule: %w", err) } defaultDestination := net.IPNet{IP: net.IPv4(0, 0, 0, 0), Mask: net.IPv4Mask(0, 0, 0, 0)} if err := r.addRouteVia(defaultDestination, defaultGateway, defaultInterface, inboundTable); err != nil { - return fmt.Errorf("%w: %s", errRouteAdd, err) + return fmt.Errorf("cannot add route: %w", err) } return nil @@ -35,11 +30,11 @@ func (r *Routing) unrouteInboundFromDefault(defaultGateway net.IP, defaultInterface string) (err error) { defaultDestination := net.IPNet{IP: net.IPv4(0, 0, 0, 0), Mask: net.IPv4Mask(0, 0, 0, 0)} if err := r.deleteRouteVia(defaultDestination, defaultGateway, defaultInterface, inboundTable); err != nil { - return fmt.Errorf("%w: %s", errRouteDelete, err) + return fmt.Errorf("cannot delete route: %w", err) } if err := r.delRuleInboundFromDefault(inboundTable); err != nil { - return fmt.Errorf("%w: %s", errRuleDelete, err) + return fmt.Errorf("cannot delete rule: %w", err) } return nil @@ -48,14 +43,14 @@ func (r *Routing) unrouteInboundFromDefault(defaultGateway net.IP, func (r *Routing) addRuleInboundFromDefault(table int) (err error) { defaultIP, err := r.DefaultIP() if err != nil { - return fmt.Errorf("%w: %s", errDefaultIP, err) + return fmt.Errorf("cannot find default IP: %w", err) } defaultIPMasked32 := netlink.NewIPNet(defaultIP) ruleDstNet := (*net.IPNet)(nil) err = r.addIPRule(defaultIPMasked32, ruleDstNet, table, inboundPriority) if err != nil { - return fmt.Errorf("%w: %s", errRuleAdd, err) + return fmt.Errorf("cannot add rule: %w", err) } return nil @@ -64,14 +59,14 @@ func (r *Routing) addRuleInboundFromDefault(table int) (err error) { func (r *Routing) delRuleInboundFromDefault(table int) (err error) { defaultIP, err := r.DefaultIP() if err != nil { - return fmt.Errorf("%w: %s", errDefaultIP, err) + return fmt.Errorf("cannot find default IP: %w", err) } defaultIPMasked32 := netlink.NewIPNet(defaultIP) ruleDstNet := (*net.IPNet)(nil) err = r.deleteIPRule(defaultIPMasked32, ruleDstNet, table, inboundPriority) if err != nil { - return fmt.Errorf("%w: %s", errRuleDelete, err) + return fmt.Errorf("cannot delete rule: %w", err) } return nil diff --git a/internal/routing/ip.go b/internal/routing/ip.go index c9f3a7b6..217d30d8 100644 --- a/internal/routing/ip.go +++ b/internal/routing/ip.go @@ -13,18 +13,16 @@ func IPIsPrivate(ip net.IP) bool { var ( errInterfaceIPNotFound = errors.New("IP address not found for interface") - errInterfaceListAddr = errors.New("cannot list interface addresses") - errInterfaceNotFound = errors.New("network interface not found") ) func (r *Routing) assignedIP(interfaceName string) (ip net.IP, err error) { iface, err := net.InterfaceByName(interfaceName) if err != nil { - return nil, fmt.Errorf("%w: %s: %s", errInterfaceNotFound, interfaceName, err) + return nil, fmt.Errorf("network interface %s not found: %w", interfaceName, err) } addresses, err := iface.Addrs() if err != nil { - return nil, fmt.Errorf("%w: %s: %s", errInterfaceListAddr, interfaceName, err) + return nil, fmt.Errorf("cannot list interface %s addresses: %w", interfaceName, err) } for _, address := range addresses { switch value := address.(type) { diff --git a/internal/routing/local.go b/internal/routing/local.go index 7601e310..6b6bd596 100644 --- a/internal/routing/local.go +++ b/internal/routing/local.go @@ -9,7 +9,6 @@ import ( ) var ( - ErrLinkList = errors.New("cannot list links") ErrLinkLocalNotFound = errors.New("local link not found") ErrSubnetDefaultNotFound = errors.New("default subnet not found") ErrSubnetLocalNotFound = errors.New("local subnet not found") @@ -28,7 +27,7 @@ type LocalSubnetGetter interface { func (r *Routing) LocalSubnet() (defaultSubnet net.IPNet, err error) { routes, err := r.netLinker.RouteList(nil, netlink.FAMILY_ALL) if err != nil { - return defaultSubnet, fmt.Errorf("%w: %s", ErrRoutesList, err) + return defaultSubnet, fmt.Errorf("cannot list routes: %w", err) } defaultLinkIndex := -1 @@ -61,7 +60,7 @@ type LocalNetworksGetter interface { func (r *Routing) LocalNetworks() (localNetworks []LocalNetwork, err error) { links, err := r.netLinker.LinkList() if err != nil { - return localNetworks, fmt.Errorf("%w: %s", ErrLinkList, err) + return localNetworks, fmt.Errorf("cannot list links: %w", err) } localLinks := make(map[int]struct{}) @@ -81,7 +80,7 @@ func (r *Routing) LocalNetworks() (localNetworks []LocalNetwork, err error) { routes, err := r.netLinker.RouteList(nil, netlink.FAMILY_V4) if err != nil { - return localNetworks, fmt.Errorf("%w: %s", ErrRoutesList, err) + return localNetworks, fmt.Errorf("cannot list routes: %w", err) } for _, route := range routes { @@ -98,7 +97,7 @@ func (r *Routing) LocalNetworks() (localNetworks []LocalNetwork, err error) { link, err := r.netLinker.LinkByIndex(route.LinkIndex) if err != nil { - return localNetworks, fmt.Errorf("%w: at index %d: %s", ErrLinkByIndex, route.LinkIndex, err) + return localNetworks, fmt.Errorf("cannot find link at index %d: %w", route.LinkIndex, err) } localNet.InterfaceName = link.Attrs().Name diff --git a/internal/routing/outbound.go b/internal/routing/outbound.go index 9d5abd6a..39ec3af8 100644 --- a/internal/routing/outbound.go +++ b/internal/routing/outbound.go @@ -1,7 +1,6 @@ package routing import ( - "errors" "fmt" "net" @@ -13,10 +12,6 @@ const ( outboundPriority = 99 ) -var ( - errAddOutboundSubnet = errors.New("cannot add outbound subnet to routes") -) - type OutboundRoutesSetter interface { SetOutboundRoutes(outboundSubnets []net.IPNet) error } @@ -48,7 +43,7 @@ func (r *Routing) setOutboundRoutes(outboundSubnets []net.IPNet, err = r.addOutboundSubnets(subnetsToAdd, defaultInterfaceName, defaultGateway) if err != nil { - return fmt.Errorf("%w: %s", errAddOutboundSubnet, err) + return fmt.Errorf("cannot add outbound subnet to routes: %w", err) } return nil @@ -68,7 +63,7 @@ func (r *Routing) removeOutboundSubnets(subnets []net.IPNet, err = r.deleteIPRule(ruleSrcNet, ruleDstNet, outboundTable, outboundPriority) if err != nil { warnings = append(warnings, - errRuleDelete.Error()+": for subnet "+subNet.String()+": "+err.Error()) + "cannot delete rule: for subnet "+subNet.String()+": "+err.Error()) continue } @@ -83,16 +78,14 @@ func (r *Routing) addOutboundSubnets(subnets []net.IPNet, for i, subnet := range subnets { err := r.addRouteVia(subnet, defaultGateway, defaultInterfaceName, outboundTable) if err != nil { - return fmt.Errorf("%w: for subnet %s: %s", - errRouteAdd, subnet, err) + return fmt.Errorf("cannot add route for subnet %s: %w", subnet, err) } ruleSrcNet := (*net.IPNet)(nil) ruleDstNet := &subnets[i] err = r.addIPRule(ruleSrcNet, ruleDstNet, outboundTable, outboundPriority) if err != nil { - return fmt.Errorf("%w: for subnet %s: %s", - errRuleAdd, subnet, err) + return fmt.Errorf("cannot add rule: for subnet %s: %w", subnet, err) } r.outboundSubnets = append(r.outboundSubnets, subnet) diff --git a/internal/routing/routes.go b/internal/routing/routes.go index 2ff35001..ddcc76a0 100644 --- a/internal/routing/routes.go +++ b/internal/routing/routes.go @@ -1,7 +1,6 @@ package routing import ( - "errors" "fmt" "net" "strconv" @@ -9,12 +8,6 @@ import ( "github.com/qdm12/gluetun/internal/netlink" ) -var ( - errLinkByName = errors.New("cannot obtain link by name") - errRouteAdd = errors.New("cannot add route") - errRouteDelete = errors.New("cannot delete route") -) - func (r *Routing) addRouteVia(destination net.IPNet, gateway net.IP, iface string, table int) error { destinationStr := destination.String() @@ -26,7 +19,7 @@ func (r *Routing) addRouteVia(destination net.IPNet, gateway net.IP, link, err := r.netLinker.LinkByName(iface) if err != nil { - return fmt.Errorf("%w: interface %s: %s", errLinkByName, iface, err) + return fmt.Errorf("cannot find link for interface %s: %w", iface, err) } route := netlink.Route{ @@ -36,8 +29,8 @@ func (r *Routing) addRouteVia(destination net.IPNet, gateway net.IP, Table: table, } if err := r.netLinker.RouteReplace(&route); err != nil { - return fmt.Errorf("%w: for subnet %s at interface %s", - err, destinationStr, iface) + return fmt.Errorf("cannot replace route for subnet %s at interface %s: %w", + destinationStr, iface, err) } return nil @@ -54,7 +47,7 @@ func (r *Routing) deleteRouteVia(destination net.IPNet, gateway net.IP, link, err := r.netLinker.LinkByName(iface) if err != nil { - return fmt.Errorf("%w: for interface %s: %s", errLinkByName, iface, err) + return fmt.Errorf("cannot find link for interface %s: %w", iface, err) } route := netlink.Route{ @@ -64,8 +57,8 @@ func (r *Routing) deleteRouteVia(destination net.IPNet, gateway net.IP, Table: table, } if err := r.netLinker.RouteDel(&route); err != nil { - return fmt.Errorf("%w: for subnet %s at interface %s", - err, destinationStr, iface) + return fmt.Errorf("cannot delete route: for subnet %s at interface %s: %w", + destinationStr, iface, err) } return nil diff --git a/internal/routing/rules.go b/internal/routing/rules.go index 1213e495..68234a3d 100644 --- a/internal/routing/rules.go +++ b/internal/routing/rules.go @@ -2,19 +2,12 @@ package routing import ( "bytes" - "errors" "fmt" "net" "github.com/qdm12/gluetun/internal/netlink" ) -var ( - errRulesList = errors.New("cannot list rules") - errRuleAdd = errors.New("cannot add rule") - errRuleDelete = errors.New("cannot delete rule") -) - func (r *Routing) addIPRule(src, dst *net.IPNet, table, priority int) error { const add = true r.logger.Debug(ruleDbgMsg(add, src, dst, table, priority)) @@ -27,7 +20,7 @@ func (r *Routing) addIPRule(src, dst *net.IPNet, table, priority int) error { existingRules, err := r.netLinker.RuleList(netlink.FAMILY_ALL) if err != nil { - return fmt.Errorf("%w: %s", errRulesList, err) + return fmt.Errorf("cannot list rules: %w", err) } for i := range existingRules { if !rulesAreEqual(&existingRules[i], rule) { @@ -37,7 +30,7 @@ func (r *Routing) addIPRule(src, dst *net.IPNet, table, priority int) error { } if err := r.netLinker.RuleAdd(rule); err != nil { - return fmt.Errorf("%w: for rule: %s", err, rule) + return fmt.Errorf("cannot add rule %s: %w", rule, err) } return nil } @@ -54,14 +47,14 @@ func (r *Routing) deleteIPRule(src, dst *net.IPNet, table, priority int) error { existingRules, err := r.netLinker.RuleList(netlink.FAMILY_ALL) if err != nil { - return fmt.Errorf("%w: %s", errRulesList, err) + return fmt.Errorf("cannot list rules: %w", err) } for i := range existingRules { if !rulesAreEqual(&existingRules[i], rule) { continue } if err := r.netLinker.RuleDel(rule); err != nil { - return fmt.Errorf("%w: for rule: %s", err, rule) + return fmt.Errorf("cannot delete rule %s: %w", rule, err) } } return nil diff --git a/internal/routing/rules_test.go b/internal/routing/rules_test.go index 7e5767ba..f7b49ce1 100644 --- a/internal/routing/rules_test.go +++ b/internal/routing/rules_test.go @@ -88,7 +88,7 @@ func Test_Routing_addIPRule(t *testing.T) { ruleToAdd: makeIPRule(t, makeIPNet(t, 1), makeIPNet(t, 2), 99, 99), err: errDummy, }, - err: errors.New("dummy error: for rule: ip rule 99: from 1.1.1.0/24 to 2.2.2.0/24 table 99"), + err: errors.New("cannot add rule ip rule 99: from 1.1.1.0/24 to 2.2.2.0/24 table 99: dummy error"), }, "add rule success": { src: makeIPNet(t, 1), @@ -193,7 +193,7 @@ func Test_Routing_deleteIPRule(t *testing.T) { ruleToDel: makeIPRule(t, makeIPNet(t, 1), makeIPNet(t, 2), 99, 99), err: errDummy, }, - err: errors.New("dummy error: for rule: ip rule 99: from 1.1.1.0/24 to 2.2.2.0/24 table 99"), + err: errors.New("cannot delete rule ip rule 99: from 1.1.1.0/24 to 2.2.2.0/24 table 99: dummy error"), }, "rule deleted": { src: makeIPNet(t, 1), diff --git a/internal/routing/vpn.go b/internal/routing/vpn.go index 908c262b..70df8fc4 100644 --- a/internal/routing/vpn.go +++ b/internal/routing/vpn.go @@ -21,7 +21,7 @@ type VPNDestinationIPGetter interface { func (r *Routing) VPNDestinationIP() (ip net.IP, err error) { routes, err := r.netLinker.RouteList(nil, netlink.FAMILY_ALL) if err != nil { - return nil, fmt.Errorf("%w: %s", ErrRoutesList, err) + return nil, fmt.Errorf("cannot list routes: %w", err) } defaultLinkIndex := -1 @@ -53,12 +53,12 @@ type VPNLocalGatewayIPGetter interface { func (r *Routing) VPNLocalGatewayIP(vpnIntf string) (ip net.IP, err error) { routes, err := r.netLinker.RouteList(nil, netlink.FAMILY_ALL) if err != nil { - return nil, fmt.Errorf("%w: %s", ErrRoutesList, err) + return nil, fmt.Errorf("cannot list routes: %w", err) } for _, route := range routes { link, err := r.netLinker.LinkByIndex(route.LinkIndex) if err != nil { - return nil, fmt.Errorf("%w: %s", ErrLinkByIndex, err) + return nil, fmt.Errorf("cannot find link at index %d: %w", route.LinkIndex, err) } interfaceName := link.Attrs().Name if interfaceName == vpnIntf && diff --git a/internal/storage/read.go b/internal/storage/read.go index 2ed8038f..95d11622 100644 --- a/internal/storage/read.go +++ b/internal/storage/read.go @@ -35,8 +35,6 @@ func (s *Storage) readFromFile(filepath string, hardcoded models.AllServers) ( } var ( - errDecodeVersions = errors.New("cannot decode versions") - errDecodeServers = errors.New("cannot decode servers") errDecodeProvider = errors.New("cannot decode servers for provider") ) @@ -44,12 +42,12 @@ func (s *Storage) extractServersFromBytes(b []byte, hardcoded models.AllServers) servers models.AllServers, err error) { var versions allVersions if err := json.Unmarshal(b, &versions); err != nil { - return servers, fmt.Errorf("%w: %s", errDecodeVersions, err) + return servers, fmt.Errorf("cannot decode versions: %w", err) } var rawMessages allJSONRawMessages if err := json.Unmarshal(b, &rawMessages); err != nil { - return servers, fmt.Errorf("%w: %s", errDecodeServers, err) + return servers, fmt.Errorf("cannot decode servers: %w", err) } // TODO simplify with generics in Go 1.18 diff --git a/internal/storage/sync.go b/internal/storage/sync.go index 2466121d..e6ca57bb 100644 --- a/internal/storage/sync.go +++ b/internal/storage/sync.go @@ -1,18 +1,12 @@ package storage import ( - "errors" "fmt" "reflect" "github.com/qdm12/gluetun/internal/models" ) -var ( - ErrCannotReadFile = errors.New("cannot read servers from file") - ErrCannotWriteFile = errors.New("cannot write servers to file") -) - func countServers(allServers models.AllServers) int { return len(allServers.Cyberghost.Servers) + len(allServers.Expressvpn.Servers) + @@ -39,7 +33,7 @@ func countServers(allServers models.AllServers) int { func (s *Storage) SyncServers() (err error) { serversOnFile, err := s.readFromFile(s.filepath, s.hardcodedServers) if err != nil { - return fmt.Errorf("%w: %s", ErrCannotReadFile, err) + return fmt.Errorf("cannot read servers from file: %w", err) } hardcodedCount := countServers(s.hardcodedServers) @@ -64,7 +58,7 @@ func (s *Storage) SyncServers() (err error) { } if err := flushToFile(s.filepath, s.mergedServers); err != nil { - return fmt.Errorf("%w: %s", ErrCannotWriteFile, err) + return fmt.Errorf("cannot write servers to file: %w", err) } return nil } diff --git a/internal/tun/check.go b/internal/tun/check.go index a554f7b2..7620e23c 100644 --- a/internal/tun/check.go +++ b/internal/tun/check.go @@ -12,24 +12,21 @@ type Checker interface { } var ( - ErrTUNNotAvailable = errors.New("TUN device is not available") - ErrTUNStat = errors.New("cannot stat TUN file") - ErrTUNInfo = errors.New("cannot get syscall stat info of TUN file") - ErrTUNBadRdev = errors.New("TUN file has an unexpected rdev") - ErrTUNClose = errors.New("cannot close TUN device") + ErrTUNInfo = errors.New("cannot get syscall stat info of TUN file") + ErrTUNBadRdev = errors.New("TUN file has an unexpected rdev") ) // Check checks the tunnel device specified by path is present and accessible. func (t *Tun) Check(path string) error { f, err := os.OpenFile(path, os.O_RDWR, 0) if err != nil { - return fmt.Errorf("%w: %s", ErrTUNNotAvailable, err) + return fmt.Errorf("TUN device is not available: %w", err) } defer f.Close() info, err := f.Stat() if err != nil { - return fmt.Errorf("%w: %s", ErrTUNStat, err) + return fmt.Errorf("cannot stat TUN file: %w", err) } sys, ok := info.Sys().(*syscall.Stat_t) @@ -44,7 +41,7 @@ func (t *Tun) Check(path string) error { } if err := f.Close(); err != nil { - return fmt.Errorf("%w: %s", ErrTUNClose, err) + return fmt.Errorf("cannot close TUN device: %w", err) } return nil diff --git a/internal/tun/create.go b/internal/tun/create.go index 3143449d..e642a2e4 100644 --- a/internal/tun/create.go +++ b/internal/tun/create.go @@ -1,7 +1,6 @@ package tun import ( - "errors" "fmt" "os" "path/filepath" @@ -13,12 +12,6 @@ type Creator interface { Create(path string) error } -var ( - ErrMknod = errors.New("cannot create TUN device file node") - ErrUnixOpen = errors.New("cannot Unix Open TUN device file") - ErrSetNonBlock = errors.New("cannot set non block to TUN device file descriptor") -) - // Create creates a TUN device at the path specified. func (t *Tun) Create(path string) error { parentDir := filepath.Dir(path) @@ -33,18 +26,18 @@ func (t *Tun) Create(path string) error { dev := unix.Mkdev(major, minor) err := t.mknod(path, unix.S_IFCHR, int(dev)) if err != nil { - return fmt.Errorf("%w: %s", ErrMknod, err) + return fmt.Errorf("cannot create TUN device file node: %w", err) } fd, err := unix.Open(path, 0, 0) if err != nil { - return fmt.Errorf("%w: %s", ErrUnixOpen, err) + return fmt.Errorf("cannot Unix Open TUN device file: %w", err) } const nonBlocking = true err = unix.SetNonblock(fd, nonBlocking) if err != nil { - return fmt.Errorf("%w: %s", ErrSetNonBlock, err) + return fmt.Errorf("cannot set non block to TUN device file descriptor: %w", err) } return nil diff --git a/internal/updater/providers/ivpn/api.go b/internal/updater/providers/ivpn/api.go index 766000be..55540135 100644 --- a/internal/updater/providers/ivpn/api.go +++ b/internal/updater/providers/ivpn/api.go @@ -9,11 +9,7 @@ import ( ) var ( - errBuildRequest = errors.New("cannot build HTTP request") - errDoRequest = errors.New("failed doing HTTP request") - errHTTPStatusCodeNotOK = errors.New("HTTP status code not OK") - errUnmarshalResponseBody = errors.New("failed unmarshaling response body") - errCloseBody = errors.New("failed closing HTTP body") + errHTTPStatusCodeNotOK = errors.New("HTTP status code not OK") ) type apiData struct { @@ -40,12 +36,12 @@ func fetchAPI(ctx context.Context, client *http.Client) ( request, err := http.NewRequestWithContext(ctx, http.MethodGet, url, nil) if err != nil { - return data, fmt.Errorf("%w: %s", errBuildRequest, err) + return data, err } response, err := client.Do(request) if err != nil { - return data, fmt.Errorf("%w: %s", errDoRequest, err) + return data, err } if response.StatusCode != http.StatusOK { @@ -57,11 +53,11 @@ func fetchAPI(ctx context.Context, client *http.Client) ( decoder := json.NewDecoder(response.Body) if err := decoder.Decode(&data); err != nil { _ = response.Body.Close() - return data, fmt.Errorf("%w: %s", errUnmarshalResponseBody, err) + return data, fmt.Errorf("failed unmarshaling response body: %w", err) } if err := response.Body.Close(); err != nil { - return data, fmt.Errorf("%w: %s", errCloseBody, err) + return data, fmt.Errorf("cannot close response body: %w", err) } return data, nil diff --git a/internal/updater/providers/ivpn/servers.go b/internal/updater/providers/ivpn/servers.go index 596ac9fc..cbf3ac18 100644 --- a/internal/updater/providers/ivpn/servers.go +++ b/internal/updater/providers/ivpn/servers.go @@ -14,7 +14,6 @@ import ( ) var ( - ErrFetchAPI = errors.New("failed fetching API") ErrNotEnoughServers = errors.New("not enough servers found") ) @@ -23,7 +22,7 @@ func GetServers(ctx context.Context, client *http.Client, servers []models.IvpnServer, warnings []string, err error) { data, err := fetchAPI(ctx, client) if err != nil { - return nil, nil, fmt.Errorf("%w: %s", ErrFetchAPI, err) + return nil, nil, fmt.Errorf("failed fetching API: %w", err) } hosts := make([]string, 0, len(data.Servers)) diff --git a/internal/updater/providers/mullvad/api.go b/internal/updater/providers/mullvad/api.go index 9ca17164..f9825e57 100644 --- a/internal/updater/providers/mullvad/api.go +++ b/internal/updater/providers/mullvad/api.go @@ -41,7 +41,8 @@ func fetchAPI(ctx context.Context, client *http.Client) (data []serverData, err defer response.Body.Close() if response.StatusCode != http.StatusOK { - return nil, fmt.Errorf("%w: %s", ErrHTTPStatusCodeNotOK, response.Status) + return nil, fmt.Errorf("%w: %d %s", ErrHTTPStatusCodeNotOK, + response.StatusCode, response.Status) } decoder := json.NewDecoder(response.Body) diff --git a/internal/updater/providers/nordvpn/api.go b/internal/updater/providers/nordvpn/api.go index b7359100..3b5df5ab 100644 --- a/internal/updater/providers/nordvpn/api.go +++ b/internal/updater/providers/nordvpn/api.go @@ -9,8 +9,7 @@ import ( ) var ( - ErrHTTPStatusCodeNotOK = errors.New("HTTP status code not OK") - ErrUnmarshalResponseBody = errors.New("failed unmarshaling response body") + ErrHTTPStatusCodeNotOK = errors.New("HTTP status code not OK") ) type serverData struct { @@ -44,7 +43,7 @@ func fetchAPI(ctx context.Context, client *http.Client) (data []serverData, err decoder := json.NewDecoder(response.Body) if err := decoder.Decode(&data); err != nil { - return nil, fmt.Errorf("%w: %s", ErrUnmarshalResponseBody, err) + return nil, fmt.Errorf("failed unmarshaling response body: %w", err) } if err := response.Body.Close(); err != nil { diff --git a/internal/updater/providers/pia/api.go b/internal/updater/providers/pia/api.go index c142de96..5efff7cb 100644 --- a/internal/updater/providers/pia/api.go +++ b/internal/updater/providers/pia/api.go @@ -51,7 +51,8 @@ func fetchAPI(ctx context.Context, client *http.Client) ( defer response.Body.Close() if response.StatusCode != http.StatusOK { - return data, fmt.Errorf("%w: %s", ErrHTTPStatusCodeNotOK, response.Status) + return data, fmt.Errorf("%w: %d %s", ErrHTTPStatusCodeNotOK, + response.StatusCode, response.Status) } b, err := io.ReadAll(response.Body) diff --git a/internal/updater/providers/privatevpn/filename.go b/internal/updater/providers/privatevpn/filename.go index bb60c7ec..e1ccec76 100644 --- a/internal/updater/providers/privatevpn/filename.go +++ b/internal/updater/providers/privatevpn/filename.go @@ -44,8 +44,7 @@ func parseFilename(fileName string) ( parts := strings.Split(s, "-") const minParts = 2 if len(parts) < minParts { - return "", "", fmt.Errorf("%w: %s", - errNotEnoughParts, fileName) + return "", "", fmt.Errorf("%w: %s", errNotEnoughParts, fileName) } countryCode, city = parts[0], parts[1] diff --git a/internal/updater/providers/protonvpn/api.go b/internal/updater/providers/protonvpn/api.go index 3cc5ad23..ccfae25e 100644 --- a/internal/updater/providers/protonvpn/api.go +++ b/internal/updater/providers/protonvpn/api.go @@ -10,8 +10,7 @@ import ( ) var ( - ErrHTTPStatusCodeNotOK = errors.New("HTTP status code not OK") - ErrUnmarshalResponseBody = errors.New("failed unmarshaling response body") + ErrHTTPStatusCodeNotOK = errors.New("HTTP status code not OK") ) type apiData struct { @@ -49,12 +48,13 @@ func fetchAPI(ctx context.Context, client *http.Client) ( defer response.Body.Close() if response.StatusCode != http.StatusOK { - return data, fmt.Errorf("%w: %s", ErrHTTPStatusCodeNotOK, response.Status) + return data, fmt.Errorf("%w: %d %s", ErrHTTPStatusCodeNotOK, + response.StatusCode, response.Status) } decoder := json.NewDecoder(response.Body) if err := decoder.Decode(&data); err != nil { - return data, fmt.Errorf("%w: %s", ErrUnmarshalResponseBody, err) + return data, fmt.Errorf("failed unmarshaling response body: %w", err) } if err := response.Body.Close(); err != nil { diff --git a/internal/updater/providers/surfshark/api.go b/internal/updater/providers/surfshark/api.go index 28ff17ca..7dee7cb7 100644 --- a/internal/updater/providers/surfshark/api.go +++ b/internal/updater/providers/surfshark/api.go @@ -33,8 +33,7 @@ func addServersFromAPI(ctx context.Context, client *http.Client, } var ( - ErrHTTPStatusCodeNotOK = errors.New("HTTP status code not OK") - ErrUnmarshalResponseBody = errors.New("failed unmarshaling response body") + ErrHTTPStatusCodeNotOK = errors.New("HTTP status code not OK") ) type serverData struct { @@ -66,7 +65,7 @@ func fetchAPI(ctx context.Context, client *http.Client) ( decoder := json.NewDecoder(response.Body) if err := decoder.Decode(&servers); err != nil { - return nil, fmt.Errorf("%w: %s", ErrUnmarshalResponseBody, err) + return nil, fmt.Errorf("failed unmarshaling response body: %w", err) } if err := response.Body.Close(); err != nil { diff --git a/internal/updater/providers/surfshark/servers.go b/internal/updater/providers/surfshark/servers.go index 2239ef66..cc1c792b 100644 --- a/internal/updater/providers/surfshark/servers.go +++ b/internal/updater/providers/surfshark/servers.go @@ -14,8 +14,6 @@ import ( ) var ( - ErrGetZip = errors.New("cannot get OpenVPN ZIP file") - ErrGetAPI = errors.New("cannot fetch server information from API") ErrNotEnoughServers = errors.New("not enough servers found") ) @@ -26,12 +24,12 @@ func GetServers(ctx context.Context, unzipper unzip.Unzipper, err = addServersFromAPI(ctx, client, hts) if err != nil { - return nil, nil, fmt.Errorf("%w: %s", ErrGetAPI, err) + return nil, nil, fmt.Errorf("cannot fetch server information from API: %w", err) } warnings, err = addOpenVPNServersFromZip(ctx, unzipper, hts) if err != nil { - return nil, nil, fmt.Errorf("%w: %s", ErrGetZip, err) + return nil, nil, fmt.Errorf("cannot get OpenVPN ZIP file: %w", err) } getRemainingServers(hts) diff --git a/internal/updater/providers/windscribe/api.go b/internal/updater/providers/windscribe/api.go index d6f706ac..e8947b7a 100644 --- a/internal/updater/providers/windscribe/api.go +++ b/internal/updater/providers/windscribe/api.go @@ -12,8 +12,7 @@ import ( ) var ( - ErrHTTPStatusCodeNotOK = errors.New("HTTP status code not OK") - ErrUnmarshalResponseBody = errors.New("failed unmarshaling response body") + ErrHTTPStatusCodeNotOK = errors.New("HTTP status code not OK") ) type apiData struct { @@ -63,7 +62,7 @@ func fetchAPI(ctx context.Context, client *http.Client) ( decoder := json.NewDecoder(response.Body) if err := decoder.Decode(&data); err != nil { - return data, fmt.Errorf("%w: %s", ErrUnmarshalResponseBody, err) + return data, fmt.Errorf("failed unmarshaling response body: %w", err) } return data, nil diff --git a/internal/updater/resolver/repeat.go b/internal/updater/resolver/repeat.go index a394b042..3c087def 100644 --- a/internal/updater/resolver/repeat.go +++ b/internal/updater/resolver/repeat.go @@ -66,7 +66,6 @@ func (r *repeat) Resolve(ctx context.Context, host string, settings RepeatSettin var ( ErrMaxNoNew = errors.New("reached the maximum number of no new update") ErrMaxFails = errors.New("reached the maximum number of consecutive failures") - ErrTimeout = errors.New("reached the timeout") ) func (r *repeat) resolveOnce(ctx, timedCtx context.Context, host string, @@ -120,7 +119,7 @@ func (r *repeat) resolveOnce(ctx, timedCtx context.Context, host string, return noNewCounter, failCounter, err } return noNewCounter, failCounter, - fmt.Errorf("%w: %s", ErrTimeout, timedCtx.Err()) + fmt.Errorf("reached the timeout: %w", timedCtx.Err()) } } diff --git a/internal/updater/unzip/fetch.go b/internal/updater/unzip/fetch.go index 87617fc1..7e9c526b 100644 --- a/internal/updater/unzip/fetch.go +++ b/internal/updater/unzip/fetch.go @@ -26,7 +26,8 @@ func (u *unzipper) FetchAndExtract(ctx context.Context, url string) ( defer response.Body.Close() if response.StatusCode != http.StatusOK { - return nil, fmt.Errorf("%w: %s for %s", ErrHTTPStatusCodeNotOK, response.Status, url) + return nil, fmt.Errorf("%w: %s: %d %s", ErrHTTPStatusCodeNotOK, + url, response.StatusCode, response.Status) } b, err := io.ReadAll(response.Body) diff --git a/internal/version/github.go b/internal/version/github.go index 791b0099..7d413ef8 100644 --- a/internal/version/github.go +++ b/internal/version/github.go @@ -41,7 +41,8 @@ func getGithubReleases(ctx context.Context, client *http.Client) (releases []git defer response.Body.Close() if response.StatusCode != http.StatusOK { - return nil, fmt.Errorf("%w: %s", errHTTPStatusCode, response.Status) + return nil, fmt.Errorf("%w: %d %s", errHTTPStatusCode, + response.StatusCode, response.Status) } decoder := json.NewDecoder(response.Body) diff --git a/internal/vpn/openvpn.go b/internal/vpn/openvpn.go index e8db25e7..f50a9c43 100644 --- a/internal/vpn/openvpn.go +++ b/internal/vpn/openvpn.go @@ -2,7 +2,6 @@ package vpn import ( "context" - "errors" "fmt" "github.com/qdm12/gluetun/internal/configuration/settings" @@ -12,14 +11,6 @@ import ( "github.com/qdm12/golibs/command" ) -var ( - errServerConn = errors.New("failed finding a valid server connection") - errBuildConfig = errors.New("failed building configuration") - errWriteConfig = errors.New("failed writing configuration to file") - errWriteAuth = errors.New("failed writing auth to file") - errFirewall = errors.New("failed allowing VPN connection through firewall") -) - // setupOpenVPN sets OpenVPN up using the configurators and settings given. // It returns a serverName for port forwarding (PIA) and an error if it fails. func setupOpenVPN(ctx context.Context, fw firewall.VPNConnectionSetter, @@ -28,27 +19,27 @@ func setupOpenVPN(ctx context.Context, fw firewall.VPNConnectionSetter, runner vpnRunner, serverName string, err error) { connection, err := providerConf.GetConnection(settings.Provider.ServerSelection) if err != nil { - return nil, "", fmt.Errorf("%w: %s", errServerConn, err) + return nil, "", fmt.Errorf("failed finding a valid server connection: %w", err) } lines, err := providerConf.BuildConf(connection, settings.OpenVPN) if err != nil { - return nil, "", fmt.Errorf("%w: %s", errBuildConfig, err) + return nil, "", fmt.Errorf("failed building configuration: %w", err) } if err := openvpnConf.WriteConfig(lines); err != nil { - return nil, "", fmt.Errorf("%w: %s", errWriteConfig, err) + return nil, "", fmt.Errorf("failed writing configuration to file: %w", err) } if settings.OpenVPN.User != "" { err := openvpnConf.WriteAuthFile(settings.OpenVPN.User, settings.OpenVPN.Password) if err != nil { - return nil, "", fmt.Errorf("%w: %s", errWriteAuth, err) + return nil, "", fmt.Errorf("failed writing auth to file: %w", err) } } if err := fw.SetVPNConnection(ctx, connection, settings.OpenVPN.Interface); err != nil { - return nil, "", fmt.Errorf("%w: %s", errFirewall, err) + return nil, "", fmt.Errorf("failed allowing VPN connection through firewall: %w", err) } runner = openvpn.NewRunner(settings.OpenVPN, starter, logger) diff --git a/internal/vpn/portforward.go b/internal/vpn/portforward.go index 2ff7c139..81c82446 100644 --- a/internal/vpn/portforward.go +++ b/internal/vpn/portforward.go @@ -2,18 +2,12 @@ package vpn import ( "context" - "errors" "fmt" "time" "github.com/qdm12/gluetun/internal/portforward" ) -var ( - errObtainVPNLocalGateway = errors.New("cannot obtain VPN local gateway IP") - errStartPortForwarding = errors.New("cannot start port forwarding") -) - func (l *Loop) startPortForwarding(ctx context.Context, data tunnelUpData) (err error) { if !data.portForwarding { return nil @@ -22,7 +16,7 @@ func (l *Loop) startPortForwarding(ctx context.Context, data tunnelUpData) (err // only used for PIA for now gateway, err := l.routing.VPNLocalGatewayIP(data.vpnIntf) if err != nil { - return fmt.Errorf("%w: for interface %s: %s", errObtainVPNLocalGateway, data.vpnIntf, err) + return fmt.Errorf("cannot obtain VPN local gateway IP for interface %s: %w", data.vpnIntf, err) } l.logger.Info("VPN gateway IP address: " + gateway.String()) @@ -34,7 +28,7 @@ func (l *Loop) startPortForwarding(ctx context.Context, data tunnelUpData) (err } _, err = l.portForward.Start(ctx, pfData) if err != nil { - return fmt.Errorf("%w: %s", errStartPortForwarding, err) + return fmt.Errorf("cannot start port forwarding: %w", err) } return nil diff --git a/internal/vpn/wireguard.go b/internal/vpn/wireguard.go index b230b3ab..3ea07ec2 100644 --- a/internal/vpn/wireguard.go +++ b/internal/vpn/wireguard.go @@ -2,7 +2,6 @@ package vpn import ( "context" - "errors" "fmt" "github.com/qdm12/gluetun/internal/configuration/settings" @@ -13,11 +12,6 @@ import ( "github.com/qdm12/gluetun/internal/wireguard" ) -var ( - errGetServer = errors.New("failed finding a VPN server") - errCreateWireguard = errors.New("failed creating Wireguard") -) - // setupWireguard sets Wireguard up using the configurators and settings given. // It returns a serverName for port forwarding (PIA) and an error if it fails. func setupWireguard(ctx context.Context, netlinker netlink.NetLinker, @@ -26,7 +20,7 @@ func setupWireguard(ctx context.Context, netlinker netlink.NetLinker, wireguarder wireguard.Wireguarder, serverName string, err error) { connection, err := providerConf.GetConnection(settings.Provider.ServerSelection) if err != nil { - return nil, "", fmt.Errorf("%w: %s", errGetServer, err) + return nil, "", fmt.Errorf("failed finding a VPN server: %w", err) } wireguardSettings := utils.BuildWireguardSettings(connection, settings.Wireguard) @@ -37,12 +31,12 @@ func setupWireguard(ctx context.Context, netlinker netlink.NetLinker, wireguarder, err = wireguard.New(wireguardSettings, netlinker, logger) if err != nil { - return nil, "", fmt.Errorf("%w: %s", errCreateWireguard, err) + return nil, "", fmt.Errorf("failed creating Wireguard: %w", err) } err = fw.SetVPNConnection(ctx, connection, settings.Wireguard.Interface) if err != nil { - return nil, "", fmt.Errorf("%w: %s", errFirewall, err) + return nil, "", fmt.Errorf("failed setting firewall: %w", err) } return wireguarder, connection.Hostname, nil diff --git a/internal/wireguard/config.go b/internal/wireguard/config.go index fa660dce..459f14c7 100644 --- a/internal/wireguard/config.go +++ b/internal/wireguard/config.go @@ -1,7 +1,6 @@ package wireguard import ( - "errors" "fmt" "net" @@ -9,20 +8,15 @@ import ( "golang.zx2c4.com/wireguard/wgctrl/wgtypes" ) -var ( - errMakeConfig = errors.New("cannot make device configuration") - errConfigureDevice = errors.New("cannot configure device") -) - func configureDevice(client *wgctrl.Client, settings Settings) (err error) { deviceConfig, err := makeDeviceConfig(settings) if err != nil { - return fmt.Errorf("%w: %s", errMakeConfig, err) + return fmt.Errorf("cannot make device configuration: %w", err) } err = client.ConfigureDevice(settings.InterfaceName, deviceConfig) if err != nil { - return fmt.Errorf("%w: %s", errConfigureDevice, err) + return fmt.Errorf("cannot configure device: %w", err) } return nil diff --git a/internal/wireguard/ipv6.go b/internal/wireguard/ipv6.go index ff008280..45ba2a31 100644 --- a/internal/wireguard/ipv6.go +++ b/internal/wireguard/ipv6.go @@ -1,27 +1,21 @@ package wireguard import ( - "errors" "fmt" "github.com/qdm12/gluetun/internal/netlink" ) -var ( - errLinkList = errors.New("cannot list links") - errRouteList = errors.New("cannot list routes") -) - func (w *Wireguard) isIPv6Supported() (supported bool, err error) { links, err := w.netlink.LinkList() if err != nil { - return false, fmt.Errorf("%w: %s", errLinkList, err) + return false, fmt.Errorf("cannot list links: %w", err) } for _, link := range links { routes, err := w.netlink.RouteList(link, netlink.FAMILY_V6) if err != nil { - return false, fmt.Errorf("%w: %s", errRouteList, err) + return false, fmt.Errorf("cannot list routes: %w", err) } if len(routes) > 0 { diff --git a/internal/wireguard/route.go b/internal/wireguard/route.go index b1463bb9..d86bf290 100644 --- a/internal/wireguard/route.go +++ b/internal/wireguard/route.go @@ -19,7 +19,7 @@ func (w *Wireguard) addRoute(link netlink.Link, dst *net.IPNet, err = w.netlink.RouteAdd(route) if err != nil { - return fmt.Errorf("%w: when adding route: %s", err, route) + return fmt.Errorf("cannot add route %s: %w", route, err) } return err diff --git a/internal/wireguard/route_test.go b/internal/wireguard/route_test.go index 967a16b0..dc9c7dea 100644 --- a/internal/wireguard/route_test.go +++ b/internal/wireguard/route_test.go @@ -53,7 +53,7 @@ func Test_Wireguard_addRoute(t *testing.T) { Table: firewallMark, }, routeAddErr: errDummy, - err: errors.New("dummy: when adding route: {Ifindex: 88 Dst: 1.2.3.4/32 Src: Gw: Flags: [] Table: 51820 Realm: 0}"), //nolint:lll + err: errors.New("cannot add route {Ifindex: 88 Dst: 1.2.3.4/32 Src: Gw: Flags: [] Table: 51820 Realm: 0}: dummy"), //nolint:lll }, } diff --git a/internal/wireguard/rule.go b/internal/wireguard/rule.go index c4344e0b..9e2f41f8 100644 --- a/internal/wireguard/rule.go +++ b/internal/wireguard/rule.go @@ -14,13 +14,13 @@ func (w *Wireguard) addRule(rulePriority, firewallMark int) ( rule.Mark = firewallMark rule.Table = firewallMark if err := w.netlink.RuleAdd(rule); err != nil { - return nil, fmt.Errorf("%w: when adding rule: %s", err, rule) + return nil, fmt.Errorf("cannot add rule %s: %w", rule, err) } cleanup = func() error { err := w.netlink.RuleDel(rule) if err != nil { - return fmt.Errorf("%w: when deleting rule: %s", err, rule) + return fmt.Errorf("cannot delete rule %s: %w", rule, err) } return nil } diff --git a/internal/wireguard/rule_test.go b/internal/wireguard/rule_test.go index bd434b07..ed408df1 100644 --- a/internal/wireguard/rule_test.go +++ b/internal/wireguard/rule_test.go @@ -51,7 +51,7 @@ func Test_Wireguard_addRule(t *testing.T) { SuppressPrefixlen: -1, }, ruleAddErr: errDummy, - err: errors.New("dummy: when adding rule: ip rule 987: from all to all table 456"), + err: errors.New("cannot add rule ip rule 987: from all to all table 456: dummy"), }, "rule delete error": { expectedRule: &netlink.Rule{ @@ -66,7 +66,7 @@ func Test_Wireguard_addRule(t *testing.T) { SuppressPrefixlen: -1, }, ruleDelErr: errDummy, - cleanupErr: errors.New("dummy: when deleting rule: ip rule 987: from all to all table 456"), + cleanupErr: errors.New("cannot delete rule ip rule 987: from all to all table 456: dummy"), }, }