chore: use gofumpt for code formatting

This commit is contained in:
Quentin McGaw 2024-10-11 19:20:48 +00:00
parent 3daf15a612
commit 76a4bb5dc3
No known key found for this signature in database
289 changed files with 784 additions and 548 deletions

View File

@ -81,7 +81,8 @@
}, },
"gopls": { "gopls": {
"usePlaceholders": false, "usePlaceholders": false,
"staticcheck": true "staticcheck": true,
"formatting.gofumpt": true,
}, },
"go.lintTool": "golangci-lint", "go.lintTool": "golangci-lint",
"go.lintOnSave": "package", "go.lintOnSave": "package",

View File

@ -52,6 +52,7 @@ linters:
- gocritic - gocritic
- gocyclo - gocyclo
- godot - godot
- gofumpt
- goheader - goheader
- goimports - goimports
- gomoddirectives - gomoddirectives

View File

@ -140,15 +140,14 @@ func main() {
} }
} }
var ( var errCommandUnknown = errors.New("command is unknown")
errCommandUnknown = errors.New("command is unknown")
)
//nolint:gocognit,gocyclo,maintidx //nolint:gocognit,gocyclo,maintidx
func _main(ctx context.Context, buildInfo models.BuildInformation, func _main(ctx context.Context, buildInfo models.BuildInformation,
args []string, logger log.LoggerInterface, reader *reader.Reader, args []string, logger log.LoggerInterface, reader *reader.Reader,
tun Tun, netLinker netLinker, cmder RunStarter, tun Tun, netLinker netLinker, cmder RunStarter,
cli clier) error { cli clier,
) error {
if len(args) > 1 { // cli operation if len(args) > 1 { // cli operation
switch args[1] { switch args[1] {
case "healthcheck": case "healthcheck":
@ -288,7 +287,7 @@ func _main(ctx context.Context, buildInfo models.BuildInformation,
logger.Warn(warning) logger.Warn(warning)
} }
const permission = fs.FileMode(0644) const permission = fs.FileMode(0o644)
err = os.MkdirAll("/tmp/gluetun", permission) err = os.MkdirAll("/tmp/gluetun", permission)
if err != nil { if err != nil {
return err return err
@ -366,7 +365,8 @@ func _main(ctx context.Context, buildInfo models.BuildInformation,
} }
defaultGroupOptions := []group.Option{ defaultGroupOptions := []group.Option{
group.OptionTimeout(defaultShutdownTimeout), group.OptionTimeout(defaultShutdownTimeout),
group.OptionOnSuccess(defaultShutdownOnSuccess)} group.OptionOnSuccess(defaultShutdownOnSuccess),
}
controlGroupHandler := goshutdown.NewGroupHandler("control", defaultGroupOptions...) controlGroupHandler := goshutdown.NewGroupHandler("control", defaultGroupOptions...)
tickersGroupHandler := goshutdown.NewGroupHandler("tickers", defaultGroupOptions...) tickersGroupHandler := goshutdown.NewGroupHandler("tickers", defaultGroupOptions...)
@ -532,7 +532,8 @@ type infoer interface {
} }
func printVersions(ctx context.Context, logger infoer, func printVersions(ctx context.Context, logger infoer,
elements []printVersionElement) (err error) { elements []printVersionElement,
) (err error) {
const timeout = 5 * time.Second const timeout = 5 * time.Second
ctx, cancel := context.WithTimeout(ctx, timeout) ctx, cancel := context.WithTimeout(ctx, timeout)
defer cancel() defer cancel()

View File

@ -9,9 +9,7 @@ import (
"strconv" "strconv"
) )
var ( var ErrUserAlreadyExists = errors.New("user already exists")
ErrUserAlreadyExists = errors.New("user already exists")
)
// CreateUser creates a user in Alpine with the given UID. // CreateUser creates a user in Alpine with the given UID.
func (a *Alpine) CreateUser(username string, uid int) (createdUsername string, err error) { func (a *Alpine) CreateUser(username string, uid int) (createdUsername string, err error) {
@ -40,7 +38,7 @@ func (a *Alpine) CreateUser(username string, uid int) (createdUsername string, e
ErrUserAlreadyExists, username, u.Uid, uid) ErrUserAlreadyExists, username, u.Uid, uid)
} }
const permission = fs.FileMode(0644) const permission = fs.FileMode(0o644)
file, err := os.OpenFile(a.passwdPath, os.O_APPEND|os.O_WRONLY, permission) file, err := os.OpenFile(a.passwdPath, os.O_APPEND|os.O_WRONLY, permission)
if err != nil { if err != nil {
return "", err return "", err

View File

@ -22,7 +22,8 @@ var (
) )
func addProviderFlag(flagSet *flag.FlagSet, providerToFormat map[string]*bool, func addProviderFlag(flagSet *flag.FlagSet, providerToFormat map[string]*bool,
provider string, titleCaser cases.Caser) { provider string, titleCaser cases.Caser,
) {
boolPtr, ok := providerToFormat[provider] boolPtr, ok := providerToFormat[provider]
if !ok { if !ok {
panic(fmt.Sprintf("unknown provider in format map: %s", provider)) panic(fmt.Sprintf("unknown provider in format map: %s", provider))
@ -91,7 +92,7 @@ func (c *CLI) FormatServers(args []string) error {
} }
output = filepath.Clean(output) output = filepath.Clean(output)
const permission = fs.FileMode(0644) const permission = fs.FileMode(0o644)
file, err := os.OpenFile(output, os.O_TRUNC|os.O_WRONLY|os.O_CREATE, permission) file, err := os.OpenFile(output, os.O_TRUNC|os.O_WRONLY|os.O_CREATE, permission)
if err != nil { if err != nil {
return fmt.Errorf("opening output file: %w", err) return fmt.Errorf("opening output file: %w", err)

View File

@ -42,7 +42,8 @@ type IPv6Checker interface {
} }
func (c *CLI) OpenvpnConfig(logger OpenvpnConfigLogger, reader *reader.Reader, func (c *CLI) OpenvpnConfig(logger OpenvpnConfigLogger, reader *reader.Reader,
ipv6Checker IPv6Checker) error { ipv6Checker IPv6Checker,
) error {
storage, err := storage.New(logger, constants.ServersData) storage, err := storage.New(logger, constants.ServersData)
if err != nil { if err != nil {
return err return err

View File

@ -13,12 +13,14 @@ import (
// if the command fails later. // if the command fails later.
func (c *Cmder) Start(cmd *exec.Cmd) ( func (c *Cmder) Start(cmd *exec.Cmd) (
stdoutLines, stderrLines <-chan string, stdoutLines, stderrLines <-chan string,
waitError <-chan error, startErr error) { waitError <-chan error, startErr error,
) {
return start(cmd) return start(cmd)
} }
func start(cmd execCmd) (stdoutLines, stderrLines <-chan string, func start(cmd execCmd) (stdoutLines, stderrLines <-chan string,
waitError <-chan error, startErr error) { waitError <-chan error, startErr error,
) {
stop := make(chan struct{}) stop := make(chan struct{})
stdoutReady := make(chan struct{}) stdoutReady := make(chan struct{})
stdoutLinesCh := make(chan string) stdoutLinesCh := make(chan string)
@ -68,7 +70,8 @@ func start(cmd execCmd) (stdoutLines, stderrLines <-chan string,
func streamToChannel(ready chan<- struct{}, func streamToChannel(ready chan<- struct{},
stop <-chan struct{}, done chan<- struct{}, stop <-chan struct{}, done chan<- struct{},
stream io.Reader, lines chan<- string) { stream io.Reader, lines chan<- string,
) {
defer close(done) defer close(done)
close(ready) close(ready)
scanner := bufio.NewScanner(stream) scanner := bufio.NewScanner(stream)

View File

@ -76,7 +76,8 @@ func (b *DNSBlacklist) overrideWith(other DNSBlacklist) {
} }
func (b DNSBlacklist) ToBlockBuilderSettings(client *http.Client) ( func (b DNSBlacklist) ToBlockBuilderSettings(client *http.Client) (
settings blockbuilder.Settings) { settings blockbuilder.Settings,
) {
return blockbuilder.Settings{ return blockbuilder.Settings{
Client: client, Client: client,
BlockMalicious: b.BlockMalicious, BlockMalicious: b.BlockMalicious,
@ -159,12 +160,11 @@ func (b *DNSBlacklist) read(r *reader.Reader) (err error) {
return nil return nil
} }
var ( var ErrPrivateAddressNotValid = errors.New("private address is not a valid IP or CIDR range")
ErrPrivateAddressNotValid = errors.New("private address is not a valid IP or CIDR range")
)
func readDoTPrivateAddresses(reader *reader.Reader) (ips []netip.Addr, func readDoTPrivateAddresses(reader *reader.Reader) (ips []netip.Addr,
ipPrefixes []netip.Prefix, err error) { ipPrefixes []netip.Prefix, err error,
) {
privateAddresses := reader.CSV("DOT_PRIVATE_ADDRESS") privateAddresses := reader.CSV("DOT_PRIVATE_ADDRESS")
if len(privateAddresses) == 0 { if len(privateAddresses) == 0 {
return nil, nil, nil return nil, nil, nil

View File

@ -35,9 +35,7 @@ type DoT struct {
Blacklist DNSBlacklist Blacklist DNSBlacklist
} }
var ( var ErrDoTUpdatePeriodTooShort = errors.New("update period is too short")
ErrDoTUpdatePeriodTooShort = errors.New("update period is too short")
)
func (d DoT) validate() (err error) { func (d DoT) validate() (err error) {
const minUpdatePeriod = 30 * time.Second const minUpdatePeriod = 30 * time.Second

View File

@ -4,7 +4,8 @@ package settings
// and SERVER_REGIONS is now the continent field for servers. // and SERVER_REGIONS is now the continent field for servers.
// TODO v4 remove. // TODO v4 remove.
func nordvpnRetroRegion(selection ServerSelection, validRegions, validCountries []string) ( func nordvpnRetroRegion(selection ServerSelection, validRegions, validCountries []string) (
updatedSelection ServerSelection) { updatedSelection ServerSelection,
) {
validRegionsMap := stringSliceToMap(validRegions) validRegionsMap := stringSliceToMap(validRegions)
validCountriesMap := stringSliceToMap(validCountries) validCountriesMap := stringSliceToMap(validCountries)

View File

@ -155,7 +155,8 @@ func (o OpenVPN) validate(vpnProvider string) (err error) {
} }
func validateOpenVPNConfigFilepath(isCustom bool, func validateOpenVPNConfigFilepath(isCustom bool,
confFile string) (err error) { confFile string,
) (err error) {
if !isCustom { if !isCustom {
return nil return nil
} }
@ -179,7 +180,8 @@ func validateOpenVPNConfigFilepath(isCustom bool,
} }
func validateOpenVPNClientCertificate(vpnProvider, func validateOpenVPNClientCertificate(vpnProvider,
clientCert string) (err error) { clientCert string,
) (err error) {
switch vpnProvider { switch vpnProvider {
case case
providers.Airvpn, providers.Airvpn,
@ -226,7 +228,8 @@ func validateOpenVPNClientKey(vpnProvider, clientKey string) (err error) {
} }
func validateOpenVPNEncryptedKey(vpnProvider, func validateOpenVPNEncryptedKey(vpnProvider,
encryptedPrivateKey string) (err error) { encryptedPrivateKey string,
) (err error) {
if vpnProvider == providers.VPNSecure && encryptedPrivateKey == "" { if vpnProvider == providers.VPNSecure && encryptedPrivateKey == "" {
return fmt.Errorf("%w", ErrMissingValue) return fmt.Errorf("%w", ErrMissingValue)
} }

View File

@ -122,7 +122,8 @@ func (p *PublicIP) read(r *reader.Reader, warner Warner) (err error) {
} }
func readPublicIPEnabled(r *reader.Reader, warner Warner) ( func readPublicIPEnabled(r *reader.Reader, warner Warner) (
enabled *bool, err error) { enabled *bool, err error,
) {
periodPtr, err := r.DurationPtr("PUBLICIP_PERIOD") // Retro-compatibility periodPtr, err := r.DurationPtr("PUBLICIP_PERIOD") // Retro-compatibility
if err != nil { if err != nil {
return nil, err return nil, err

View File

@ -91,7 +91,8 @@ var (
) )
func (ss *ServerSelection) validate(vpnServiceProvider string, func (ss *ServerSelection) validate(vpnServiceProvider string,
filterChoicesGetter FilterChoicesGetter, warner Warner) (err error) { filterChoicesGetter FilterChoicesGetter, warner Warner,
) (err error) {
switch ss.VPN { switch ss.VPN {
case vpn.OpenVPN, vpn.Wireguard: case vpn.OpenVPN, vpn.Wireguard:
default: default:
@ -143,7 +144,8 @@ func (ss *ServerSelection) validate(vpnServiceProvider string,
func getLocationFilterChoices(vpnServiceProvider string, func getLocationFilterChoices(vpnServiceProvider string,
ss *ServerSelection, filterChoicesGetter FilterChoicesGetter, warner Warner) ( ss *ServerSelection, filterChoicesGetter FilterChoicesGetter, warner Warner) (
filterChoices models.FilterChoices, err error) { filterChoices models.FilterChoices, err error,
) {
filterChoices = filterChoicesGetter.GetFilterChoices(vpnServiceProvider) filterChoices = filterChoicesGetter.GetFilterChoices(vpnServiceProvider)
if vpnServiceProvider == providers.Surfshark { if vpnServiceProvider == providers.Surfshark {
@ -165,7 +167,8 @@ func getLocationFilterChoices(vpnServiceProvider string,
// validateServerFilters validates filters against the choices given as arguments. // validateServerFilters validates filters against the choices given as arguments.
// Set an argument to nil to pass the check for a particular filter. // Set an argument to nil to pass the check for a particular filter.
func validateServerFilters(settings ServerSelection, filterChoices models.FilterChoices, func validateServerFilters(settings ServerSelection, filterChoices models.FilterChoices,
vpnServiceProvider string, warner Warner) (err error) { vpnServiceProvider string, warner Warner,
) (err error) {
err = atLeastOneIsOneOfCaseInsensitive(settings.Countries, filterChoices.Countries, warner) err = atLeastOneIsOneOfCaseInsensitive(settings.Countries, filterChoices.Countries, warner)
if err != nil { if err != nil {
return fmt.Errorf("%w: %w", ErrCountryNotValid, err) return fmt.Errorf("%w: %w", ErrCountryNotValid, err)
@ -219,7 +222,8 @@ func validateServerFilters(settings ServerSelection, filterChoices models.Filter
} }
func atLeastOneIsOneOfCaseInsensitive(values, choices []string, func atLeastOneIsOneOfCaseInsensitive(values, choices []string,
warner Warner) (err error) { warner Warner,
) (err error) {
if len(values) > 0 && len(choices) == 0 { if len(values) > 0 && len(choices) == 0 {
return fmt.Errorf("%w", validate.ErrNoChoice) return fmt.Errorf("%w", validate.ErrNoChoice)
} }
@ -456,7 +460,8 @@ func (ss ServerSelection) WithDefaults(provider string) ServerSelection {
} }
func (ss *ServerSelection) read(r *reader.Reader, func (ss *ServerSelection) read(r *reader.Reader,
vpnProvider, vpnType string) (err error) { vpnProvider, vpnType string,
) (err error) {
ss.VPN = vpnType ss.VPN = vpnType
ss.TargetIP, err = r.NetipAddr("OPENVPN_ENDPOINT_IP", ss.TargetIP, err = r.NetipAddr("OPENVPN_ENDPOINT_IP",

View File

@ -38,7 +38,8 @@ type FilterChoicesGetter interface {
// if one of them is not valid. // if one of them is not valid.
// TODO v4 remove pointer for receiver (because of Surfshark). // TODO v4 remove pointer for receiver (because of Surfshark).
func (s *Settings) Validate(filterChoicesGetter FilterChoicesGetter, ipv6Supported bool, func (s *Settings) Validate(filterChoicesGetter FilterChoicesGetter, ipv6Supported bool,
warner Warner) (err error) { warner Warner,
) (err error) {
nameToValidation := map[string]func() error{ nameToValidation := map[string]func() error{
"control server": s.ControlServer.validate, "control server": s.ControlServer.validate,
"dns": s.DNS.validate, "dns": s.DNS.validate,
@ -88,7 +89,8 @@ func (s *Settings) copy() (copied Settings) {
} }
func (s *Settings) OverrideWith(other Settings, func (s *Settings) OverrideWith(other Settings,
filterChoicesGetter FilterChoicesGetter, ipv6Supported bool, warner Warner) (err error) { filterChoicesGetter FilterChoicesGetter, ipv6Supported bool, warner Warner,
) (err error) {
patchedSettings := s.copy() patchedSettings := s.copy()
patchedSettings.ControlServer.overrideWith(other.ControlServer) patchedSettings.ControlServer.overrideWith(other.ControlServer)
patchedSettings.DNS.overrideWith(other.DNS) patchedSettings.DNS.overrideWith(other.DNS)

View File

@ -7,7 +7,8 @@ import (
) )
func surfsharkRetroRegion(selection ServerSelection) ( func surfsharkRetroRegion(selection ServerSelection) (
updatedSelection ServerSelection) { updatedSelection ServerSelection,
) {
locationData := servers.LocationData() locationData := servers.LocationData()
retroToLocation := make(map[string]servers.ServerLocation, len(locationData)) retroToLocation := make(map[string]servers.ServerLocation, len(locationData))

View File

@ -34,9 +34,7 @@ type WireguardConfig struct {
EndpointPort *string EndpointPort *string
} }
var ( var regexINISectionNotExist = regexp.MustCompile(`^section ".+" does not exist$`)
regexINISectionNotExist = regexp.MustCompile(`^section ".+" does not exist$`)
)
func ParseWireguardConf(path string) (config WireguardConfig, err error) { func ParseWireguardConf(path string) (config WireguardConfig, err error) {
iniFile, err := ini.InsensitiveLoad(path) iniFile, err := ini.InsensitiveLoad(path)
@ -68,18 +66,18 @@ func ParseWireguardConf(path string) (config WireguardConfig, err error) {
} }
func parseWireguardInterfaceSection(interfaceSection *ini.Section) ( func parseWireguardInterfaceSection(interfaceSection *ini.Section) (
privateKey, addresses *string) { privateKey, addresses *string,
) {
privateKey = getINIKeyFromSection(interfaceSection, "PrivateKey") privateKey = getINIKeyFromSection(interfaceSection, "PrivateKey")
addresses = getINIKeyFromSection(interfaceSection, "Address") addresses = getINIKeyFromSection(interfaceSection, "Address")
return privateKey, addresses return privateKey, addresses
} }
var ( var ErrEndpointHostNotIP = errors.New("endpoint host is not an IP")
ErrEndpointHostNotIP = errors.New("endpoint host is not an IP")
)
func parseWireguardPeerSection(peerSection *ini.Section) ( func parseWireguardPeerSection(peerSection *ini.Section) (
preSharedKey, publicKey, endpointIP, endpointPort *string) { preSharedKey, publicKey, endpointIP, endpointPort *string,
) {
preSharedKey = getINIKeyFromSection(peerSection, "PresharedKey") preSharedKey = getINIKeyFromSection(peerSection, "PresharedKey")
publicKey = getINIKeyFromSection(peerSection, "PublicKey") publicKey = getINIKeyFromSection(peerSection, "PublicKey")
endpoint := getINIKeyFromSection(peerSection, "Endpoint") endpoint := getINIKeyFromSection(peerSection, "Endpoint")
@ -96,9 +94,7 @@ func parseWireguardPeerSection(peerSection *ini.Section) (
return preSharedKey, publicKey, endpointIP, endpointPort return preSharedKey, publicKey, endpointIP, endpointPort
} }
var ( var regexINIKeyNotExist = regexp.MustCompile(`key ".*" not exists$`)
regexINIKeyNotExist = regexp.MustCompile(`key ".*" not exists$`)
)
func getINIKeyFromSection(section *ini.Section, key string) (value *string) { func getINIKeyFromSection(section *ini.Section, key string) (value *string) {
iniKey, err := section.GetKey(key) iniKey, err := section.GetKey(key)

View File

@ -77,7 +77,7 @@ PresharedKey = YJ680VN+dGrdsWNjSFqZ6vvwuiNhbq502ZL3G7Q3o3g=
t.Parallel() t.Parallel()
configFile := filepath.Join(t.TempDir(), "wg.conf") configFile := filepath.Join(t.TempDir(), "wg.conf")
const permission = fs.FileMode(0600) const permission = fs.FileMode(0o600)
err := os.WriteFile(configFile, []byte(testCase.fileContent), permission) err := os.WriteFile(configFile, []byte(testCase.fileContent), permission)
require.NoError(t, err) require.NoError(t, err)

View File

@ -39,7 +39,7 @@ func Test_Source_Get(t *testing.T) {
"empty_secret_file": { "empty_secret_file": {
makeSource: func(tempDir string) (source *Source, err error) { makeSource: func(tempDir string) (source *Source, err error) {
secretFilepath := filepath.Join(tempDir, "test_file") secretFilepath := filepath.Join(tempDir, "test_file")
const permission = fs.FileMode(0600) const permission = fs.FileMode(0o600)
err = os.WriteFile(secretFilepath, nil, permission) err = os.WriteFile(secretFilepath, nil, permission)
if err != nil { if err != nil {
return nil, err return nil, err
@ -55,7 +55,7 @@ func Test_Source_Get(t *testing.T) {
"default_secret_file": { "default_secret_file": {
makeSource: func(tempDir string) (source *Source, err error) { makeSource: func(tempDir string) (source *Source, err error) {
secretFilepath := filepath.Join(tempDir, "test_file") secretFilepath := filepath.Join(tempDir, "test_file")
const permission = fs.FileMode(0600) const permission = fs.FileMode(0o600)
err = os.WriteFile(secretFilepath, []byte{'A'}, permission) err = os.WriteFile(secretFilepath, []byte{'A'}, permission)
if err != nil { if err != nil {
return nil, err return nil, err
@ -72,7 +72,7 @@ func Test_Source_Get(t *testing.T) {
"env_specified_secret_file": { "env_specified_secret_file": {
makeSource: func(tempDir string) (source *Source, err error) { makeSource: func(tempDir string) (source *Source, err error) {
secretFilepath := filepath.Join(tempDir, "test_file_custom") secretFilepath := filepath.Join(tempDir, "test_file_custom")
const permission = fs.FileMode(0600) const permission = fs.FileMode(0o600)
err = os.WriteFile(secretFilepath, []byte{'A'}, permission) err = os.WriteFile(secretFilepath, []byte{'A'}, permission)
if err != nil { if err != nil {
return nil, err return nil, err

View File

@ -37,7 +37,8 @@ type Loop struct {
const defaultBackoffTime = 10 * time.Second const defaultBackoffTime = 10 * time.Second
func NewLoop(settings settings.DNS, func NewLoop(settings settings.DNS,
client *http.Client, logger Logger) (loop *Loop, err error) { client *http.Client, logger Logger,
) (loop *Loop, err error) {
start := make(chan struct{}) start := make(chan struct{})
running := make(chan models.LoopStatus) running := make(chan models.LoopStatus)
stop := make(chan struct{}) stop := make(chan struct{})

View File

@ -16,13 +16,15 @@ import (
func (l *Loop) GetSettings() (settings settings.DNS) { return l.state.GetSettings() } func (l *Loop) GetSettings() (settings settings.DNS) { return l.state.GetSettings() }
func (l *Loop) SetSettings(ctx context.Context, settings settings.DNS) ( func (l *Loop) SetSettings(ctx context.Context, settings settings.DNS) (
outcome string) { outcome string,
) {
return l.state.SetSettings(ctx, settings) return l.state.SetSettings(ctx, settings)
} }
func buildDoTSettings(settings settings.DNS, func buildDoTSettings(settings settings.DNS,
filter *mapfilter.Filter, logger Logger) ( filter *mapfilter.Filter, logger Logger) (
dotSettings dot.ServerSettings, err error) { dotSettings dot.ServerSettings, err error,
) {
var middlewares []dot.Middleware var middlewares []dot.Middleware
if *settings.DoT.Caching { if *settings.DoT.Caching {

View File

@ -15,7 +15,8 @@ func (s *State) GetSettings() (settings settings.DNS) {
} }
func (s *State) SetSettings(ctx context.Context, settings settings.DNS) ( func (s *State) SetSettings(ctx context.Context, settings settings.DNS) (
outcome string) { outcome string,
) {
s.settingsMu.Lock() s.settingsMu.Lock()
settingsUnchanged := reflect.DeepEqual(s.settings, settings) settingsUnchanged := reflect.DeepEqual(s.settings, settings)

View File

@ -10,7 +10,8 @@ import (
func New(statusApplier StatusApplier, func New(statusApplier StatusApplier,
settings settings.DNS, settings settings.DNS,
updateTicker chan<- struct{}) *State { updateTicker chan<- struct{},
) *State {
return &State{ return &State{
statusApplier: statusApplier, statusApplier: statusApplier,
settings: settings, settings: settings,

View File

@ -11,6 +11,7 @@ func (l *Loop) GetStatus() (status models.LoopStatus) {
} }
func (l *Loop) ApplyStatus(ctx context.Context, status models.LoopStatus) ( func (l *Loop) ApplyStatus(ctx context.Context, status models.LoopStatus) (
outcome string, err error) { outcome string, err error,
) {
return l.statusManager.ApplyStatus(ctx, status) return l.statusManager.ApplyStatus(ctx, status)
} }

View File

@ -33,7 +33,8 @@ func isDeleteMatchInstruction(instruction string) bool {
} }
func deleteIPTablesRule(ctx context.Context, iptablesBinary, instruction string, func deleteIPTablesRule(ctx context.Context, iptablesBinary, instruction string,
runner CmdRunner, logger Logger) (err error) { runner CmdRunner, logger Logger,
) (err error) {
targetRule, err := parseIptablesInstruction(instruction) targetRule, err := parseIptablesInstruction(instruction)
if err != nil { if err != nil {
return fmt.Errorf("parsing iptables command: %w", err) return fmt.Errorf("parsing iptables command: %w", err)
@ -69,9 +70,12 @@ func deleteIPTablesRule(ctx context.Context, iptablesBinary, instruction string,
// It returns 0 if the rule is not found. // It returns 0 if the rule is not found.
func findLineNumber(ctx context.Context, iptablesBinary string, func findLineNumber(ctx context.Context, iptablesBinary string,
instruction iptablesInstruction, runner CmdRunner, logger Logger) ( instruction iptablesInstruction, runner CmdRunner, logger Logger) (
lineNumber uint16, err error) { lineNumber uint16, err error,
listFlags := []string{"-t", instruction.table, "-L", instruction.chain, ) {
"--line-numbers", "-n", "-v"} listFlags := []string{
"-t", instruction.table, "-L", instruction.chain,
"--line-numbers", "-n", "-v",
}
cmd := exec.CommandContext(ctx, iptablesBinary, listFlags...) // #nosec G204 cmd := exec.CommandContext(ctx, iptablesBinary, listFlags...) // #nosec G204
logger.Debug(cmd.String()) logger.Debug(cmd.String())
output, err := runner.Run(cmd) output, err := runner.Run(cmd)

View File

@ -36,7 +36,8 @@ type Config struct { //nolint:maligned
// if no iptables implementation is available. // if no iptables implementation is available.
func NewConfig(ctx context.Context, logger Logger, func NewConfig(ctx context.Context, logger Logger,
runner CmdRunner, defaultRoutes []routing.DefaultRoute, runner CmdRunner, defaultRoutes []routing.DefaultRoute,
localNetworks []routing.LocalNetwork) (config *Config, err error) { localNetworks []routing.LocalNetwork,
) (config *Config, err error) {
iptables, err := checkIptablesSupport(ctx, runner, "iptables", "iptables-nft", "iptables-legacy") iptables, err := checkIptablesSupport(ctx, runner, "iptables", "iptables-nft", "iptables-legacy")
if err != nil { if err != nil {
return nil, err return nil, err

View File

@ -12,7 +12,8 @@ import (
// and returns the iptables path that is supported. If none work, an // and returns the iptables path that is supported. If none work, an
// empty string path is returned. // empty string path is returned.
func findIP6tablesSupported(ctx context.Context, runner CmdRunner) ( func findIP6tablesSupported(ctx context.Context, runner CmdRunner) (
ip6tablesPath string, err error) { ip6tablesPath string, err error,
) {
ip6tablesPath, err = checkIptablesSupport(ctx, runner, "ip6tables", "ip6tables-nft", "ip6tables-legacy") ip6tablesPath, err = checkIptablesSupport(ctx, runner, "ip6tables", "ip6tables-nft", "ip6tables-legacy")
if errors.Is(err, ErrIPTablesNotSupported) { if errors.Is(err, ErrIPTablesNotSupported) {
return "", nil return "", nil

View File

@ -112,7 +112,8 @@ func (c *Config) acceptInputThroughInterface(ctx context.Context, intf string, r
} }
func (c *Config) acceptInputToSubnet(ctx context.Context, intf string, func (c *Config) acceptInputToSubnet(ctx context.Context, intf string,
destination netip.Prefix, remove bool) error { destination netip.Prefix, remove bool,
) error {
interfaceFlag := "-i " + intf interfaceFlag := "-i " + intf
if intf == "*" { // all interfaces if intf == "*" { // all interfaces
interfaceFlag = "" interfaceFlag = ""
@ -144,7 +145,8 @@ func (c *Config) acceptEstablishedRelatedTraffic(ctx context.Context, remove boo
} }
func (c *Config) acceptOutputTrafficToVPN(ctx context.Context, func (c *Config) acceptOutputTrafficToVPN(ctx context.Context,
defaultInterface string, connection models.Connection, remove bool) error { defaultInterface string, connection models.Connection, remove bool,
) error {
protocol := connection.Protocol protocol := connection.Protocol
if protocol == "tcp-client" { if protocol == "tcp-client" {
protocol = "tcp" //nolint:goconst protocol = "tcp" //nolint:goconst
@ -162,7 +164,8 @@ func (c *Config) acceptOutputTrafficToVPN(ctx context.Context,
// Thanks to @npawelek. // Thanks to @npawelek.
func (c *Config) acceptOutputFromIPToSubnet(ctx context.Context, func (c *Config) acceptOutputFromIPToSubnet(ctx context.Context,
intf string, sourceIP netip.Addr, destinationSubnet netip.Prefix, remove bool) error { intf string, sourceIP netip.Addr, destinationSubnet netip.Prefix, remove bool,
) error {
doIPv4 := sourceIP.Is4() && destinationSubnet.Addr().Is4() doIPv4 := sourceIP.Is4() && destinationSubnet.Addr().Is4()
interfaceFlag := "-o " + intf interfaceFlag := "-o " + intf
@ -183,7 +186,8 @@ func (c *Config) acceptOutputFromIPToSubnet(ctx context.Context,
// NDP uses multicast address (theres no broadcast in IPv6 like ARP uses in IPv4). // NDP uses multicast address (theres no broadcast in IPv6 like ARP uses in IPv4).
func (c *Config) acceptIpv6MulticastOutput(ctx context.Context, func (c *Config) acceptIpv6MulticastOutput(ctx context.Context,
intf string, remove bool) error { intf string, remove bool,
) error {
interfaceFlag := "-o " + intf interfaceFlag := "-o " + intf
if intf == "*" { // all interfaces if intf == "*" { // all interfaces
interfaceFlag = "" interfaceFlag = ""
@ -207,7 +211,8 @@ func (c *Config) acceptInputToPort(ctx context.Context, intf string, port uint16
// Used for VPN server side port forwarding, with intf set to the VPN tunnel interface. // Used for VPN server side port forwarding, with intf set to the VPN tunnel interface.
func (c *Config) redirectPort(ctx context.Context, intf string, func (c *Config) redirectPort(ctx context.Context, intf string,
sourcePort, destinationPort uint16, remove bool) (err error) { sourcePort, destinationPort uint16, remove bool,
) (err error) {
interfaceFlag := "-i " + intf interfaceFlag := "-i " + intf
if intf == "*" { // all interfaces if intf == "*" { // all interfaces
interfaceFlag = "" interfaceFlag = ""

View File

@ -32,9 +32,7 @@ type chainRule struct {
ctstate []string // for example ["RELATED","ESTABLISHED"]. Can be empty. ctstate []string // for example ["RELATED","ESTABLISHED"]. Can be empty.
} }
var ( var ErrChainListMalformed = errors.New("iptables chain list output is malformed")
ErrChainListMalformed = errors.New("iptables chain list output is malformed")
)
func parseChain(iptablesOutput string) (c chain, err error) { func parseChain(iptablesOutput string) (c chain, err error) {
// Text example: // Text example:
@ -146,9 +144,7 @@ func parseChainGeneralDataLine(line string) (base chain, err error) {
return base, nil return base, nil
} }
var ( var ErrChainRuleMalformed = errors.New("chain rule is malformed")
ErrChainRuleMalformed = errors.New("chain rule is malformed")
)
func parseChainRuleLine(line string) (rule chainRule, err error) { func parseChainRuleLine(line string) (rule chainRule, err error) {
line = strings.TrimSpace(line) line = strings.TrimSpace(line)
@ -300,9 +296,7 @@ func parsePortsCSV(s string) (ports []uint16, err error) {
return ports, nil return ports, nil
} }
var ( var ErrLineNumberIsZero = errors.New("line number is zero")
ErrLineNumberIsZero = errors.New("line number is zero")
)
func parseLineNumber(s string) (n uint16, err error) { func parseLineNumber(s string) (n uint16, err error) {
const base, bitLength = 10, 16 const base, bitLength = 10, 16
@ -315,9 +309,7 @@ func parseLineNumber(s string) (n uint16, err error) {
return uint16(lineNumber), nil return uint16(lineNumber), nil
} }
var ( var ErrTargetUnknown = errors.New("unknown target")
ErrTargetUnknown = errors.New("unknown target")
)
func checkTarget(target string) (err error) { func checkTarget(target string) (err error) {
switch target { switch target {
@ -327,9 +319,7 @@ func checkTarget(target string) (err error) {
return fmt.Errorf("%w: %s", ErrTargetUnknown, target) return fmt.Errorf("%w: %s", ErrTargetUnknown, target)
} }
var ( var ErrProtocolUnknown = errors.New("unknown protocol")
ErrProtocolUnknown = errors.New("unknown protocol")
)
func parseProtocol(s string) (protocol string, err error) { func parseProtocol(s string) (protocol string, err error) {
switch s { switch s {
@ -344,9 +334,7 @@ func parseProtocol(s string) (protocol string, err error) {
return protocol, nil return protocol, nil
} }
var ( var ErrMetricSizeMalformed = errors.New("metric size is malformed")
ErrMetricSizeMalformed = errors.New("metric size is malformed")
)
// parseMetricSize parses a metric size string like 140K or 226M and // parseMetricSize parses a metric size string like 140K or 226M and
// returns the raw integer matching it. // returns the raw integer matching it.

View File

@ -70,9 +70,7 @@ func ipPrefixesEqual(instruction, chainRule netip.Prefix) bool {
(!instruction.IsValid() && chainRule.Bits() == 0 && chainRule.Addr().IsUnspecified()) (!instruction.IsValid() && chainRule.Bits() == 0 && chainRule.Addr().IsUnspecified())
} }
var ( var ErrIptablesCommandMalformed = errors.New("iptables command is malformed")
ErrIptablesCommandMalformed = errors.New("iptables command is malformed")
)
func parseIptablesInstruction(s string) (instruction iptablesInstruction, err error) { func parseIptablesInstruction(s string) (instruction iptablesInstruction, err error) {
if s == "" { if s == "" {

View File

@ -11,7 +11,8 @@ import (
// If the destination port is zero, the redirection for the source port is removed // If the destination port is zero, the redirection for the source port is removed
// and no new redirection is added. // and no new redirection is added.
func (c *Config) RedirectPort(ctx context.Context, intf string, sourcePort, func (c *Config) RedirectPort(ctx context.Context, intf string, sourcePort,
destinationPort uint16) (err error) { destinationPort uint16,
) (err error) {
c.stateMutex.Lock() c.stateMutex.Lock()
defer c.stateMutex.Unlock() defer c.stateMutex.Unlock()
@ -90,7 +91,8 @@ func (p *portRedirections) remove(intf string, sourcePort uint16) {
} }
func (p *portRedirections) check(dryRun portRedirection) (alreadyExists bool, func (p *portRedirections) check(dryRun portRedirection) (alreadyExists bool,
conflict *portRedirection) { conflict *portRedirection,
) {
slice := *p slice := *p
for _, redirection := range slice { for _, redirection := range slice {
interfaceMatch := redirection.interfaceName == "" || interfaceMatch := redirection.interfaceName == "" ||

View File

@ -18,7 +18,8 @@ var (
) )
func checkIptablesSupport(ctx context.Context, runner CmdRunner, func checkIptablesSupport(ctx context.Context, runner CmdRunner,
iptablesPathsToTry ...string) (iptablesPath string, err error) { iptablesPathsToTry ...string,
) (iptablesPath string, err error) {
iptablesPathToUnsupportedMessage := make(map[string]string, len(iptablesPathsToTry)) iptablesPathToUnsupportedMessage := make(map[string]string, len(iptablesPathsToTry))
for _, pathToTest := range iptablesPathsToTry { for _, pathToTest := range iptablesPathsToTry {
ok, unsupportedMessage, err := testIptablesPath(ctx, pathToTest, runner) ok, unsupportedMessage, err := testIptablesPath(ctx, pathToTest, runner)
@ -61,7 +62,8 @@ func checkIptablesSupport(ctx context.Context, runner CmdRunner,
func testIptablesPath(ctx context.Context, path string, func testIptablesPath(ctx context.Context, path string,
runner CmdRunner) (ok bool, unsupportedMessage string, runner CmdRunner) (ok bool, unsupportedMessage string,
criticalErr error) { criticalErr error,
) {
// Just listing iptables rules often work but we need // Just listing iptables rules often work but we need
// to modify them to ensure we can support the iptables // to modify them to ensure we can support the iptables
// being tested. // being tested.

View File

@ -116,8 +116,7 @@ func Test_checkIptablesSupport(t *testing.T) {
runner := testCase.buildRunner(ctrl) runner := testCase.buildRunner(ctrl)
iptablesPath, err := iptablesPath, err := checkIptablesSupport(ctx, runner, testCase.iptablesPathsToTry...)
checkIptablesSupport(ctx, runner, testCase.iptablesPathsToTry...)
require.ErrorIs(t, err, testCase.errSentinel) require.ErrorIs(t, err, testCase.errSentinel)
if testCase.errSentinel != nil { if testCase.errSentinel != nil {
@ -254,8 +253,7 @@ func Test_testIptablesPath(t *testing.T) {
runner := testCase.buildRunner(ctrl) runner := testCase.buildRunner(ctrl)
ok, unsupportedMessage, criticalErr := ok, unsupportedMessage, criticalErr := testIptablesPath(ctx, path, runner)
testIptablesPath(ctx, path, runner)
assert.Equal(t, testCase.ok, ok) assert.Equal(t, testCase.ok, ok)
assert.Equal(t, testCase.unsupportedMessage, unsupportedMessage) assert.Equal(t, testCase.unsupportedMessage, unsupportedMessage)

View File

@ -8,7 +8,8 @@ import (
) )
func (c *Config) SetVPNConnection(ctx context.Context, func (c *Config) SetVPNConnection(ctx context.Context,
connection models.Connection, vpnIntf string) (err error) { connection models.Connection, vpnIntf string,
) (err error) {
c.stateMutex.Lock() c.stateMutex.Lock()
defer c.stateMutex.Unlock() defer c.stateMutex.Unlock()

View File

@ -8,9 +8,7 @@ import (
"net/http" "net/http"
) )
var ( var ErrHTTPStatusNotOK = errors.New("HTTP response status is not OK")
ErrHTTPStatusNotOK = errors.New("HTTP response status is not OK")
)
type Client struct { type Client struct {
httpClient *http.Client httpClient *http.Client

View File

@ -17,7 +17,8 @@ type Server struct {
} }
func NewServer(config settings.Health, func NewServer(config settings.Health,
logger Logger, vpnLoop StatusApplier) *Server { logger Logger, vpnLoop StatusApplier,
) *Server {
return &Server{ return &Server{
logger: logger, logger: logger,
handler: newHandler(), handler: newHandler(),

View File

@ -8,14 +8,16 @@ import (
) )
func newHandler(ctx context.Context, wg *sync.WaitGroup, logger Logger, func newHandler(ctx context.Context, wg *sync.WaitGroup, logger Logger,
stealth, verbose bool, username, password string) http.Handler { stealth, verbose bool, username, password string,
) http.Handler {
const httpTimeout = 24 * time.Hour const httpTimeout = 24 * time.Hour
return &handler{ return &handler{
ctx: ctx, ctx: ctx,
wg: wg, wg: wg,
client: &http.Client{ client: &http.Client{
Timeout: httpTimeout, Timeout: httpTimeout,
CheckRedirect: returnRedirect}, CheckRedirect: returnRedirect,
},
logger: logger, logger: logger,
verbose: verbose, verbose: verbose,
stealth: stealth, stealth: stealth,

View File

@ -18,7 +18,8 @@ type Server struct {
func New(ctx context.Context, address string, logger Logger, func New(ctx context.Context, address string, logger Logger,
stealth, verbose bool, username, password string, stealth, verbose bool, username, password string,
readHeaderTimeout, readTimeout time.Duration) *Server { readHeaderTimeout, readTimeout time.Duration,
) *Server {
wg := &sync.WaitGroup{} wg := &sync.WaitGroup{}
return &Server{ return &Server{
address: address, address: address,

View File

@ -11,6 +11,7 @@ func (l *Loop) GetSettings() (settings settings.HTTPProxy) {
} }
func (l *Loop) SetSettings(ctx context.Context, settings settings.HTTPProxy) ( func (l *Loop) SetSettings(ctx context.Context, settings settings.HTTPProxy) (
outcome string) { outcome string,
) {
return l.state.SetSettings(ctx, settings) return l.state.SetSettings(ctx, settings)
} }

View File

@ -15,7 +15,8 @@ func (s *State) GetSettings() (settings settings.HTTPProxy) {
} }
func (s *State) SetSettings(ctx context.Context, func (s *State) SetSettings(ctx context.Context,
settings settings.HTTPProxy) (outcome string) { settings settings.HTTPProxy,
) (outcome string) {
s.settingsMu.Lock() s.settingsMu.Lock()
settingsUnchanged := reflect.DeepEqual(settings, s.settings) settingsUnchanged := reflect.DeepEqual(settings, s.settings)
if settingsUnchanged { if settingsUnchanged {

View File

@ -9,7 +9,8 @@ import (
) )
func New(statusApplier StatusApplier, func New(statusApplier StatusApplier,
settings settings.HTTPProxy) *State { settings settings.HTTPProxy,
) *State {
return &State{ return &State{
statusApplier: statusApplier, statusApplier: statusApplier,
settings: settings, settings: settings,

View File

@ -11,6 +11,7 @@ func (l *Loop) GetStatus() (status models.LoopStatus) {
} }
func (l *Loop) ApplyStatus(ctx context.Context, status models.LoopStatus) ( func (l *Loop) ApplyStatus(ctx context.Context, status models.LoopStatus) (
outcome string, err error) { outcome string, err error,
) {
return l.statusManager.ApplyStatus(ctx, status) return l.statusManager.ApplyStatus(ctx, status)
} }

View File

@ -16,7 +16,8 @@ var ErrInvalidStatus = errors.New("invalid status")
// matches the requested one. It is thread safe and a synchronous call // matches the requested one. It is thread safe and a synchronous call
// since it waits to the loop to fully change its status. // since it waits to the loop to fully change its status.
func (s *State) ApplyStatus(ctx context.Context, status models.LoopStatus) ( func (s *State) ApplyStatus(ctx context.Context, status models.LoopStatus) (
outcome string, err error) { outcome string, err error,
) {
// prevent simultaneous loop changes by restricting // prevent simultaneous loop changes by restricting
// multiple ApplyStatus calls to run sequentially. // multiple ApplyStatus calls to run sequentially.
s.loopMu.Lock() s.loopMu.Lock()

View File

@ -8,7 +8,8 @@ import (
func New(status models.LoopStatus, func New(status models.LoopStatus,
start chan<- struct{}, running <-chan models.LoopStatus, start chan<- struct{}, running <-chan models.LoopStatus,
stop chan<- struct{}, stopped <-chan struct{}) *State { stop chan<- struct{}, stopped <-chan struct{},
) *State {
return &State{ return &State{
status: status, status: status,
start: start, start: start,

View File

@ -26,9 +26,7 @@ type moduleInfo struct {
dependencyPaths []string dependencyPaths []string
} }
var ( var ErrModulesDirectoryNotFound = errors.New("modules directory not found")
ErrModulesDirectoryNotFound = errors.New("modules directory not found")
)
func getModulesInfo() (modulesInfo map[string]moduleInfo, err error) { func getModulesInfo() (modulesInfo map[string]moduleInfo, err error) {
var utsName unix.Utsname var utsName unix.Utsname
@ -177,9 +175,7 @@ func getLoadedModules(modulesInfo map[string]moduleInfo) (err error) {
return nil return nil
} }
var ( var ErrModulePathNotFound = errors.New("module path not found")
ErrModulePathNotFound = errors.New("module path not found")
)
func findModulePath(moduleName string, modulesInfo map[string]moduleInfo) (modulePath string, err error) { func findModulePath(moduleName string, modulesInfo map[string]moduleInfo) (modulePath string, err error) {
// Kernel module names can have underscores or hyphens in their names, // Kernel module names can have underscores or hyphens in their names,

View File

@ -109,15 +109,15 @@ func (s *Servers) toMarkdown(vpnProvider string) (formatted string, err error) {
return formatted, nil return formatted, nil
} }
var ( var ErrMarkdownHeadersNotDefined = errors.New("markdown headers not defined")
ErrMarkdownHeadersNotDefined = errors.New("markdown headers not defined")
)
func getMarkdownHeaders(vpnProvider string) (headers []string, err error) { func getMarkdownHeaders(vpnProvider string) (headers []string, err error) {
switch vpnProvider { switch vpnProvider {
case providers.Airvpn: case providers.Airvpn:
return []string{regionHeader, countryHeader, cityHeader, vpnHeader, return []string{
udpHeader, tcpHeader, hostnameHeader, nameHeader}, nil regionHeader, countryHeader, cityHeader, vpnHeader,
udpHeader, tcpHeader, hostnameHeader, nameHeader,
}, nil
case providers.Cyberghost: case providers.Cyberghost:
return []string{countryHeader, hostnameHeader, tcpHeader, udpHeader}, nil return []string{countryHeader, hostnameHeader, tcpHeader, udpHeader}, nil
case providers.Expressvpn: case providers.Expressvpn:
@ -145,15 +145,19 @@ func getMarkdownHeaders(vpnProvider string) (headers []string, err error) {
case providers.Privatevpn: case providers.Privatevpn:
return []string{countryHeader, cityHeader, hostnameHeader}, nil return []string{countryHeader, cityHeader, hostnameHeader}, nil
case providers.Protonvpn: case providers.Protonvpn:
return []string{countryHeader, regionHeader, cityHeader, hostnameHeader, vpnHeader, return []string{
freeHeader, portForwardHeader, secureHeader, torHeader}, nil countryHeader, regionHeader, cityHeader, hostnameHeader, vpnHeader,
freeHeader, portForwardHeader, secureHeader, torHeader,
}, nil
case providers.Purevpn: case providers.Purevpn:
return []string{countryHeader, regionHeader, cityHeader, hostnameHeader, tcpHeader, udpHeader}, nil return []string{countryHeader, regionHeader, cityHeader, hostnameHeader, tcpHeader, udpHeader}, nil
case providers.SlickVPN: case providers.SlickVPN:
return []string{regionHeader, countryHeader, cityHeader, hostnameHeader}, nil return []string{regionHeader, countryHeader, cityHeader, hostnameHeader}, nil
case providers.Surfshark: case providers.Surfshark:
return []string{regionHeader, countryHeader, cityHeader, hostnameHeader, return []string{
vpnHeader, multiHopHeader, tcpHeader, udpHeader}, nil regionHeader, countryHeader, cityHeader, hostnameHeader,
vpnHeader, multiHopHeader, tcpHeader, udpHeader,
}, nil
case providers.Torguard: case providers.Torguard:
return []string{countryHeader, cityHeader, hostnameHeader, tcpHeader, udpHeader}, nil return []string{countryHeader, cityHeader, hostnameHeader, tcpHeader, udpHeader}, nil
case providers.VPNSecure: case providers.VPNSecure:

View File

@ -158,9 +158,7 @@ type Servers struct {
Servers []Server `json:"servers,omitempty"` Servers []Server `json:"servers,omitempty"`
} }
var ( var ErrServersFormatNotSupported = errors.New("servers format not supported")
ErrServersFormatNotSupported = errors.New("servers format not supported")
)
func (s *Servers) Format(vpnProvider, format string) (formatted string, err error) { func (s *Servers) Format(vpnProvider, format string) (formatted string, err error) {
switch format { switch format {

View File

@ -6,9 +6,7 @@ import (
"fmt" "fmt"
) )
var ( var ErrRequestSizeTooSmall = errors.New("message size is too small")
ErrRequestSizeTooSmall = errors.New("message size is too small")
)
func checkRequest(request []byte) (err error) { func checkRequest(request []byte) (err error) {
const minMessageSize = 2 // version number + operation code const minMessageSize = 2 // version number + operation code
@ -28,7 +26,8 @@ var (
) )
func checkResponse(response []byte, expectedOperationCode byte, func checkResponse(response []byte, expectedOperationCode byte,
expectedResponseSize uint) (err error) { expectedResponseSize uint,
) (err error) {
const minResponseSize = 4 const minResponseSize = 4
if len(response) < minResponseSize { if len(response) < minResponseSize {
return fmt.Errorf("%w: need at least %d bytes and got %d byte(s)", return fmt.Errorf("%w: need at least %d bytes and got %d byte(s)",

View File

@ -13,7 +13,8 @@ import (
// See https://www.ietf.org/rfc/rfc6886.html#section-3.2 // See https://www.ietf.org/rfc/rfc6886.html#section-3.2
func (c *Client) ExternalAddress(ctx context.Context, gateway netip.Addr) ( func (c *Client) ExternalAddress(ctx context.Context, gateway netip.Addr) (
durationSinceStartOfEpoch time.Duration, durationSinceStartOfEpoch time.Duration,
externalIPv4Address netip.Addr, err error) { externalIPv4Address netip.Addr, err error,
) {
request := []byte{0, 0} // version 0, operationCode 0 request := []byte{0, 0} // version 0, operationCode 0
const responseSize = 12 const responseSize = 12
response, err := c.rpc(ctx, gateway, request, responseSize) response, err := c.rpc(ctx, gateway, request, responseSize)

View File

@ -57,8 +57,7 @@ func Test_Client_ExternalAddress(t *testing.T) {
maxRetries: 1, maxRetries: 1,
} }
durationSinceStartOfEpoch, externalIPv4Address, err := durationSinceStartOfEpoch, externalIPv4Address, err := client.ExternalAddress(testCase.ctx, testCase.gateway)
client.ExternalAddress(testCase.ctx, testCase.gateway)
assert.ErrorIs(t, err, testCase.err) assert.ErrorIs(t, err, testCase.err)
if testCase.err != nil { if testCase.err != nil {
assert.EqualError(t, err, testCase.errMessage) assert.EqualError(t, err, testCase.errMessage)

View File

@ -27,7 +27,8 @@ type udpExchange struct {
// port is dynamically assigned by the OS so calling tests // port is dynamically assigned by the OS so calling tests
// can run in parallel. // can run in parallel.
func launchUDPServer(t *testing.T, exchanges []udpExchange) ( func launchUDPServer(t *testing.T, exchanges []udpExchange) (
remoteAddress *net.UDPAddr) { remoteAddress *net.UDPAddr,
) {
t.Helper() t.Helper()
conn, err := net.ListenUDP("udp", nil) conn, err := net.ListenUDP("udp", nil)

View File

@ -21,7 +21,8 @@ func (c *Client) AddPortMapping(ctx context.Context, gateway netip.Addr,
protocol string, internalPort, requestedExternalPort uint16, protocol string, internalPort, requestedExternalPort uint16,
lifetime time.Duration) (durationSinceStartOfEpoch time.Duration, lifetime time.Duration) (durationSinceStartOfEpoch time.Duration,
assignedInternalPort, assignedExternalPort uint16, assignedLifetime time.Duration, assignedInternalPort, assignedExternalPort uint16, assignedLifetime time.Duration,
err error) { err error,
) {
lifetimeSecondsFloat := lifetime.Seconds() lifetimeSecondsFloat := lifetime.Seconds()
const maxLifetimeSeconds = uint64(^uint32(0)) const maxLifetimeSeconds = uint64(^uint32(0))
if uint64(lifetimeSecondsFloat) > maxLifetimeSeconds { if uint64(lifetimeSecondsFloat) > maxLifetimeSeconds {

View File

@ -127,10 +127,9 @@ func Test_Client_AddPortMapping(t *testing.T) {
} }
durationSinceStartOfEpoch, assignedInternalPort, durationSinceStartOfEpoch, assignedInternalPort,
assignedExternalPort, assignedLifetime, err := assignedExternalPort, assignedLifetime, err := client.AddPortMapping(testCase.ctx, testCase.gateway,
client.AddPortMapping(testCase.ctx, testCase.gateway, testCase.protocol, testCase.internalPort,
testCase.protocol, testCase.internalPort, testCase.requestedExternalPort, testCase.lifetime)
testCase.requestedExternalPort, testCase.lifetime)
assert.Equal(t, testCase.durationSinceStartOfEpoch, durationSinceStartOfEpoch) assert.Equal(t, testCase.durationSinceStartOfEpoch, durationSinceStartOfEpoch)
assert.Equal(t, testCase.assignedInternalPort, assignedInternalPort) assert.Equal(t, testCase.assignedInternalPort, assignedInternalPort)

View File

@ -18,7 +18,8 @@ var (
func (c *Client) rpc(ctx context.Context, gateway netip.Addr, func (c *Client) rpc(ctx context.Context, gateway netip.Addr,
request []byte, responseSize uint) ( request []byte, responseSize uint) (
response []byte, err error) { response []byte, err error,
) {
if gateway.IsUnspecified() || !gateway.IsValid() { if gateway.IsUnspecified() || !gateway.IsValid() {
return nil, fmt.Errorf("%w", ErrGatewayIPUnspecified) return nil, fmt.Errorf("%w", ErrGatewayIPUnspecified)
} }

View File

@ -7,7 +7,8 @@ import (
) )
func (n *NetLink) AddrList(link Link, family int) ( func (n *NetLink) AddrList(link Link, family int) (
addresses []Addr, err error) { addresses []Addr, err error,
) {
netlinkLink := linkToNetlinkLink(&link) netlinkLink := linkToNetlinkLink(&link)
netlinkAddresses, err := netlink.AddrList(netlinkLink, family) netlinkAddresses, err := netlink.AddrList(netlinkLink, family)
if err != nil { if err != nil {

View File

@ -3,7 +3,8 @@
package netlink package netlink
func (n *NetLink) AddrList(link Link, family int) ( func (n *NetLink) AddrList(link Link, family int) (
addresses []Addr, err error) { addresses []Addr, err error,
) {
panic("not implemented") panic("not implemented")
} }

View File

@ -3,7 +3,8 @@
package netlink package netlink
func (n *NetLink) RouteList(family int) ( func (n *NetLink) RouteList(family int) (
routes []Route, err error) { routes []Route, err error,
) {
panic("not implemented") panic("not implemented")
} }

View File

@ -23,7 +23,7 @@ func writeIfDifferent(path, content string, puid, pgid int) (err error) {
return fmt.Errorf("obtaining file information: %w", err) return fmt.Errorf("obtaining file information: %w", err)
} }
const perm = os.FileMode(0400) const perm = os.FileMode(0o400)
var writeData, setChown bool var writeData, setChown bool
if os.IsNotExist(err) { if os.IsNotExist(err) {
writeData = true writeData = true

View File

@ -6,7 +6,7 @@ import (
) )
func (c *Configurator) WriteConfig(lines []string) error { func (c *Configurator) WriteConfig(lines []string) error {
const permission = 0644 const permission = 0o644
file, err := os.OpenFile(c.configPath, os.O_CREATE|os.O_TRUNC|os.O_WRONLY, permission) file, err := os.OpenFile(c.configPath, os.O_CREATE|os.O_TRUNC|os.O_WRONLY, permission)
if err != nil { if err != nil {
return err return err

View File

@ -14,7 +14,8 @@ var (
// Data extracts the lines and connection from the OpenVPN configuration file. // Data extracts the lines and connection from the OpenVPN configuration file.
func (e *Extractor) Data(filepath string) (lines []string, func (e *Extractor) Data(filepath string) (lines []string,
connection models.Connection, err error) { connection models.Connection, err error,
) {
lines, err = readCustomConfigLines(filepath) lines, err = readCustomConfigLines(filepath)
if err != nil { if err != nil {
return nil, connection, fmt.Errorf("reading configuration file: %w", err) return nil, connection, fmt.Errorf("reading configuration file: %w", err)

View File

@ -11,12 +11,11 @@ import (
"github.com/qdm12/gluetun/internal/models" "github.com/qdm12/gluetun/internal/models"
) )
var ( var errRemoteLineNotFound = errors.New("remote line not found")
errRemoteLineNotFound = errors.New("remote line not found")
)
func extractDataFromLines(lines []string) ( func extractDataFromLines(lines []string) (
connection models.Connection, err error) { connection models.Connection, err error,
) {
for i, line := range lines { for i, line := range lines {
hashSymbolIndex := strings.Index(line, "#") hashSymbolIndex := strings.Index(line, "#")
if hashSymbolIndex >= 0 { if hashSymbolIndex >= 0 {
@ -54,7 +53,8 @@ func extractDataFromLines(lines []string) (
} }
func extractDataFromLine(line string) ( func extractDataFromLine(line string) (
ip netip.Addr, port uint16, protocol string, err error) { ip netip.Addr, port uint16, protocol string, err error,
) {
switch { switch {
case strings.HasPrefix(line, "proto "): case strings.HasPrefix(line, "proto "):
protocol, err = extractProto(line) protocol, err = extractProto(line)
@ -108,7 +108,8 @@ var (
) )
func extractRemote(line string) (ip netip.Addr, port uint16, func extractRemote(line string) (ip netip.Addr, port uint16,
protocol string, err error) { protocol string, err error,
) {
fields := strings.Fields(line) fields := strings.Fields(line)
n := len(fields) n := len(fields)
@ -146,9 +147,7 @@ func extractRemote(line string) (ip netip.Addr, port uint16,
return ip, port, protocol, nil return ip, port, protocol, nil
} }
var ( var errPostLineFieldsCount = errors.New("post line has not 2 fields as expected")
errPostLineFieldsCount = errors.New("post line has not 2 fields as expected")
)
func extractPort(line string) (port uint16, err error) { func extractPort(line string) (port uint16, err error) {
fields := strings.Fields(line) fields := strings.Fields(line)

View File

@ -7,9 +7,7 @@ import (
"fmt" "fmt"
) )
var ( var errPEMDecode = errors.New("cannot decode PEM encoded block")
errPEMDecode = errors.New("cannot decode PEM encoded block")
)
func PEM(b []byte) (encodedData string, err error) { func PEM(b []byte) (encodedData string, err error) {
pemBlock, _ := pem.Decode(b) pemBlock, _ := pem.Decode(b)

View File

@ -7,7 +7,8 @@ import (
) )
func readCustomConfigLines(filepath string) ( func readCustomConfigLines(filepath string) (
lines []string, err error) { lines []string, err error,
) {
file, err := os.Open(filepath) file, err := os.Open(filepath)
if err != nil { if err != nil {
return nil, err return nil, err

View File

@ -18,31 +18,38 @@ func Test_processLogLine(t *testing.T) {
"openvpn unknown": { "openvpn unknown": {
"message", "message",
"message", "message",
levelInfo}, levelInfo,
},
"openvpn note": { "openvpn note": {
"NOTE: message", "NOTE: message",
"message", "message",
levelInfo}, levelInfo,
},
"openvpn warning": { "openvpn warning": {
"WARNING: message", "WARNING: message",
"message", "message",
levelWarn}, levelWarn,
},
"openvpn options error": { "openvpn options error": {
"Options error: message", "Options error: message",
"message", "message",
levelError}, levelError,
},
"openvpn ignored message": { "openvpn ignored message": {
"NOTE: UID/GID downgrade will be delayed because of --client, --pull, or --up-delay", "NOTE: UID/GID downgrade will be delayed because of --client, --pull, or --up-delay",
"", "",
levelInfo}, levelInfo,
},
"openvpn success": { "openvpn success": {
"Initialization Sequence Completed", "Initialization Sequence Completed",
"Initialization Sequence Completed", "Initialization Sequence Completed",
levelInfo}, levelInfo,
},
"openvpn auth failed": { "openvpn auth failed": {
"AUTH: Received control message: AUTH_FAILED", "AUTH: Received control message: AUTH_FAILED",
"AUTH: Received control message: AUTH_FAILED\n\nYour credentials might be wrong 🤨\n\n", "AUTH: Received control message: AUTH_FAILED\n\nYour credentials might be wrong 🤨\n\n",
levelError}, levelError,
},
"TLS key negotiation error": { "TLS key negotiation error": {
s: "TLS Error: TLS key negotiation failed to occur within " + s: "TLS Error: TLS key negotiation failed to occur within " +
"60 seconds (check your network connectivity)", "60 seconds (check your network connectivity)",

View File

@ -14,7 +14,8 @@ type Configurator struct {
} }
func New(logger Infoer, cmder CmdRunStarter, func New(logger Infoer, cmder CmdRunStarter,
puid, pgid int) *Configurator { puid, pgid int,
) *Configurator {
return &Configurator{ return &Configurator{
logger: logger, logger: logger,
cmder: cmder, cmder: cmder,

View File

@ -7,15 +7,11 @@ import (
"fmt" "fmt"
) )
var ( // Algorithm identifiers are listed at
// Algorithm identifiers are listed at // https://www.ibm.com/docs/en/zos/2.3.0?topic=programming-object-identifiers
// https://www.ibm.com/docs/en/zos/2.3.0?topic=programming-object-identifiers var oidDESCBC = asn1.ObjectIdentifier{1, 3, 14, 3, 2, 7} //nolint:gochecknoglobals
oidDESCBC = asn1.ObjectIdentifier{1, 3, 14, 3, 2, 7} //nolint:gochecknoglobals
)
var ( var ErrEncryptionAlgorithmNotPBES2 = errors.New("encryption algorithm is not PBES2")
ErrEncryptionAlgorithmNotPBES2 = errors.New("encryption algorithm is not PBES2")
)
type encryptedPrivateKey struct { type encryptedPrivateKey struct {
EncryptionAlgorithm pkix.AlgorithmIdentifier EncryptionAlgorithm pkix.AlgorithmIdentifier
@ -28,7 +24,8 @@ type encryptedAlgorithmParams struct {
} }
func getEncryptionAlgorithmOid(der []byte) ( func getEncryptionAlgorithmOid(der []byte) (
encryptionSchemeAlgorithm asn1.ObjectIdentifier, err error) { encryptionSchemeAlgorithm asn1.ObjectIdentifier, err error,
) {
var encryptedPrivateKeyData encryptedPrivateKey var encryptedPrivateKeyData encryptedPrivateKey
_, err = asn1.Unmarshal(der, &encryptedPrivateKeyData) _, err = asn1.Unmarshal(der, &encryptedPrivateKeyData)
if err != nil { if err != nil {

View File

@ -8,9 +8,7 @@ import (
pkcs8lib "github.com/youmark/pkcs8" pkcs8lib "github.com/youmark/pkcs8"
) )
var ( var ErrUnsupportedKeyType = errors.New("unsupported key type")
ErrUnsupportedKeyType = errors.New("unsupported key type")
)
// UpgradeEncryptedKey eventually upgrades an encrypted key to a newer encryption // UpgradeEncryptedKey eventually upgrades an encrypted key to a newer encryption
// if its encryption is too weak for Openvpn/Openssl. // if its encryption is too weak for Openvpn/Openssl.

View File

@ -13,7 +13,8 @@ type Runner struct {
} }
func NewRunner(settings settings.OpenVPN, starter CmdStarter, func NewRunner(settings settings.OpenVPN, starter CmdStarter,
logger Logger) *Runner { logger Logger,
) *Runner {
return &Runner{ return &Runner{
starter: starter, starter: starter,
logger: logger, logger: logger,

View File

@ -18,7 +18,8 @@ const (
) )
func start(ctx context.Context, starter CmdStarter, version string, flags []string) ( func start(ctx context.Context, starter CmdStarter, version string, flags []string) (
stdoutLines, stderrLines <-chan string, waitError <-chan error, err error) { stdoutLines, stderrLines <-chan string, waitError <-chan error, err error,
) {
var bin string var bin string
switch version { switch version {
case openvpn.Openvpn25: case openvpn.Openvpn25:

View File

@ -7,7 +7,8 @@ import (
func streamLines(ctx context.Context, done chan<- struct{}, func streamLines(ctx context.Context, done chan<- struct{},
logger Logger, stdout, stderr <-chan string, logger Logger, stdout, stderr <-chan string,
tunnelReady chan<- struct{}) { tunnelReady chan<- struct{},
) {
defer close(done) defer close(done)
var line string var line string

View File

@ -34,7 +34,8 @@ type Loop struct {
func NewLoop(settings settings.PortForwarding, routing Routing, func NewLoop(settings settings.PortForwarding, routing Routing,
client *http.Client, portAllower PortAllower, client *http.Client, portAllower PortAllower,
logger Logger, uid, gid int) *Loop { logger Logger, uid, gid int,
) *Loop {
return &Loop{ return &Loop{
settings: Settings{ settings: Settings{
VPNIsUp: ptrTo(false), VPNIsUp: ptrTo(false),
@ -75,7 +76,8 @@ func (l *Loop) Start(_ context.Context) (runError <-chan error, _ error) {
func (l *Loop) run(runCtx context.Context, runDone chan<- struct{}, func (l *Loop) run(runCtx context.Context, runDone chan<- struct{},
runErrorCh chan<- error, updateTrigger <-chan Settings, runErrorCh chan<- error, updateTrigger <-chan Settings,
updateResult chan<- error) { updateResult chan<- error,
) {
defer close(runDone) defer close(runDone)
var serviceRunError <-chan error var serviceRunError <-chan error

View File

@ -15,7 +15,7 @@ func (s *Service) writePortForwardedFile(ports []uint16) (err error) {
filepath := s.settings.Filepath filepath := s.settings.Filepath
s.logger.Info("writing port file " + filepath) s.logger.Info("writing port file " + filepath)
const perms = os.FileMode(0644) const perms = os.FileMode(0o644)
err = os.WriteFile(filepath, fileData, perms) err = os.WriteFile(filepath, fileData, perms)
if err != nil { if err != nil {
return fmt.Errorf("writing file: %w", err) return fmt.Errorf("writing file: %w", err)

View File

@ -26,7 +26,8 @@ type Service struct {
} }
func New(settings Settings, routing Routing, client *http.Client, func New(settings Settings, routing Routing, client *http.Client,
portAllower PortAllower, logger Logger, puid, pgid int) *Service { portAllower PortAllower, logger Logger, puid, pgid int,
) *Service {
return &Service{ return &Service{
// Fixed parameters // Fixed parameters
settings: settings, settings: settings,

View File

@ -82,7 +82,8 @@ func (s *Service) Start(ctx context.Context) (runError <-chan error, err error)
readyCh := make(chan struct{}) readyCh := make(chan struct{})
go func(ctx context.Context, portForwarder PortForwarder, go func(ctx context.Context, portForwarder PortForwarder,
obj utils.PortForwardObjects, readyCh chan<- struct{}, obj utils.PortForwardObjects, readyCh chan<- struct{},
runError chan<- error, doneCh chan<- struct{}) { runError chan<- error, doneCh chan<- struct{},
) {
defer close(doneCh) defer close(doneCh)
close(readyCh) close(readyCh)
err = portForwarder.KeepPortForward(ctx, obj) err = portForwarder.KeepPortForward(ctx, obj)

View File

@ -18,7 +18,8 @@ type Settings struct {
// and returns them if they are valid, or returns an error otherwise. // and returns them if they are valid, or returns an error otherwise.
// In all cases, the receiving settings are unmodified. // In all cases, the receiving settings are unmodified.
func (s Settings) updateWith(partialUpdate Settings, func (s Settings) updateWith(partialUpdate Settings,
forStartup bool) (updated Settings, err error) { forStartup bool,
) (updated Settings, err error) {
updated = s.copy() updated = s.copy()
updated.overrideWith(partialUpdate) updated.overrideWith(partialUpdate)
err = updated.validate(forStartup) err = updated.validate(forStartup)

View File

@ -7,7 +7,8 @@ import (
) )
func (p *Provider) GetConnection(selection settings.ServerSelection, ipv6Supported bool) ( func (p *Provider) GetConnection(selection settings.ServerSelection, ipv6Supported bool) (
connection models.Connection, err error) { connection models.Connection, err error,
) {
defaults := utils.NewConnectionDefaults(443, 1194, 1637) //nolint:mnd defaults := utils.NewConnectionDefaults(443, 1194, 1637) //nolint:mnd
return utils.GetConnection(p.Name(), return utils.GetConnection(p.Name(),
p.storage, selection, defaults, ipv6Supported, p.randSource) p.storage, selection, defaults, ipv6Supported, p.randSource)

View File

@ -10,7 +10,8 @@ import (
) )
func (p *Provider) OpenVPNConfig(connection models.Connection, func (p *Provider) OpenVPNConfig(connection models.Connection,
settings settings.OpenVPN, ipv6Supported bool) (lines []string) { settings settings.OpenVPN, ipv6Supported bool,
) (lines []string) {
const defaultMTU = 1320 // see https://github.com/qdm12/gluetun/issues/1650#issuecomment-1988298206 const defaultMTU = 1320 // see https://github.com/qdm12/gluetun/issues/1650#issuecomment-1988298206
const defaultMSSFix = defaultMTU - 28 // 28 bytes of IPv4 UDP header size const defaultMSSFix = defaultMTU - 28 // 28 bytes of IPv4 UDP header size
providerSettings := utils.OpenVPNProviderSettings{ providerSettings := utils.OpenVPNProviderSettings{
@ -31,7 +32,8 @@ func (p *Provider) OpenVPNConfig(connection models.Connection,
providerSettings.Ciphers = []string{ providerSettings.Ciphers = []string{
openvpn.AES256gcm, openvpn.AES256cbc, openvpn.AES192gcm, openvpn.AES256gcm, openvpn.AES256cbc, openvpn.AES192gcm,
openvpn.AES192cbc, openvpn.AES128gcm, openvpn.AES128cbc, openvpn.AES192cbc, openvpn.AES128gcm, openvpn.AES128cbc,
openvpn.Chacha20Poly1305} openvpn.Chacha20Poly1305,
}
default: default:
panic(fmt.Sprintf("openvpn version %q is not implemented", settings.Version)) panic(fmt.Sprintf("openvpn version %q is not implemented", settings.Version))
} }

View File

@ -16,7 +16,8 @@ type Provider struct {
} }
func New(storage common.Storage, randSource rand.Source, func New(storage common.Storage, randSource rand.Source,
client *http.Client) *Provider { client *http.Client,
) *Provider {
return &Provider{ return &Provider{
storage: storage, storage: storage,
randSource: randSource, randSource: randSource,

View File

@ -32,7 +32,8 @@ type apiServer struct {
} }
func fetchAPI(ctx context.Context, client *http.Client) ( func fetchAPI(ctx context.Context, client *http.Client) (
data apiData, err error) { data apiData, err error,
) {
const url = "https://airvpn.org/api/status/" const url = "https://airvpn.org/api/status/"
request, err := http.NewRequestWithContext(ctx, http.MethodGet, url, nil) request, err := http.NewRequestWithContext(ctx, http.MethodGet, url, nil)

View File

@ -13,7 +13,8 @@ import (
) )
func (u *Updater) FetchServers(ctx context.Context, minServers int) ( func (u *Updater) FetchServers(ctx context.Context, minServers int) (
servers []models.Server, err error) { servers []models.Server, err error,
) {
data, err := fetchAPI(ctx, u.client) data, err := fetchAPI(ctx, u.client)
if err != nil { if err != nil {
return nil, fmt.Errorf("fetching API: %w", err) return nil, fmt.Errorf("fetching API: %w", err)

View File

@ -2,6 +2,4 @@ package common
import "errors" import "errors"
var ( var ErrPortForwardNotSupported = errors.New("port forwarding not supported")
ErrPortForwardNotSupported = errors.New("port forwarding not supported")
)

View File

@ -10,13 +10,12 @@ import (
"github.com/qdm12/gluetun/internal/models" "github.com/qdm12/gluetun/internal/models"
) )
var ( var ErrVPNTypeNotSupported = errors.New("VPN type not supported for custom provider")
ErrVPNTypeNotSupported = errors.New("VPN type not supported for custom provider")
)
// GetConnection gets the connection from the OpenVPN configuration file. // GetConnection gets the connection from the OpenVPN configuration file.
func (p *Provider) GetConnection(selection settings.ServerSelection, _ bool) ( func (p *Provider) GetConnection(selection settings.ServerSelection, _ bool) (
connection models.Connection, err error) { connection models.Connection, err error,
) {
switch selection.VPN { switch selection.VPN {
case vpn.OpenVPN: case vpn.OpenVPN:
return getOpenVPNConnection(p.extractor, selection) return getOpenVPNConnection(p.extractor, selection)
@ -29,7 +28,8 @@ func (p *Provider) GetConnection(selection settings.ServerSelection, _ bool) (
func getOpenVPNConnection(extractor Extractor, func getOpenVPNConnection(extractor Extractor,
selection settings.ServerSelection) ( selection settings.ServerSelection) (
connection models.Connection, err error) { connection models.Connection, err error,
) {
_, connection, err = extractor.Data(*selection.OpenVPN.ConfFile) _, connection, err = extractor.Data(*selection.OpenVPN.ConfFile)
if err != nil { if err != nil {
return connection, fmt.Errorf("extracting connection: %w", err) return connection, fmt.Errorf("extracting connection: %w", err)
@ -52,7 +52,8 @@ func getOpenVPNConnection(extractor Extractor,
} }
func getWireguardConnection(selection settings.ServerSelection) ( func getWireguardConnection(selection settings.ServerSelection) (
connection models.Connection) { connection models.Connection,
) {
connection = models.Connection{ connection = models.Connection{
Type: vpn.Wireguard, Type: vpn.Wireguard,
IP: selection.Wireguard.EndpointIP, IP: selection.Wireguard.EndpointIP,

View File

@ -15,7 +15,8 @@ import (
var ErrExtractData = errors.New("failed extracting information from custom configuration file") var ErrExtractData = errors.New("failed extracting information from custom configuration file")
func (p *Provider) OpenVPNConfig(connection models.Connection, func (p *Provider) OpenVPNConfig(connection models.Connection,
settings settings.OpenVPN, ipv6Supported bool) (lines []string) { settings settings.OpenVPN, ipv6Supported bool,
) (lines []string) {
lines, _, err := p.extractor.Data(*settings.ConfFile) lines, _, err := p.extractor.Data(*settings.ConfFile)
if err != nil { if err != nil {
// Configuration file is already validated in settings validation in // Configuration file is already validated in settings validation in
@ -30,7 +31,8 @@ func (p *Provider) OpenVPNConfig(connection models.Connection,
} }
func modifyConfig(lines []string, connection models.Connection, func modifyConfig(lines []string, connection models.Connection,
settings settings.OpenVPN, ipv6Supported bool) (modified []string) { settings settings.OpenVPN, ipv6Supported bool,
) (modified []string) {
// Remove some lines // Remove some lines
for _, line := range lines { for _, line := range lines {
switch { switch {

View File

@ -7,7 +7,8 @@ import (
) )
func (p *Provider) GetConnection(selection settings.ServerSelection, ipv6Supported bool) ( func (p *Provider) GetConnection(selection settings.ServerSelection, ipv6Supported bool) (
connection models.Connection, err error) { connection models.Connection, err error,
) {
defaults := utils.NewConnectionDefaults(443, 443, 0) //nolint:mnd defaults := utils.NewConnectionDefaults(443, 443, 0) //nolint:mnd
return utils.GetConnection(p.Name(), return utils.GetConnection(p.Name(),
p.storage, selection, defaults, ipv6Supported, p.randSource) p.storage, selection, defaults, ipv6Supported, p.randSource)

View File

@ -8,7 +8,8 @@ import (
) )
func (p *Provider) OpenVPNConfig(connection models.Connection, func (p *Provider) OpenVPNConfig(connection models.Connection,
settings settings.OpenVPN, ipv6Supported bool) (lines []string) { settings settings.OpenVPN, ipv6Supported bool,
) (lines []string) {
//nolint:mnd //nolint:mnd
providerSettings := utils.OpenVPNProviderSettings{ providerSettings := utils.OpenVPNProviderSettings{
RemoteCertTLS: true, RemoteCertTLS: true,

View File

@ -15,7 +15,8 @@ type Provider struct {
} }
func New(storage common.Storage, randSource rand.Source, func New(storage common.Storage, randSource rand.Source,
parallelResolver common.ParallelResolver) *Provider { parallelResolver common.ParallelResolver,
) *Provider {
return &Provider{ return &Provider{
storage: storage, storage: storage,
randSource: randSource, randSource: randSource,

View File

@ -10,7 +10,8 @@ import (
) )
func (u *Updater) FetchServers(ctx context.Context, minServers int) ( func (u *Updater) FetchServers(ctx context.Context, minServers int) (
servers []models.Server, err error) { servers []models.Server, err error,
) {
possibleServers := getPossibleServers() possibleServers := getPossibleServers()
possibleHosts := possibleServers.hostsSlice() possibleHosts := possibleServers.hostsSlice()

View File

@ -7,7 +7,8 @@ import (
) )
func (p *Provider) GetConnection(selection settings.ServerSelection, ipv6Supported bool) ( func (p *Provider) GetConnection(selection settings.ServerSelection, ipv6Supported bool) (
connection models.Connection, err error) { connection models.Connection, err error,
) {
// TODO: Set the default ports for each VPN protocol+network protocol // TODO: Set the default ports for each VPN protocol+network protocol
// combination. If one combination is not supported, set it to `0`. // combination. If one combination is not supported, set it to `0`.
defaults := utils.NewConnectionDefaults(443, 1194, 51820) //nolint:mnd defaults := utils.NewConnectionDefaults(443, 1194, 51820) //nolint:mnd

View File

@ -8,7 +8,8 @@ import (
) )
func (p *Provider) OpenVPNConfig(connection models.Connection, func (p *Provider) OpenVPNConfig(connection models.Connection,
settings settings.OpenVPN, ipv6Supported bool) (lines []string) { settings settings.OpenVPN, ipv6Supported bool,
) (lines []string) {
// TODO: Set the necessary fields in `providerSettings` to // TODO: Set the necessary fields in `providerSettings` to
// generate the right OpenVPN configuration file. // generate the right OpenVPN configuration file.
//nolint:mnd //nolint:mnd

View File

@ -18,7 +18,8 @@ type Provider struct {
// TODO: remove unneeded arguments once the updater is implemented. // TODO: remove unneeded arguments once the updater is implemented.
func New(storage common.Storage, randSource rand.Source, func New(storage common.Storage, randSource rand.Source,
updaterWarner common.Warner, client *http.Client, updaterWarner common.Warner, client *http.Client,
unzipper common.Unzipper, parallelResolver common.ParallelResolver) *Provider { unzipper common.Unzipper, parallelResolver common.ParallelResolver,
) *Provider {
return &Provider{ return &Provider{
storage: storage, storage: storage,
randSource: randSource, randSource: randSource,

View File

@ -8,9 +8,7 @@ import (
"net/http" "net/http"
) )
var ( var errHTTPStatusCodeNotOK = errors.New("HTTP status code not OK")
errHTTPStatusCodeNotOK = errors.New("HTTP status code not OK")
)
type apiData struct { type apiData struct {
Servers []apiServer `json:"servers"` Servers []apiServer `json:"servers"`
@ -26,7 +24,8 @@ type apiServer struct {
} }
func fetchAPI(ctx context.Context, client *http.Client) ( func fetchAPI(ctx context.Context, client *http.Client) (
data apiData, err error) { data apiData, err error,
) {
// TODO: adapt this URL and the structures above to match the real // TODO: adapt this URL and the structures above to match the real
// API models you have. // API models you have.
const url = "https://example.com/servers" const url = "https://example.com/servers"

View File

@ -11,7 +11,8 @@ import (
) )
func (u *Updater) FetchServers(ctx context.Context, minServers int) ( func (u *Updater) FetchServers(ctx context.Context, minServers int) (
servers []models.Server, err error) { servers []models.Server, err error,
) {
// FetchServers obtains information for each VPN server // FetchServers obtains information for each VPN server
// for the VPN service provider. // for the VPN service provider.
// //

View File

@ -15,7 +15,8 @@ type Updater struct {
} }
func New(warner common.Warner, unzipper common.Unzipper, func New(warner common.Warner, unzipper common.Unzipper,
client *http.Client, parallelResolver common.ParallelResolver) *Updater { client *http.Client, parallelResolver common.ParallelResolver,
) *Updater {
// TODO: remove arguments not used by the updater // TODO: remove arguments not used by the updater
return &Updater{ return &Updater{
client: client, client: client,

View File

@ -7,7 +7,8 @@ import (
) )
func (p *Provider) GetConnection(selection settings.ServerSelection, ipv6Supported bool) ( func (p *Provider) GetConnection(selection settings.ServerSelection, ipv6Supported bool) (
connection models.Connection, err error) { connection models.Connection, err error,
) {
defaults := utils.NewConnectionDefaults(0, 1195, 0) //nolint:mnd defaults := utils.NewConnectionDefaults(0, 1195, 0) //nolint:mnd
return utils.GetConnection(p.Name(), return utils.GetConnection(p.Name(),
p.storage, selection, defaults, ipv6Supported, p.randSource) p.storage, selection, defaults, ipv6Supported, p.randSource)

View File

@ -8,7 +8,8 @@ import (
) )
func (p *Provider) OpenVPNConfig(connection models.Connection, func (p *Provider) OpenVPNConfig(connection models.Connection,
settings settings.OpenVPN, ipv6Supported bool) (lines []string) { settings settings.OpenVPN, ipv6Supported bool,
) (lines []string) {
//nolint:mnd //nolint:mnd
providerSettings := utils.OpenVPNProviderSettings{ providerSettings := utils.OpenVPNProviderSettings{
RemoteCertTLS: true, RemoteCertTLS: true,

View File

@ -16,7 +16,8 @@ type Provider struct {
func New(storage common.Storage, randSource rand.Source, func New(storage common.Storage, randSource rand.Source,
unzipper common.Unzipper, updaterWarner common.Warner, unzipper common.Unzipper, updaterWarner common.Warner,
parallelResolver common.ParallelResolver) *Provider { parallelResolver common.ParallelResolver,
) *Provider {
return &Provider{ return &Provider{
storage: storage, storage: storage,
randSource: randSource, randSource: randSource,

View File

@ -11,7 +11,8 @@ import (
) )
func (u *Updater) FetchServers(ctx context.Context, minServers int) ( func (u *Updater) FetchServers(ctx context.Context, minServers int) (
servers []models.Server, err error) { servers []models.Server, err error,
) {
servers = hardcodedServers() servers = hardcodedServers()
hosts := make([]string, len(servers)) hosts := make([]string, len(servers))

View File

@ -11,7 +11,8 @@ type Updater struct {
} }
func New(unzipper common.Unzipper, warner common.Warner, func New(unzipper common.Unzipper, warner common.Warner,
parallelResolver common.ParallelResolver) *Updater { parallelResolver common.ParallelResolver,
) *Updater {
return &Updater{ return &Updater{
unzipper: unzipper, unzipper: unzipper,
parallelResolver: parallelResolver, parallelResolver: parallelResolver,

View File

@ -7,7 +7,8 @@ import (
) )
func (p *Provider) GetConnection(selection settings.ServerSelection, ipv6Supported bool) ( func (p *Provider) GetConnection(selection settings.ServerSelection, ipv6Supported bool) (
connection models.Connection, err error) { connection models.Connection, err error,
) {
defaults := utils.NewConnectionDefaults(4443, 4443, 51820) //nolint:mnd defaults := utils.NewConnectionDefaults(4443, 4443, 51820) //nolint:mnd
return utils.GetConnection(p.Name(), return utils.GetConnection(p.Name(),
p.storage, selection, defaults, ipv6Supported, p.randSource) p.storage, selection, defaults, ipv6Supported, p.randSource)

View File

@ -8,7 +8,8 @@ import (
) )
func (p *Provider) OpenVPNConfig(connection models.Connection, func (p *Provider) OpenVPNConfig(connection models.Connection,
settings settings.OpenVPN, ipv6Supported bool) (lines []string) { settings settings.OpenVPN, ipv6Supported bool,
) (lines []string) {
//nolint:mnd //nolint:mnd
providerSettings := utils.OpenVPNProviderSettings{ providerSettings := utils.OpenVPNProviderSettings{
AuthUserPass: true, AuthUserPass: true,

View File

@ -17,7 +17,8 @@ type Provider struct {
func New(storage common.Storage, randSource rand.Source, func New(storage common.Storage, randSource rand.Source,
client *http.Client, updaterWarner common.Warner, client *http.Client, updaterWarner common.Warner,
parallelResolver common.ParallelResolver) *Provider { parallelResolver common.ParallelResolver,
) *Provider {
return &Provider{ return &Provider{
storage: storage, storage: storage,
randSource: randSource, randSource: randSource,

Some files were not shown because too many files have changed in this diff Show More