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  }