github.heygears.com/openimsdk/tools@v0.0.49/utils/network/ip.go (about) 1 // Copyright © 2023 OpenIM. All rights reserved. 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain 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, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 package network 16 17 import ( 18 "errors" 19 "net" 20 "net/http" 21 "strings" 22 23 _ "github.com/openimsdk/tools/errs" 24 ) 25 26 // Define http headers. 27 const ( 28 XForwardedFor = "X-Forwarded-For" 29 XRealIP = "X-Real-IP" 30 XClientIP = "x-client-ip" 31 ) 32 33 func GetLocalIP() (string, error) { 34 // Fetch all network interfaces 35 interfaces, err := net.Interfaces() 36 if err != nil { 37 return "", err 38 } 39 // Iterate over each interface 40 for _, iface := range interfaces { 41 // Check if the interface is up and not a loopback 42 if iface.Flags&net.FlagUp == 0 || iface.Flags&net.FlagLoopback != 0 { 43 continue 44 } 45 46 // Get all addresses associated with the interface 47 addrs, err := iface.Addrs() 48 if err != nil { 49 return "", err 50 } 51 52 // Check each address for a valid IPv4 address that is not a loopback 53 for _, addr := range addrs { 54 // Try to parse the address as an IPNet (CIDR notation) 55 ipNet, ok := addr.(*net.IPNet) 56 if !ok || ipNet.IP.IsLoopback() { 57 continue 58 } 59 60 ip4 := ipNet.IP.To4() 61 if ip4 != nil && !ip4.IsLoopback() { 62 // Ensure the IP is not a multicast address 63 if !ip4.IsMulticast() { 64 return ip4.String(), nil 65 } 66 } 67 } 68 } 69 // If no suitable IP is found, return an error 70 return "", errors.New("no suitable local IP address found") 71 } 72 73 func GetRpcRegisterIP(configIP string) (string, error) { 74 registerIP := configIP 75 if registerIP == "" { 76 ip, err := GetLocalIP() 77 if err != nil { 78 return "", err 79 } 80 registerIP = ip 81 } 82 return registerIP, nil 83 } 84 85 func GetListenIP(configIP string) string { 86 if configIP == "" { 87 return "0.0.0.0" 88 } 89 return configIP 90 } 91 92 // RemoteIP returns the remote ip of the request. 93 func RemoteIP(req *http.Request) string { 94 if ip := req.Header.Get(XClientIP); ip != "" { 95 return ip 96 } else if ip := req.Header.Get(XRealIP); ip != "" { 97 return ip 98 } else if ip := req.Header.Get(XForwardedFor); ip != "" { 99 parts := strings.Split(ip, ",") 100 return strings.TrimSpace(parts[0]) 101 } 102 103 ip, _, err := net.SplitHostPort(req.RemoteAddr) 104 if err != nil { 105 ip = req.RemoteAddr 106 } 107 108 if ip == "::1" { 109 return "127.0.0.1" 110 } 111 return ip 112 }