--- /dev/null
+package p2p
+
+import (
+ "net"
+)
+
+// ExternalIPv4 returns the first IPv4 available.
+func ExternalIPv4() (string, error) {
+ ifaces, err := net.Interfaces()
+ if err != nil {
+ return "", err
+ }
+
+ for _, iface := range ifaces {
+ // interface down
+ if iface.Flags&net.FlagUp == 0 {
+ continue
+ }
+ // loopback interface
+ if iface.Flags&net.FlagLoopback != 0 {
+ continue
+ }
+ addrs, err := iface.Addrs()
+ if err != nil {
+ return "", err
+ }
+
+ 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 == nil || ip.IsLoopback() {
+ continue
+ }
+ ip = ip.To4()
+ if ip == nil {
+ continue // not an ipv4 address
+ }
+ return ip.String(), nil
+ }
+ }
+ return "127.0.0.1", nil
+}