235 lines
		
	
	
		
			4.6 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
		
		
			
		
	
	
			235 lines
		
	
	
		
			4.6 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
| 
								 | 
							
								package utility
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								import (
							 | 
						||
| 
								 | 
							
									"errors"
							 | 
						||
| 
								 | 
							
									"net"
							 | 
						||
| 
								 | 
							
									"net/url"
							 | 
						||
| 
								 | 
							
									"sort"
							 | 
						||
| 
								 | 
							
									"strconv"
							 | 
						||
| 
								 | 
							
									"strings"
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									"github.com/gin-gonic/gin"
							 | 
						||
| 
								 | 
							
								)
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								func GetIp(ctx *gin.Context) string {
							 | 
						||
| 
								 | 
							
									ip := ctx.ClientIP()
							 | 
						||
| 
								 | 
							
									if len(ip) > 0 {
							 | 
						||
| 
								 | 
							
										return ip
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
									return ""
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								// ExternalIP get external ip. 获取外部的ip
							 | 
						||
| 
								 | 
							
								func ExternalIP() (res []string) {
							 | 
						||
| 
								 | 
							
									inters, err := net.Interfaces()
							 | 
						||
| 
								 | 
							
									if err != nil {
							 | 
						||
| 
								 | 
							
										return
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
									for _, inter := range inters {
							 | 
						||
| 
								 | 
							
										if !strings.HasPrefix(inter.Name, "lo") {
							 | 
						||
| 
								 | 
							
											addrs, err := inter.Addrs()
							 | 
						||
| 
								 | 
							
											if err != nil {
							 | 
						||
| 
								 | 
							
												continue
							 | 
						||
| 
								 | 
							
											}
							 | 
						||
| 
								 | 
							
											for _, addr := range addrs {
							 | 
						||
| 
								 | 
							
												if ipNet, ok := addr.(*net.IPNet); ok {
							 | 
						||
| 
								 | 
							
													if ipNet.IP.IsLoopback() || ipNet.IP.IsLinkLocalMulticast() || ipNet.IP.IsLinkLocalUnicast() {
							 | 
						||
| 
								 | 
							
														continue
							 | 
						||
| 
								 | 
							
													}
							 | 
						||
| 
								 | 
							
													if ip4 := ipNet.IP.To4(); ip4 != nil {
							 | 
						||
| 
								 | 
							
														switch true {
							 | 
						||
| 
								 | 
							
														case ip4[0] == 10:
							 | 
						||
| 
								 | 
							
															continue
							 | 
						||
| 
								 | 
							
														case ip4[0] == 172 && ip4[1] >= 16 && ip4[1] <= 31:
							 | 
						||
| 
								 | 
							
															continue
							 | 
						||
| 
								 | 
							
														case ip4[0] == 192 && ip4[1] == 168:
							 | 
						||
| 
								 | 
							
															continue
							 | 
						||
| 
								 | 
							
														default:
							 | 
						||
| 
								 | 
							
															res = append(res, ipNet.IP.String())
							 | 
						||
| 
								 | 
							
														}
							 | 
						||
| 
								 | 
							
													}
							 | 
						||
| 
								 | 
							
												}
							 | 
						||
| 
								 | 
							
											}
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
									return
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								// InternalIP get internal ip. 获取内部的ip
							 | 
						||
| 
								 | 
							
								func InternalIP() string {
							 | 
						||
| 
								 | 
							
									inters, err := net.Interfaces()
							 | 
						||
| 
								 | 
							
									if err != nil {
							 | 
						||
| 
								 | 
							
										return ""
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
									for _, inter := range inters {
							 | 
						||
| 
								 | 
							
										if inter.Flags&net.FlagUp == net.FlagUp {
							 | 
						||
| 
								 | 
							
											continue
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
										if !strings.HasPrefix(inter.Name, "lo") {
							 | 
						||
| 
								 | 
							
											addrs, err := inter.Addrs()
							 | 
						||
| 
								 | 
							
											if err != nil {
							 | 
						||
| 
								 | 
							
												continue
							 | 
						||
| 
								 | 
							
											}
							 | 
						||
| 
								 | 
							
											for _, addr := range addrs {
							 | 
						||
| 
								 | 
							
												if ipnet, ok := addr.(*net.IPNet); ok && !ipnet.IP.IsLoopback() {
							 | 
						||
| 
								 | 
							
													if ipnet.IP.To4() != nil {
							 | 
						||
| 
								 | 
							
														return ipnet.IP.String()
							 | 
						||
| 
								 | 
							
													}
							 | 
						||
| 
								 | 
							
												}
							 | 
						||
| 
								 | 
							
											}
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
									return ""
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								// GetFreePort gets a free port. 获得一个自由端口
							 | 
						||
| 
								 | 
							
								func GetFreePort() (port int, err error) {
							 | 
						||
| 
								 | 
							
									listener, err := net.Listen("tcp", "127.0.0.1:0")
							 | 
						||
| 
								 | 
							
									if err != nil {
							 | 
						||
| 
								 | 
							
										return 0, err
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
									defer listener.Close()
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									addr := listener.Addr().String()
							 | 
						||
| 
								 | 
							
									_, portString, err := net.SplitHostPort(addr)
							 | 
						||
| 
								 | 
							
									if err != nil {
							 | 
						||
| 
								 | 
							
										return 0, err
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									return strconv.Atoi(portString)
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								// ParseRpcAddress parses rpc address such as tcp@127.0.0.1:8972  quic@192.168.1.1:9981
							 | 
						||
| 
								 | 
							
								func ParseRpcAddress(addr string) (network string, ip string, port int, err error) {
							 | 
						||
| 
								 | 
							
									ati := strings.Index(addr, "@")
							 | 
						||
| 
								 | 
							
									if ati <= 0 {
							 | 
						||
| 
								 | 
							
										return "", "", 0, errors.New("invalid rpc address: " + addr)
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									network = addr[:ati]
							 | 
						||
| 
								 | 
							
									addr = addr[ati+1:]
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									var portStr string
							 | 
						||
| 
								 | 
							
									ip, portStr, err = net.SplitHostPort(addr)
							 | 
						||
| 
								 | 
							
									if err != nil {
							 | 
						||
| 
								 | 
							
										return "", "", 0, err
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									port, err = strconv.Atoi(portStr)
							 | 
						||
| 
								 | 
							
									return network, ip, port, err
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								func ConvertMeta2Map(meta string) map[string]string {
							 | 
						||
| 
								 | 
							
									var rt = make(map[string]string)
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									if meta == "" {
							 | 
						||
| 
								 | 
							
										return rt
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									v, err := url.ParseQuery(meta)
							 | 
						||
| 
								 | 
							
									if err != nil {
							 | 
						||
| 
								 | 
							
										return rt
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									for key := range v {
							 | 
						||
| 
								 | 
							
										rt[key] = v.Get(key)
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
									return rt
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								func ConvertMap2String(meta map[string]string) string {
							 | 
						||
| 
								 | 
							
									var buf strings.Builder
							 | 
						||
| 
								 | 
							
									keys := make([]string, 0, len(meta))
							 | 
						||
| 
								 | 
							
									for k := range meta {
							 | 
						||
| 
								 | 
							
										keys = append(keys, k)
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
									sort.Strings(keys)
							 | 
						||
| 
								 | 
							
									for _, k := range keys {
							 | 
						||
| 
								 | 
							
										vs := meta[k]
							 | 
						||
| 
								 | 
							
										keyEscaped := url.QueryEscape(k)
							 | 
						||
| 
								 | 
							
										if buf.Len() > 0 {
							 | 
						||
| 
								 | 
							
											buf.WriteByte('&')
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
										buf.WriteString(keyEscaped)
							 | 
						||
| 
								 | 
							
										buf.WriteByte('=')
							 | 
						||
| 
								 | 
							
										buf.WriteString(url.QueryEscape(vs))
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
									return buf.String()
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								// ExternalIPV4 gets external IPv4 address of this server.
							 | 
						||
| 
								 | 
							
								func ExternalIPV4() (string, error) {
							 | 
						||
| 
								 | 
							
									ifaces, err := net.Interfaces()
							 | 
						||
| 
								 | 
							
									if err != nil {
							 | 
						||
| 
								 | 
							
										return "", err
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
									for _, iface := range ifaces {
							 | 
						||
| 
								 | 
							
										if iface.Flags&net.FlagUp == 0 {
							 | 
						||
| 
								 | 
							
											continue // interface down
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
										if iface.Flags&net.FlagLoopback != 0 {
							 | 
						||
| 
								 | 
							
											continue // loopback interface
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
										addrs, err := iface.Addrs()
							 | 
						||
| 
								 | 
							
										if err != nil {
							 | 
						||
| 
								 | 
							
											return "", err
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
										for _, addr := range addrs {
							 | 
						||
| 
								 | 
							
											var ip net.IP
							 | 
						||
| 
								 | 
							
											switch v := addr.(type) {
							 | 
						||
| 
								 | 
							
											case *net.IPNet:
							 | 
						||
| 
								 | 
							
												ip = v.IP
							 | 
						||
| 
								 | 
							
											case *net.IPAddr:
							 | 
						||
| 
								 | 
							
												ip = v.IP
							 | 
						||
| 
								 | 
							
											}
							 | 
						||
| 
								 | 
							
											if ip == nil || ip.IsLoopback() {
							 | 
						||
| 
								 | 
							
												continue
							 | 
						||
| 
								 | 
							
											}
							 | 
						||
| 
								 | 
							
											ip = ip.To4()
							 | 
						||
| 
								 | 
							
											if ip == nil {
							 | 
						||
| 
								 | 
							
												continue // not an ipv4 address
							 | 
						||
| 
								 | 
							
											}
							 | 
						||
| 
								 | 
							
											return ip.String(), nil
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
									return "", errors.New("are you connected to the network?")
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								// ExternalIPV6 gets external IPv6 address of this server.
							 | 
						||
| 
								 | 
							
								func ExternalIPV6() (string, error) {
							 | 
						||
| 
								 | 
							
									ifaces, err := net.Interfaces()
							 | 
						||
| 
								 | 
							
									if err != nil {
							 | 
						||
| 
								 | 
							
										return "", err
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
									for _, iface := range ifaces {
							 | 
						||
| 
								 | 
							
										if iface.Flags&net.FlagUp == 0 {
							 | 
						||
| 
								 | 
							
											continue // interface down
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
										if iface.Flags&net.FlagLoopback != 0 {
							 | 
						||
| 
								 | 
							
											continue // loopback interface
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
										addrs, err := iface.Addrs()
							 | 
						||
| 
								 | 
							
										if err != nil {
							 | 
						||
| 
								 | 
							
											return "", err
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
										for _, addr := range addrs {
							 | 
						||
| 
								 | 
							
											var ip net.IP
							 | 
						||
| 
								 | 
							
											switch v := addr.(type) {
							 | 
						||
| 
								 | 
							
											case *net.IPNet:
							 | 
						||
| 
								 | 
							
												ip = v.IP
							 | 
						||
| 
								 | 
							
											case *net.IPAddr:
							 | 
						||
| 
								 | 
							
												ip = v.IP
							 | 
						||
| 
								 | 
							
											}
							 | 
						||
| 
								 | 
							
											if ip == nil || ip.IsLoopback() {
							 | 
						||
| 
								 | 
							
												continue
							 | 
						||
| 
								 | 
							
											}
							 | 
						||
| 
								 | 
							
											ip = ip.To16()
							 | 
						||
| 
								 | 
							
											if ip == nil {
							 | 
						||
| 
								 | 
							
												continue // not an ipv4 address
							 | 
						||
| 
								 | 
							
											}
							 | 
						||
| 
								 | 
							
											return ip.String(), nil
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
									return "", errors.New("are you connected to the network?")
							 | 
						||
| 
								 | 
							
								}
							 |