OSDN Git Service

Change get external ip method (#1649)
authoryahtoo <yahtoo.ma@gmail.com>
Wed, 27 Mar 2019 03:19:36 +0000 (11:19 +0800)
committerPaladz <yzhu101@uottawa.ca>
Wed, 27 Mar 2019 03:19:36 +0000 (11:19 +0800)
* Change get external ip method

* Add test info

* opz code format

* Opz address display

* Fix review bug

* Change cmn.PanicCrisis to log.Panic

p2p/connection/secret_connection.go
p2p/external_ip.go [new file with mode: 0644]
p2p/external_ip_test.go [new file with mode: 0644]
p2p/listener.go
p2p/peer.go
p2p/public_ip.go [deleted file]

index 63d135b..69d175e 100644 (file)
@@ -10,6 +10,7 @@ import (
        "net"
        "time"
 
+       log "github.com/sirupsen/logrus"
        "golang.org/x/crypto/nacl/box"
        "golang.org/x/crypto/nacl/secretbox"
        "golang.org/x/crypto/ripemd160"
@@ -213,7 +214,7 @@ func genEphKeys() (ephPub, ephPriv *[32]byte) {
        var err error
        ephPub, ephPriv, err = box.GenerateKey(crand.Reader)
        if err != nil {
-               cmn.PanicCrisis("Could not generate ephemeral keypairs")
+               log.Panic("Could not generate ephemeral keypairs")
        }
        return
 }
diff --git a/p2p/external_ip.go b/p2p/external_ip.go
new file mode 100644 (file)
index 0000000..5c2c90c
--- /dev/null
@@ -0,0 +1,47 @@
+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
+}
diff --git a/p2p/external_ip_test.go b/p2p/external_ip_test.go
new file mode 100644 (file)
index 0000000..18601fe
--- /dev/null
@@ -0,0 +1,22 @@
+package p2p
+
+import (
+       "regexp"
+       "testing"
+)
+
+func TestExternalIPv4(t *testing.T) {
+       // Regular expression format for IPv4
+       IPv4Format := `\.\d{1,3}\.\d{1,3}\b`
+       test, err := ExternalIPv4()
+
+       if err != nil {
+               t.Errorf("Test check external ipv4 failed with %v", err)
+       }
+
+       valid := regexp.MustCompile(IPv4Format)
+
+       if !valid.MatchString(test) {
+               t.Errorf("Wanted: %v, got: %v", IPv4Format, test)
+       }
+}
index 204b686..d7a1199 100644 (file)
@@ -81,27 +81,6 @@ func getUPNPExternalAddress(externalPort, internalPort int) (*NetAddress, error)
        return NewNetAddressIPPort(ext, uint16(externalPort)), nil
 }
 
