summaryrefslogtreecommitdiff
path: root/client
diff options
context:
space:
mode:
Diffstat (limited to 'client')
-rw-r--r--client/client.go93
-rw-r--r--client/fsm.go17
2 files changed, 73 insertions, 37 deletions
diff --git a/client/client.go b/client/client.go
index adc66d0..f0add42 100644
--- a/client/client.go
+++ b/client/client.go
@@ -162,6 +162,17 @@ func (c *Client) forwardTokens(srv server.Server) error {
return nil
}
+func (c *Client) goTransition(id fsm.StateID) error {
+ handled, err := c.FSM.GoTransition(id)
+ if err != nil {
+ return err
+ }
+ if !handled {
+ log.Logger.Debugf("transition not handled by the client: %s", GetStateName(id))
+ }
+ return nil
+}
+
// New creates a new client with the following parameters:
// - name: the name of the client
// - directory: the directory where the config files are stored. Absolute or relative
@@ -223,7 +234,10 @@ func (c *Client) Register() error {
if !c.FSM.InState(StateDeregistered) {
return errors.Errorf("fsm attempt to register while in '%v'", c.FSM.Current)
}
- c.FSM.GoTransition(StateNoServer)
+ err := c.goTransition(StateNoServer)
+ if err != nil {
+ return errors.WrapPrefix(err, "failed to register", 0)
+ }
return nil
}
@@ -340,9 +354,9 @@ func (c *Client) locationCallback(ck *cookie.Cookie) error {
if err != nil {
return err
}
- t := c.FSM.GoTransition(StateChosenLocation)
- if !t {
- log.Logger.Warningf("transition chosen location not completed")
+ err = c.goTransition(StateChosenLocation)
+ if err != nil {
+ return err
}
return nil
}
@@ -372,16 +386,16 @@ func (c *Client) callbacks(ck *cookie.Cookie, srv server.Server, forceauth bool)
}
}
- t := c.FSM.GoTransition(StateChosenServer)
- if !t {
- log.Logger.Warningf("transition not completed for chosen server")
+ err := c.goTransition(StateChosenServer)
+ if err != nil {
+ return err
}
// oauth
// TODO: This should be ck.Context()
// But needsrelogin needs a rewrite to support this properly
// first make sure we get the most up to date tokens from the client
- err := c.updateTokens(srv)
+ err = c.updateTokens(srv)
if err != nil {
log.Logger.Debugf("failed to get tokens from client: %v", err)
}
@@ -396,9 +410,9 @@ func (c *Client) callbacks(ck *cookie.Cookie, srv server.Server, forceauth bool)
return err
}
}
- t = c.FSM.GoTransition(StateAuthorized)
- if !t {
- log.Logger.Warningf("transition authorized not completed")
+ err = c.goTransition(StateAuthorized)
+ if err != nil {
+ return err
}
return nil
@@ -434,37 +448,34 @@ func (c *Client) profileCallback(ck *cookie.Cookie, srv server.Server) error {
return err
}
}
- t := c.FSM.GoTransition(StateChosenProfile)
- if !t {
- log.Logger.Warningf("transition chosen profile not completed")
+ err = c.goTransition(StateChosenProfile)
+ if err != nil {
+ return err
}
return nil
}
// AddServer adds a server with identifier and type
func (c *Client) AddServer(ck *cookie.Cookie, identifier string, _type srvtypes.Type, ni bool) (err error) {
+
// If we have failed to add the server, we remove it again
// We add the server because we can then obtain it in other callback functions
+ previousState := c.FSM.Current
defer func() {
if err != nil {
_ = c.RemoveServer(identifier, _type) //nolint:errcheck
}
- if !ni {
- c.FSM.GoTransition(StateNoServer)
+ // If we must run callbacks, go to the previous state if we're not in it
+ if !ni && !c.FSM.InState(previousState) {
+ c.FSM.GoTransition(previousState)
}
}()
if !ni {
- // Try to go to no server
- c.FSM.GoTransition(StateNoServer)
-
- // If the transition was not successful, log
- if !c.FSM.InState(StateNoServer) {
- return errors.Errorf("wrong state to add a server: %s", GetStateName(c.FSM.Current))
- }
- t := c.FSM.GoTransition(StateLoadingServer)
- if !t {
- log.Logger.Warningf("transition not completed for loading server")
+ // This only returns a boolean if it was handled
+ err = c.goTransition(StateLoadingServer)
+ if err != nil {
+ return err
}
}
@@ -533,9 +544,9 @@ func (c *Client) config(ck *cookie.Cookie, srv server.Server, pTCP bool, forceAu
return nil, err
}
- t := c.FSM.GoTransition(StateRequestConfig)
- if !t {
- log.Logger.Warningf("transition not completed for requesting config")
+ err = c.goTransition(StateRequestConfig)
+ if err != nil {
+ return nil, err
}
err = c.profileCallback(ck, srv)
@@ -577,12 +588,15 @@ func (c *Client) server(identifier string, _type srvtypes.Type) (srv server.Serv
// GetConfig gets a VPN configuration
func (c *Client) GetConfig(ck *cookie.Cookie, identifier string, _type srvtypes.Type, pTCP bool) (cfg *srvtypes.Configuration, err error) {
+ previousState := c.FSM.Current
defer func() {
if err == nil {
c.FSM.GoTransition(StateGotConfig)
} else {
- // go back if an error occurred
- c.FSM.GoTransition(StateNoServer)
+ if !c.FSM.InState(previousState) {
+ // go back to the previous state if an error occurred
+ c.FSM.GoTransition(previousState)
+ }
}
}()
if _type != srvtypes.TypeSecureInternet {
@@ -591,9 +605,9 @@ func (c *Client) GetConfig(ck *cookie.Cookie, identifier string, _type srvtypes.
return nil, err
}
}
- t := c.FSM.GoTransition(StateLoadingServer)
- if !t {
- log.Logger.Warningf("transition not completed for loading server")
+ err = c.goTransition(StateLoadingServer)
+ if err != nil {
+ return nil, err
}
srv, set, err := c.server(identifier, _type)
if err != nil {
@@ -862,3 +876,14 @@ func (c *Client) StartFailover(ck *cookie.Cookie, gateway string, mtu int, readR
return f.Start(ck.Context(), gateway, mtu)
}
+
+
+func (c *Client) SetState(state FSMStateID) error {
+ err := c.FSM.CheckTransition(state)
+ if err != nil {
+ return err
+ }
+ // TODO: Now we don't pass any data :/
+ c.FSM.GoTransition(state)
+ return nil
+}
diff --git a/client/fsm.go b/client/fsm.go
index 038e6cf..9c83b9b 100644
--- a/client/fsm.go
+++ b/client/fsm.go
@@ -98,12 +98,14 @@ func newFSM(
Transitions: []FSMTransition{
{To: StateChosenLocation, Description: "Location chosen"},
{To: StateNoServer, Description: "Go back or Error"},
+ {To: StateGotConfig, Description: "Go back or Error"},
},
},
StateChosenLocation: FSMState{
Transitions: []FSMTransition{
{To: StateChosenServer, Description: "Server has been chosen"},
{To: StateNoServer, Description: "Go back or Error"},
+ {To: StateGotConfig, Description: "Go back or Error"},
},
},
StateLoadingServer: FSMState{
@@ -114,45 +116,54 @@ func newFSM(
Description: "User chooses a Secure Internet server but no location is configured",
},
{To: StateNoServer, Description: "Go back or Error"},
+ {To: StateGotConfig, Description: "Go back or Error"},
},
},
StateChosenServer: FSMState{
Transitions: []FSMTransition{
{To: StateAuthorized, Description: "Found tokens in config"},
{To: StateOAuthStarted, Description: "No tokens found in config"},
+ {To: StateNoServer, Description: "Go back or Error"},
+ {To: StateGotConfig, Description: "Go back or Error"},
},
},
StateOAuthStarted: FSMState{
Transitions: []FSMTransition{
{To: StateAuthorized, Description: "User authorizes with browser"},
{To: StateNoServer, Description: "Go back or Error"},
+ {To: StateGotConfig, Description: "Go back or Error"},
},
},
StateAuthorized: FSMState{
Transitions: []FSMTransition{
{To: StateOAuthStarted, Description: "Re-authorize with OAuth"},
{To: StateRequestConfig, Description: "Client requests a config"},
- {To: StateNoServer, Description: "Client wants to go back to the main screen"},
+ {To: StateNoServer, Description: "Go back or Error"},
+ {To: StateGotConfig, Description: "Go back or Error"},
},
},
StateRequestConfig: FSMState{
Transitions: []FSMTransition{
{To: StateAskProfile, Description: "Multiple profiles found and no profile chosen"},
{To: StateChosenProfile, Description: "Only one profile or profile already chosen"},
- {To: StateNoServer, Description: "Cancel or Error"},
{To: StateOAuthStarted, Description: "Re-authorize"},
+ {To: StateNoServer, Description: "Go back or Error"},
+ {To: StateGotConfig, Description: "Go back or Error"},
},
},
StateAskProfile: FSMState{
Transitions: []FSMTransition{
{To: StateNoServer, Description: "Cancel or Error"},
{To: StateChosenProfile, Description: "Profile has been chosen"},
+ {To: StateNoServer, Description: "Go back or Error"},
+ {To: StateGotConfig, Description: "Go back or Error"},
},
},
StateChosenProfile: FSMState{
Transitions: []FSMTransition{
- {To: StateNoServer, Description: "Cancel or Error"},
{To: StateGotConfig, Description: "Config has been obtained"},
+ {To: StateNoServer, Description: "Go back or Error"},
+ {To: StateGotConfig, Description: "Go back or Error"},
},
},
StateGotConfig: FSMState{