diff --git a/p2p/frp/server.go b/p2p/frp/server.go index bf4ed7a..abf9443 100644 --- a/p2p/frp/server.go +++ b/p2p/frp/server.go @@ -4,6 +4,8 @@ import ( "github.com/fatedier/frp/pkg/config" "github.com/fatedier/frp/server" "github.com/phayes/freeport" + "io/ioutil" + "net/http" ) // TODO: Implement a way to @@ -67,3 +69,23 @@ func (s *Server) StartFRPServer() error { service.Run() return nil } + +// GetFRPServerPort Gets the port no from the FRPServer to establish +// the FRP connection needed. +func GetFRPServerPort(host string) (string, error) { + resp, err := http.Get(host + "/FRPPort") + + if err != nil { + return "", err + } + + defer resp.Body.Close() + + body, err := ioutil.ReadAll(resp.Body) + + if err != nil { + return "", err + } + + return string(body), nil +} diff --git a/server/server.go b/server/server.go index 5d41c8a..833d77a 100644 --- a/server/server.go +++ b/server/server.go @@ -1,222 +1,225 @@ 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" + "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" ) 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 + // update IPTable with new port and ip address and update ip table + var ProxyIpAddr 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)) + } - if ProxyIpAddr.Ipv4 != "" { - err := frp.StartFRPCDockerContainer(ProxyIpAddr.Ipv4, ProxyIpAddr.ProxyPort, resp) - if err != nil { - c.String(http.StatusInternalServerError, fmt.Sprintf("error: %s", err)) - } - } + if ProxyIpAddr.Ipv4 != "" { + err := frp.StartFRPCDockerContainer(ProxyIpAddr.Ipv4, ProxyIpAddr.ProxyPort, 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)) + }) - //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 lowestLatencyIpAddress p2p.IpAddress - 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 != "" { - lowestLatency = table.IpAddress[i].Latency.Milliseconds() - lowestLatencyIpAddress = table.IpAddress[i] - } - } + var lowestLatency int64 + // random large number + lowestLatency = 10000000 + var lowestLatencyIpAddress p2p.IpAddress + 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 { - // Starts FRP as a client with - proxyPort, err := frp.StartFRPClientForServer(lowestLatencyIpAddress.Ipv4, lowestLatencyIpAddress.ProxyPort, config.ServerPort) - if err != nil { - return err - } + // If there is an identified node + if lowestLatency != 10000000 { + serverPort, err := frp.GetFRPServerPort("https://" + lowestLatencyIpAddress.Ipv4 + ":" + lowestLatencyIpAddress.ServerPort) + if err != nil { + return err + } + // Starts FRP as a client with + proxyPort, err := frp.StartFRPClientForServer(lowestLatencyIpAddress.Ipv4, serverPort, config.ServerPort) + if err != nil { + return err + } - fmt.Println(proxyPort) + // 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 table.SpeedTest() - } + } - } + // 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 }