From f7a3b72287f4027fcbbfb9517abec98486440f9c Mon Sep 17 00:00:00 2001 From: Akilan Date: Sat, 21 Jan 2023 21:13:50 +0000 Subject: [PATCH] changed way network learns about nodes --- client/Iptable.go | 239 ------------- client/clientIPTable/Iptable.go | 239 +++++++++++++ client/{ => clientIPTable}/iptable_test.go | 3 +- cmd/action.go | 3 +- server/server.go | 373 +++++++++++---------- 5 files changed, 429 insertions(+), 428 deletions(-) delete mode 100644 client/Iptable.go create mode 100644 client/clientIPTable/Iptable.go rename client/{ => clientIPTable}/iptable_test.go (86%) diff --git a/client/Iptable.go b/client/Iptable.go deleted file mode 100644 index 09c59ce..0000000 --- a/client/Iptable.go +++ /dev/null @@ -1,239 +0,0 @@ -package client - -import ( - "encoding/json" - "fmt" - "git.sr.ht/~akilan1999/p2p-rendering-computation/config" - "git.sr.ht/~akilan1999/p2p-rendering-computation/p2p" - "io" - "io/ioutil" - "mime/multipart" - "net/http" - "os" -) - -// UpdateIpTable Does the following to update it's IP table -func UpdateIpTable(IpAddress string, serverPort string) error { - - config, err := config.ConfigInit() - if err != nil { - return err - } - - client := http.Client{} - - var resp []byte - - version := p2p.Ip4or6(IpAddress) - if version == "version 6" { - resp, err = UploadMultipartFile(client, "http://["+IpAddress+"]:"+serverPort+"/IpTable", "json", config.IPTable) - if err != nil { - return err - } - } else { - resp, err = UploadMultipartFile(client, "http://"+IpAddress+":"+serverPort+"/IpTable", "json", config.IPTable) - if err != nil { - return err - } - } - - if resp == nil { - return nil - } - - //resp, err := SendPostRequest("http://"+IpAddress+":8088/IpTable", - // config.IPTable, - // "json") - // - //if err != nil { - // return err - //} - - var ipStruct p2p.IpAddresses - json.Unmarshal(resp, &ipStruct) - - // Updates IP table based on information provided - // by the server - if len(ipStruct.IpAddress) > 0 { - err = ipStruct.SpeedTestUpdatedIPTable() - if err != nil { - return err - } - } - - return nil -} - -// UpdateIpTableListClient updates IP tables (Default 3 hops) based on server information available -//on the ip tables -func UpdateIpTableListClient() error { - - // Ensure that the IP Table has Node pingable - err := p2p.LocalSpeedTestIpTable() - if err != nil { - return err - } - - // IP addresses to not append to struct due to - // duplication - - Addresses, err := p2p.ReadIpTable() - //var DoNotRead p2p.IpAddresses - - currentIPV4, err := p2p.CurrentPublicIP() - if err != nil { - return err - } - - // Run loop 1 times - for i := 0; i < 1; i++ { - // Gets information from IP table - //Addresses, err = p2p.ReadIpTable() - //if err != nil { - // return err - //} - // - //DoNotRead.IpAddress = append(DoNotRead.IpAddress, PublicIP) - - // Updates IP table based on server IP table - for j := range Addresses.IpAddress { - - //Exists := false - // - //if PublicIP.Ipv4 == Addresses.IpAddress[j].Ipv4 || (PublicIP.Ipv6 != "" && Addresses.IpAddress[j].Ipv6 == PublicIP.Ipv6){ - // Exists = true - //} - // - //// Check if IP addresses is there in the struct DoNotRead - //for k := range DoNotRead.IpAddress { - // if DoNotRead.IpAddress[k].Ipv4 == Addresses.IpAddress[j].Ipv4 || (DoNotRead.IpAddress[k].Ipv6 != "" && Addresses.IpAddress[j].Ipv6 == DoNotRead.IpAddress[k].Ipv6) { - // Exists = true - // break - // } - //} - // - //// If the struct exists then continues - //if Exists { - // continue - //} - - if Addresses.IpAddress[j].Ipv6 != "" { - err = UpdateIpTable(Addresses.IpAddress[j].Ipv6, Addresses.IpAddress[j].ServerPort) - } else if Addresses.IpAddress[j].Ipv4 != currentIPV4 { - err = UpdateIpTable(Addresses.IpAddress[j].Ipv4, Addresses.IpAddress[j].ServerPort) - } - - if err != nil { - return err - } - - //Appends server1 IP address to variable DoNotRead - //DoNotRead.IpAddress = append(DoNotRead.IpAddress, Addresses.IpAddress[j]) - } - } - - return nil -} - -// SendPostRequest Sends a file as a -//POST request. -// Reference (https://stackoverflow.com/questions/51234464/upload-a-file-with-post-request-golang) -//func SendPostRequest (url string, filename string, filetype string) ([]byte,error) { -// file, err := os.Open(filename) -// if err != nil { -// return nil,err -// } -// defer file.Close() -// -// -// body := &bytes.Buffer{} -// writer := multipart.NewWriter(body) -// part, err := writer.CreateFormFile(filetype, filepath.Base(file.Name())) -// -// if err != nil { -// return nil,err -// } -// -// io.Copy(part, file) -// writer.Close() -// request, err := http.NewRequest("POST", url, body) -// -// if err != nil { -// return nil,err -// } -// -// request.Header.Add("Content-Type", writer.FormDataContentType()) -// client := &http.Client{} -// -// response, err := client.Do(request) -// -// if err != nil { -// return nil,err -// } -// defer response.Body.Close() -// -// content, err := ioutil.ReadAll(response.Body) -// -// if err != nil { -// return nil,err -// } -// -// return content, nil -//} - -func UploadMultipartFile(client http.Client, uri, key, path string) ([]byte, error) { - body, writer := io.Pipe() - - req, err := http.NewRequest(http.MethodPost, uri, body) - if err != nil { - return nil, err - } - - mwriter := multipart.NewWriter(writer) - req.Header.Add("Content-Type", mwriter.FormDataContentType()) - - errchan := make(chan error) - - go func() { - defer close(errchan) - defer writer.Close() - defer mwriter.Close() - - w, err := mwriter.CreateFormFile(key, path) - if err != nil { - errchan <- err - return - } - - in, err := os.Open(path) - if err != nil { - errchan <- err - return - } - defer in.Close() - - if written, err := io.Copy(w, in); err != nil { - errchan <- fmt.Errorf("error copying %s (%d bytes written): %v", path, written, err) - return - } - - if err := mwriter.Close(); err != nil { - errchan <- err - return - } - }() - - resp, err := client.Do(req) - if err != nil { - return nil, err - } - - content, err := ioutil.ReadAll(resp.Body) - - if err != nil { - return nil, err - } - - return content, nil - -} diff --git a/client/clientIPTable/Iptable.go b/client/clientIPTable/Iptable.go new file mode 100644 index 0000000..1817cef --- /dev/null +++ b/client/clientIPTable/Iptable.go @@ -0,0 +1,239 @@ +package clientIPTable + +import ( + "encoding/json" + "fmt" + "git.sr.ht/~akilan1999/p2p-rendering-computation/config" + "git.sr.ht/~akilan1999/p2p-rendering-computation/p2p" + "io" + "io/ioutil" + "mime/multipart" + "net/http" + "os" +) + +// UpdateIpTable Does the following to update it's IP table +func UpdateIpTable(IpAddress string, serverPort string) error { + + config, err := config.ConfigInit() + if err != nil { + return err + } + + client := http.Client{} + + var resp []byte + + version := p2p.Ip4or6(IpAddress) + if version == "version 6" { + resp, err = UploadMultipartFile(client, "http://["+IpAddress+"]:"+serverPort+"/IpTable", "json", config.IPTable) + if err != nil { + return err + } + } else { + resp, err = UploadMultipartFile(client, "http://"+IpAddress+":"+serverPort+"/IpTable", "json", config.IPTable) + if err != nil { + return err + } + } + + if resp == nil { + return nil + } + + //resp, err := SendPostRequest("http://"+IpAddress+":8088/IpTable", + // config.IPTable, + // "json") + // + //if err != nil { + // return err + //} + + var ipStruct p2p.IpAddresses + json.Unmarshal(resp, &ipStruct) + + // Updates IP table based on information provided + // by the server + if len(ipStruct.IpAddress) > 0 { + err = ipStruct.SpeedTestUpdatedIPTable() + if err != nil { + return err + } + } + + return nil +} + +// UpdateIpTableListClient updates IP tables (Default 3 hops) based on server information available +// on the ip tables +func UpdateIpTableListClient() error { + + // Ensure that the IP Table has Node pingable + err := p2p.LocalSpeedTestIpTable() + if err != nil { + return err + } + + // IP addresses to not append to struct due to + // duplication + + Addresses, err := p2p.ReadIpTable() + //var DoNotRead p2p.IpAddresses + + currentIPV4, err := p2p.CurrentPublicIP() + if err != nil { + return err + } + + // Run loop 1 times + for i := 0; i < 1; i++ { + // Gets information from IP table + //Addresses, err = p2p.ReadIpTable() + //if err != nil { + // return err + //} + // + //DoNotRead.IpAddress = append(DoNotRead.IpAddress, PublicIP) + + // Updates IP table based on server IP table + for j := range Addresses.IpAddress { + + //Exists := false + // + //if PublicIP.Ipv4 == Addresses.IpAddress[j].Ipv4 || (PublicIP.Ipv6 != "" && Addresses.IpAddress[j].Ipv6 == PublicIP.Ipv6){ + // Exists = true + //} + // + //// Check if IP addresses is there in the struct DoNotRead + //for k := range DoNotRead.IpAddress { + // if DoNotRead.IpAddress[k].Ipv4 == Addresses.IpAddress[j].Ipv4 || (DoNotRead.IpAddress[k].Ipv6 != "" && Addresses.IpAddress[j].Ipv6 == DoNotRead.IpAddress[k].Ipv6) { + // Exists = true + // break + // } + //} + // + //// If the struct exists then continues + //if Exists { + // continue + //} + + if Addresses.IpAddress[j].Ipv6 != "" { + err = UpdateIpTable(Addresses.IpAddress[j].Ipv6, Addresses.IpAddress[j].ServerPort) + } else if Addresses.IpAddress[j].Ipv4 != currentIPV4 { + err = UpdateIpTable(Addresses.IpAddress[j].Ipv4, Addresses.IpAddress[j].ServerPort) + } + + if err != nil { + return err + } + + //Appends server1 IP address to variable DoNotRead + //DoNotRead.IpAddress = append(DoNotRead.IpAddress, Addresses.IpAddress[j]) + } + } + + return nil +} + +// SendPostRequest Sends a file as a +//POST request. +// Reference (https://stackoverflow.com/questions/51234464/upload-a-file-with-post-request-golang) +//func SendPostRequest (url string, filename string, filetype string) ([]byte,error) { +// file, err := os.Open(filename) +// if err != nil { +// return nil,err +// } +// defer file.Close() +// +// +// body := &bytes.Buffer{} +// writer := multipart.NewWriter(body) +// part, err := writer.CreateFormFile(filetype, filepath.Base(file.Name())) +// +// if err != nil { +// return nil,err +// } +// +// io.Copy(part, file) +// writer.Close() +// request, err := http.NewRequest("POST", url, body) +// +// if err != nil { +// return nil,err +// } +// +// request.Header.Add("Content-Type", writer.FormDataContentType()) +// client := &http.Client{} +// +// response, err := client.Do(request) +// +// if err != nil { +// return nil,err +// } +// defer response.Body.Close() +// +// content, err := ioutil.ReadAll(response.Body) +// +// if err != nil { +// return nil,err +// } +// +// return content, nil +//} + +func UploadMultipartFile(client http.Client, uri, key, path string) ([]byte, error) { + body, writer := io.Pipe() + + req, err := http.NewRequest(http.MethodPost, uri, body) + if err != nil { + return nil, err + } + + mwriter := multipart.NewWriter(writer) + req.Header.Add("Content-Type", mwriter.FormDataContentType()) + + errchan := make(chan error) + + go func() { + defer close(errchan) + defer writer.Close() + defer mwriter.Close() + + w, err := mwriter.CreateFormFile(key, path) + if err != nil { + errchan <- err + return + } + + in, err := os.Open(path) + if err != nil { + errchan <- err + return + } + defer in.Close() + + if written, err := io.Copy(w, in); err != nil { + errchan <- fmt.Errorf("error copying %s (%d bytes written): %v", path, written, err) + return + } + + if err := mwriter.Close(); err != nil { + errchan <- err + return + } + }() + + resp, err := client.Do(req) + if err != nil { + return nil, err + } + + content, err := ioutil.ReadAll(resp.Body) + + if err != nil { + return nil, err + } + + return content, nil + +} diff --git a/client/iptable_test.go b/client/clientIPTable/iptable_test.go similarity index 86% rename from client/iptable_test.go rename to client/clientIPTable/iptable_test.go index 51e6de1..53a755a 100644 --- a/client/iptable_test.go +++ b/client/clientIPTable/iptable_test.go @@ -1,4 +1,4 @@ -package client +package clientIPTable import ( "testing" @@ -11,4 +11,3 @@ func TestUpdateIpTableListClient(t *testing.T) { t.Error(err) } } - diff --git a/cmd/action.go b/cmd/action.go index c30c263..fc6532b 100644 --- a/cmd/action.go +++ b/cmd/action.go @@ -3,6 +3,7 @@ package cmd import ( "fmt" "git.sr.ht/~akilan1999/p2p-rendering-computation/client" + "git.sr.ht/~akilan1999/p2p-rendering-computation/client/clientIPTable" "git.sr.ht/~akilan1999/p2p-rendering-computation/config" "git.sr.ht/~akilan1999/p2p-rendering-computation/generate" "git.sr.ht/~akilan1999/p2p-rendering-computation/p2p" @@ -22,7 +23,7 @@ var CliAction = func(ctx *cli.Context) error { //Listing servers and also updates IP tables (Default 3 hops) if UpdateServerList { - err := client.UpdateIpTableListClient() + err := clientIPTable.UpdateIpTableListClient() if err != nil { fmt.Print(err) } diff --git a/server/server.go b/server/server.go index b780fdb..dfff38b 100644 --- a/server/server.go +++ b/server/server.go @@ -1,231 +1,232 @@ package server import ( - "encoding/json" - "fmt" - "git.sr.ht/~akilan1999/p2p-rendering-computation/config" - "git.sr.ht/~akilan1999/p2p-rendering-computation/p2p" - "git.sr.ht/~akilan1999/p2p-rendering-computation/p2p/frp" - "git.sr.ht/~akilan1999/p2p-rendering-computation/server/docker" - "github.com/gin-gonic/gin" - "io/ioutil" - "net/http" - "strconv" - "time" + "encoding/json" + "fmt" + "git.sr.ht/~akilan1999/p2p-rendering-computation/client/clientIPTable" + "git.sr.ht/~akilan1999/p2p-rendering-computation/config" + "git.sr.ht/~akilan1999/p2p-rendering-computation/p2p" + "git.sr.ht/~akilan1999/p2p-rendering-computation/p2p/frp" + "git.sr.ht/~akilan1999/p2p-rendering-computation/server/docker" + "github.com/gin-gonic/gin" + "io/ioutil" + "net/http" + "strconv" + "time" ) func Server() error { - r := gin.Default() + r := gin.Default() - // 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 - config, err := config.ConfigInit() - if err != nil { - c.String(http.StatusOK, fmt.Sprint(err)) - } - c.File(config.SpeedTestFile) - }) + // Speed test with 50 mbps + r.GET("/50", func(c *gin.Context) { + // Get Path from config + config, err := config.ConfigInit() + if err != nil { + c.String(http.StatusOK, fmt.Sprint(err)) + } + 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 + //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() - } + 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", "") - 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", "") + var PortsInt int - // Convert Get Request value to int - fmt.Sscanf(Ports, "%d", &PortsInt) + // Convert Get Request value to int + fmt.Sscanf(Ports, "%d", &PortsInt) - // Creates container and returns-back result to - // access container - resp, err := docker.BuildRunContainer(PortsInt, GPU, ContainerName) + // Creates container and returns-back result to + // access container + resp, err := docker.BuildRunContainer(PortsInt, GPU, ContainerName) - 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:8088" && c.Request.Host != "0.0.0.0:8088" { - resp, err = frp.StartFRPCDockerContainer(ProxyIpAddr.Ipv4, lowestLatencyIpAddress.ServerPort, resp) - if err != nil { - c.String(http.StatusInternalServerError, fmt.Sprintf("error: %s", err)) - } - fmt.Println(resp) - } + // Ensures that FRP is triggered only if a proxy address is provided + if ProxyIpAddr.Ipv4 != "" && c.Request.Host != "localhost:8088" && c.Request.Host != "0.0.0.0:8088" { + resp, err = frp.StartFRPCDockerContainer(ProxyIpAddr.Ipv4, lowestLatencyIpAddress.ServerPort, resp) + if err != nil { + c.String(http.StatusInternalServerError, fmt.Sprintf("error: %s", err)) + } + fmt.Println(resp) + } - 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)) + }) - //Get Server port based on the config file - config, err := config.ConfigInit() - if err != nil { - return err - } + //Get Server port based on the config file + config, err := config.ConfigInit() + if err != nil { + return err + } - // 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() + } - // 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" { - table, err := p2p.ReadIpTable() - if err != nil { - return 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 == "True" { + 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 { - 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 { + 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, config.ServerPort) - 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, config.ServerPort) + if err != nil { + return err + } - // updating with the current proxy address - ProxyIpAddr.Ipv4 = lowestLatencyIpAddress.Ipv4 - ProxyIpAddr.ServerPort = proxyPort - ProxyIpAddr.ProxyPort = lowestLatencyIpAddress.ProxyPort - ProxyIpAddr.Name = config.MachineName + // updating with the current proxy address + ProxyIpAddr.Ipv4 = lowestLatencyIpAddress.Ipv4 + ProxyIpAddr.ServerPort = proxyPort + ProxyIpAddr.ProxyPort = lowestLatencyIpAddress.ProxyPort + ProxyIpAddr.Name = config.MachineName - // append the following to the ip table - table.IpAddress = append(table.IpAddress, ProxyIpAddr) - // write information back to the IP Table - table.WriteIpTable() - // update ip table - go table.SpeedTest() - } + // append the following to the ip table + table.IpAddress = append(table.IpAddress, ProxyIpAddr) + // write information back to the IP Table + table.WriteIpTable() + // update ip table + go clientIPTable.UpdateIpTableListClient() + } - } + } - // Run gin server on the specified port - err = r.Run(":" + config.ServerPort) - if err != nil { - return err - } + // Run gin server on the specified port + err = r.Run(":" + config.ServerPort) + if err != nil { + return err + } - return nil + return nil }