From 37bf5829324fb69dbd141d0436367600606557bd Mon Sep 17 00:00:00 2001 From: johnysigma Date: Wed, 6 Aug 2025 08:14:29 +0300 Subject: [PATCH] Fix bootstrap node detection to prevent self-join in RQLite The VPS at 57.129.81.31 was incorrectly trying to join itself as a regular node instead of being detected as a bootstrap node. Added isLocalIP() function to check if bootstrap peer IPs match local machine IPs using 'ip addr show' and 'hostname -I' commands. This should resolve the 'invalid join address' error where the bootstrap node was trying to join http://57.129.81.31:4001 (itself). --- cmd/node/main.go | 31 +++++++++++++++++++++++++++++-- 1 file changed, 29 insertions(+), 2 deletions(-) diff --git a/cmd/node/main.go b/cmd/node/main.go index 9cde66b..4429063 100644 --- a/cmd/node/main.go +++ b/cmd/node/main.go @@ -6,6 +6,7 @@ import ( "fmt" "log" "os" + "os/exec" "os/signal" "path/filepath" "strings" @@ -175,8 +176,12 @@ func isBootstrapNode() bool { return true // In development, assume we're running the bootstrap } - // Check if this is a production bootstrap server - // You could add more sophisticated host matching here + // Check if this is a production bootstrap server by IP + if host != "" && isLocalIP(host) { + return true + } + + // Check if this is a production bootstrap server by hostname if hostname != "" && strings.Contains(peerAddr, hostname) { return true } @@ -200,6 +205,28 @@ func parseHostFromMultiaddr(multiaddr string) string { return "" } +// isLocalIP checks if the given IP address belongs to this machine +func isLocalIP(ip string) bool { + // Try to run ip command to get local IPs + if output, err := exec.Command("ip", "addr", "show").Output(); err == nil { + if strings.Contains(string(output), ip) { + return true + } + } + + // Fallback: try hostname -I command + if output, err := exec.Command("hostname", "-I").Output(); err == nil { + ips := strings.Fields(strings.TrimSpace(string(output))) + for _, localIP := range ips { + if localIP == ip { + return true + } + } + } + + return false +} + func startNode(ctx context.Context, cfg *config.Config, port int, isBootstrap bool, logger *logging.StandardLogger) error { // Create and start node using the unified node implementation n, err := node.NewNode(cfg)