diff --git a/main.go b/main.go index 2bf253b..42807db 100644 --- a/main.go +++ b/main.go @@ -509,6 +509,7 @@ var rpcQueryHost string var rpcQueryHostname string var rpcGetRoutes bool var rpcGetKeys bool +var rpcXml bool func rpcMain() { var cl rpc.LuxRpcClient @@ -550,10 +551,20 @@ func rpcMain() { fmt.Fprintf(os.Stderr, "RPC error %d: %s\n", rpcErr.ErrorCode, rpcErr.Message) os.Exit(1) } + if rpcXml { + xmlBytes, err := xml.Marshal(&rpcRes) + if err != nil { + fmt.Fprintf(os.Stderr, "failed to marshal rpc output: %v\n", err) + os.Exit(1) + } + + fmt.Println(string(xmlBytes)) + return + } // pretty print routes for _, route := range rpcRes.Routes { - fmt.Println(route) + fmt.Println(route.String()) } } @@ -574,6 +585,16 @@ func rpcMain() { fmt.Fprintf(os.Stderr, "RPC error %d: %s\n", rpcErr.ErrorCode, rpcErr.Message) os.Exit(1) } + if rpcXml { + xmlBytes, err := xml.Marshal(&rpcRes) + if err != nil { + fmt.Fprintf(os.Stderr, "failed to marshal rpc output: %v\n", err) + os.Exit(1) + } + + fmt.Println(string(xmlBytes)) + return + } // pretty print keys for _, node := range rpcRes.Keystore.Nodes { @@ -601,6 +622,16 @@ func rpcMain() { fmt.Fprintf(os.Stderr, "RPC error %d: %s\n", rpcErr.ErrorCode, rpcErr.Message) os.Exit(1) } + if rpcXml { + xmlBytes, err := xml.Marshal(&rpcRes) + if err != nil { + fmt.Fprintf(os.Stderr, "failed to marshal rpc output: %v\n", err) + os.Exit(1) + } + + fmt.Println(string(xmlBytes)) + return + } // deserialize keystore _, err = crypto.LuxKeyStoreFromRpc(rpcRes.Keystore, rpcNewHost) @@ -626,6 +657,16 @@ func rpcMain() { fmt.Fprintf(os.Stderr, "RPC error %d: %s\n", rpcErr.ErrorCode, rpcErr.Message) os.Exit(1) } + if rpcXml { + xmlBytes, err := xml.Marshal(&rpcRes) + if err != nil { + fmt.Fprintf(os.Stderr, "failed to marshal rpc output: %v\n", err) + os.Exit(1) + } + + fmt.Println(string(xmlBytes)) + return + } // deserialize keystore _, err = crypto.LuxKeyStoreFromRpc(rpcRes.Keystore, rpcNewHost) @@ -633,6 +674,58 @@ func rpcMain() { fmt.Fprintf(os.Stderr, "failed to save node keystore: %v\n", err) } } + + if rpcQueryHost != "" || rpcQueryHostname != "" { + var rpcReq rpc.LuxRpcRequest + if rpcQueryHost != "" { + rpcReq = rpc.LuxRpcRequest{ + RequestID: counter, + Controller: "node", + Command: "query", + Hosts: []rpc.LuxRpcHost{ + {HostID: rpcQueryHost}, + }, + } + } else { + rpcReq = rpc.LuxRpcRequest{ + RequestID: counter, + Controller: "node", + Command: "query", + Hosts: []rpc.LuxRpcHost{ + {Hostname: rpcQueryHostname}, + }, + } + } + + rpcRes, rpcErr, err := cl.Execute(rpcReq) + if err != nil { + fmt.Fprintf(os.Stderr, "failed to send request: %v\n", err) + os.Exit(1) + } + counter++ + + if rpcErr.ErrorCode != 0 { + // we got error + fmt.Fprintf(os.Stderr, "RPC error %d: %s\n", rpcErr.ErrorCode, rpcErr.Message) + os.Exit(1) + } + if rpcXml { + xmlBytes, err := xml.Marshal(&rpcRes) + if err != nil { + fmt.Fprintf(os.Stderr, "failed to marshal rpc output: %v\n", err) + os.Exit(1) + } + + fmt.Println(string(xmlBytes)) + return + } + + // print state + host := rpcRes.Hosts[0] + + fmt.Printf("host %s hostname %s\n", host.HostID, host.Hostname) + fmt.Printf("wan addr4 %s addr6 %s\n", host.State.WAN.Addr4, host.State.WAN.Addr6) + } } func main() { @@ -654,6 +747,7 @@ func main() { flag.StringVar(&rpcQueryHostname, "rpc-query-hostname", "", "RPC node querty host state by hostname") flag.BoolVar(&rpcGetRoutes, "rpc-get-routes", false, "RPC node list established routes") flag.BoolVar(&rpcGetKeys, "rpc-get-keys", false, "RPC node list keys") + flag.BoolVar(&rpcXml, "rpc-xml", false, "output RPC results in XML") flag.Parse() if rpcPath != "" { diff --git a/node/lux_node.go b/node/lux_node.go index e086f29..e3d5406 100644 --- a/node/lux_node.go +++ b/node/lux_node.go @@ -305,8 +305,10 @@ func (node *LuxNode) Handle(request rpc.LuxRpcRequest, rpcType rpc.LuxRpcType) ( }, rpc.LuxRpcError{}, true } else if request.Command == "query" { // now we get host states either by ID or hostname - node.stateLock.RLock() - defer node.stateLock.RUnlock() + + // FIXME: causes self locking + // node.stateLock.RLock() + // defer node.stateLock.RUnlock() foundHosts := make([]rpc.LuxRpcHost, 0) @@ -323,7 +325,7 @@ func (node *LuxNode) Handle(request rpc.LuxRpcRequest, rpcType rpc.LuxRpcType) ( var ok bool hostState, ok = node.state.hosts[hostId] if !ok { - return rpcRes, rpc.LuxRpcGenericError(err), false + return rpcRes, rpc.LUX_RPC_ERROR_HOST_NOT_FOUND, false } } else if queryHost.Hostname != "" { // find by hostname