From 7b839fb2045d989ad3652edcb5356e3db62701f6 Mon Sep 17 00:00:00 2001
From: Jonas Theis <work@jonastheis.de>
Date: Tue, 25 Feb 2020 12:20:02 +0100
Subject: [PATCH] Clean up PortCheck plugin and make it standalone #259 (#271)

Co-authored-by: Hans Moog <hm@mkjc.net>
---
 main.go                     |  4 +-
 plugins/gossip/gossip.go    |  8 ++--
 plugins/portcheck/plugin.go | 94 +++++++++++++++++++++++++------------
 3 files changed, 70 insertions(+), 36 deletions(-)

diff --git a/main.go b/main.go
index efcc34bc..435ede0c 100644
--- a/main.go
+++ b/main.go
@@ -38,12 +38,12 @@ func main() {
 			logger.PLUGIN,
 			cli.PLUGIN,
 			remotelog.PLUGIN,
-			gracefulshutdown.PLUGIN,
+			portcheck.PLUGIN,
 
 			autopeering.PLUGIN,
 			tangle.PLUGIN,
 			gossip.PLUGIN,
-			portcheck.PLUGIN,
+			gracefulshutdown.PLUGIN,
 
 			analysis.PLUGIN,
 			metrics.PLUGIN,
diff --git a/plugins/gossip/gossip.go b/plugins/gossip/gossip.go
index be01dbdf..4995280f 100644
--- a/plugins/gossip/gossip.go
+++ b/plugins/gossip/gossip.go
@@ -19,7 +19,7 @@ import (
 var (
 	log *logger.Logger
 	mgr *gp.Manager
-	Srv *server.TCP
+	srv *server.TCP
 )
 
 func configureGossip() {
@@ -64,10 +64,10 @@ func start(shutdownSignal <-chan struct{}) {
 	}
 	defer listener.Close()
 
-	Srv = server.ServeTCP(lPeer, listener, log)
-	defer Srv.Close()
+	srv = server.ServeTCP(lPeer, listener, log)
+	defer srv.Close()
 
-	mgr.Start(Srv)
+	mgr.Start(srv)
 	defer mgr.Close()
 
 	log.Infof("%s started: Address=%s/%s", name, gossipAddr.String(), gossipAddr.Network())
diff --git a/plugins/portcheck/plugin.go b/plugins/portcheck/plugin.go
index 7a9d77d4..b87d29b5 100644
--- a/plugins/portcheck/plugin.go
+++ b/plugins/portcheck/plugin.go
@@ -6,84 +6,118 @@ import (
 
 	"github.com/iotaledger/goshimmer/packages/gossip/server"
 	"github.com/iotaledger/goshimmer/packages/netutil"
+	"github.com/iotaledger/goshimmer/plugins/autopeering"
 	"github.com/iotaledger/goshimmer/plugins/autopeering/local"
 	"github.com/iotaledger/goshimmer/plugins/banner"
 	"github.com/iotaledger/goshimmer/plugins/config"
 	"github.com/iotaledger/goshimmer/plugins/gossip"
 
-	"github.com/iotaledger/hive.go/autopeering/peer"
 	"github.com/iotaledger/hive.go/autopeering/peer/service"
 	"github.com/iotaledger/hive.go/logger"
 	"github.com/iotaledger/hive.go/node"
 )
 
-var PLUGIN = node.NewPlugin("Port Check", node.Enabled, run)
+const (
+	PLUGIN_NAME = "PortCheck"
+)
+
+var (
+	PLUGIN = node.NewPlugin(PLUGIN_NAME, node.Enabled, configure, run)
+	log    *logger.Logger
+)
 
-var log *logger.Logger
+func configure(plugin *node.Plugin) {
+	log = logger.NewLogger(PLUGIN_NAME)
+}
 
 func run(ctx *node.Plugin) {
-	log = logger.NewLogger("Tangle")
+	if !node.IsSkipped(autopeering.PLUGIN) {
+		log.Info("Testing autopeering service ...")
+		checkAutopeeringConnection()
+		log.Info("Testing autopeering service ... done")
+	}
 
-	lPeer := local.GetInstance()
+	if !node.IsSkipped(gossip.PLUGIN) {
+		log.Info("Testing gossip service ...")
+		checkGossipConnection()
+		log.Info("Testing gossip service ... done")
+	}
+}
+
+// check that discovery is working and the port is open
+func checkAutopeeringConnection() {
+	peering := local.GetInstance().Services().Get(service.PeeringKey)
 
 	// use the port of the peering service
-	peeringAddr := lPeer.Services().Get(service.PeeringKey)
-	_, peeringPort, err := net.SplitHostPort(peeringAddr.String())
+	_, peeringPort, err := net.SplitHostPort(peering.String())
 	if err != nil {
 		panic(err)
 	}
 
 	// resolve the bind address
 	address := net.JoinHostPort(config.Node.GetString(local.CFG_BIND), peeringPort)
-	localAddr, err := net.ResolveUDPAddr(peeringAddr.Network(), address)
+	localAddr, err := net.ResolveUDPAddr(peering.Network(), address)
 	if err != nil {
 		log.Fatalf("Error resolving %s: %v", local.CFG_BIND, err)
 	}
 
-	// check that discovery is working and the port is open
-	log.Info("Testing service ...")
-	checkAutopeeringConnection(localAddr, &lPeer.Peer)
-	log.Info("Testing service ... done")
-
-	//check that the server is working and the port is open
-	log.Info("Testing service ...")
-	checkGossipConnection(gossip.Srv, &lPeer.Peer)
-	log.Info("Testing service ... done")
-}
-
-func checkAutopeeringConnection(localAddr *net.UDPAddr, self *peer.Peer) {
-	peering := self.Services().Get(service.PeeringKey)
 	remoteAddr, err := net.ResolveUDPAddr(peering.Network(), peering.String())
 	if err != nil {
 		panic(err)
 	}
 
-	// do not check the address as a NAT may change them for local connections
-	err = netutil.CheckUDP(localAddr, remoteAddr, false, true)
+	// do not check address and port as a NAT may change them for local connections
+	err = netutil.CheckUDP(localAddr, remoteAddr, false, false)
 	if err != nil {
-		log.Errorf("Error testing service: %s", err)
+		log.Errorf("Error testing autopeering service: %s", err)
 		log.Panicf("Please check that %s is publicly reachable at %s/%s",
 			banner.AppName, peering.String(), peering.Network())
 	}
 }
 
-func checkGossipConnection(srv *server.TCP, self *peer.Peer) {
+// check that the gossip server is working and the port is open
+func checkGossipConnection() {
+	// listen on TCP gossip port
+	lPeer := local.GetInstance()
+	// use the port of the gossip service
+	gossipAddr := lPeer.Services().Get(service.GossipKey)
+	_, gossipPort, err := net.SplitHostPort(gossipAddr.String())
+	if err != nil {
+		panic(err)
+	}
+
+	// resolve the bind address
+	address := net.JoinHostPort(config.Node.GetString(local.CFG_BIND), gossipPort)
+	localAddr, err := net.ResolveTCPAddr(gossipAddr.Network(), address)
+	if err != nil {
+		log.Fatalf("Error resolving %s: %v", local.CFG_BIND, err)
+	}
+
+	listener, err := net.ListenTCP(gossipAddr.Network(), localAddr)
+	if err != nil {
+		log.Fatalf("Error listening: %v", err)
+	}
+	defer listener.Close()
+
+	srv := server.ServeTCP(lPeer, listener, log)
+	defer srv.Close()
+
+	// do the actual check
 	var wg sync.WaitGroup
 	wg.Add(1)
 	go func() {
 		defer wg.Done()
-		conn, err := srv.AcceptPeer(self)
-		if err != nil {
+		conn, acceptErr := srv.AcceptPeer(&lPeer.Peer)
+		if acceptErr != nil {
 			return
 		}
 		_ = conn.Close()
 	}()
-	conn, err := srv.DialPeer(self)
+	conn, err := srv.DialPeer(&lPeer.Peer)
 	if err != nil {
 		log.Errorf("Error testing: %s", err)
-		addr := self.Services().Get(service.GossipKey)
 		log.Panicf("Please check that %s is publicly reachable at %s/%s",
-			banner.AppName, addr.String(), addr.Network())
+			banner.AppName, gossipAddr.String(), gossipAddr.Network())
 	}
 	_ = conn.Close()
 	wg.Wait()
-- 
GitLab