diff --git a/ethr.go b/ethr.go index d1a9c21..2eb59d0 100644 --- a/ethr.go +++ b/ethr.go @@ -157,7 +157,12 @@ func main() { } if *ip != "" { - gLocalIP = *ip + ipToParse := *ip + // Strip brackets from IPv6 addresses if present (e.g., "[2001:db8::1]") + if strings.HasPrefix(ipToParse, "[") && strings.HasSuffix(ipToParse, "]") { + ipToParse = ipToParse[1 : len(ipToParse)-1] + } + gLocalIP = ipToParse ipAddr := net.ParseIP(gLocalIP) if ipAddr == nil { printUsageError(fmt.Sprintf("Invalid IP address: <%s> specified.", *ip)) diff --git a/server.go b/server.go index 116886d..75aac28 100644 --- a/server.go +++ b/server.go @@ -204,7 +204,7 @@ func trySyncStartWithClient(test *ethrTest, conn net.Conn) (isControl bool, err } func srvrRunTCPServer() error { - l, err := net.Listen(Tcp(), gLocalIP+":"+gEthrPortStr) + l, err := net.Listen(Tcp(), formatListenAddress(gLocalIP, gEthrPortStr)) if err != nil { return err } @@ -378,7 +378,7 @@ func srvrRunTCPLatencyTest(test *ethrTest, clientParam EthrClientParam, conn net } func srvrRunUDPServer() error { - udpAddr, err := net.ResolveUDPAddr(Udp(), gLocalIP+":"+gEthrPortStr) + udpAddr, err := net.ResolveUDPAddr(Udp(), formatListenAddress(gLocalIP, gEthrPortStr)) if err != nil { ui.printDbg("Unable to resolve UDP address: %v", err) return err diff --git a/utils.go b/utils.go index 89c0c41..f93cb29 100644 --- a/utils.go +++ b/utils.go @@ -35,6 +35,30 @@ const ( // gPrecision controls decimal places for rate display (1 or 2) var gPrecision int = 1 +// formatListenAddress formats a local IP and port into a proper listen address. +// For IPv4, it returns "ip:port". +// For IPv6, it returns "[ip]:port". +// Empty IP returns ":port" (listen on all interfaces). +func formatListenAddress(ip string, port string) string { + if ip == "" { + return ":" + port + } + + parsedIP := net.ParseIP(ip) + if parsedIP == nil { + // Not a valid IP, return as-is + return ip + ":" + port + } + + if parsedIP.To4() == nil { + // IPv6 address - wrap in brackets + return "[" + ip + "]:" + port + } + + // IPv4 address + return ip + ":" + port +} + func numberToUnit(num uint64) string { unit := "" value := float64(num)