Skip to content

Commit

Permalink
Update NordWhisper disabled handling:
Browse files Browse the repository at this point in the history
  • Loading branch information
bartoszWojciechO committed Dec 18, 2024
1 parent d8ee054 commit 7eca2ec
Show file tree
Hide file tree
Showing 9 changed files with 90 additions and 34 deletions.
2 changes: 2 additions & 0 deletions cli/cli_connect.go
Original file line number Diff line number Diff line change
Expand Up @@ -141,6 +141,8 @@ func (c *cmd) Connect(ctx *cli.Context) error {
rpcErr = errors.New(internal.ServerUnavailableErrorMessage)
case internal.CodeDoubleGroupError:
rpcErr = errors.New(internal.DoubleGroupErrorMessage)
case internal.CodeTechnologyDisabled:
rpcErr = errors.New(TechnologyDisabledMessage)
case internal.CodeVPNRunning:
color.Yellow(client.ConnectConnected)
case internal.CodeNothingToDo:
Expand Down
1 change: 1 addition & 0 deletions cli/messages.go
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,7 @@ Example: nordvpn set %s on`
NoPreferredDedicatedIPLocationSelected = "It looks like you haven’t selected the preferred server location for your dedicated IP. Please head over to Nord Account and set up your dedicated IP server."
NoSuchCommand = "Command '%s' doesn't exist."
MsgListIsEmpty = "We couldn’t load the list of %s. Please try again later."
TechnologyDisabledMessage = "The technology you have configured is not available right now. Please switch to a different technology using nordvpn set technology command and try again."

// Meshnet
MsgSetMeshnetUsage = "Enables or disables Meshnet on this device."
Expand Down
25 changes: 8 additions & 17 deletions cmd/daemon/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,6 @@ import (
"github.com/NordSecurity/nordvpn-linux/events/meshunsetter"
"github.com/NordSecurity/nordvpn-linux/events/refresher"
"github.com/NordSecurity/nordvpn-linux/events/subs"
"github.com/NordSecurity/nordvpn-linux/features"
grpcmiddleware "github.com/NordSecurity/nordvpn-linux/grpc_middleware"
"github.com/NordSecurity/nordvpn-linux/internal"
"github.com/NordSecurity/nordvpn-linux/ipv6"
Expand Down Expand Up @@ -147,21 +146,6 @@ func main() {
}

rcConfig := getRemoteConfigGetter(fsystem)
nordWhisperEnabled, err := rcConfig.GetNordWhisperEnabled(Version)
if err != nil {
log.Println("failed to determine if NordWhisper is enabled:", err)
}

// fallback to Nordlynx if NordWhisper was enabled in previous installation and is disabled now
if (features.NordWhisperEnabled || !nordWhisperEnabled) && cfg.Technology == config.Technology_NORDWHISPER {
err := fsystem.SaveWith(func(c config.Config) config.Config {
c.Technology = config.Technology_NORDLYNX
return c
})
if err != nil {
log.Println(internal.ErrorPrefix, "failed to fallback to Nordlynx tech:", err)
}
}

// Events

Expand Down Expand Up @@ -209,6 +193,7 @@ func main() {
)

// API
var err error
var validator response.Validator
if !internal.IsProdEnv(Environment) && os.Getenv(EnvIgnoreHeaderValidation) == "1" {
validator = response.NoopValidator{}
Expand Down Expand Up @@ -323,7 +308,13 @@ func main() {

vpn, err := vpnFactory(cfg.Technology)
if err != nil {
log.Fatalln(err)
// if NordWhiser was disabled we'll fall back automatically to NordLynx if autoconnect is enabled or tell user
// to switch to a different tech
if !errors.Is(err, ErrNordWhisperDisabled) {
log.Fatalln(err)
} else {
log.Println(internal.ErrorPrefix, "failed to build NordWhisper VPN, it was disabled during compilation")
}
}

devices, err := device.ListPhysical()
Expand Down
18 changes: 13 additions & 5 deletions cmd/daemon/vpn_factory.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,23 +11,31 @@ import (
"github.com/NordSecurity/nordvpn-linux/internal"
)

var ErrNordWhisperDisabled = errors.New("NordWhisper technology was disabled in compile time")

func getVpnFactory(eventsDbPath string, fwmark uint32, envIsDev bool,
cfg vpn.LibConfigGetter, appVersion string, eventsPublisher *vpn.Events,
) daemon.FactoryFunc {
nordlynxVPN, err := getNordlynxVPN(envIsDev, eventsDbPath, fwmark, cfg, appVersion, eventsPublisher)
if err != nil {
nordlynxVPN, nordLynxErr := getNordlynxVPN(envIsDev, eventsDbPath, fwmark, cfg, appVersion, eventsPublisher)
if nordLynxErr != nil {
// don't exit with `err` here in case the factory will be called with
// technology different than `config.Technology_NORDLYNX`
log.Println(internal.ErrorPrefix, "getting NordLynx vpn:", err)
log.Println(internal.ErrorPrefix, "getting NordLynx vpn:", nordLynxErr)
}

nordWhisperVPN, nordWhisperErr := getNordWhisperVPN(fwmark)
if nordWhisperErr != nil {
log.Println(internal.ErrorPrefix, "getting NordWhisper vpn:", nordWhisperErr)
}

return func(tech config.Technology) (vpn.VPN, error) {
switch tech {
case config.Technology_NORDLYNX:
return nordlynxVPN, err
return nordlynxVPN, nordLynxErr
case config.Technology_OPENVPN:
return openvpn.New(fwmark, eventsPublisher), nil
case config.Technology_NORDWHISPER:
return getNordWhisperVPN(fwmark)
return nordWhisperVPN, nordWhisperErr
case config.Technology_UNKNOWN_TECHNOLOGY:
fallthrough
default:
Expand Down
19 changes: 17 additions & 2 deletions cmd/daemon/vpn_no_quench.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,26 @@
package main

import (
"fmt"
"context"

"github.com/NordSecurity/nordvpn-linux/daemon/vpn"
"github.com/NordSecurity/nordvpn-linux/tunnel"
)

func getNordWhisperVPN(fwmark uint32) (vpn.VPN, error) {
return nil, fmt.Errorf("NordWhisper is not enabled")
return noopNordWhisper{}, ErrNordWhisperDisabled
}

// noopMesh is a noop implementation of meshnet. It is used when telio
// is not available and should be used only for development purposes
type noopNordWhisper struct{}

func (noopNordWhisper) Start(context.Context, vpn.Credentials, vpn.ServerData) error { return nil }
func (noopNordWhisper) Stop() error { return nil }
func (noopNordWhisper) State() vpn.State { return "" }
func (noopNordWhisper) IsActive() bool { return false }
func (noopNordWhisper) Tun() tunnel.T { return &tunnel.Tunnel{} }
func (noopNordWhisper) NetworkChanged() error { return nil }
func (noopNordWhisper) GetConnectionParameters() (vpn.ServerData, bool) {
return vpn.ServerData{}, false
}
22 changes: 12 additions & 10 deletions config/remote/firebase.go
Original file line number Diff line number Diff line change
Expand Up @@ -72,19 +72,19 @@ func (rc *RConfig) fetchRemoteConfigIfTime() error {
remoteConfig := []byte(cfg.RemoteConfig)

// don't fetch the remote config too often even if there is nothing cached
if time.Now().After(cfg.RCLastUpdate.Add(rc.updatePeriod)) {
if fetchedConfig, err := rc.fetchAndSaveRemoteConfig(); err != nil {
// if there no is cached config return error
// otherwise use the cached data
if len(remoteConfig) == 0 {
return err
} else {
log.Println(internal.ErrorPrefix, "use cached config because fetch failed:", err)
}
// if time.Now().After(cfg.RCLastUpdate.Add(rc.updatePeriod)) {
if fetchedConfig, err := rc.fetchAndSaveRemoteConfig(); err != nil {
// if there no is cached config return error
// otherwise use the cached data
if len(remoteConfig) == 0 {
return err
} else {
remoteConfig = fetchedConfig
log.Println(internal.ErrorPrefix, "use cached config because fetch failed:", err)
}
} else {
remoteConfig = fetchedConfig
}
// }

if err := json.Unmarshal(remoteConfig, rc.config); err != nil {
return fmt.Errorf("parsing remote config from JSON: %w", err)
Expand Down Expand Up @@ -172,6 +172,8 @@ func (rc *RConfig) GetNordWhisperEnabled(stringVersion string) (bool, error) {
return false, fmt.Errorf("fetching the telio config: %w", err)
}

log.Println("DEBUG: ", enabledStr)

enabled, err := strconv.ParseBool(enabledStr)
if err != nil {
return false, fmt.Errorf("parsing firebase parameter: %w", err)
Expand Down
19 changes: 19 additions & 0 deletions daemon/jobs.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import (
"github.com/NordSecurity/nordvpn-linux/daemon/pb"
"github.com/NordSecurity/nordvpn-linux/daemon/state"
"github.com/NordSecurity/nordvpn-linux/events"
"github.com/NordSecurity/nordvpn-linux/features"
"github.com/NordSecurity/nordvpn-linux/internal"
"github.com/NordSecurity/nordvpn-linux/meshnet"

Expand Down Expand Up @@ -233,6 +234,24 @@ func (r *RPC) StartAutoConnect(timeoutFn GetTimeoutFunc) error {
return err
}

if cfg.Technology == config.Technology_NORDWHISPER {
nordWhisperEnabled, err := r.remoteConfigGetter.GetNordWhisperEnabled(r.version)
if err != nil {
log.Println("failed to determine if NordWhisper is enabled:", err)
}

// fallback to Nordlynx if NordWhisper was enabled in previous installation and is disabled now
if features.NordWhisperEnabled || !nordWhisperEnabled {
err := r.cm.SaveWith(func(c config.Config) config.Config {
c.Technology = config.Technology_NORDLYNX
return c
})
if err != nil {
log.Println(internal.ErrorPrefix, "failed to fallback to Nordlynx tech:", err)
}
}
}

server := autoconnectServer{}
err = r.Connect(&pb.ConnectRequest{ServerTag: cfg.AutoConnectData.ServerTag}, &server)
if connectErrorCheck(err) && server.err == nil {
Expand Down
17 changes: 17 additions & 0 deletions daemon/rpc_connect.go
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,23 @@ func (r *RPC) connect(
if err := r.cm.Load(&cfg); err != nil {
log.Println(internal.ErrorPrefix, err)
}

if cfg.Technology == config.Technology_NORDWHISPER {
if !features.NordWhisperEnabled {
return srv.Send(&pb.Payload{Type: internal.CodeTechnologyDisabled})
}

nordWhisperEnabled, err := r.remoteConfigGetter.GetNordWhisperEnabled(r.version)
if err != nil {
log.Println(internal.ErrorPrefix, "failed to retrieve remote config for NordWhisper:", err)
return srv.Send(&pb.Payload{Type: internal.CodeTechnologyDisabled})
}

if !nordWhisperEnabled {
return srv.Send(&pb.Payload{Type: internal.CodeTechnologyDisabled})
}
}

cfg = r.nordWhisperConfigFallback(cfg)

insights := r.dm.GetInsightsData().Insights
Expand Down
1 change: 1 addition & 0 deletions internal/codes.go
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@ const (
CodePqAndMeshnetSimultaneously int64 = 3048
CodePqWithoutNordlynx int64 = 3049
CodeFeatureHidden int64 = 3050
CodeTechnologyDisabled int64 = 3051
)

type ErrorWithCode struct {
Expand Down

0 comments on commit 7eca2ec

Please sign in to comment.