Ver código fonte

three node init commit

Toby Chui 3 anos atrás
pai
commit
3ceccfaeb3
7 arquivos alterados com 202 adições e 0 exclusões
  1. 7 0
      go.mod
  2. 4 0
      go.sum
  3. 185 0
      main.go
  4. 2 0
      node1.sh
  5. 2 0
      node2.sh
  6. 2 0
      node3.sh
  7. BIN
      three-nodes.exe

+ 7 - 0
go.mod

@@ -0,0 +1,7 @@
+module git.hkwtc.org/TC/three-nodes
+
+go 1.17
+
+require github.com/tobychui/go-DDDNS v0.0.0-20211217035254-2c2b43aa046c
+
+require github.com/xlzd/gotp v0.0.0-20181030022105-c8557ba2c119 // indirect

+ 4 - 0
go.sum

@@ -0,0 +1,4 @@
+github.com/tobychui/go-DDDNS v0.0.0-20211217035254-2c2b43aa046c h1:A4cFOlnHi3TTa0uJcfRGn85IAJX5rWjwqthRKTufiOU=
+github.com/tobychui/go-DDDNS v0.0.0-20211217035254-2c2b43aa046c/go.mod h1:4VHLl5Luo+TEaMmdwvxctuFdcs2k82cruhGoSJuZDJE=
+github.com/xlzd/gotp v0.0.0-20181030022105-c8557ba2c119 h1:YyPWX3jLOtYKulBR6AScGIs74lLrJcgeKRwcbAuQOG4=
+github.com/xlzd/gotp v0.0.0-20181030022105-c8557ba2c119/go.mod h1:/nuTSlK+okRfR/vnIPqR89fFKonnWPiZymN5ydRJkX8=

+ 185 - 0
main.go

