summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--cli/main.go11
-rw-r--r--exports/exports.go4
-rw-r--r--src/fsm.go67
-rw-r--r--src/state.go28
-rw-r--r--wrappers/python/eduvpncommon/__init__.py2
-rw-r--r--wrappers/python/eduvpncommon/main.py8
6 files changed, 97 insertions, 23 deletions
diff --git a/cli/main.go b/cli/main.go
index d0b2165..33fb7d7 100644
--- a/cli/main.go
+++ b/cli/main.go
@@ -12,8 +12,8 @@ import (
)
func openBrowser(urlString string) {
- log.Printf("OAuth: Initialized with AuthURL %s\n", urlString)
- log.Println("OAuth: Opening browser with xdg-open...")
+ fmt.Printf("OAuth: Initialized with AuthURL %s\n", urlString)
+ fmt.Println("OAuth: Opening browser with xdg-open...")
exec.Command("xdg-open", urlString).Start()
}
@@ -40,8 +40,10 @@ func getGraphviz(fsm *eduvpn.FSM, graph string) string {
graph += "bgcolor=\"red\"\n"
}
if (fsm.Current == name) {
+ graph += "style=\"bold\"\n"
graph += "color=\"blue\"\n"
} else {
+ graph += "style=\"\"\n"
graph += "color=\"\"\n"
}
graph += "label=" + name.String()
@@ -66,7 +68,6 @@ func generateGraph() string {
}
func main() {
- generateGraph()
fileGraph := flag.String("dumpgraph", "", "Dump the FSM to a graphviz fdp file")
urlArg := flag.String("url", "", "The url of the vpn")
flag.Parse()
@@ -95,7 +96,7 @@ func main() {
state := eduvpn.GetVPNState()
- state.Register("org.eduvpn.app.linux", "configs", logState)
+ state.Register("org.eduvpn.app.linux", "configs", logState, true)
config, configErr := state.Connect(urlString)
if configErr != nil {
@@ -103,7 +104,7 @@ func main() {
return
}
- log.Println(config)
+ fmt.Println(config)
return
}
diff --git a/exports/exports.go b/exports/exports.go
index 5a4d7b9..e34721e 100644
--- a/exports/exports.go
+++ b/exports/exports.go
@@ -32,10 +32,10 @@ func StateCallback(old_state string, new_state string, data string) {
}
//export Register
-func Register(name *C.char, config_directory *C.char, stateCallback C.PythonCB) *C.char {
+func Register(name *C.char, config_directory *C.char, stateCallback C.PythonCB, debug C.int) *C.char {
P_StateCallback = stateCallback
state := eduvpn.GetVPNState()
- registerErr := state.Register(C.GoString(name), C.GoString(config_directory), StateCallback)
+ registerErr := state.Register(C.GoString(name), C.GoString(config_directory), StateCallback, debug != 0)
return C.CString(ErrorToString(registerErr))
}
diff --git a/src/fsm.go b/src/fsm.go
index 9978fde..2b61cda 100644
--- a/src/fsm.go
+++ b/src/fsm.go
@@ -2,6 +2,7 @@ package eduvpn
import (
"errors"
+ "os"
)
type FSMStateID int8
@@ -152,18 +153,84 @@ func (eduvpn *VPNState) HasTransition(check FSMStateID) bool {
return ok && fsm != nil
}
+func (eduvpn *VPNState) InState(check FSMStateID) bool {
+ fsm := FindFSMState(check, eduvpn.FSM)
+
+ if fsm == nil {
+ return false
+ }
+
+ return fsm.Current == check
+}
+
+func (eduvpn *VPNState) writeGraph() {
+ graph := eduvpn.GenerateGraph()
+
+ f, err := os.Create("debug.graph")
+
+ if err != nil {
+ panic(err)
+ }
+
+ defer f.Close()
+
+ f.WriteString(graph)
+}
+
func (eduvpn *VPNState) GoTransition(newState FSMStateID, data string) bool {
fsm, ok := eduvpn.findTransition(newState)
if ok {
oldState := fsm.Current
fsm.Current = newState
+ if eduvpn.Debug {
+ eduvpn.writeGraph()
+ }
eduvpn.StateCallback(oldState.String(), newState.String(), data)
}
return ok
}
+func getGraphviz(fsm *FSM, graph string) string {
+ if fsm == nil {
+ return graph
+ }
+
+ for name, state := range fsm.States {
+ for _, transition := range state.Transition {
+ graph += "\n" + "cluster_" + name.String() + " -> cluster_" + transition.String()
+ }
+
+ graph += "\nsubgraph cluster_" + name.String() + "{\n"
+ if (state.Locked) {
+ graph += "style=\"dotted\"\n"
+ } else {
+ graph += "style=\"\"\n"
+ }
+ if (fsm.Current == name) {
+ graph += "color=\"blue\"\n"
+ graph += "fontcolor=\"blue\"\n"
+ } else {
+ graph += "color=\"\"\n"
+ graph += "fontcolor=\"\"\n"
+ }
+ graph += "label=" + name.String()
+ graph = getGraphviz(state.Sub, graph)
+ graph += "\n}"
+ }
+ return graph
+}
+
+func (eduvpn *VPNState) GenerateGraph() string {
+ graph := "digraph fsm {\n"
+ graph += "nodesep=2"
+ graph = getGraphviz(eduvpn.FSM, graph)
+ graph += "\n}"
+
+ return graph
+}
+
func (eduvpn *VPNState) InitializeFSM() {
// The states when a server is authenticated
serverAuthenticated := &FSMState{Sub: &FSM{States: FSMStates{
diff --git a/src/state.go b/src/state.go
index aa31513..ec927f9 100644
--- a/src/state.go
+++ b/src/state.go
@@ -19,29 +19,36 @@ type VPNState struct {
// The file we keep open for logging
LogFile *FileLogger `json:"-"`
+ // The fsm
FSM *FSM `json:"-"`
+
+ // Whether to enable debugging
+ Debug bool `json:"-"`
}
-func (state *VPNState) Register(name string, directory string, stateCallback func(string, string, string)) error {
- if state.FSM == nil {
- state.InitializeFSM()
- }
+func (state *VPNState) Register(name string, directory string, stateCallback func(string, string, string), debug bool) error {
+ state.InitializeFSM()
if !state.HasTransition(APP_REGISTERED) {
return errors.New("app already registered")
}
state.Name = name
state.ConfigDirectory = directory
state.StateCallback = stateCallback
+ state.Debug = debug
- // Initialize the logger
- // state.InitLog(LOG_WARNING)
+ LogLevel := LOG_WARNING
- // state.Log(LOG_INFO, "App registered")
+ if debug {
+ LogLevel = LOG_INFO
+ }
+
+ // Initialize the logger
+ state.InitLog(LogLevel)
// Try to load the previous configuration
if state.LoadConfig() != nil {
// This error can be safely ignored, as when the config does not load, the struct will not be filled
- // state.Log(LOG_INFO, "Previous configuration not found")
+ state.Log(LOG_INFO, "Previous configuration not found")
}
state.GoTransition(APP_REGISTERED, "HALLO")
return nil
@@ -54,9 +61,8 @@ func (state *VPNState) Deregister() error {
// Close the log file
state.CloseLog()
- // Re-initialize everything
- state = &VPNState{}
- state.GoTransition(APP_DEREGISTERED, "")
+ state.Server = &Server{}
+ state.InitializeFSM()
return nil
}
diff --git a/wrappers/python/eduvpncommon/__init__.py b/wrappers/python/eduvpncommon/__init__.py
index 4c1872f..056ce18 100644
--- a/wrappers/python/eduvpncommon/__init__.py
+++ b/wrappers/python/eduvpncommon/__init__.py
@@ -35,7 +35,7 @@ VPNStateChange = CFUNCTYPE(None, c_char_p, c_char_p, c_char_p)
# Exposed functions
lib.Connect.argtypes, lib.Connect.restype = [c_char_p], DataError
lib.Deregister.argtypes, lib.Deregister.restype = [], None
-lib.Register.argtypes, lib.Register.restype = [c_char_p, c_char_p, VPNStateChange], None
+lib.Register.argtypes, lib.Register.restype = [c_char_p, c_char_p, VPNStateChange, c_int], c_void_p
lib.GetOrganizationsList.argtypes, lib.GetOrganizationsList.restype = [], DataError
lib.GetServersList.argtypes, lib.GetServersList.restype = [], DataError
# We have to use c_void_p instead of c_char_p to free it properly
diff --git a/wrappers/python/eduvpncommon/main.py b/wrappers/python/eduvpncommon/main.py
index 16d7baa..e718718 100644
--- a/wrappers/python/eduvpncommon/main.py
+++ b/wrappers/python/eduvpncommon/main.py
@@ -12,10 +12,10 @@ class StateType(Enum):
# name: The name of the app to be registered
# url: The url of the server to connect to, FIXME: To be removed
# state_callback: The callback to trigger whenever a state is changed, FIXME: Remove whenever this wrapper has implemented callbacks using function decorations
-def Register(name, config_directory, state_callback):
+def Register(name, config_directory, state_callback, debug):
name_bytes = name.encode("utf-8")
dir_bytes = config_directory.encode("utf-8")
- ptr_err = lib.Register(name_bytes, dir_bytes, state_callback)
+ ptr_err = lib.Register(name_bytes, dir_bytes, state_callback, debug)
err_string = GetPtrString(ptr_err)
return err_string
@@ -57,8 +57,8 @@ class EduVPN(object):
def __del__(self):
Deregister()
- def register(self) -> bool:
- return Register(self.name, self.config_directory, callback_function) == ""
+ def register(self, debug=False) -> bool:
+ return Register(self.name, self.config_directory, callback_function, debug) == ""
def get_disco(self):
return GetDiscoServers()