diff --git a/p2p/frp/client.go b/p2p/frp/client.go index a302b93..444ebe9 100644 --- a/p2p/frp/client.go +++ b/p2p/frp/client.go @@ -1,6 +1,7 @@ package frp import ( + "fmt" "git.sr.ht/~akilan1999/p2p-rendering-computation/server/docker" "github.com/fatedier/frp/client" "github.com/fatedier/frp/pkg/config" @@ -72,7 +73,13 @@ func StartFRPClientForServer(ipaddress string, port string, localport string) (s } -func StartFRPCDockerContainer(ipaddress string, port string, docker *docker.DockerVM) (*docker.DockerVM, error) { +func StartFRPCDockerContainer(ipaddress string, port string, Docker *docker.DockerVM) (*docker.DockerVM, error) { + // setting new docker variable + + //var DockerFRP docker.DockerVM + + //DockerFRP = *Docker + //DockerFRP.Ports.PortSet = []docker.Port{} // Setup server information var s Server s.address = ipaddress @@ -90,47 +97,32 @@ func StartFRPCDockerContainer(ipaddress string, port string, docker *docker.Dock // set client mapping //var clientMappings []ClientMapping - for i, _ := range docker.Ports.PortSet { - // Set client mapping - var clientMapping ClientMapping - portMap := docker.Ports.PortSet[i].ExternalPort - clientMapping.LocalIP = "localhost" - clientMapping.LocalPort = portMap - OpenPorts, err := freeport.GetFreePorts(1) - if err != nil { - return nil, err - } - clientMapping.RemotePort = OpenPorts[0] + fmt.Println(len(Docker.Ports.PortSet)) + for i, _ := range Docker.Ports.PortSet { + portMap := Docker.Ports.PortSet[i].ExternalPort serverPort, err := GetFRPServerPort("http://" + ipaddress + ":" + port) if err != nil { return nil, err } - // Create 3 second delay to allow FRP server to start - time.Sleep(3000) - // Starts FRP as a client with - _, err = StartFRPClientForServer(ipaddress, serverPort, strconv.Itoa(portMap)) + //delay to allow the FRP server to start + time.Sleep(1 * time.Second) + + proxyPort, err := StartFRPClientForServer(ipaddress, serverPort, strconv.Itoa(portMap)) if err != nil { return nil, err } - //portInt, err := strconv.Atoi(proxyPort) - //if err != nil { - // return nil, err - //} + portInt, err = strconv.Atoi(proxyPort) + if err != nil { + return nil, err + } - //PointerDocker := &docker.Ports.PortSet[i] - //PointerDocker.ExternalPort = portInt - - // Append to array - //clientMappings = append(clientMappings, clientMapping) + Docker.Ports.PortSet[i].ExternalPort = portInt } - // Start client server - //go c.StartFRPClient() - - return docker, nil + return Docker, nil } diff --git a/server/server.go b/server/server.go index 3624a2c..b780fdb 100644 --- a/server/server.go +++ b/server/server.go @@ -1,229 +1,231 @@ 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/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 + // 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)) + } - if ProxyIpAddr.Ipv4 != "" { - respFrpDocker, err := frp.StartFRPCDockerContainer(ProxyIpAddr.Ipv4, ProxyIpAddr.ProxyPort, resp) - if err != nil { - c.String(http.StatusInternalServerError, fmt.Sprintf("error: %s", err)) - } - c.JSON(http.StatusOK, respFrpDocker) - } + // 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 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] - } - } + var lowestLatency int64 + // random large number + lowestLatency = 10000000 - // 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(3000) - // Starts FRP as a client with - proxyPort, err := frp.StartFRPClientForServer(lowestLatencyIpAddress.Ipv4, serverPort, config.ServerPort) - if err != nil { - return err - } + 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] + } + } - // updating with the current proxy address - ProxyIpAddr.Ipv4 = lowestLatencyIpAddress.Ipv4 - ProxyIpAddr.ServerPort = proxyPort - ProxyIpAddr.ProxyPort = lowestLatencyIpAddress.ProxyPort - ProxyIpAddr.Name = config.MachineName + // 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 + } - // 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() - } + // 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() + } - // Run gin server on the specified port - err = r.Run(":" + config.ServerPort) - if err != nil { - return err - } + } - return nil + // Run gin server on the specified port + err = r.Run(":" + config.ServerPort) + if err != nil { + return err + } + + return nil }