@@ -0,0 +1,185 @@
+package main
+
+/*
+
+	Two-Nodes
+
+	A simple demo for showcasing the go-DDDNS working in a two nodes environment
+
+*/
+import (
+	"errors"
+	"flag"
+	"io/ioutil"
+	"log"
+	"net/http"
+	"os"
+	"os/signal"
+	"strconv"
+	"syscall"
+	"time"
+
+	godddns "github.com/tobychui/go-DDDNS/godddns"
+)
+
+var (
+	//Flags
+	//Current node
+	thisNodeUUID = flag.String("nid", "node1", "The UUID of this node")
+
+	//Remote nodes
+	remoteNodeAUUID   = flag.String("rida", "node2", "The UUID of the remote node A")
+	remoteNodeAIPAddr = flag.String("ripa", "127.0.0.1", "The remote node A current IP address")
+	remoteNodeBUUID   = flag.String("ridb", "node3", "The UUID of the remote node B")
+	remoteNodeBIPAddr = flag.String("ripb", "127.0.0.1", "The remote node B current IP address")
+
+	//The following flags assume both remote node A and B are hosted on the same port and with same connection endpoint
+	connPath           = flag.String("conn", "/conn", "The relative path for connection establishment")
+	thisNodeRecvPort   = flag.Int("np", 8080, "This node receive port")
+	remoteNodeRecvPort = flag.Int("rp", 8080, "Remote nodes (A and B) receive port")
+
+	//Paramter, which we hardcoded here for now
+	syncInterval  int64 = 10
+	serviceRouter *godddns.ServiceRouter
+)
+
+//Dummy function which allow all login to pass through
+func ValidateCred(username string, password string) bool {
+	return true
+}
+
+func cleanup(configFilename string) {
+	//Save the router record to json file
+	js, err := serviceRouter.ExportRouterToJSON()
+	if err != nil {
+		panic(err)
+	}
+	ioutil.WriteFile(configFilename, []byte(js), 0755)
+
+	//Close the service router
+	serviceRouter.Close()
+}
+
+func main() {
+	//Set-ups
+	flag.Parse()
+	configFilename := *thisNodeUUID + "_config.json"
+	c := make(chan os.Signal)
+	signal.Notify(c, os.Interrupt, syscall.SIGTERM)
+	go func() {
+		<-c
+		cleanup(configFilename)
+		os.Exit(1)
+	}()
+
+	//Step 1: we want to create a new service router based on the given information
+	if fileExists(configFilename) {
+		//Load service router from file
+		s, err := godddns.NewRouterFromJSONFile(configFilename)
+		if err != nil {
+			log.Println("Failed to load service router from file: ")
+			panic(err)
+		}
+
+		s.InjectAuthFunction(ValidateCred)
+		serviceRouter = s
+		log.Println("Service Router Config Loaded")
+	} else {
+		//Create a new service router
+		serviceRouter = godddns.NewServiceRouter(godddns.RouterOptions{
+			DeviceUUID:   *thisNodeUUID,
+			AuthFunction: ValidateCred,
+			SyncInterval: syncInterval,
+		})
+		log.Println("Service Router Created")
+	}
+
+	//Optional: Enable verbal output on router
+	serviceRouter.Options.Verbal = true
+
+	//Step 2: Create HTTP listening endpoint for incoming connection requests and heartbeat
+	go func() {
+		http.HandleFunc("/conn", serviceRouter.HandleConnections)
+		log.Println("HTTP Listening endpoint started on :" + strconv.Itoa(*thisNodeRecvPort))
+		http.ListenAndServe(":"+strconv.Itoa(*thisNodeRecvPort), nil)
+	}()
+
+	if !fileExists(configFilename) {
+		//Step 3: we want to add the remote nodes to the list
+		//Node A
+		nodeA := serviceRouter.NewNode(godddns.NodeOptions{
+			NodeID:        *remoteNodeAUUID,
+			Port:          *remoteNodeRecvPort,
+			RESTInterface: *connPath,
+			RequireHTTPS:  false,
+		})
+		serviceRouter.AddNode(nodeA)
+		log.Println("Remote NodeA Added")
+
+		//Node B
+		nodeB := serviceRouter.NewNode(godddns.NodeOptions{
+			NodeID:        *remoteNodeBUUID,
+			Port:          *remoteNodeRecvPort,
+			RESTInterface: *connPath,
+			RequireHTTPS:  false,
+		})
+		serviceRouter.AddNode(nodeB)
+		log.Println("Remote NodeB Added")
+
+		//Step 4: Start the connection to Node 1 (Replace username and password with real value here)
+		retryCount := 0
+		retry := true
+		for retry {
+			if retryCount > 10 {
+				log.Println("Connection to remote node " + nodeA.UUID + " failed. Skipping.")
+				break
+			}
+			assignedSendingTOTP, err := nodeA.StartConnection(*remoteNodeAIPAddr, "username", "password")
+			if err != nil {
+				log.Println("Unable to establish connection to Node A. Retrying in 3 seconds", assignedSendingTOTP)
+				retryCount++
+
+				time.Sleep(3 * time.Second)
+			} else {
+				log.Println("Remote Node A TOTP exchange done:", assignedSendingTOTP)
+				retry = false
+			}
+
+		}
+
+		//Start connection to Node 2
+		retryCount = 0
+		retry = true
+		for retry {
+			if retryCount > 10 {
+				log.Println("Connection to remote node " + nodeB.UUID + " failed. Skipping.")
+				break
+			}
+			assignedSendingTOTP, err := nodeB.StartConnection(*remoteNodeBIPAddr, "username", "password")
+			if err != nil {
+				log.Println("Unable to establish connection to Node B. Retrying in 3 seconds", assignedSendingTOTP)
+				retryCount++
+
+				time.Sleep(3 * time.Second)
+			} else {
+				log.Println("Node B TOTP exchange done:", assignedSendingTOTP)
+				retry = false
+			}
+
+		}
+	}
+
+	//Step 4: Start Heartbeat to the remote node(s)
+	serviceRouter.StartHeartBeat()
+	log.Println("Heartbeat schedule started")
+
+	//Do a blocking loop
+	select {}
+}
+
+func fileExists(filename string) bool {
+	if _, err := os.Stat(filename); errors.Is(err, os.ErrNotExist) {
+		return false
+	}
+	return true
+}

+ 2 - 0
node1.sh

@@ -0,0 +1,2 @@
+#/bin/bash
+./three-nodes.exe -nid "node1" -np 8080 -rida "node2" -ripa "192.168.0.101" -ridb "node3" -ripb "192.168.0.102" -rp 8080

+ 2 - 0
node2.sh

@@ -0,0 +1,2 @@
+#/bin/bash
+./three-nodes.exe -nid "node2" -np 8080 -rida "node1" -ripa "192.168.0.100" -ridb "node3" -ripb "192.168.0.102" -rp 8080

+ 2 - 0
node3.sh

@@ -0,0 +1,2 @@
+#/bin/bash
+./three-nodes.exe -nid "node3" -np 8080 -rida "node2" -ripa "192.168.0.101" -ridb "node1" -ripb "192.168.0.100" -rp 8080

BIN
three-nodes.exe