mirror of
https://github.com/datarhei/core.git
synced 2025-09-27 04:16:25 +08:00
131 lines
2.3 KiB
Go
131 lines
2.3 KiB
Go
package net
|
|
|
|
// from github.com/simplesurance/go-ip-anonymizer
|
|
|
|
import (
|
|
"fmt"
|
|
"io"
|
|
"net"
|
|
"net/http"
|
|
"sync"
|
|
"time"
|
|
)
|
|
|
|
var (
|
|
defaultIPv4Mask = net.IPv4Mask(255, 255, 255, 0) // /24
|
|
defaultIPv6Mask = net.IPMask{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0, 0, 0, 0, 0, 0, 0, 0} // /64
|
|
)
|
|
|
|
func AnonymizeIPString(ipAddress string) (string, error) {
|
|
switch ipVersion(ipAddress) {
|
|
case 4:
|
|
ip4 := net.ParseIP(ipAddress)
|
|
if ip4 == nil {
|
|
return ipAddress, fmt.Errorf("invalid IPv4 address")
|
|
}
|
|
|
|
return AnonymizeIPv4(ip4).String(), nil
|
|
|
|
case 6:
|
|
ipv6 := net.ParseIP(ipAddress)
|
|
if ipv6 == nil {
|
|
return ipAddress, fmt.Errorf("invalid IPv6 address")
|
|
}
|
|
|
|
return AnonymizeIPv6(ipv6).String(), nil
|
|
|
|
default:
|
|
return ipAddress, fmt.Errorf("invalid IP address")
|
|
}
|
|
}
|
|
|
|
// IPv4 anonymizes an IPv4 address by zeroing it's host part.
|
|
func AnonymizeIPv4(ip net.IP) net.IP {
|
|
return ip.Mask(defaultIPv4Mask)
|
|
}
|
|
|
|
// IPv6 anonymizes an IPv4 address by zeroing it's host part.
|
|
func AnonymizeIPv6(ip net.IP) net.IP {
|
|
return ip.Mask(defaultIPv6Mask)
|
|
}
|
|
|
|
func ipVersion(ipAddress string) int {
|
|
// copied from net.ParseIP()
|
|
for i := 0; i < len(ipAddress); i++ {
|
|
switch ipAddress[i] {
|
|
case '.':
|
|
return 4
|
|
case ':':
|
|
return 6
|
|
}
|
|
}
|
|
|
|
return 0
|
|
}
|
|
|
|
// GetPublicIPs will try to figure out the public IPs (v4 and v6)
|
|
// we're running on. If it fails, an empty list will be returned.
|
|
func GetPublicIPs(timeout time.Duration) []string {
|
|
var wg sync.WaitGroup
|
|
|
|
ipv4 := ""
|
|
ipv6 := ""
|
|
|
|
wg.Add(2)
|
|
|
|
go func() {
|
|
defer wg.Done()
|
|
|
|
ipv4 = doRequest("https://api.ipify.org", timeout)
|
|
}()
|
|
|
|
go func() {
|
|
defer wg.Done()
|
|
|
|
ipv6 = doRequest("https://api6.ipify.org", timeout)
|
|
}()
|
|
|
|
wg.Wait()
|
|
|
|
ips := []string{}
|
|
|
|
if len(ipv4) != 0 {
|
|
ips = append(ips, ipv4)
|
|
}
|
|
|
|
if len(ipv6) != 0 && ipv4 != ipv6 {
|
|
ips = append(ips, ipv6)
|
|
}
|
|
|
|
return ips
|
|
}
|
|
|
|
func doRequest(url string, timeout time.Duration) string {
|
|
client := &http.Client{
|
|
Timeout: timeout,
|
|
}
|
|
|
|
req, err := http.NewRequest("GET", url, nil)
|
|
if err != nil {
|
|
return ""
|
|
}
|
|
|
|
resp, err := client.Do(req)
|
|
if err != nil {
|
|
return ""
|
|
}
|
|
|
|
defer resp.Body.Close()
|
|
|
|
body, err := io.ReadAll(resp.Body)
|
|
if err != nil {
|
|
return ""
|
|
}
|
|
|
|
if resp.StatusCode != 200 {
|
|
return ""
|
|
}
|
|
|
|
return string(body)
|
|
}
|