github.com/XiaoMi/Gaea@v1.2.5/util/ip.go (about) 1 // Copyright 2016 The kingshard Authors. All rights reserved. 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"): you may 4 // not use this file except in compliance with the License. You may obtain 5 // a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 11 // WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 12 // License for the specific language governing permissions and limitations 13 // under the License. 14 15 package util 16 17 import ( 18 "errors" 19 "fmt" 20 "net" 21 "strings" 22 ) 23 24 // IPInfo ip information 25 type IPInfo struct { 26 info string 27 isIPNet bool 28 ip net.IP 29 ipNet net.IPNet 30 } 31 32 // ParseIPInfo parse ip 33 func ParseIPInfo(v string) (IPInfo, error) { 34 if ip, ipNet, err := net.ParseCIDR(v); err == nil { 35 return IPInfo{ 36 info: v, 37 isIPNet: true, 38 ip: ip, 39 ipNet: *ipNet, 40 }, nil 41 } 42 43 if ip := net.ParseIP(v); ip != nil { 44 return IPInfo{ 45 info: v, 46 isIPNet: false, 47 ip: ip, 48 }, nil 49 } 50 51 return IPInfo{}, errors.New("invalid ip address") 52 } 53 54 // Info return information of ip 55 func (t *IPInfo) Info() string { 56 return t.info 57 } 58 59 // Match check if ip matched 60 func (t *IPInfo) Match(ip net.IP) bool { 61 if t.isIPNet { 62 return t.ipNet.Contains(ip) 63 } 64 return t.ip.Equal(ip) 65 } 66 67 func parseAllowIps(allowIpsStr string) ([]IPInfo, error) { 68 if len(allowIpsStr) == 0 { 69 return make([]IPInfo, 0, 10), nil 70 } 71 ipVec := strings.Split(allowIpsStr, ",") 72 allowIpsList := make([]IPInfo, 0, 10) 73 for _, ipStr := range ipVec { 74 if ip, err := ParseIPInfo(strings.TrimSpace(ipStr)); err == nil { 75 allowIpsList = append(allowIpsList, ip) 76 } 77 } 78 return allowIpsList, nil 79 } 80 81 func resolveAddr(network string, address string, replaceZeroAddr bool) (string, error) { 82 switch network { 83 default: 84 return "", fmt.Errorf("invalid network '%s'", network) 85 86 case "unix", "unixpacket": 87 return address, nil 88 89 case "tcp", "tcp4", "tcp6": 90 addr, err := net.ResolveTCPAddr(network, address) 91 if err != nil { 92 return "", err 93 } 94 if addr.Port != 0 { 95 //是否为空地址 96 if !isZeroIPAddr(addr) { 97 return addr.String(), nil 98 } 99 if replaceZeroAddr { 100 ifaddrs, err := net.InterfaceAddrs() 101 if err != nil { 102 return "", err 103 } 104 for _, ifaddr := range ifaddrs { 105 switch in := ifaddr.(type) { 106 case *net.IPNet: 107 if in.IP.IsGlobalUnicast() { 108 addr.IP = in.IP 109 return addr.String(), nil 110 } 111 } 112 } 113 } 114 } 115 return "", fmt.Errorf("invalid address '%s'", addr.String()) 116 } 117 } 118 119 // ResolveAddr return real ip by net interface 120 func ResolveAddr(network string, locAddr string) (string, error) { 121 return resolveAddr(network, locAddr, true) 122 } 123 124 func isZeroIPAddr(addr *net.TCPAddr) bool { 125 if ipv4 := addr.IP.To4(); ipv4 != nil { 126 return net.IPv4zero.Equal(ipv4) 127 } else if ipv6 := addr.IP.To16(); ipv6 != nil { 128 return net.IPv6zero.Equal(ipv6) 129 } 130 return false 131 } 132 133 // HostName return hostname by ip 134 func HostName(ip string) (hostname string, err error) { 135 hostName, err := net.LookupAddr(ip) 136 if err != nil { 137 return "", err 138 } 139 return hostName[0], err 140 }