| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475 | package controllerimport (	"fmt"	"net"	"net/http"	"strings"	"github.com/gorilla/mux"	"github.com/gravitl/netmaker/netclient/ncutils")func ipHandlers(r *mux.Router) {	r.HandleFunc("/api/getip", http.HandlerFunc(getPublicIP)).Methods(http.MethodGet)}// @Summary     Get the current public IP address.// @Router      /api/getip [get]// @Tags        IP Service// @Security    oauth2// @Success     200 {string} string "The public IP address."// @Failure     400 {string} string "Invalid IP address or no IP found."func getPublicIP(w http.ResponseWriter, r *http.Request) {	r.Header.Set("Connection", "close")	ip, err := parseIP(r)	if err != nil {		w.WriteHeader(400)		switch {		case ip != "":			_, _ = w.Write([]byte("ip is invalid: " + ip))		case ip == "":			_, _ = w.Write([]byte("no ip found"))		default:			fmt.Println(err)		}		return	}	w.WriteHeader(200)	_, _ = w.Write([]byte(ip))}func parseIP(r *http.Request) (string, error) {	// Get Public IP from header	ip := r.Header.Get("X-REAL-IP")	ipnet := net.ParseIP(ip)	if ipnet != nil && !ncutils.IpIsPrivate(ipnet) {		return ip, nil	}	// If above fails, get Public IP from other header instead	forwardips := r.Header.Get("X-FORWARDED-FOR")	iplist := strings.Split(forwardips, ",")	for _, ip := range iplist {		ipnet := net.ParseIP(ip)		if ipnet != nil && !ncutils.IpIsPrivate(ipnet) {			return ip, nil		}	}	// If above also fails, get Public IP from Remote Address of request	ip, _, err := net.SplitHostPort(r.RemoteAddr)	if err != nil {		return "", err	}	ipnet = net.ParseIP(ip)	if ipnet != nil {		if ncutils.IpIsPrivate(ipnet) {			return ip, fmt.Errorf("ip is a private address")		}		return ip, nil	}	return "", fmt.Errorf("no ip found")}
 |