diff options
| -rw-r--r-- | cli/main.go | 11 | ||||
| -rw-r--r-- | exports/exports.go | 4 | ||||
| -rw-r--r-- | src/fsm.go | 67 | ||||
| -rw-r--r-- | src/state.go | 28 | ||||
| -rw-r--r-- | wrappers/python/eduvpncommon/__init__.py | 2 | ||||
| -rw-r--r-- | wrappers/python/eduvpncommon/main.py | 8 |
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)) } @@ -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() |
