diff --git a/server/server.go b/server/server.go index 7d9898e..0e56ed1 100644 --- a/server/server.go +++ b/server/server.go @@ -1,449 +1,451 @@ package server import ( - b64 "encoding/base64" - "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" - "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() - //} - // - //// 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)) - //} - // - //// 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)) - //} - // - //json.Unmarshal(file, &IPTable) - // - ////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)) - //} + //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() + //} - // Reads IP addresses from ip table - IpAddresses, err := p2p.ReadIpTable() - if err != nil { - c.String(http.StatusOK, fmt.Sprint(err)) - } + // Variable to store IP table information + var IPTable p2p.IpAddresses - c.JSON(http.StatusOK, IpAddresses) - }) + // Receive file from POST request + body, err := c.FormFile("json") + if err != nil { + c.String(http.StatusOK, fmt.Sprint(err)) + } - // 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 + // Open file + open, err := body.Open() + if err != nil { + c.String(http.StatusOK, fmt.Sprint(err)) + } - if PublicKey == "" { - c.String(http.StatusInternalServerError, fmt.Sprintf("error: %s", "Publickey not passed")) - } + // Open received file + file, err := ioutil.ReadAll(open) + if err != nil { + c.String(http.StatusOK, fmt.Sprint(err)) + } - PublicKeyDecoded, err := b64.StdEncoding.DecodeString(PublicKey) - if err != nil { - c.String(http.StatusInternalServerError, fmt.Sprintf("error: %s", err)) - } + json.Unmarshal(file, &IPTable) - // Convert Get Request value to int - fmt.Sscanf(Ports, "%d", &PortsInt) + //Add Client IP address to IPTable struct + //IPTable.IpAddress = append(IPTable.IpAddress, ClientHost) - fmt.Println(string(PublicKeyDecoded[:])) + // 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)) + } - // Creates container and returns-back result to - // access container - resp, err := docker.BuildRunContainer(PortsInt, GPU, ContainerName, BaseImage, string(PublicKeyDecoded[:])) + // Reads IP addresses from ip table + IpAddresses, err := p2p.ReadIpTable() + if err != nil { + c.String(http.StatusOK, fmt.Sprint(err)) + } - if err != nil { - c.String(http.StatusInternalServerError, fmt.Sprintf("error: %s", err)) - } + c.JSON(http.StatusOK, IpAddresses) + }) - // 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)) - } - } + // 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 - c.JSON(http.StatusOK, resp) - }) + if PublicKey == "" { + c.String(http.StatusInternalServerError, fmt.Sprintf("error: %s", "Publickey not passed")) + } - //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") - }) + PublicKeyDecoded, err := b64.StdEncoding.DecodeString(PublicKey) + if err != nil { + c.String(http.StatusInternalServerError, fmt.Sprintf("error: %s", err)) + } - //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) - }) + // Convert Get Request value to int + fmt.Sscanf(Ports, "%d", &PortsInt) - // 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)) - } + fmt.Println(string(PublicKeyDecoded[:])) - c.String(http.StatusOK, strconv.Itoa(port)) - }) + // Creates container and returns-back result to + // access container + resp, err := docker.BuildRunContainer(PortsInt, GPU, ContainerName, BaseImage, string(PublicKeyDecoded[:])) - 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)) - } + if err != nil { + c.String(http.StatusInternalServerError, fmt.Sprintf("error: %s", err)) + } - c.String(http.StatusOK, url) - }) + // 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)) + } + } - r.GET("/AddProxy", func(c *gin.Context) { - DomainName := c.DefaultQuery("domain_name", "") - ip_address := c.DefaultQuery("ip_address", "") - Ports := c.DefaultQuery("port", "") + c.JSON(http.StatusOK, resp) + }) - 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")) - } + //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") + }) - err := SaveRegistration(DomainName, ip_address+":"+Ports) - if err != nil { - c.String(http.StatusInternalServerError, fmt.Sprintf(err.Error())) - } + //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) + }) - //_, 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") + // 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)) + }) - //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("/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)) + } - // If there is a proxy port specified - // then starts the FRP server - //if config.FRPServerPort != "0" { - // go frp.StartFRPProxyFromRandom() - //} + c.String(http.StatusOK, url) + }) - // Remove nodes currently not pingable - clientIPTable.RemoveOfflineNodes() + r.GET("/AddProxy", func(c *gin.Context) { + DomainName := c.DefaultQuery("domain_name", "") + ip_address := c.DefaultQuery("ip_address", "") + Ports := c.DefaultQuery("port", "") - table, err := p2p.ReadIpTable() + 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")) + } - // 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 == "True" { - if err != nil { - return nil, err - } + err := SaveRegistration(DomainName, ip_address+":"+Ports) + if err != nil { + c.String(http.StatusInternalServerError, fmt.Sprintf(err.Error())) + } - var lowestLatency int64 - // random large number - lowestLatency = 10000000 + //_, 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") - 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 - } + //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) + // } + // + //}) - // 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 there is a proxy port specified + // then starts the FRP server + //if config.FRPServerPort != "0" { + // go frp.StartFRPProxyFromRandom() + //} - if config.BareMetal { - _, SSHPort, err := MapPort("22", "") - if err != nil { - return nil, err - } - ProxyIpAddr.BareMetalSSHPort = SSHPort - } + // Remove nodes currently not pingable + clientIPTable.RemoveOfflineNodes() - //ProxyIpAddr.CustomInformationKey = p2p.GenerateHashSHA256(config.IPTableKey) - // write information back to the IP Table - } + table, err := p2p.ReadIpTable() - } 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" - } + // 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 == "True" { + if err != nil { + return nil, err + } - } + var lowestLatency int64 + // random large number + lowestLatency = 10000000 - // 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() + 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 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 + } - // append the following to the ip table - table.IpAddress = append(table.IpAddress, ProxyIpAddr) + // 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" - // Writing results to the IPTable - err = table.WriteIpTable() - if err != nil { - return nil, err - } + if config.BareMetal { + _, SSHPort, err := MapPort("22", "") + if err != nil { + return nil, err + } + ProxyIpAddr.BareMetalSSHPort = SSHPort + } - // update ip table - go func() error { - err := clientIPTable.UpdateIpTableListClient() - if err != nil { - fmt.Println(err) - return err - } - return nil - }() + //ProxyIpAddr.CustomInformationKey = p2p.GenerateHashSHA256(config.IPTableKey) + // write information back to the IP Table + } - if config.ProxyPort != "" { - go ProxyRun(config.ProxyPort) - } + } 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" + } - // Run gin server on the specified port - go r.Run(":" + config.ServerPort) + } - return r, nil + // 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 + } + + // 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 + } + + // 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) + } + + // Run gin server on the specified port + go r.Run(":" + config.ServerPort) + + return r, nil } func MapPort(port string, domainName string) (string, string, error) { - //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 == "True" { - 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 == "True" { + 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 }