diff --git a/Simulation/simulation.sh b/Simulation/simulation.sh index d42c2e9..86b3555 100644 --- a/Simulation/simulation.sh +++ b/Simulation/simulation.sh @@ -31,9 +31,11 @@ P2PRC_instances() { p2prc --as 0.0.0.0 -p "$NEW_PORT" # Replace the ServerPort in config + # test-$counter sed -i.bak "s/\"ServerPort\": \"[0-9]*\"/\"ServerPort\": \"$NEW_PORT\"/" "./config.json" sed -i.bak "s/\"Test\": false/\"Test\": true/" "./config.json" sed -i.bak "s/\"BehindNAT\": true/\"BehindNAT\": false/" "./config.json" + # sed -i.bak "s/\"MachineName\": "Akilans-MacBook-Pro.local-J2UbbkF"/\"MachineName\": \"test-$counter\"/" "./config.json" cat config.json @@ -92,6 +94,15 @@ Update_All_IP_Tables() { done } +# Test function for the root to custom information +# through the network +Send_Information() { + ls + cd test-2/ + p2prc --amd "test message" + cd .. +} + # ---------------- Work flow test --------------- @@ -104,6 +115,12 @@ P2PRC_instances 3 ## Start instances Start_all_instances 3 + +# Send test information from node 1 +sleep 10 +Send_Information + +sleep 10 ## List ip tables of nodes started IP_Tables_after_Started 3 # @@ -112,3 +129,4 @@ Remove_all_test_files ## Kill all instances Kill_all_instances + diff --git a/client/clientIPTable/AddCustomInformationToIPTable.go b/client/clientIPTable/AddCustomInformationToIPTable.go index a6b8c4e..b8f0d60 100644 --- a/client/clientIPTable/AddCustomInformationToIPTable.go +++ b/client/clientIPTable/AddCustomInformationToIPTable.go @@ -1,40 +1,40 @@ package clientIPTable import ( - "errors" - "github.com/Akilan1999/p2p-rendering-computation/config" - "github.com/Akilan1999/p2p-rendering-computation/p2p" + "errors" + "github.com/Akilan1999/p2p-rendering-computation/config" + "github.com/Akilan1999/p2p-rendering-computation/p2p" ) func AddCustomInformationToIPTable(text string) error { - // Get config information - Config, err := config.ConfigInit(nil, nil) - if err != nil { - return err - } + // Get config information + Config, err := config.ConfigInit(nil, nil) + if err != nil { + return err + } - // Get IPTable information - table, err := p2p.ReadIpTable() - if err != nil { - return err - } + // Get IPTable information + table, err := p2p.ReadIpTable() + if err != nil { + return err + } - found := false + found := false - for i, _ := range table.IpAddress { - if table.IpAddress[i].Name == Config.MachineName { - table.IpAddress[i].CustomInformation = text - found = true - } - } + for i, _ := range table.IpAddress { + if table.IpAddress[i].Name == Config.MachineName { + table.IpAddress[i].CustomInformation = text + found = true + } + } - if found { - table.WriteIpTable() - // update IPTable after modified entry - go UpdateIpTableListClient() - } else { - return errors.New("start server with p2prc -s as the server is currently not running") - } + if found { + table.WriteIpTable() + // update IPTable after modified entry + UpdateIpTableListClient() + } else { + return errors.New("start server with p2prc -s as the server is currently not running") + } - return nil + return nil } diff --git a/p2p/iptable.go b/p2p/iptable.go index d64e203..52b7f9c 100644 --- a/p2p/iptable.go +++ b/p2p/iptable.go @@ -1,296 +1,297 @@ package p2p import ( - "bytes" - "crypto/sha256" - "encoding/json" - "fmt" - "github.com/Akilan1999/p2p-rendering-computation/config" - "io/ioutil" - "net" - "net/http" - "os" - "time" + "bytes" + "crypto/sha256" + "encoding/json" + "fmt" + "github.com/Akilan1999/p2p-rendering-computation/config" + "io/ioutil" + "net" + "net/http" + "os" + "time" ) // Get IP table Data type IpAddresses struct { - IpAddress []IpAddress `json:"ip_address"` + IpAddress []IpAddress `json:"ip_address"` } type IpAddress struct { - Name string `json:"Name"` - MachineUsername string `json:"MachineUsername"` - Ipv4 string `json:"IPV4"` - Ipv6 string `json:"IPV6"` - Latency time.Duration `json:"Latency"` - Download float64 `json:"Download"` - Upload float64 `json:"Upload"` - ServerPort string `json:"ServerPort"` - BareMetalSSHPort string `json:"BareMetalSSHPort"` - NAT bool `json:"NAT"` - EscapeImplementation string `json:"EscapeImplementation"` - ProxyServer bool `json:"ProxyServer"` - UnSafeMode bool `json:"UnSafeMode"` - PublicKey string `json:"PublicKey"` - CustomInformation string `json:"CustomInformation"` - //CustomInformationKey []byte `json:"CustomInformationKey"` + Name string `json:"Name"` + MachineUsername string `json:"MachineUsername"` + Ipv4 string `json:"IPV4"` + Ipv6 string `json:"IPV6"` + Latency time.Duration `json:"Latency"` + Download float64 `json:"Download"` + Upload float64 `json:"Upload"` + ServerPort string `json:"ServerPort"` + BareMetalSSHPort string `json:"BareMetalSSHPort"` + NAT bool `json:"NAT"` + EscapeImplementation string `json:"EscapeImplementation"` + ProxyServer bool `json:"ProxyServer"` + UnSafeMode bool `json:"UnSafeMode"` + PublicKey string `json:"PublicKey"` + CustomInformation string `json:"CustomInformation"` + //CustomInformationKey []byte `json:"CustomInformationKey"` } type IP struct { - Query string + Query string } var Test = false // ReadIpTable Read data from Ip tables from json file func ReadIpTable() (*IpAddresses, error) { - // Get Path from config - config, err := config.ConfigInit(nil, nil) - if err != nil { - return nil, err - } - jsonFile, err := os.Open(config.IPTable) - // if we os.Open returns an error then handle it - if err != nil { - return nil, err - } + // Get Path from config + config, err := config.ConfigInit(nil, nil) + if err != nil { + return nil, err + } + jsonFile, err := os.Open(config.IPTable) + // if we os.Open returns an error then handle it + if err != nil { + return nil, err + } - // defer the closing of our jsonFile so that we can parse it later on - defer jsonFile.Close() + // defer the closing of our jsonFile so that we can parse it later on + defer jsonFile.Close() - // read our opened xmlFile as a byte array. - byteValue, _ := ioutil.ReadAll(jsonFile) + // read our opened xmlFile as a byte array. + byteValue, _ := ioutil.ReadAll(jsonFile) - // we initialize our Users array - var ipAddresses IpAddresses + // we initialize our Users array + var ipAddresses IpAddresses - // we unmarshal our byteArray which contains our - // jsonFile's content into 'users' which we defined above - json.Unmarshal(byteValue, &ipAddresses) + // we unmarshal our byteArray which contains our + // jsonFile's content into 'users' which we defined above + json.Unmarshal(byteValue, &ipAddresses) - var PublicIP IpAddress + var PublicIP IpAddress - ipv6, err := GetCurrentIPV6() - if err != nil { - return nil, err - } + ipv6, err := GetCurrentIPV6() + if err != nil { + return nil, err + } - ip, err := CurrentPublicIP() - if err != nil { - return nil, err - } - PublicIP.Ipv4 = ip - PublicIP.Ipv6 = ipv6 - PublicIP.ServerPort = config.ServerPort - PublicIP.Name = config.MachineName - PublicIP.NAT = config.BehindNAT - PublicIP.EscapeImplementation = "None" + ip, err := CurrentPublicIP() + if err != nil { + return nil, err + } + PublicIP.Ipv4 = ip + PublicIP.Ipv6 = ipv6 + PublicIP.ServerPort = config.ServerPort + PublicIP.Name = config.MachineName + PublicIP.NAT = config.BehindNAT + PublicIP.EscapeImplementation = "None" - // Updates current machine IP address to the IP table - ipAddresses.IpAddress = append(ipAddresses.IpAddress, PublicIP) + // Updates current machine IP address to the IP table + ipAddresses.IpAddress = append(ipAddresses.IpAddress, PublicIP) - //before writing to iptable ensures the duplicates are removed - if err = ipAddresses.RemoveDuplicates(); err != nil { - return nil, err - } + //before writing to iptable ensures the duplicates are removed + if err = ipAddresses.RemoveDuplicates(); err != nil { + return nil, err + } - return &ipAddresses, nil + return &ipAddresses, nil } // WriteIpTable Write to IP table json file func (i *IpAddresses) WriteIpTable() error { - //before writing to iptable ensures the duplicates are removed - if err := i.RemoveDuplicates(); err != nil { - return err - } + //before writing to iptable ensures the duplicates are removed + if err := i.RemoveDuplicates(); err != nil { + return err + } - file, err := json.MarshalIndent(i, "", " ") - if err != nil { - return err - } + file, err := json.MarshalIndent(i, "", " ") + if err != nil { + return err + } - // Get Path from config - config, err := config.ConfigInit(nil, nil) - if err != nil { - return err - } + // Get Path from config + config, err := config.ConfigInit(nil, nil) + if err != nil { + return err + } - err = ioutil.WriteFile(config.IPTable, file, 0644) - if err != nil { - return err - } + err = ioutil.WriteFile(config.IPTable, file, 0644) + if err != nil { + return err + } - return nil + return nil } // PrintIpTable Print Ip table data for Cli func PrintIpTable() error { - table, err := ReadIpTable() - // - if err != nil { - return err - } - // - //for i := 0; i < len(table.IpAddress); i++ { - // fmt.Printf("\nMachine Name: %s\nIP Address: %s\nIPV6: %s\nLatency: %s\nServerPort: %s\nbehindNAT: %s\nEscapeImplementation: %s\n-----------"+ - // "-----------------\n", table.IpAddress[i].Name, table.IpAddress[i].Ipv4, table.IpAddress[i].Ipv6, - // table.IpAddress[i].Latency, table.IpAddress[i].ServerPort, table.IpAddress[i].NAT, table.IpAddress[i].EscapeImplementation) - //} - PrettyPrint(table) + table, err := ReadIpTable() + // + if err != nil { + return err + } + // + //for i := 0; i < len(table.IpAddress); i++ { + // fmt.Printf("\nMachine Name: %s\nIP Address: %s\nIPV6: %s\nLatency: %s\nServerPort: %s\nbehindNAT: %s\nEscapeImplementation: %s\n-----------"+ + // "-----------------\n", table.IpAddress[i].Name, table.IpAddress[i].Ipv4, table.IpAddress[i].Ipv6, + // table.IpAddress[i].Latency, table.IpAddress[i].ServerPort, table.IpAddress[i].NAT, table.IpAddress[i].EscapeImplementation) + //} + PrettyPrint(table) - return nil + return nil } // RemoveDuplicates This is a temporary fix current functions failing to remove // Duplicate IP addresses from local IP table func (table *IpAddresses) RemoveDuplicates() error { - var NoDuplicates IpAddresses - for i, _ := range table.IpAddress { - Exists := false - for k := range NoDuplicates.IpAddress { - // Statements checked for - // - duplicate IPV4 addresses [:] - // - duplicate IPV6 addresses [] - // - Node is behind NAT and no escape implementation provided - if (NoDuplicates.IpAddress[k].Ipv4 != "" && NoDuplicates.IpAddress[k].Ipv4 == table.IpAddress[i].Ipv4 && - NoDuplicates.IpAddress[k].ServerPort == table.IpAddress[i].ServerPort) || - (NoDuplicates.IpAddress[k].Ipv6 != "" && NoDuplicates.IpAddress[k].Ipv6 == table.IpAddress[i].Ipv6) { - Exists = true - break - } - } + var NoDuplicates IpAddresses + for i, _ := range table.IpAddress { + Exists := false + for k := range NoDuplicates.IpAddress { + // Statements checked for + // - duplicate IPV4 addresses [:] + // - duplicate IPV6 addresses [] + // - Node is behind NAT and no escape implementation provided + if (NoDuplicates.IpAddress[k].Ipv4 != "" && NoDuplicates.IpAddress[k].Ipv4 == table.IpAddress[i].Ipv4 && + NoDuplicates.IpAddress[k].ServerPort == table.IpAddress[i].ServerPort) || + (NoDuplicates.IpAddress[k].Ipv6 != "" && NoDuplicates.IpAddress[k].Ipv6 == table.IpAddress[i].Ipv6) { + Exists = true + break + } + } - if table.IpAddress[i].NAT && table.IpAddress[i].EscapeImplementation == "None" { - Exists = true - } + if table.IpAddress[i].NAT && table.IpAddress[i].EscapeImplementation == "None" { + Exists = true + } - if Exists { - continue - } - NoDuplicates.IpAddress = append(NoDuplicates.IpAddress, table.IpAddress[i]) - } + if Exists { + continue + } + NoDuplicates.IpAddress = append(NoDuplicates.IpAddress, table.IpAddress[i]) + } - table.IpAddress = NoDuplicates.IpAddress + table.IpAddress = NoDuplicates.IpAddress - return nil + return nil } // CurrentPublicIP Get Current Public IP address func CurrentPublicIP() (string, error) { - // Get configs - Config, err := config.ConfigInit(nil, nil) - if err != nil { - return "", err - } - // If test mode is on then return local address - if Config.Test { - return "0.0.0.0", nil - } + // Get configs + Config, err := config.ConfigInit(nil, nil) + if err != nil { + return "", err + } + // If test mode is on then return local address + if Config.Test { + return "0.0.0.0", nil + } - req, err := http.Get("http://ip-api.com/json/") - if err != nil { - return "", err - } - defer req.Body.Close() + req, err := http.Get("http://ip-api.com/json/") + if err != nil { + return "", err + } + defer req.Body.Close() - body, err := ioutil.ReadAll(req.Body) - if err != nil { - return "", err - } + body, err := ioutil.ReadAll(req.Body) + if err != nil { + return "", err + } - var ip IP - json.Unmarshal(body, &ip) + var ip IP + json.Unmarshal(body, &ip) + + return ip.Query, nil - return ip.Query, nil } // GetCurrentIPV6 gets the current IPV6 address based on the interface // specified in the config file func GetCurrentIPV6() (string, error) { - Config, err := config.ConfigInit(nil, nil) - if err != nil { - return "", err - } + Config, err := config.ConfigInit(nil, nil) + if err != nil { + return "", err + } - // Fix in future release - //byNameInterface, err := net.InterfaceByName(Config.NetworkInterface) - //if err != nil { - // return "",err - //} - //addresses, err := byNameInterface.Addrs() - //if err != nil { - // return "",err - //} - //if addresses[1].String() == "" { - // return "",errors.New("IPV6 address not detected") - //} - //IP,_,err := net.ParseCIDR(addresses[Config.NetworkInterfaceIPV6Index].String()) - //if err != nil { - // return "",err - //} + // Fix in future release + //byNameInterface, err := net.InterfaceByName(Config.NetworkInterface) + //if err != nil { + // return "",err + //} + //addresses, err := byNameInterface.Addrs() + //if err != nil { + // return "",err + //} + //if addresses[1].String() == "" { + // return "",errors.New("IPV6 address not detected") + //} + //IP,_,err := net.ParseCIDR(addresses[Config.NetworkInterfaceIPV6Index].String()) + //if err != nil { + // return "",err + //} - return Config.IPV6Address, nil + return Config.IPV6Address, nil } // ViewNetworkInterface This function is created to view the network interfaces available func ViewNetworkInterface() error { - ifaces, err := net.Interfaces() - if err != nil { - return err - } - for _, i := range ifaces { - addrs, err := i.Addrs() - if err != nil { - return err - } - for index, a := range addrs { - switch v := a.(type) { - case *net.IPAddr: - fmt.Printf("(%v) %v : %s (%s)\n", index, i.Name, v, v.IP.DefaultMask()) + ifaces, err := net.Interfaces() + if err != nil { + return err + } + for _, i := range ifaces { + addrs, err := i.Addrs() + if err != nil { + return err + } + for index, a := range addrs { + switch v := a.(type) { + case *net.IPAddr: + fmt.Printf("(%v) %v : %s (%s)\n", index, i.Name, v, v.IP.DefaultMask()) - case *net.IPNet: - fmt.Printf("(%v) %v : %s \n", index, i.Name, v) - } + case *net.IPNet: + fmt.Printf("(%v) %v : %s \n", index, i.Name, v) + } - } - } - return nil + } + } + return nil } // Ip4or6 Helper function to check if the IP address is IPV4 or // IPV6 (https://socketloop.com/tutorials/golang-check-if-ip-address-is-version-4-or-6) func Ip4or6(s string) string { - for i := 0; i < len(s); i++ { - switch s[i] { - case '.': - return "version 4" - case ':': - return "version 6" - } - } - return "version 6" + for i := 0; i < len(s); i++ { + switch s[i] { + case '.': + return "version 4" + case ':': + return "version 6" + } + } + return "version 6" } func PrettyPrint(data interface{}) { - var p []byte - // var err := error - p, err := json.MarshalIndent(data, "", "\t") - if err != nil { - fmt.Println(err) - return - } - fmt.Printf("%s \n", p) + var p []byte + // var err := error + p, err := json.MarshalIndent(data, "", "\t") + if err != nil { + fmt.Println(err) + return + } + fmt.Printf("%s \n", p) } func GenerateHashSHA256(text string) []byte { - h := sha256.New() - h.Write([]byte(text)) + h := sha256.New() + h.Write([]byte(text)) - return h.Sum(nil) + return h.Sum(nil) } // ValidateHashSHA256 CustomInformationKey the text and check if the text and @@ -299,12 +300,12 @@ func GenerateHashSHA256(text string) []byte { // SHA256 is the current hashing algorthm // used. func ValidateHashSHA256(text string, Hash []byte) bool { - h := sha256.New() - h.Write([]byte(text)) + h := sha256.New() + h.Write([]byte(text)) - textHash := h.Sum(nil) - if bytes.Equal(textHash, Hash) { - return true - } - return false + textHash := h.Sum(nil) + if bytes.Equal(textHash, Hash) { + return true + } + return false } diff --git a/p2p/speedtest.go b/p2p/speedtest.go index e6b80e9..654390b 100644 --- a/p2p/speedtest.go +++ b/p2p/speedtest.go @@ -1,136 +1,137 @@ package p2p import ( - "github.com/Akilan1999/p2p-rendering-computation/config" + "github.com/Akilan1999/p2p-rendering-computation/config" ) // SpeedTest Runs a speed test and does updates IP tables accordingly func (ip *IpAddresses) SpeedTest() error { - //temp variable to store elements IP addresses and other information - // of IP addresses that are pingable - var ActiveIP IpAddresses + //temp variable to store elements IP addresses and other information + // of IP addresses that are pingable + var ActiveIP IpAddresses - // Index to remove from struct - for _, value := range ip.IpAddress { + // Index to remove from struct + for _, value := range ip.IpAddress { - var err error - //if len(ip.IpAddress) == 1 { - // i = 0 - //} + var err error + //if len(ip.IpAddress) == 1 { + // i = 0 + //} - // Ping Test - err = value.PingTest() + // Ping Test + err = value.PingTest() - if err != nil { - continue - } + if err != nil { + continue + } - //Upload Speed Test - //err = value.UploadSpeed() - //if err != nil { - // return err - //} - // - //err = value.DownloadSpeed() - //if err != nil { - // return err - //} + //Upload Speed Test + //err = value.UploadSpeed() + //if err != nil { + // return err + //} + // + //err = value.DownloadSpeed() + //if err != nil { + // return err + //} - //Set value to the list + //Set value to the list - ActiveIP.IpAddress = append(ActiveIP.IpAddress, value) - } + ActiveIP.IpAddress = append(ActiveIP.IpAddress, value) + } - ip.IpAddress = ActiveIP.IpAddress + ip.IpAddress = ActiveIP.IpAddress - err := ip.WriteIpTable() - if err != nil { - return err - } + err := ip.WriteIpTable() + if err != nil { + return err + } - return nil + return nil } // SpeedTestUpdatedIPTable Called when ip tables from httpclient/server is also passed on func (ip *IpAddresses) SpeedTestUpdatedIPTable() error { - Config, err := config.ConfigInit(nil, nil) - if err != nil { - return err - } + Config, err := config.ConfigInit(nil, nil) + if err != nil { + return err + } - targets, err := ReadIpTable() - if err != nil { - return err - } + targets, err := ReadIpTable() + if err != nil { + return err + } - // Checks if baremetal mode and unsafe mode - // is enabled. If it is enabled it adds the - // the propagated public key to the list. + // Checks if baremetal mode and unsafe mode + // is enabled. If it is enabled it adds the + // the propagated public key to the list. - AddPublicKey := false - if Config.BareMetal && Config.UnsafeMode { - AddPublicKey = true - } + AddPublicKey := false + if Config.BareMetal && Config.UnsafeMode { + AddPublicKey = true + } - // To ensure struct has no duplicates IP addresses - //DoNotRead := targets + // To ensure struct has no duplicates IP addresses + //DoNotRead := targets - // Appends all IP addresses - for i, _ := range targets.IpAddress { + // Appends all IP addresses + for i, _ := range targets.IpAddress { - //To ensure that there are no duplicate IP addresses - Exists := false - for k := range ip.IpAddress { - if AddPublicKey && ip.IpAddress[k].PublicKey != "" { - // This function call (AddAuthorisationKey) is inefficient but to be optimised later on. - // This is because when if the user is running on as unsafe mode the authorization file - // is opened from the SSH directory and then iterates through every single SSH entry - // to find out if the SSH entry exists or not. This will incur multiple CPU cycles - // for no reason. A better approach would be to have been to store the states on memory and only - // add when needed based on the memory location. This is something is to be discussed - // and look upon later on. - AddAuthorisationKey(ip.IpAddress[k].PublicKey) - } - // Checks if both the IPV4 addresses are the same or the IPV6 address is not - // an empty string and IPV6 address are the same - if (ip.IpAddress[k].Ipv4 == targets.IpAddress[i].Ipv4 && targets.IpAddress[i].NAT) || (targets.IpAddress[i].Ipv6 != "" && ip.IpAddress[k].Ipv6 == targets.IpAddress[i].Ipv6) { - Exists = true - break - } - } + //To ensure that there are no duplicate IP addresses + Exists := false + for k := range ip.IpAddress { + if AddPublicKey && ip.IpAddress[k].PublicKey != "" { + // This function call (AddAuthorisationKey) is inefficient but to be optimised later on. + // This is because when if the user is running on as unsafe mode the authorization file + // is opened from the SSH directory and then iterates through every single SSH entry + // to find out if the SSH entry exists or not. This will incur multiple CPU cycles + // for no reason. A better approach would be to have been to store the states on memory and only + // add when needed based on the memory location. This is something is to be discussed + // and look upon later on. + AddAuthorisationKey(ip.IpAddress[k].PublicKey) + } + targets.IpAddress[i].CustomInformation = ip.IpAddress[k].CustomInformation + // Checks if both the IPV4 addresses are the same or the IPV6 address is not + // an empty string and IPV6 address are the same + if (ip.IpAddress[k].Ipv4 == targets.IpAddress[i].Ipv4 && targets.IpAddress[i].NAT) || (targets.IpAddress[i].Ipv6 != "" && ip.IpAddress[k].Ipv6 == targets.IpAddress[i].Ipv6) { + Exists = true + break + } + } - // If the struct exists then continues - if Exists { - continue - } + // If the struct exists then continues + if Exists { + continue + } - ip.IpAddress = append(ip.IpAddress, targets.IpAddress[i]) - } + ip.IpAddress = append(ip.IpAddress, targets.IpAddress[i]) + } - err = ip.SpeedTest() + err = ip.SpeedTest() - if err != nil { - return err - } + if err != nil { + return err + } - return nil + return nil } // LocalSpeedTestIpTable Runs speed test in iptables locally only func LocalSpeedTestIpTable() error { - targets, err := ReadIpTable() - if err != nil { - return err - } + targets, err := ReadIpTable() + if err != nil { + return err + } - err = targets.SpeedTest() - if err != nil { - return err - } + err = targets.SpeedTest() + if err != nil { + return err + } - return nil + return nil } // Helper function to remove element from an array of a struct diff --git a/server/server.go b/server/server.go index 33063fe..baf433a 100644 --- a/server/server.go +++ b/server/server.go @@ -1,479 +1,477 @@ package server import ( - b64 "encoding/base64" - "encoding/json" - "errors" - "fmt" - "github.com/Akilan1999/p2p-rendering-computation/client/clientIPTable" - "github.com/Akilan1999/p2p-rendering-computation/config" - "github.com/Akilan1999/p2p-rendering-computation/p2p" - "github.com/Akilan1999/p2p-rendering-computation/p2p/frp" - "github.com/Akilan1999/p2p-rendering-computation/server/docker" - "github.com/gin-gonic/gin" - "io/ioutil" - "net/http" - "os/user" - "strconv" - "time" + b64 "encoding/base64" + "encoding/json" + "errors" + "fmt" + "github.com/Akilan1999/p2p-rendering-computation/client/clientIPTable" + "github.com/Akilan1999/p2p-rendering-computation/config" + "github.com/Akilan1999/p2p-rendering-computation/p2p" + "github.com/Akilan1999/p2p-rendering-computation/p2p/frp" + "github.com/Akilan1999/p2p-rendering-computation/server/docker" + "github.com/gin-gonic/gin" + "io/ioutil" + "net/http" + "os/user" + "strconv" + "time" ) type ReverseProxy struct { - IPAddress string - Port string + IPAddress string + Port string } // ReverseProxies Reverse to the map such as ReverseProxies[]ReverseProxy type var ReverseProxies map[string]ReverseProxy func Server() (*gin.Engine, error) { - r := gin.Default() + r := gin.Default() - // "The make function allocates and initializes a hash map data - //structure and returns a map value that points to it. - //The specifics of that data structure are an implementation - //detail of the runtime and are not specified by the language itself." - // source: https://go.dev/blog/maps - ReverseProxies = make(map[string]ReverseProxy) + // "The make function allocates and initializes a hash map data + //structure and returns a map value that points to it. + //The specifics of that data structure are an implementation + //detail of the runtime and are not specified by the language itself." + // source: https://go.dev/blog/maps + ReverseProxies = make(map[string]ReverseProxy) - //Get Server port based on the config file - config, err := config.ConfigInit(nil, nil) - if err != nil { - return nil, err - } + //Get Server port based on the config file + config, err := config.ConfigInit(nil, nil) + if err != nil { + return nil, err + } - // update IPTable with new port and ip address and update ip table - var ProxyIpAddr p2p.IpAddress - var lowestLatencyIpAddress p2p.IpAddress + // update IPTable with new port and ip address and update ip table + var ProxyIpAddr p2p.IpAddress + var lowestLatencyIpAddress p2p.IpAddress - // Gets default information of the server - r.GET("/server_info", func(c *gin.Context) { - c.JSON(http.StatusOK, ServerInfo()) - }) + // Gets default information of the server + r.GET("/server_info", func(c *gin.Context) { + c.JSON(http.StatusOK, ServerInfo()) + }) - // Speed test with 50 mbps - r.GET("/50", func(c *gin.Context) { - // Get Path from config - c.File(config.SpeedTestFile) - }) + // Speed test with 50 mbps + r.GET("/50", func(c *gin.Context) { + // Get Path from config + c.File(config.SpeedTestFile) + }) - // Route build to do a speed test - r.GET("/upload", func(c *gin.Context) { - file, _ := c.FormFile("file") + // Route build to do a speed test + r.GET("/upload", func(c *gin.Context) { + file, _ := c.FormFile("file") - // Upload the file to specific dst. - // c.SaveUploadedFile(file, dst) + // Upload the file to specific dst. + // c.SaveUploadedFile(file, dst) - c.String(http.StatusOK, fmt.Sprintf("'%s' uploaded!", file.Filename)) - }) + c.String(http.StatusOK, fmt.Sprintf("'%s' uploaded!", file.Filename)) + }) - //Gets Ip Table from server node - r.POST("/IpTable", func(c *gin.Context) { - // Getting IPV4 address of client - //var ClientHost p2p.IpAddress - // - //if p2p.Ip4or6(c.ClientIP()) == "version 6" { - // ClientHost.Ipv6 = c.ClientIP() - //} else { - // ClientHost.Ipv4 = c.ClientIP() - //} + //Gets Ip Table from server node + r.POST("/IpTable", func(c *gin.Context) { + // Getting IPV4 address of client + //var ClientHost p2p.IpAddress + // + //if p2p.Ip4or6(c.ClientIP()) == "version 6" { + // ClientHost.Ipv6 = c.ClientIP() + //} else { + // ClientHost.Ipv4 = c.ClientIP() + //} - // Variable to store IP table information - var IPTable p2p.IpAddresses + // Variable to store IP table information + var IPTable p2p.IpAddresses - // Receive file from POST request - body, err := c.FormFile("json") - if err != nil { - c.String(http.StatusOK, fmt.Sprint(err)) - } + // Receive file from POST request + body, err := c.FormFile("json") + if err != nil { + c.String(http.StatusOK, fmt.Sprint(err)) + } - // Open file - open, err := body.Open() - if err != nil { - c.String(http.StatusOK, fmt.Sprint(err)) - } + // Open file + open, err := body.Open() + if err != nil { + c.String(http.StatusOK, fmt.Sprint(err)) + } - // Open received file - file, err := ioutil.ReadAll(open) - if err != nil { - c.String(http.StatusOK, fmt.Sprint(err)) - } + // Open received file + file, err := ioutil.ReadAll(open) + if err != nil { + c.String(http.StatusOK, fmt.Sprint(err)) + } - json.Unmarshal(file, &IPTable) + json.Unmarshal(file, &IPTable) - //Add Client IP address to IPTable struct - //IPTable.IpAddress = append(IPTable.IpAddress, ClientHost) + //Add Client IP address to IPTable struct + //IPTable.IpAddress = append(IPTable.IpAddress, ClientHost) - // Runs speed test to return only servers in the IP table pingable - err = IPTable.SpeedTestUpdatedIPTable() - if err != nil { - c.String(http.StatusOK, fmt.Sprint(err)) - } + // Runs speed test to return only servers in the IP table pingable + err = IPTable.SpeedTestUpdatedIPTable() + if err != nil { + c.String(http.StatusOK, fmt.Sprint(err)) + } - // Reads IP addresses from ip table - IpAddresses, err := p2p.ReadIpTable() - if err != nil { - c.String(http.StatusOK, fmt.Sprint(err)) - } + // Reads IP addresses from ip table + IpAddresses, err := p2p.ReadIpTable() + if err != nil { + c.String(http.StatusOK, fmt.Sprint(err)) + } - c.JSON(http.StatusOK, IpAddresses) - }) + c.JSON(http.StatusOK, IpAddresses) + }) - // Starts docker container in server - r.GET("/startcontainer", func(c *gin.Context) { - // Get Number of ports to open and whether to use GPU or not - Ports := c.DefaultQuery("ports", "0") - GPU := c.DefaultQuery("GPU", "false") - ContainerName := c.DefaultQuery("ContainerName", "") - BaseImage := c.DefaultQuery("BaseImage", "") - PublicKey := c.DefaultQuery("PublicKey", "") - var PortsInt int + // Starts docker container in server + r.GET("/startcontainer", func(c *gin.Context) { + // Get Number of ports to open and whether to use GPU or not + Ports := c.DefaultQuery("ports", "0") + GPU := c.DefaultQuery("GPU", "false") + ContainerName := c.DefaultQuery("ContainerName", "") + BaseImage := c.DefaultQuery("BaseImage", "") + PublicKey := c.DefaultQuery("PublicKey", "") + var PortsInt int - if PublicKey == "" { - c.String(http.StatusInternalServerError, fmt.Sprintf("error: %s", "Publickey not passed")) - } + if PublicKey == "" { + c.String(http.StatusInternalServerError, fmt.Sprintf("error: %s", "Publickey not passed")) + } - PublicKeyDecoded, err := b64.StdEncoding.DecodeString(PublicKey) - if err != nil { - c.String(http.StatusInternalServerError, fmt.Sprintf("error: %s", err)) - } + PublicKeyDecoded, err := b64.StdEncoding.DecodeString(PublicKey) + if err != nil { + c.String(http.StatusInternalServerError, fmt.Sprintf("error: %s", err)) + } - // Convert Get Request value to int - fmt.Sscanf(Ports, "%d", &PortsInt) + // Convert Get Request value to int + fmt.Sscanf(Ports, "%d", &PortsInt) - fmt.Println(string(PublicKeyDecoded[:])) + // Creates container and returns-back result to + // access container + resp, err := docker.BuildRunContainer(PortsInt, GPU, ContainerName, BaseImage, string(PublicKeyDecoded[:])) - // Creates container and returns-back result to - // access container - resp, err := docker.BuildRunContainer(PortsInt, GPU, ContainerName, BaseImage, string(PublicKeyDecoded[:])) + if err != nil { + c.String(http.StatusInternalServerError, fmt.Sprintf("error: %s", err)) + } - if err != nil { - c.String(http.StatusInternalServerError, fmt.Sprintf("error: %s", err)) - } + // Ensures that FRP is triggered only if a proxy address is provided + if ProxyIpAddr.Ipv4 != "" && c.Request.Host != "localhost:"+config.ServerPort && c.Request.Host != "0.0.0.0:"+config.ServerPort { + resp, err = frp.StartFRPCDockerContainer(ProxyIpAddr.Ipv4, lowestLatencyIpAddress.ServerPort, resp) + if err != nil { + c.String(http.StatusInternalServerError, fmt.Sprintf("error: %s", err)) + } + } - // Ensures that FRP is triggered only if a proxy address is provided - if ProxyIpAddr.Ipv4 != "" && c.Request.Host != "localhost:"+config.ServerPort && c.Request.Host != "0.0.0.0:"+config.ServerPort { - resp, err = frp.StartFRPCDockerContainer(ProxyIpAddr.Ipv4, lowestLatencyIpAddress.ServerPort, resp) - if err != nil { - c.String(http.StatusInternalServerError, fmt.Sprintf("error: %s", err)) - } - } + c.JSON(http.StatusOK, resp) + }) - c.JSON(http.StatusOK, resp) - }) + //Remove container + r.GET("/RemoveContainer", func(c *gin.Context) { + ID := c.DefaultQuery("id", "0") + if err := docker.StopAndRemoveContainer(ID); err != nil { + c.String(http.StatusInternalServerError, fmt.Sprintf("error: %s", err)) + } + c.String(http.StatusOK, "success") + }) - //Remove container - r.GET("/RemoveContainer", func(c *gin.Context) { - ID := c.DefaultQuery("id", "0") - if err := docker.StopAndRemoveContainer(ID); err != nil { - c.String(http.StatusInternalServerError, fmt.Sprintf("error: %s", err)) - } - c.String(http.StatusOK, "success") - }) + //Show images available + r.GET("/ShowImages", func(c *gin.Context) { + resp, err := docker.ViewAllContainers() + if err != nil { + c.String(http.StatusInternalServerError, fmt.Sprintf("error: %s", err)) + } + c.JSON(http.StatusOK, resp) + }) - //Show images available - r.GET("/ShowImages", func(c *gin.Context) { - resp, err := docker.ViewAllContainers() - if err != nil { - c.String(http.StatusInternalServerError, fmt.Sprintf("error: %s", err)) - } - c.JSON(http.StatusOK, resp) - }) + // Request for port no from Server with address + r.GET("/FRPPort", func(c *gin.Context) { + port, err := frp.StartFRPProxyFromRandom() + if err != nil { + c.String(http.StatusInternalServerError, fmt.Sprintf("error: %s", err)) + } - // Request for port no from Server with address - r.GET("/FRPPort", func(c *gin.Context) { - port, err := frp.StartFRPProxyFromRandom() - if err != nil { - c.String(http.StatusInternalServerError, fmt.Sprintf("error: %s", err)) - } + c.String(http.StatusOK, strconv.Itoa(port)) + }) - c.String(http.StatusOK, strconv.Itoa(port)) - }) + r.GET("/MAPPort", func(c *gin.Context) { + Ports := c.DefaultQuery("port", "0") + DomainName := c.DefaultQuery("domain_name", "") + url, _, err := MapPort(Ports, DomainName) + if err != nil { + c.String(http.StatusInternalServerError, fmt.Sprintf("error: %s", err)) + } - r.GET("/MAPPort", func(c *gin.Context) { - Ports := c.DefaultQuery("port", "0") - DomainName := c.DefaultQuery("domain_name", "") - url, _, err := MapPort(Ports, DomainName) - if err != nil { - c.String(http.StatusInternalServerError, fmt.Sprintf("error: %s", err)) - } + c.String(http.StatusOK, url) + }) - c.String(http.StatusOK, url) - }) + r.GET("/AddProxy", func(c *gin.Context) { + DomainName := c.DefaultQuery("domain_name", "") + ip_address := c.DefaultQuery("ip_address", "") + Ports := c.DefaultQuery("port", "") - r.GET("/AddProxy", func(c *gin.Context) { - DomainName := c.DefaultQuery("domain_name", "") - ip_address := c.DefaultQuery("ip_address", "") - Ports := c.DefaultQuery("port", "") + if DomainName == "" || ip_address == "" || Ports == "" { + c.String(http.StatusInternalServerError, fmt.Sprintf("All get parameters npt provided"+ + " do ensure domain_name, ip_Address and port no is provided")) + } - if DomainName == "" || ip_address == "" || Ports == "" { - c.String(http.StatusInternalServerError, fmt.Sprintf("All get parameters npt provided"+ - " do ensure domain_name, ip_Address and port no is provided")) - } + err := SaveRegistration(DomainName, ip_address+":"+Ports) + if err != nil { + c.String(http.StatusInternalServerError, fmt.Sprintf(err.Error())) + } - err := SaveRegistration(DomainName, ip_address+":"+Ports) - if err != nil { - c.String(http.StatusInternalServerError, fmt.Sprintf(err.Error())) - } + //_, ok := ReverseProxies[DomainName] + //// To check if the subdomain entry exists + //if ok { + // c.String(http.StatusInternalServerError, fmt.Sprintf("The domain entry already exists as a reverse"+ + // " proxy entry")) + //} + // + //// added proxy as a map entry + //ReverseProxies[DomainName] = ReverseProxy{IPAddress: ip_address, Port: Ports} + c.String(http.StatusOK, "Sucess") - //_, ok := ReverseProxies[DomainName] - //// To check if the subdomain entry exists - //if ok { - // c.String(http.StatusInternalServerError, fmt.Sprintf("The domain entry already exists as a reverse"+ - // " proxy entry")) - //} - // - //// added proxy as a map entry - //ReverseProxies[DomainName] = ReverseProxy{IPAddress: ip_address, Port: Ports} - c.String(http.StatusOK, "Sucess") + }) - }) + //r.GET("/RemoveProxy", func(c *gin.Context) { + // DomainName := c.DefaultQuery("domain_name", "") + // + // _, ok := ReverseProxies[DomainName] + // if !ok { + // c.String(http.StatusInternalServerError, fmt.Sprintf("Domain name does exist in entries of proxies")) + // } else { + // delete(ReverseProxies, DomainName) + // } + // + //}) - //r.GET("/RemoveProxy", func(c *gin.Context) { - // DomainName := c.DefaultQuery("domain_name", "") - // - // _, ok := ReverseProxies[DomainName] - // if !ok { - // c.String(http.StatusInternalServerError, fmt.Sprintf("Domain name does exist in entries of proxies")) - // } else { - // delete(ReverseProxies, DomainName) - // } - // - //}) + // If there is a proxy port specified + // then starts the FRP server + //if config.FRPServerPort != "0" { + // go frp.StartFRPProxyFromRandom() + //} - // If there is a proxy port specified - // then starts the FRP server - //if config.FRPServerPort != "0" { - // go frp.StartFRPProxyFromRandom() - //} + // Remove nodes currently not pingable + clientIPTable.RemoveOfflineNodes() - // Remove nodes currently not pingable - clientIPTable.RemoveOfflineNodes() + table, err := p2p.ReadIpTable() - table, err := p2p.ReadIpTable() + // TODO check if IPV6 or Proxy port is specified + // if not update current entry as proxy address + // with appropriate port on IP Table + if config.BehindNAT { + if err != nil { + return nil, err + } - // TODO check if IPV6 or Proxy port is specified - // if not update current entry as proxy address - // with appropriate port on IP Table - if config.BehindNAT { - if err != nil { - return nil, err - } + var lowestLatency int64 + // random large number + lowestLatency = 10000000 - var lowestLatency int64 - // random large number - lowestLatency = 10000000 + for i, _ := range table.IpAddress { + // Checks if the ping is the lowest and if the following node is acting as a proxy + //if table.IpAddress[i].Latency.Milliseconds() < lowestLatency && table.IpAddress[i].ProxyPort != "" { + if table.IpAddress[i].Latency.Milliseconds() < lowestLatency && !table.IpAddress[i].NAT { + lowestLatency = table.IpAddress[i].Latency.Milliseconds() + lowestLatencyIpAddress = table.IpAddress[i] + } + } - for i, _ := range table.IpAddress { - // Checks if the ping is the lowest and if the following node is acting as a proxy - //if table.IpAddress[i].Latency.Milliseconds() < lowestLatency && table.IpAddress[i].ProxyPort != "" { - if table.IpAddress[i].Latency.Milliseconds() < lowestLatency && !table.IpAddress[i].NAT { - lowestLatency = table.IpAddress[i].Latency.Milliseconds() - lowestLatencyIpAddress = table.IpAddress[i] - } - } + // If there is an identified node + if lowestLatency != 10000000 { + serverPort, err := frp.GetFRPServerPort("http://" + lowestLatencyIpAddress.Ipv4 + ":" + lowestLatencyIpAddress.ServerPort) + if err != nil { + return nil, err + } + // Create 3 second delay to allow FRP server to start + time.Sleep(1 * time.Second) + // Starts FRP as a client with + proxyPort, err := frp.StartFRPClientForServer(lowestLatencyIpAddress.Ipv4, serverPort, config.ServerPort, "") + if err != nil { + return nil, err + } - // If there is an identified node - if lowestLatency != 10000000 { - serverPort, err := frp.GetFRPServerPort("http://" + lowestLatencyIpAddress.Ipv4 + ":" + lowestLatencyIpAddress.ServerPort) - if err != nil { - return nil, err - } - // Create 3 second delay to allow FRP server to start - time.Sleep(1 * time.Second) - // Starts FRP as a client with - proxyPort, err := frp.StartFRPClientForServer(lowestLatencyIpAddress.Ipv4, serverPort, config.ServerPort, "") - if err != nil { - return nil, err - } + // updating with the current proxy address + ProxyIpAddr.Ipv4 = lowestLatencyIpAddress.Ipv4 + ProxyIpAddr.ServerPort = proxyPort + ProxyIpAddr.Name = config.MachineName + ProxyIpAddr.NAT = false + ProxyIpAddr.ProxyServer = false + ProxyIpAddr.EscapeImplementation = "FRP" - // updating with the current proxy address - ProxyIpAddr.Ipv4 = lowestLatencyIpAddress.Ipv4 - ProxyIpAddr.ServerPort = proxyPort - ProxyIpAddr.Name = config.MachineName - ProxyIpAddr.NAT = false - ProxyIpAddr.ProxyServer = false - ProxyIpAddr.EscapeImplementation = "FRP" + if config.BareMetal { + _, SSHPort, err := MapPort("22", "") + if err != nil { + return nil, err + } + ProxyIpAddr.BareMetalSSHPort = SSHPort + } - if config.BareMetal { - _, SSHPort, err := MapPort("22", "") - if err != nil { - return nil, err - } - ProxyIpAddr.BareMetalSSHPort = SSHPort - } + //ProxyIpAddr.CustomInformationKey = p2p.GenerateHashSHA256(config.IPTableKey) + // write information back to the IP Table + } - //ProxyIpAddr.CustomInformationKey = p2p.GenerateHashSHA256(config.IPTableKey) - // write information back to the IP Table - } + } else { + ProxyIpAddr.Ipv4, err = p2p.CurrentPublicIP() + if err != nil { + fmt.Println(err) + } - } else { - ProxyIpAddr.Ipv4, err = p2p.CurrentPublicIP() - if err != nil { - fmt.Println(err) - } + ProxyIpAddr.ServerPort = config.ServerPort + ProxyIpAddr.Name = config.MachineName + ProxyIpAddr.NAT = false + if config.ProxyPort != "" { + ProxyIpAddr.ProxyServer = true + } + ProxyIpAddr.EscapeImplementation = "" + if config.BareMetal { + ProxyIpAddr.BareMetalSSHPort = "22" + } - ProxyIpAddr.ServerPort = config.ServerPort - ProxyIpAddr.Name = config.MachineName - ProxyIpAddr.NAT = false - if config.ProxyPort != "" { - ProxyIpAddr.ProxyServer = true - } - ProxyIpAddr.EscapeImplementation = "" - if config.BareMetal { - ProxyIpAddr.BareMetalSSHPort = "22" - } + } - } + // Get machine username + currentUser, err := user.Current() + if err != nil { + return nil, err + } + // Add username p2prc binary is being run under + ProxyIpAddr.MachineUsername = currentUser.Username + ProxyIpAddr.UnSafeMode = config.UnsafeMode + // Adds the public key information to the IPTable + // improving transmission of IPTables without the + // entire public key is future work to be improved + // in the P2PRC protocol level (Improving by adding + // UDP with TCP reliability layer). + ProxyIpAddr.PublicKey, err = config.GetPublicKey() - // Get machine username - currentUser, err := user.Current() - if err != nil { - return nil, err - } - // Add username p2prc binary is being run under - ProxyIpAddr.MachineUsername = currentUser.Username - ProxyIpAddr.UnSafeMode = config.UnsafeMode - // Adds the public key information to the IPTable - // improving transmission of IPTables without the - // entire public key is future work to be improved - // in the P2PRC protocol level (Improving by adding - // UDP with TCP reliability layer). - ProxyIpAddr.PublicKey, err = config.GetPublicKey() + if err != nil { + return nil, err + } - if err != nil { - return nil, err - } + // append the following to the ip table + table.IpAddress = append(table.IpAddress, ProxyIpAddr) - // append the following to the ip table - table.IpAddress = append(table.IpAddress, ProxyIpAddr) + // Writing results to the IPTable + err = table.WriteIpTable() + if err != nil { + return nil, err + } - // Writing results to the IPTable - err = table.WriteIpTable() - if err != nil { - return nil, err - } + // update ip table + go func() error { + err := clientIPTable.UpdateIpTableListClient() + if err != nil { + fmt.Println(err) + return err + } + return nil + }() - // update ip table - go func() error { - err := clientIPTable.UpdateIpTableListClient() - if err != nil { - fmt.Println(err) - return err - } - return nil - }() + if config.ProxyPort != "" { + go ProxyRun(config.ProxyPort) + } - if config.ProxyPort != "" { - go ProxyRun(config.ProxyPort) - } + // Run gin server on the specified port + go r.Run(":" + config.ServerPort) - // Run gin server on the specified port - go r.Run(":" + config.ServerPort) - - return r, nil + return r, nil } func MapPort(port string, domainName string) (string, string, error) { - // if server address is provided to do call RESTAPI to remotely open port. - //if serverAddress != "" { - // requestURL := fmt.Sprintf("http://%v/MAPPort?port=%v&domain_name=%v", serverAddress, port, domainName) - // req, err := http.NewRequest(http.MethodGet, requestURL, nil) - // if err != nil { - // return "", "", err - // } - // - // res, err := http.DefaultClient.Do(req) - // if err != nil { - // return "", "", err - // } - // - // resBody, err := io.ReadAll(res.Body) - // if err != nil { - // return "", "", err - // } - // - // _, Exposedport, err := net.SplitHostPort(string(resBody)) - // if err != nil { - // return "", "", err - // } - // - // return string(resBody), Exposedport, nil - //} + // if server address is provided to do call RESTAPI to remotely open port. + //if serverAddress != "" { + // requestURL := fmt.Sprintf("http://%v/MAPPort?port=%v&domain_name=%v", serverAddress, port, domainName) + // req, err := http.NewRequest(http.MethodGet, requestURL, nil) + // if err != nil { + // return "", "", err + // } + // + // res, err := http.DefaultClient.Do(req) + // if err != nil { + // return "", "", err + // } + // + // resBody, err := io.ReadAll(res.Body) + // if err != nil { + // return "", "", err + // } + // + // _, Exposedport, err := net.SplitHostPort(string(resBody)) + // if err != nil { + // return "", "", err + // } + // + // return string(resBody), Exposedport, nil + //} - //Get Server port based on the config file - config, err := config.ConfigInit(nil, nil) - if err != nil { - return "", "", err - } + //Get Server port based on the config file + config, err := config.ConfigInit(nil, nil) + if err != nil { + return "", "", err + } - // update IPTable with new port and ip address and update ip table - var ProxyIpAddr p2p.IpAddress - var lowestLatencyIpAddress p2p.IpAddress + // update IPTable with new port and ip address and update ip table + var ProxyIpAddr p2p.IpAddress + var lowestLatencyIpAddress p2p.IpAddress - clientIPTable.RemoveOfflineNodes() + clientIPTable.RemoveOfflineNodes() - table, err := p2p.ReadIpTable() - if err != nil { - return "", "", err - } + table, err := p2p.ReadIpTable() + if err != nil { + return "", "", err + } - var lowestLatency int64 - // random large number - lowestLatency = 10000000 + var lowestLatency int64 + // random large number + lowestLatency = 10000000 - for i, _ := range table.IpAddress { - // Checks if the ping is the lowest and if the following node is acting as a proxy - //if table.IpAddress[i].Latency.Milliseconds() < lowestLatency && table.IpAddress[i].ProxyPort != "" { - if table.IpAddress[i].Latency.Milliseconds() < lowestLatency && !table.IpAddress[i].NAT { - // Filter based on nodes with proxy enabled - if domainName != "" && table.IpAddress[i].ProxyServer { - lowestLatency = table.IpAddress[i].Latency.Milliseconds() - lowestLatencyIpAddress = table.IpAddress[i] - continue - } - lowestLatency = table.IpAddress[i].Latency.Milliseconds() - lowestLatencyIpAddress = table.IpAddress[i] - } - } + for i, _ := range table.IpAddress { + // Checks if the ping is the lowest and if the following node is acting as a proxy + //if table.IpAddress[i].Latency.Milliseconds() < lowestLatency && table.IpAddress[i].ProxyPort != "" { + if table.IpAddress[i].Latency.Milliseconds() < lowestLatency && !table.IpAddress[i].NAT { + // Filter based on nodes with proxy enabled + if domainName != "" && table.IpAddress[i].ProxyServer { + lowestLatency = table.IpAddress[i].Latency.Milliseconds() + lowestLatencyIpAddress = table.IpAddress[i] + continue + } + lowestLatency = table.IpAddress[i].Latency.Milliseconds() + lowestLatencyIpAddress = table.IpAddress[i] + } + } - // If there is an identified node - if lowestLatency != 10000000 { - serverPort, err := frp.GetFRPServerPort("http://" + lowestLatencyIpAddress.Ipv4 + ":" + lowestLatencyIpAddress.ServerPort) - if err != nil { - return "", "", err - } - // Create 3 second delay to allow FRP server to start - time.Sleep(1 * time.Second) - // Starts FRP as a client with - proxyPort, err := frp.StartFRPClientForServer(lowestLatencyIpAddress.Ipv4, serverPort, port, "") - if err != nil { - return "", "", err - } + // If there is an identified node + if lowestLatency != 10000000 { + serverPort, err := frp.GetFRPServerPort("http://" + lowestLatencyIpAddress.Ipv4 + ":" + lowestLatencyIpAddress.ServerPort) + if err != nil { + return "", "", err + } + // Create 3 second delay to allow FRP server to start + time.Sleep(1 * time.Second) + // Starts FRP as a client with + proxyPort, err := frp.StartFRPClientForServer(lowestLatencyIpAddress.Ipv4, serverPort, port, "") + if err != nil { + return "", "", err + } - // Doing the proxy mapping for the domain name - if domainName != "" { - fmt.Println("http://" + lowestLatencyIpAddress.Ipv4 + ":" + lowestLatencyIpAddress.ServerPort + "/AddProxy?port=" + proxyPort + "&domain_name=" + domainName + "&ip_address=" + lowestLatencyIpAddress.Ipv4) - URL := "http://" + lowestLatencyIpAddress.Ipv4 + ":" + lowestLatencyIpAddress.ServerPort + "/AddProxy?port=" + proxyPort + "&domain_name=" + domainName + "&ip_address=" + lowestLatencyIpAddress.Ipv4 - //} else { - // URL = "http://" + IP + ":" + serverPort + "/server_info" - //} - http.Get(URL) - //SaveRegistration(domainName, lowestLatencyIpAddress.Ipv4+":"+proxyPort) - } + // Doing the proxy mapping for the domain name + if domainName != "" { + fmt.Println("http://" + lowestLatencyIpAddress.Ipv4 + ":" + lowestLatencyIpAddress.ServerPort + "/AddProxy?port=" + proxyPort + "&domain_name=" + domainName + "&ip_address=" + lowestLatencyIpAddress.Ipv4) + URL := "http://" + lowestLatencyIpAddress.Ipv4 + ":" + lowestLatencyIpAddress.ServerPort + "/AddProxy?port=" + proxyPort + "&domain_name=" + domainName + "&ip_address=" + lowestLatencyIpAddress.Ipv4 + //} else { + // URL = "http://" + IP + ":" + serverPort + "/server_info" + //} + http.Get(URL) + //SaveRegistration(domainName, lowestLatencyIpAddress.Ipv4+":"+proxyPort) + } - // updating with the current proxy address - ProxyIpAddr.Ipv4 = lowestLatencyIpAddress.Ipv4 - ProxyIpAddr.ServerPort = proxyPort - ProxyIpAddr.Name = config.MachineName - ProxyIpAddr.NAT = false - ProxyIpAddr.EscapeImplementation = "FRP" + // updating with the current proxy address + ProxyIpAddr.Ipv4 = lowestLatencyIpAddress.Ipv4 + ProxyIpAddr.ServerPort = proxyPort + ProxyIpAddr.Name = config.MachineName + ProxyIpAddr.NAT = false + ProxyIpAddr.EscapeImplementation = "FRP" - //ProxyIpAddr.CustomInformationKey = p2p.GenerateHashSHA256(config.IPTableKey) - } else { - return "", "", errors.New("proxy IP not found") - } + //ProxyIpAddr.CustomInformationKey = p2p.GenerateHashSHA256(config.IPTableKey) + } else { + return "", "", errors.New("proxy IP not found") + } - return ProxyIpAddr.Ipv4 + ":" + ProxyIpAddr.ServerPort, ProxyIpAddr.ServerPort, nil + return ProxyIpAddr.Ipv4 + ":" + ProxyIpAddr.ServerPort, ProxyIpAddr.ServerPort, nil }