summaryrefslogtreecommitdiffstats
path: root/pkg/common
diff options
context:
space:
mode:
authorJason Song <i@wolfogre.com>2023-05-04 11:45:53 +0200
committerJason Song <i@wolfogre.com>2023-05-04 11:45:53 +0200
commit229dbaf1532c7de89875153186e225b457307a03 (patch)
tree0f5bfd48d34f47f623edfa56690b66a516480ea9 /pkg/common
parentSupport services `credentials` (#51) (diff)
parentchore: bump VERSION to 0.2.45 (diff)
downloadforgejo-act-229dbaf1532c7de89875153186e225b457307a03.tar.xz
forgejo-act-229dbaf1532c7de89875153186e225b457307a03.zip
Merge tag 'nektos/v0.2.45'
Diffstat (limited to 'pkg/common')
-rw-r--r--pkg/common/outbound_ip.go72
1 files changed, 63 insertions, 9 deletions
diff --git a/pkg/common/outbound_ip.go b/pkg/common/outbound_ip.go
index eaa4cce..66e15e5 100644
--- a/pkg/common/outbound_ip.go
+++ b/pkg/common/outbound_ip.go
@@ -2,20 +2,74 @@ package common
import (
"net"
-
- log "github.com/sirupsen/logrus"
+ "sort"
+ "strings"
)
-// https://stackoverflow.com/a/37382208
-// Get preferred outbound ip of this machine
+// GetOutboundIP returns an outbound IP address of this machine.
+// It tries to access the internet and returns the local IP address of the connection.
+// If the machine cannot access the internet, it returns a preferred IP address from network interfaces.
+// It returns nil if no IP address is found.
func GetOutboundIP() net.IP {
+ // See https://stackoverflow.com/a/37382208
conn, err := net.Dial("udp", "8.8.8.8:80")
- if err != nil {
- log.Fatal(err)
+ if err == nil {
+ defer conn.Close()
+ return conn.LocalAddr().(*net.UDPAddr).IP
}
- defer conn.Close()
- localAddr := conn.LocalAddr().(*net.UDPAddr)
+ // So the machine cannot access the internet. Pick an IP address from network interfaces.
+ if ifs, err := net.Interfaces(); err == nil {
+ type IP struct {
+ net.IP
+ net.Interface
+ }
+ var ips []IP
+ for _, i := range ifs {
+ if addrs, err := i.Addrs(); err == nil {
+ 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.IsGlobalUnicast() {
+ ips = append(ips, IP{ip, i})
+ }
+ }
+ }
+ }
+ if len(ips) > 1 {
+ sort.Slice(ips, func(i, j int) bool {
+ ifi := ips[i].Interface
+ ifj := ips[j].Interface
+
+ // ethernet is preferred
+ if vi, vj := strings.HasPrefix(ifi.Name, "e"), strings.HasPrefix(ifj.Name, "e"); vi != vj {
+ return vi
+ }
+
+ ipi := ips[i].IP
+ ipj := ips[j].IP
+
+ // IPv4 is preferred
+ if vi, vj := ipi.To4() != nil, ipj.To4() != nil; vi != vj {
+ return vi
+ }
+
+ // en0 is preferred to en1
+ if ifi.Name != ifj.Name {
+ return ifi.Name < ifj.Name
+ }
+
+ // fallback
+ return ipi.String() < ipj.String()
+ })
+ return ips[0].IP
+ }
+ }
- return localAddr.IP
+ return nil
}