diff --git a/.vscode/launch.json b/.vscode/launch.json new file mode 100644 index 00000000..686e1dfc --- /dev/null +++ b/.vscode/launch.json @@ -0,0 +1,38 @@ +{ + // Use IntelliSense to learn about possible attributes. + // Hover to view descriptions of existing attributes. + // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 + "version": "0.2.0", + "configurations": [ + { + "name": "Debug Yggdrasil with Config (Root)", + "type": "go", + "request": "launch", + "mode": "auto", + "program": "${workspaceFolder}/cmd/yggdrasil", + "cwd": "${workspaceFolder}", + "env": {}, + "args": [ + "-useconffile", + "yggdrasil.json" + ], + "showLog": true, + "console": "integratedTerminal", + "internalConsoleOptions": "neverOpen", + "asRoot": true + }, + { + "name": "Debug Yggdrasilctl", + "type": "go", + "request": "launch", + "mode": "auto", + "program": "${workspaceFolder}/cmd/yggdrasilctl", + "cwd": "${workspaceFolder}", + "env": {}, + "args": [], + "showLog": true, + "console": "integratedTerminal", + "internalConsoleOptions": "neverOpen" + } + ] +} \ No newline at end of file diff --git a/cmd/yggdrasilctl/main.go b/cmd/yggdrasilctl/main.go index 51c25dcd..9fbd2626 100644 --- a/cmd/yggdrasilctl/main.go +++ b/cmd/yggdrasilctl/main.go @@ -208,11 +208,18 @@ func run() int { if peer.TXRate > 0 { txr = peer.TXRate.String() + "/s" } + + // Format IP address with name if available + ipDisplay := peer.IPAddress + if peer.Name != "" { + ipDisplay = fmt.Sprintf("%s (%s)", peer.Name, peer.IPAddress) + } + table.Append([]string{ uristring, state, dir, - peer.IPAddress, + ipDisplay, (time.Duration(peer.Uptime) * time.Second).String(), rtt, peer.RXBytes.String(), diff --git a/src/admin/getpeers.go b/src/admin/getpeers.go index 0384b792..8d3145c7 100644 --- a/src/admin/getpeers.go +++ b/src/admin/getpeers.go @@ -2,12 +2,16 @@ package admin import ( "encoding/hex" + "fmt" "net" "slices" "strings" "time" + "encoding/json" + "github.com/yggdrasil-network/yggdrasil-go/src/address" + "github.com/yggdrasil-network/yggdrasil-go/src/core" ) type GetPeersRequest struct { @@ -34,6 +38,7 @@ type PeerEntry struct { Latency time.Duration `json:"latency,omitempty"` LastErrorTime time.Duration `json:"last_error_time,omitempty"` LastError string `json:"last_error,omitempty"` + Name string `json:"name,omitempty"` } func (a *AdminSocket) getPeersHandler(_ *GetPeersRequest, res *GetPeersResponse) error { @@ -64,6 +69,25 @@ func (a *AdminSocket) getPeersHandler(_ *GetPeersRequest, res *GetPeersResponse) peer.LastError = p.LastError.Error() peer.LastErrorTime = time.Since(p.LastErrorTime) } + + // Get nodeinfo from peer to extract name + if p.Up && len(p.Key) > 0 { + if nodeInfo, err := a.CallHandler("getNodeInfo", []byte(fmt.Sprintf(`{"key":"%s"}`, hex.EncodeToString(p.Key[:])))); err == nil { + if nodeInfoMap, ok := nodeInfo.(core.GetNodeInfoResponse); ok { + for _, nodeInfoData := range nodeInfoMap { + var nodeInfoObj map[string]interface{} + if json.Unmarshal(nodeInfoData, &nodeInfoObj) == nil { + if name, exists := nodeInfoObj["name"]; exists { + if nameStr, ok := name.(string); ok { + peer.Name = nameStr + } + } + } + } + } + } + } + res.Peers = append(res.Peers, peer) } slices.SortStableFunc(res.Peers, func(a, b PeerEntry) int { diff --git a/src/webui/static/app.js b/src/webui/static/app.js index 6054a92b..e973b9fc 100644 --- a/src/webui/static/app.js +++ b/src/webui/static/app.js @@ -166,7 +166,9 @@ function createPeerElement(peer) { div.innerHTML = `