implement node rpc host query

This commit is contained in:
mykola2312 2025-01-24 19:08:07 +02:00
parent 097dfb5f84
commit 510bfb0e27
4 changed files with 100 additions and 10 deletions

View file

@ -1,6 +1,10 @@
package host
import "lux/proto"
import (
"encoding/base64"
"lux/proto"
"lux/rpc"
)
type LuxState struct {
Hostname string
@ -48,3 +52,33 @@ func (state *LuxState) Write(wd *proto.LuxBuffer) {
WriteLuxOption(wd, opt)
}
}
// RPC
func (state *LuxState) IntoRpc() rpc.LuxRpcState {
rpcState := rpc.LuxRpcState{
Options: make([]rpc.LuxRpcOption, 0),
}
for optType, opt := range state.Options {
switch optType {
case LuxOptionTypeWAN:
wan := opt.(*LuxOptionWAN)
rpcState.WAN = rpc.LuxRpcWAN{
Addr4: wan.Addr4.String(),
Addr6: wan.Addr4.String(),
}
default:
// encode option in base64 blob
wd := proto.NewLuxBuffer()
opt.Write(&wd)
rpcState.Options = append(rpcState.Options, rpc.LuxRpcOption{
Type: int(optType),
Blob: base64.StdEncoding.EncodeToString(wd.AllBytes()),
})
}
}
return rpcState
}

View file

@ -260,12 +260,11 @@ func (node *LuxNode) Register(sv *rpc.LuxRpcServer) {
func (node *LuxNode) Handle(request rpc.LuxRpcRequest, rpcType rpc.LuxRpcType) (rpc.LuxRpcResponse, rpc.LuxRpcError, bool) {
var rpcRes rpc.LuxRpcResponse
// only root can add hosts or neighbors
if rpcType != rpc.LuxRpcTypeRoot {
return rpcRes, rpc.LUX_RPC_ERROR_ACCESS_DENIED, false
}
if request.Command == "new-host" {
if rpcType != rpc.LuxRpcTypeRoot {
return rpcRes, rpc.LUX_RPC_ERROR_ACCESS_DENIED, false
}
ks := node.router.GetKeyStore()
// generate host key, add it to our keystore
host, err := crypto.NewLuxKey(proto.LuxTypeHost)
@ -284,6 +283,10 @@ func (node *LuxNode) Handle(request rpc.LuxRpcRequest, rpcType rpc.LuxRpcType) (
Keystore: crypto.LuxKeyStoreIntoRpc(&ksHost),
}, rpc.LuxRpcError{}, true
} else if request.Command == "new-node" {
if rpcType != rpc.LuxRpcTypeRoot {
return rpcRes, rpc.LUX_RPC_ERROR_ACCESS_DENIED, false
}
// to bootstrap neighbor node, first on this node we generate
// and add new node key, then copy all keys with new key to neighbor's keystore
ks := node.router.GetKeyStore()
@ -300,6 +303,54 @@ func (node *LuxNode) Handle(request rpc.LuxRpcRequest, rpcType rpc.LuxRpcType) (
return rpc.LuxRpcResponse{
Keystore: crypto.LuxKeyStoreIntoRpc(ks),
}, 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()
foundHosts := make([]rpc.LuxRpcHost, 0)
for _, queryHost := range request.Hosts {
var hostState *LuxHostState
if queryHost.HostID != "" {
// find by id
hostId, err := proto.ParseLuxID(queryHost.HostID)
if err != nil {
return rpcRes, rpc.LuxRpcGenericError(err), false
}
var ok bool
hostState, ok = node.state.hosts[hostId]
if !ok {
return rpcRes, rpc.LuxRpcGenericError(err), false
}
} else if queryHost.Hostname != "" {
// find by hostname
found := false
for _, item := range node.state.hosts {
if item.State.Hostname == queryHost.Hostname {
hostState = item
found = true
break
}
}
if !found {
return rpcRes, rpc.LUX_RPC_ERROR_HOST_NOT_FOUND, false
}
}
// serialize host state into xml
foundHosts = append(foundHosts, rpc.LuxRpcHost{
HostID: hostState.HostId.String(),
Hostname: hostState.State.Hostname,
State: hostState.State.IntoRpc(),
})
}
return rpc.LuxRpcResponse{Hosts: foundHosts}, rpc.LuxRpcError{}, true
}
return rpcRes, rpc.LUX_RPC_ERROR_UNKNOWN_COMMAND, false

View file

@ -23,10 +23,10 @@ type LuxRpcState struct {
}
type LuxRpcHost struct {
XMLName xml.Name `xml:"host"`
HostID string `xml:"id,attr"`
Hostname string `xml:"hostname,attr"`
StateBlob string `xml:"state"`
XMLName xml.Name `xml:"host"`
HostID string `xml:"id,attr"`
Hostname string `xml:"hostname,attr"`
State LuxRpcState `xml:"state"`
}
type LuxRpcRequest struct {

View file

@ -23,6 +23,11 @@ var LUX_RPC_ERROR_GENERIC = LuxRpcError{
Message: "generic error",
}
var LUX_RPC_ERROR_HOST_NOT_FOUND = LuxRpcError{
ErrorCode: 5,
Message: "host not found",
}
func LuxRpcGenericError(err error) LuxRpcError {
return LuxRpcError{
ErrorCode: LUX_RPC_ERROR_GENERIC.ErrorCode,