// LocalAddr helpers: resolve this node's routable LAN address used when a // forward targets a loopback (127.0.0.1/0.0.0.0/localhost) and is NOT marked // local-only — the task is distributed to the cluster, so the backend address // must be reachable from whichever node claims it. package cluster import ( "net" ) // LanAddr returns this host's first non-loopback IPv4 address ("" if none can // be determined, e.g. offline/no interface). func LanAddr() string { addrs, err := net.InterfaceAddrs() if err != nil { return "" } for _, a := range addrs { if ipn, ok := a.(*net.IPNet); ok { ip := ipn.IP if ip.IsLoopback() || ip.To4() == nil { continue } return ip.String() } } return "" } // IsLoopbackIP reports whether addr is a loopback/unspecified/localhost value // that must be rewritten to a routable address before cluster distribution. func IsLoopbackIP(addr string) bool { switch addr { case "", "127.0.0.1", "0.0.0.0", "::1", "::", "localhost": return true } return false } // RewriteForCluster returns addr if it is routable, or the LAN address when it // is loopback. Returns original when no LAN address is known (keeps ip as-is). func RewriteForCluster(addr string) string { if !IsLoopbackIP(addr) { return addr } if lan := LanAddr(); lan != "" { return lan } return addr }