-func getNaiveExternalAddress(port int, settleForLocal bool) *NetAddress {
-       addrs, err := net.InterfaceAddrs()
-       if err != nil {
-               cmn.PanicCrisis(cmn.Fmt("Could not fetch interface addresses: %v", err))
-       }
-
-       for _, a := range addrs {
-               ipnet, ok := a.(*net.IPNet)
-               if !ok {
-                       continue
-               }
-               if v4 := ipnet.IP.To4(); v4 == nil || (!settleForLocal && v4[0] == 127) {
-                       continue
-               }
-               return NewNetAddressIPPort(ipnet.IP, uint16(port))
-       }
-
-       log.Info("Node may not be connected to internet. Settling for local address")
-       return getNaiveExternalAddress(port, true)
-}
-
 func splitHostPort(addr string) (host string, port int) {
        host, portStr, err := net.SplitHostPort(addr)
        if err != nil {
@@ -135,12 +114,12 @@ func NewDefaultListener(protocol string, lAddr string, skipUPNP bool) (Listener,
                listener, err = net.Listen(protocol, lAddr)
        }
        if err != nil {
-               cmn.PanicCrisis(err)
+               log.Panic(err)
        }
 
        intAddr, err := NewNetAddressString(lAddr)
        if err != nil {
-               cmn.PanicCrisis(err)
+               log.Panic(err)
        }
 
        // Actual listener local IP & port
@@ -156,17 +135,16 @@ func NewDefaultListener(protocol string, lAddr string, skipUPNP bool) (Listener,
                log.WithFields(log.Fields{"module": logModule, "err": err}).Info("get UPNP external address")
        }
 
+       // Get the IPv4 available
        if extAddr == nil {
-               if address := GetIP(); address.Success == true {
-                       extAddr = NewNetAddressIPPort(net.ParseIP(address.IP), uint16(lAddrPort))
+               if ip, err := ExternalIPv4(); err != nil {
+                       log.WithFields(log.Fields{"module": logModule, "err": err}).Warning("get ipv4 external address")
+                       log.Panic("get ipv4 external address fail!")
+               } else {
+                       extAddr = NewNetAddressIPPort(net.ParseIP(ip), uint16(lAddrPort))
+                       log.WithFields(log.Fields{"module": logModule, "addr": extAddr}).Info("get ipv4 external address success")
                }
        }
-       if extAddr == nil {
-               extAddr = getNaiveExternalAddress(listenerPort, false)
-       }
-       if extAddr == nil {
-               cmn.PanicCrisis("could not determine external address!")
-       }
 
        dl := &DefaultListener{
                listener:    listener,
@@ -211,7 +189,7 @@ func (l *DefaultListener) listenRoutine() {
                // listener wasn't stopped,
                // yet we encountered an error.
                if err != nil {
-                       cmn.PanicCrisis(err)
+                       log.Panic(err)
                }
                l.connections <- conn
        }
index 157af7b..87c159a 100644 (file)
@@ -156,7 +156,7 @@ func (pc *peerConn) HandshakeTimeout(ourNodeInfo *NodeInfo, timeout time.Duratio
                func() {
                        var n int
                        wire.ReadBinary(peerNodeInfo, pc.conn, maxNodeInfoSize, &n, &err2)
-                       log.WithFields(log.Fields{"module": logModule, "address": peerNodeInfo.ListenAddr}).Info("Peer handshake")
+                       log.WithFields(log.Fields{"module": logModule, "address": pc.conn.RemoteAddr().String()}).Info("Peer handshake")
                })
        if err1 != nil {
                return peerNodeInfo, errors.Wrap(err1, "Error during handshake/write")
diff --git a/p2p/public_ip.go b/p2p/public_ip.go
deleted file mode 100644 (file)
index c0395f8..0000000
+++ /dev/null
@@ -1,70 +0,0 @@
-package p2p
-
-import (
-       "io/ioutil"
-       "net"
-       "net/http"
-       "strings"
-       "time"
-)
-
-var ipCheckServices = []string{
-       "http://members.3322.org/dyndns/getip",
-       "http://ifconfig.me/",
-       "http://icanhazip.com/",
-       "http://ifconfig.io/ip",
-       "http://ident.me/",
-       "http://whatismyip.akamai.com/",
-       "http://myip.dnsomatic.com/",
-       "http://diagnostic.opendns.com/myip",
-       "http://myexternalip.com/raw",
-}
-
-// IPResult is the ip check response
-type IPResult struct {
-       Success bool
-       IP      string
-}
-
-var timeout = time.Duration(5)
-
-// GetIP return the ip of the current host
-func GetIP() *IPResult {
-       resultCh := make(chan *IPResult, 1)
-       for _, s := range ipCheckServices {
-               go ipAddress(s, resultCh)
-       }
-
-       for {
-               select {
-               case result := <-resultCh:
-                       return result
-               case <-time.After(time.Second * timeout):
-                       return &IPResult{false, ""}
-               }
-       }
-}
-
-func ipAddress(service string, done chan<- *IPResult) {
-       client := http.Client{Timeout: time.Duration(timeout * time.Second)}
-       resp, err := client.Get(service)
-       if err != nil {
-               return
-       }
-
-       defer resp.Body.Close()
-       data, err := ioutil.ReadAll(resp.Body)
-       if err != nil {
-               return
-       }
-
-       address := strings.TrimSpace(string(data))
-       if ip := net.ParseIP(address); ip != nil && ip.To4() != nil {
-               select {
-               case done <- &IPResult{true, address}:
-                       return
-               default:
-                       return
-               }
-       }
-}