github.com/tickoalcantara12/micro/v3@v3.0.0-20221007104245-9d75b9bcbab9/util/addr/addr.go (about) 1 // Licensed under the Apache License, Version 2.0 (the "License"); 2 // you may not use this file except in compliance with the License. 3 // You may obtain a copy of the License at 4 // 5 // https://www.apache.org/licenses/LICENSE-2.0 6 // 7 // Unless required by applicable law or agreed to in writing, software 8 // distributed under the License is distributed on an "AS IS" BASIS, 9 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 10 // See the License for the specific language governing permissions and 11 // limitations under the License. 12 // 13 // Original source: github.com/micro/go-micro/v3/util/addr/addr.go 14 15 package addr 16 17 import ( 18 "fmt" 19 "net" 20 ) 21 22 var ( 23 privateBlocks []*net.IPNet 24 ) 25 26 func init() { 27 blocks := []string{ 28 "10.0.0.0/8", 29 "172.16.0.0/12", 30 "192.168.0.0/16", 31 "100.64.0.0/10", 32 "fd00::/8", 33 } 34 AppendPrivateBlocks(blocks...) 35 } 36 37 // AppendPrivateBlocks append private network blocks 38 func AppendPrivateBlocks(bs ...string) { 39 for _, b := range bs { 40 if _, block, err := net.ParseCIDR(b); err == nil { 41 privateBlocks = append(privateBlocks, block) 42 } 43 } 44 } 45 46 func isPrivateIP(ipAddr string) bool { 47 ip := net.ParseIP(ipAddr) 48 if ip == nil { 49 return false 50 } 51 52 for _, blocks := range privateBlocks { 53 if blocks.Contains(ip) { 54 return true 55 } 56 } 57 return false 58 } 59 60 func addrToIP(addr net.Addr) net.IP { 61 switch v := addr.(type) { 62 case *net.IPAddr: 63 return v.IP 64 case *net.IPNet: 65 return v.IP 66 default: 67 return nil 68 } 69 } 70 71 func localIPs() []string { 72 ifaces, err := net.Interfaces() 73 if err != nil { 74 return nil 75 } 76 77 var ipAddrs []string 78 79 for _, iface := range ifaces { 80 addrs, err := iface.Addrs() 81 if err != nil { 82 continue // ignore error 83 } 84 85 for _, addr := range addrs { 86 if ip := addrToIP(addr); ip != nil { 87 ipAddrs = append(ipAddrs, ip.String()) 88 } 89 } 90 } 91 92 return ipAddrs 93 } 94 95 // IsLocal tells us whether an ip is local 96 func IsLocal(addr string) bool { 97 // extract the host 98 host, _, err := net.SplitHostPort(addr) 99 if err == nil { 100 addr = host 101 } 102 103 // check if its localhost 104 if addr == "localhost" { 105 return true 106 } 107 108 // check against all local ips 109 for _, ip := range localIPs() { 110 if addr == ip { 111 return true 112 } 113 } 114 115 return false 116 } 117 118 // Extract returns a real ip 119 func Extract(addr string) (string, error) { 120 // if addr specified then its returned 121 if len(addr) > 0 { 122 if addr != "0.0.0.0" && addr != "[::]" && addr != "::" { 123 return addr, nil 124 } 125 } 126 127 var privateAddrs []string 128 var publicAddrs []string 129 var loopbackAddrs []string 130 131 for _, ipAddr := range localIPs() { 132 ip := net.ParseIP(ipAddr) 133 if ip == nil { 134 continue 135 } 136 137 if ip.IsUnspecified() { 138 continue 139 } 140 141 if ip.IsLoopback() { 142 loopbackAddrs = append(loopbackAddrs, ipAddr) 143 } else if isPrivateIP(ipAddr) { 144 privateAddrs = append(privateAddrs, ipAddr) 145 } else { 146 publicAddrs = append(publicAddrs, ipAddr) 147 } 148 } 149 150 if len(privateAddrs) > 0 { 151 return privateAddrs[0], nil 152 } else if len(publicAddrs) > 0 { 153 return publicAddrs[0], nil 154 } else if len(loopbackAddrs) > 0 { 155 return loopbackAddrs[0], nil 156 } 157 158 return "", fmt.Errorf("No IP address found, and explicit IP not provided") 159 } 160 161 // IPs returns all known ips 162 func IPs() []string { 163 return localIPs() 164 }