gitee.com/h79/goutils@v1.22.10/common/system/net.go (about) 1 package system 2 3 import ( 4 "fmt" 5 "io" 6 "net" 7 "net/http" 8 "time" 9 ) 10 11 type GetPublicIPFunc func(url string) (net.IP, error) 12 type PingIPFunc func(ip string) error 13 14 var ( 15 xx = &IP{} 16 ) 17 18 const ( 19 KLocalHost = "127.0.0.1" 20 url = "https://myexternalip.com/raw" 21 ) 22 23 type IP struct { 24 resolveIp []net.IP 25 publicIp net.IP 26 currentResolveIp net.IP 27 publicIPFunc GetPublicIPFunc 28 pingIPFunc PingIPFunc 29 publicCount int 30 } 31 32 func IPX() *IP { 33 return xx 34 } 35 36 func NewIP() *IP { 37 return &IP{} 38 } 39 40 func (p *IP) SetPublicIPFunc(fn GetPublicIPFunc) { 41 p.publicIPFunc = fn 42 } 43 44 func (p *IP) SetPingIPFunc(fn PingIPFunc) { 45 p.pingIPFunc = fn 46 } 47 48 func (p *IP) SetPublicIP(ip net.IP) { 49 p.publicIp = ip 50 } 51 52 func (p *IP) ResetCurrentPublicIP() net.IP { 53 p.publicIp = nil 54 return p.GetCurrentPublicIP() 55 } 56 57 func (p *IP) GetCurrentPublicIP() net.IP { 58 if len(p.publicIp) > 0 { 59 return p.publicIp 60 } 61 if p.publicCount > 2 { //3次 62 return net.IP{} 63 } 64 p.publicCount++ 65 var fn = p.publicIPFunc 66 if fn == nil { 67 fn = GetPublicIPWithUrl 68 } 69 ip, err := fn(url) 70 if err == nil { 71 p.publicIp = ip 72 } 73 return ip 74 } 75 76 func (p *IP) PublicIPValid() bool { 77 ret := p.GetCurrentPublicIP() 78 return len(ret) > 0 79 } 80 81 // SelfExternalIP 自己外部IP,可能是局域网IP,公网IP 82 // lan 局域网优先 83 func (p *IP) SelfExternalIP(lan bool) string { 84 pip := p.GetCurrentPublicIP() 85 rip := p.GetCurrentResolveIP() 86 if lan && IsLanIP(rip) { 87 return rip.String() 88 } 89 if IsPublicIP(pip) { 90 return pip.String() 91 } 92 return rip.String() 93 } 94 95 func (p *IP) ResetCurrentResolveIP() net.IP { 96 p.currentResolveIp = nil 97 return p.GetCurrentResolveIP() 98 } 99 100 func (p *IP) GetAllResolveIP() []net.IP { 101 if len(p.resolveIp) > 0 { 102 return p.resolveIp 103 } 104 p.GetCurrentResolveIP() 105 return p.resolveIp 106 } 107 108 func (p *IP) GetCurrentResolveIP() net.IP { 109 if len(p.currentResolveIp) > 0 { 110 return p.currentResolveIp 111 } 112 ping := p.pingIPFunc 113 if ping == nil { 114 ping = DefaultPingFunc 115 } 116 ret := p.SelectResolveIP(ping) 117 if len(ret) > 0 { 118 p.currentResolveIp = ret 119 } 120 return ret 121 } 122 123 func (p *IP) SetCurrentResolveIP(ip net.IP) { 124 p.currentResolveIp = ip 125 } 126 127 func (p *IP) SelectResolveIP(pingFunc PingIPFunc) net.IP { 128 var err error 129 if len(p.resolveIp) == 0 { 130 ips, err := p.GetResolveIP() 131 if err != nil { 132 return nil 133 } 134 p.resolveIp = append([]net.IP{}, ips...) 135 } 136 if len(p.resolveIp) == 1 { 137 return p.resolveIp[0] 138 } 139 for i := range p.resolveIp { 140 err = pingFunc(p.resolveIp[i].String()) 141 if err == nil { 142 return p.resolveIp[i] 143 } 144 } 145 return nil 146 } 147 148 func (p *IP) GetResolveIP() ([]net.IP, error) { 149 var ips, err = GetResolveIPList(func(ip net.IP) bool { 150 t := GetIPType(ip) 151 return t == IptUnk || t == IptPub 152 }) 153 if err != nil { 154 return nil, err 155 } 156 if len(ips) > 0 { 157 return ips, nil 158 } 159 return nil, fmt.Errorf("not exist") 160 } 161 162 func GetPublicIP() (net.IP, error) { 163 return GetPublicIPWithUrl(url) 164 } 165 166 func GetResolveIP() (net.IP, error) { 167 adds, err := net.InterfaceAddrs() 168 if err != nil { 169 return net.IP{}, err 170 } 171 return parseAddress(adds), nil 172 } 173 174 func GetResolveIPV3(tt IPType, index int) (net.IP, error) { 175 var ips, err = GetResolveIPList(func(ip net.IP) bool { 176 t := GetIPType(ip) 177 return t != tt 178 }) 179 if err != nil { 180 return nil, err 181 } 182 if len(ips) > 0 { 183 if index <= 0 || len(ips) <= index { 184 return ips[0], nil 185 } 186 return ips[index], nil 187 } 188 return nil, fmt.Errorf("not exist") 189 } 190 191 func GetResolveIPList(filter func(ip net.IP) bool) ([]net.IP, error) { 192 var ips []net.IP 193 var ip, err = GetClientIP() 194 if err != nil { 195 return nil, err 196 } 197 for i := range ip { 198 if filter(ip[i]) { 199 continue 200 } 201 ips = append(ips, ip[i]) 202 } 203 return ips, nil 204 } 205 206 // IPIsSelf 是否是自己 207 func IPIsSelf(ip string) string { 208 pip := xx.GetCurrentPublicIP() 209 rip := xx.GetCurrentResolveIP() 210 if pip.String() == ip { 211 return KLocalHost 212 } 213 if rip.String() == ip { 214 return KLocalHost 215 } 216 return ip 217 } 218 219 // IsLanIP 是否局域网 192.168.x.x 220 func IsLanIP(IP net.IP) bool { 221 return GetIPType(IP) == IptPriC 222 } 223 224 func IsPublicIP(IP net.IP) bool { 225 return GetIPType(IP) == IptPub 226 } 227 228 func GetClientIP() ([]net.IP, error) { 229 var ips []net.IP 230 faces, err := net.Interfaces() 231 if err != nil { 232 return nil, err 233 } 234 for _, face := range faces { 235 if face.Flags&net.FlagUp == 0 { 236 continue 237 } 238 if face.Flags&net.FlagLoopback != 0 { 239 continue 240 } 241 adds, er := face.Addrs() 242 if er != nil { 243 return nil, er 244 } 245 ip := parseAddress(adds) 246 if len(ip) > 0 { 247 ips = append(ips, ip) 248 } 249 } 250 return ips, nil 251 } 252 253 func parseAddress(adds []net.Addr) net.IP { 254 for _, addr := range adds { 255 ip := parseResolveIP(addr) 256 if len(ip) > 0 { 257 return ip 258 } 259 } 260 return net.IP{} 261 } 262 263 func parseResolveIP(addr net.Addr) net.IP { 264 var ip net.IP 265 switch v := addr.(type) { 266 case *net.IPNet: 267 ip = v.IP 268 case *net.IPAddr: 269 ip = v.IP 270 } 271 if ip == nil || ip.IsLoopback() || ip.IsLinkLocalMulticast() || ip.IsLinkLocalUnicast() { 272 return nil 273 } 274 return ip.To4() 275 } 276 277 type IPType int8 278 279 const ( 280 IptUnk = IPType(0) 281 IptPub = IPType(1) 282 IptPriA = IPType(2) 283 IptPriB = IPType(3) 284 IptPriC = IPType(4) 285 ) 286 287 func GetIPType(ip net.IP) IPType { 288 if len(ip) == 0 { 289 return IptUnk 290 } 291 if ip.IsLoopback() || ip.IsLinkLocalMulticast() || ip.IsLinkLocalUnicast() { 292 return IptUnk 293 } 294 if ip4 := ip.To4(); ip4 != nil { 295 switch true { 296 case ip4[0] == 10: 297 return IptPriA 298 case ip4[0] == 172 && ip4[1]&0xf0 == 16: 299 return IptPriB 300 case ip4[0] == 192 && ip4[1] == 168: 301 return IptPriC 302 default: 303 return IptPub 304 } 305 } 306 if len(ip) == net.IPv6len && ip[0]&0xfe == 0xfc { 307 return IptPriC 308 } 309 return IptPub 310 } 311 312 /** 313 * 私有IP 314 A 类 10.0.0.0/8:10.0.0.0~10.255.255.255 315 B 类 172.16.0.0/12:172.16.0.0~172.31.255.255 316 C 192.168.0.0/16:192.168.0.0~192.168.255.255 317 */ 318 319 func DefaultPingFunc(ip string) error { 320 return nil 321 } 322 323 func GetPublicIPWithUrl(url string) (net.IP, error) { 324 client := http.Client{Timeout: time.Second * 5} 325 resp, err := client.Get(url) 326 if err != nil { 327 return net.IP{}, err 328 } 329 defer resp.Body.Close() 330 ip, err := io.ReadAll(resp.Body) 331 if err != nil { 332 return net.IP{}, err 333 } 334 return net.ParseIP(string(ip)), nil 335 } 336 337 func PortsUsed(ports []int) []bool { 338 var used = make([]bool, len(ports)) 339 for i := range ports { 340 used[i] = PortUsed(ports[i]) 341 } 342 return used 343 } 344 345 func PortUsed(port int) bool { 346 return PortUsedV2("", port) 347 } 348 349 func PortUsedV2(ip string, port int) bool { 350 var host = fmt.Sprintf("%s:%d", ip, port) 351 if conn, _ := net.DialTimeout("tcp", host, 3*time.Second); conn != nil { 352 _ = conn.Close() 353 return true 354 } 355 return false 356 } 357 358 func PingCheck(port int) PingIPFunc { 359 return func(ip string) error { 360 var host = fmt.Sprintf("%s:%d", ip, port) 361 var lis, err = net.Listen("tcp", host) 362 if err != nil { 363 return err 364 } 365 _ = lis.Close() 366 return nil 367 } 368 }