package http import ( "fmt" "net" "strconv" "strings" "github.com/micro/go-micro/registry" "github.com/micro/go-micro/server" ) var ( privateBlocks []*net.IPNet ) func init() { for _, b := range []string{"10.0.0.0/8", "172.16.0.0/12", "192.168.0.0/16"} { if _, block, err := net.ParseCIDR(b); err == nil { privateBlocks = append(privateBlocks, block) } } } func extractAddress(addr string) (string, error) { if len(addr) > 0 && (addr != "0.0.0.0" && addr != "[::]") { return addr, nil } addrs, err := net.InterfaceAddrs() if err != nil { return "", fmt.Errorf("Failed to get interface addresses! Err: %v", err) } var ipAddr []byte for _, rawAddr := range addrs { var ip net.IP switch addr := rawAddr.(type) { case *net.IPAddr: ip = addr.IP case *net.IPNet: ip = addr.IP default: continue } if ip.To4() == nil { continue } if !isPrivateIP(ip.String()) { continue } ipAddr = ip break } if ipAddr == nil { return "", fmt.Errorf("No private IP address found, and explicit IP not provided") } return net.IP(ipAddr).String(), nil } func isPrivateIP(ipAddr string) bool { ip := net.ParseIP(ipAddr) for _, priv := range privateBlocks { if priv.Contains(ip) { return true } } return false } func serviceDef(opts server.Options) *registry.Service { var advt, host string var port int if len(opts.Advertise) > 0 { advt = opts.Advertise } else { advt = opts.Address } parts := strings.Split(advt, ":") if len(parts) > 1 { host = strings.Join(parts[:len(parts)-1], ":") port, _ = strconv.Atoi(parts[len(parts)-1]) } else { host = parts[0] } addr, err := extractAddress(host) if err != nil { addr = host } node := ®istry.Node{ Id: opts.Name + "-" + opts.Id, Address: addr, Port: port, Metadata: opts.Metadata, } node.Metadata["server"] = "http" return ®istry.Service{ Name: opts.Name, Version: opts.Version, Nodes: []*registry.Node{node}, } }