Merge pull request #87 from Akilan1999/NAT-traversal
NAT Traversal with FRP and IPTables resolved
This commit is contained in:
@@ -3,7 +3,6 @@ package client
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"git.sr.ht/~akilan1999/p2p-rendering-computation/p2p"
|
||||
"git.sr.ht/~akilan1999/p2p-rendering-computation/server"
|
||||
"io/ioutil"
|
||||
"net/http"
|
||||
@@ -12,30 +11,30 @@ import (
|
||||
// GetSpecs Gets Specs from the server such CPU, GPU usage
|
||||
// and other basic information which helps set a
|
||||
// cluster of computer
|
||||
func GetSpecs(IP string)(*server.SysInfo,error) {
|
||||
func GetSpecs(IP string) (*server.SysInfo, error) {
|
||||
var URL string
|
||||
version := p2p.Ip4or6(IP)
|
||||
//version := p2p.Ip4or6(IP)
|
||||
|
||||
//Get port number of the server
|
||||
serverPort, err := GetServerPort(IP)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
//serverPort, err := GetServerPort(IP)
|
||||
//if err != nil {
|
||||
// return nil, err
|
||||
//}
|
||||
|
||||
if version == "version 6" {
|
||||
URL = "http://[" + IP + "]:" + serverPort + "/server_info"
|
||||
} else {
|
||||
URL = "http://" + IP + ":" + serverPort + "/server_info"
|
||||
}
|
||||
//if version == "version 6" {
|
||||
URL = "http://" + IP + "/server_info"
|
||||
//} else {
|
||||
// URL = "http://" + IP + ":" + serverPort + "/server_info"
|
||||
//}
|
||||
resp, err := http.Get(URL)
|
||||
if err != nil {
|
||||
return nil,err
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// Convert response to byte value
|
||||
byteValue, err := ioutil.ReadAll(resp.Body)
|
||||
if err != nil {
|
||||
return nil,err
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// Create variable for result response type
|
||||
@@ -44,7 +43,7 @@ func GetSpecs(IP string)(*server.SysInfo,error) {
|
||||
// Adds byte value to docker.DockerVM struct
|
||||
json.Unmarshal(byteValue, &serverSpecsResult)
|
||||
if err != nil {
|
||||
return nil,err
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &serverSpecsResult, nil
|
||||
@@ -61,4 +60,4 @@ func PrettyPrint(data interface{}) {
|
||||
return
|
||||
}
|
||||
fmt.Printf("%s \n", p)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
package client
|
||||
package clientIPTable
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
@@ -22,17 +22,16 @@ func UpdateIpTable(IpAddress string, serverPort string) error {
|
||||
|
||||
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
|
||||
}
|
||||
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)
|
||||
resp, err = UploadMultipartFile(client, "http://"+IpAddress+":"+serverPort+"/IpTable", "json", config.IPTable)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -65,13 +64,17 @@ func UpdateIpTable(IpAddress string, serverPort string) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
|
||||
// UpdateIpTableListClient updates IP tables (Default 3 hops) based on server information available
|
||||
//on the ip tables
|
||||
// on the ip tables
|
||||
func UpdateIpTableListClient() error {
|
||||
// Get config information
|
||||
Config, err := config.ConfigInit()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Ensure that the IP Table has Node pingable
|
||||
err := p2p.LocalSpeedTestIpTable()
|
||||
err = p2p.LocalSpeedTestIpTable()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -80,52 +83,53 @@ func UpdateIpTableListClient() error {
|
||||
// duplication
|
||||
|
||||
Addresses, err := p2p.ReadIpTable()
|
||||
//var DoNotRead p2p.IpAddresses
|
||||
var DoNotRead p2p.IpAddresses
|
||||
|
||||
// Run loop 3 times
|
||||
for i := 0; i < 3; i++ {
|
||||
currentIPV4, err := p2p.CurrentPublicIP()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Run loop 2 times
|
||||
for i := 0; i < 2; i++ {
|
||||
// Gets information from IP table
|
||||
//Addresses, err = p2p.ReadIpTable()
|
||||
//if err != nil {
|
||||
// return err
|
||||
//}
|
||||
//
|
||||
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 {
|
||||
err = UpdateIpTable(Addresses.IpAddress[j].Ipv4, Addresses.IpAddress[j].ServerPort)
|
||||
Exists := false
|
||||
// If the address is local then add to the local list
|
||||
if currentIPV4 == Addresses.IpAddress[j].Ipv4 && Addresses.IpAddress[j].ServerPort == Config.ServerPort {
|
||||
Exists = true
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
return err
|
||||
// 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].ServerPort == Addresses.IpAddress[j].ServerPort) || (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 != "" {
|
||||
go UpdateIpTable(Addresses.IpAddress[j].Ipv6, Addresses.IpAddress[j].ServerPort)
|
||||
} else if Addresses.IpAddress[j].Ipv4 != currentIPV4 {
|
||||
go UpdateIpTable(Addresses.IpAddress[j].Ipv4, Addresses.IpAddress[j].ServerPort)
|
||||
}
|
||||
|
||||
//Appends server1 IP address to variable DoNotRead
|
||||
//DoNotRead.IpAddress = append(DoNotRead.IpAddress, Addresses.IpAddress[j])
|
||||
DoNotRead.IpAddress = append(DoNotRead.IpAddress, Addresses.IpAddress[j])
|
||||
}
|
||||
}
|
||||
|
||||
@@ -234,4 +238,3 @@ func UploadMultipartFile(client http.Client, uri, key, path string) ([]byte, err
|
||||
return content, nil
|
||||
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
package client
|
||||
package clientIPTable
|
||||
|
||||
import (
|
||||
"testing"
|
||||
@@ -11,4 +11,3 @@ func TestUpdateIpTableListClient(t *testing.T) {
|
||||
t.Error(err)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -12,39 +12,39 @@ import (
|
||||
|
||||
var (
|
||||
serverPort = "8088"
|
||||
client = http.Client{}
|
||||
client = http.Client{}
|
||||
)
|
||||
|
||||
// StartContainer Start container using REST api Implementation
|
||||
// From the selected server IP address
|
||||
// TODO: Test cases for this function
|
||||
//Calls URL ex: http://0.0.0.0:8088/startcontainer?ports=0&GPU=false&ContainerName=docker-ubuntu-sshd
|
||||
func StartContainer(IP string, NumPorts int, GPU bool, ContainerName string) (*docker.DockerVM ,error) {
|
||||
// Calls URL ex: http://0.0.0.0:8088/startcontainer?ports=0&GPU=false&ContainerName=docker-ubuntu-sshd
|
||||
func StartContainer(IP string, NumPorts int, GPU bool, ContainerName string) (*docker.DockerVM, error) {
|
||||
// Passes URL with number of TCP ports to allocated and to give GPU access to the docker container
|
||||
var URL string
|
||||
version := p2p.Ip4or6(IP)
|
||||
//version := p2p.Ip4or6(IP)
|
||||
//
|
||||
////Get port number of the server
|
||||
//serverPort, err := GetServerPort(IP)
|
||||
//if err != nil {
|
||||
// return nil, err
|
||||
//}
|
||||
|
||||
//Get port number of the server
|
||||
serverPort, err := GetServerPort(IP)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if version == "version 6" {
|
||||
URL = "http://[" + IP + "]:" + serverPort + "/startcontainer?ports=" + fmt.Sprint(NumPorts) + "&GPU=" + strconv.FormatBool(GPU) + "&ContainerName=" + ContainerName
|
||||
} else {
|
||||
URL = "http://" + IP + ":" + serverPort + "/startcontainer?ports=" + fmt.Sprint(NumPorts) + "&GPU=" + strconv.FormatBool(GPU) + "&ContainerName=" + ContainerName
|
||||
}
|
||||
//if version == "version 6" {
|
||||
// URL = "http://[" + IP + "]:" + serverPort + "/startcontainer?ports=" + fmt.Sprint(NumPorts) + "&GPU=" + strconv.FormatBool(GPU) + "&ContainerName=" + ContainerName
|
||||
//} else {
|
||||
URL = "http://" + IP + "/startcontainer?ports=" + fmt.Sprint(NumPorts) + "&GPU=" + strconv.FormatBool(GPU) + "&ContainerName=" + ContainerName
|
||||
//}
|
||||
|
||||
resp, err := http.Get(URL)
|
||||
if err != nil {
|
||||
return nil,err
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// Convert response to byte value
|
||||
byteValue, err := ioutil.ReadAll(resp.Body)
|
||||
if err != nil {
|
||||
return nil,err
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// Create variable for result response type
|
||||
@@ -53,7 +53,7 @@ func StartContainer(IP string, NumPorts int, GPU bool, ContainerName string) (*d
|
||||
// Adds byte value to docker.DockerVM struct
|
||||
json.Unmarshal(byteValue, &dockerResult)
|
||||
if err != nil {
|
||||
return nil,err
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// Adds the container to the tracked list
|
||||
@@ -66,21 +66,21 @@ func StartContainer(IP string, NumPorts int, GPU bool, ContainerName string) (*d
|
||||
}
|
||||
|
||||
// RemoveContianer Stops and removes container from the server
|
||||
func RemoveContianer(IP string,ID string) error {
|
||||
func RemoveContianer(IP string, ID string) error {
|
||||
var URL string
|
||||
version := p2p.Ip4or6(IP)
|
||||
//version := p2p.Ip4or6(IP)
|
||||
//
|
||||
////Get port number of the server
|
||||
//serverPort, err := GetServerPort(IP)
|
||||
//if err != nil {
|
||||
// return err
|
||||
//}
|
||||
|
||||
//Get port number of the server
|
||||
serverPort, err := GetServerPort(IP)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if version == "version 6" {
|
||||
URL = "http://[" + IP + "]:" + serverPort + "/RemoveContainer?id=" + ID
|
||||
} else {
|
||||
URL = "http://" + IP + ":" + serverPort + "/RemoveContainer?id=" + ID
|
||||
}
|
||||
//if version == "version 6" {
|
||||
// URL = "http://[" + IP + "]:" + serverPort + "/RemoveContainer?id=" + ID
|
||||
//} else {
|
||||
URL = "http://" + IP + "/RemoveContainer?id=" + ID
|
||||
//}
|
||||
resp, err := http.Get(URL)
|
||||
if err != nil {
|
||||
return err
|
||||
@@ -102,7 +102,7 @@ func RemoveContianer(IP string,ID string) error {
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
// Remove container created from the tracked list
|
||||
// Remove container created from the tracked list
|
||||
err = RemoveTrackedContainer(ID)
|
||||
if err != nil {
|
||||
return err
|
||||
@@ -112,31 +112,31 @@ func RemoveContianer(IP string,ID string) error {
|
||||
}
|
||||
|
||||
// ViewContainers This function displays all containers available on server side
|
||||
func ViewContainers(IP string)(*docker.DockerContainers, error){
|
||||
func ViewContainers(IP string) (*docker.DockerContainers, error) {
|
||||
// Passes URL with route /ShowImages
|
||||
var URL string
|
||||
version := p2p.Ip4or6(IP)
|
||||
//version := p2p.Ip4or6(IP)
|
||||
//
|
||||
////Get port number of the server
|
||||
//serverPort, err := GetServerPort(IP)
|
||||
//if err != nil {
|
||||
// return nil, err
|
||||
//}
|
||||
|
||||
//Get port number of the server
|
||||
serverPort, err := GetServerPort(IP)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if version == "version 6" {
|
||||
URL = "http://[" + IP + "]:" + serverPort + "/ShowImages"
|
||||
} else {
|
||||
URL = "http://" + IP + ":" + serverPort + "/ShowImages"
|
||||
}
|
||||
//if version == "version 6" {
|
||||
// URL = "http://[" + IP + "]:" + serverPort + "/ShowImages"
|
||||
//} else {
|
||||
URL = "http://" + IP + "/ShowImages"
|
||||
//}
|
||||
resp, err := http.Get(URL)
|
||||
if err != nil {
|
||||
return nil,err
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// Convert response to byte value
|
||||
byteValue, err := ioutil.ReadAll(resp.Body)
|
||||
if err != nil {
|
||||
return nil,err
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// Create variable for result response type
|
||||
@@ -145,18 +145,18 @@ func ViewContainers(IP string)(*docker.DockerContainers, error){
|
||||
// Adds byte value to docker.DockerContainers struct
|
||||
json.Unmarshal(byteValue, &Result)
|
||||
if err != nil {
|
||||
return nil,err
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &Result, nil
|
||||
}
|
||||
|
||||
// GetServerPort Helper function to do find out server port information
|
||||
func GetServerPort(IpAddress string) (string,error) {
|
||||
func GetServerPort(IpAddress string) (string, error) {
|
||||
// Getting information from the clients ip table
|
||||
ipTable, err := p2p.ReadIpTable()
|
||||
if err != nil {
|
||||
return "",err
|
||||
return "", err
|
||||
}
|
||||
|
||||
// Iterate thorough ip table struct and find
|
||||
@@ -170,7 +170,7 @@ func GetServerPort(IpAddress string) (string,error) {
|
||||
}
|
||||
|
||||
// We return default port
|
||||
return "8088",nil
|
||||
return "8088", nil
|
||||
}
|
||||
|
||||
// PrintStartContainer Prints results Generated container
|
||||
@@ -187,7 +187,6 @@ func GetServerPort(IpAddress string) (string,error) {
|
||||
// }
|
||||
//}
|
||||
|
||||
|
||||
// TODO implementation using RPC calls
|
||||
//func StartContainer(Ip string) (*docker.DockerVM,error){
|
||||
// client, err := rpc.DialHTTP("tcp",Ip + ":" + serverPort)
|
||||
|
||||
@@ -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"
|
||||
@@ -13,14 +14,16 @@ import (
|
||||
|
||||
var CliAction = func(ctx *cli.Context) error {
|
||||
if Server {
|
||||
// TODO: with RPC calls
|
||||
server.Server()
|
||||
err := server.Server()
|
||||
if err != nil {
|
||||
fmt.Print(err)
|
||||
}
|
||||
//server.Rpc()
|
||||
}
|
||||
|
||||
//Listing servers and also updates IP tables (Default 3 hops)
|
||||
if UpdateServerList {
|
||||
err := client.UpdateIpTableListClient()
|
||||
err := clientIPTable.UpdateIpTableListClient()
|
||||
if err != nil {
|
||||
fmt.Print(err)
|
||||
}
|
||||
@@ -77,7 +80,6 @@ var CliAction = func(ctx *cli.Context) error {
|
||||
// Adds the new server IP to the iptable
|
||||
res.WriteIpTable()
|
||||
|
||||
|
||||
}
|
||||
|
||||
// Displays all images available on the server side
|
||||
@@ -91,8 +93,8 @@ var CliAction = func(ctx *cli.Context) error {
|
||||
}
|
||||
|
||||
// Function called to stop and remove server from Docker
|
||||
if RemoveVM != "" && ID != "" {
|
||||
err := client.RemoveContianer(RemoveVM,ID)
|
||||
if RemoveVM != "" && ID != "" {
|
||||
err := client.RemoveContianer(RemoveVM, ID)
|
||||
if err != nil {
|
||||
fmt.Print(err)
|
||||
}
|
||||
@@ -109,7 +111,7 @@ var CliAction = func(ctx *cli.Context) error {
|
||||
}
|
||||
|
||||
// Calls function to do Api call to start the container on the server side
|
||||
imageRes, err := client.StartContainer(CreateVM,PortsInt,GPU,ContainerName)
|
||||
imageRes, err := client.StartContainer(CreateVM, PortsInt, GPU, ContainerName)
|
||||
|
||||
if err != nil {
|
||||
fmt.Print(err)
|
||||
@@ -146,9 +148,9 @@ var CliAction = func(ctx *cli.Context) error {
|
||||
}
|
||||
|
||||
// If the view plugin flag is called then display all
|
||||
// plugins available
|
||||
// plugins available
|
||||
if ViewPlugin {
|
||||
plugins ,err := plugin.DetectPlugins()
|
||||
plugins, err := plugin.DetectPlugins()
|
||||
if err != nil {
|
||||
fmt.Print(err)
|
||||
}
|
||||
@@ -205,9 +207,9 @@ var CliAction = func(ctx *cli.Context) error {
|
||||
} else {
|
||||
client.PrettyPrint(group)
|
||||
}
|
||||
} else if ID != "" { // Add container to group based on group ID provided
|
||||
} else if ID != "" { // Add container to group based on group ID provided
|
||||
// --id <Container ID>
|
||||
group, err := client.AddContainerToGroup(ID,Group)
|
||||
group, err := client.AddContainerToGroup(ID, Group)
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
} else {
|
||||
@@ -244,6 +246,16 @@ var CliAction = func(ctx *cli.Context) error {
|
||||
client.PrettyPrint(groups)
|
||||
}
|
||||
}
|
||||
|
||||
// Starts server as a reverse proxy so that
|
||||
// nodes can connect to each other behind NAT
|
||||
//if FRPProxy {
|
||||
// err := frp.StartFRPProxyFromRandom()
|
||||
// if err != nil {
|
||||
// fmt.Println(err)
|
||||
// }
|
||||
//}
|
||||
|
||||
// -- REMOVE ON REGULAR RELEASE --
|
||||
// when flag --gen is called an extension
|
||||
// of the project is created to repurpose
|
||||
@@ -252,9 +264,9 @@ var CliAction = func(ctx *cli.Context) error {
|
||||
var err error
|
||||
// If the module name is provided
|
||||
if Modulename != "" {
|
||||
err = generate.GenerateNewProject(Generate,Modulename)
|
||||
err = generate.GenerateNewProject(Generate, Modulename)
|
||||
} else {
|
||||
err = generate.GenerateNewProject(Generate,Generate)
|
||||
err = generate.GenerateNewProject(Generate, Generate)
|
||||
}
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
@@ -288,7 +300,5 @@ var CliAction = func(ctx *cli.Context) error {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
166
cmd/flags.go
166
cmd/flags.go
@@ -6,223 +6,231 @@ import (
|
||||
|
||||
// Variables declared for CLI
|
||||
var (
|
||||
AddServer string
|
||||
ViewImages string
|
||||
CreateVM string
|
||||
ContainerName string
|
||||
Ports string
|
||||
Server bool
|
||||
RemoveVM string
|
||||
ID string
|
||||
Specs string
|
||||
GPU bool
|
||||
UpdateServerList bool
|
||||
ServerList bool
|
||||
SetDefaultConfig bool
|
||||
NetworkInterface bool
|
||||
ViewPlugin bool
|
||||
TrackedContainers bool
|
||||
ExecutePlugin string
|
||||
CreateGroup bool
|
||||
Group string
|
||||
AddServer string
|
||||
ViewImages string
|
||||
CreateVM string
|
||||
ContainerName string
|
||||
Ports string
|
||||
Server bool
|
||||
RemoveVM string
|
||||
ID string
|
||||
Specs string
|
||||
GPU bool
|
||||
UpdateServerList bool
|
||||
ServerList bool
|
||||
SetDefaultConfig bool
|
||||
NetworkInterface bool
|
||||
ViewPlugin bool
|
||||
TrackedContainers bool
|
||||
ExecutePlugin string
|
||||
CreateGroup bool
|
||||
Group string
|
||||
Groups bool
|
||||
RemoveContainerGroup bool
|
||||
RemoveGroup string
|
||||
RemoveGroup string
|
||||
//FRPProxy bool
|
||||
// Generate only allowed in dev release
|
||||
// -- REMOVE ON REGULAR RELEASE --
|
||||
Generate string
|
||||
Modulename string
|
||||
Generate string
|
||||
Modulename string
|
||||
//--------------------------------
|
||||
PullPlugin string
|
||||
RemovePlugin string
|
||||
PullPlugin string
|
||||
RemovePlugin string
|
||||
)
|
||||
|
||||
var AppConfigFlags = []cli.Flag{
|
||||
// Deprecated to be implemented using GRPC
|
||||
&cli.BoolFlag{
|
||||
Name: "Server",
|
||||
Aliases: []string{"s"},
|
||||
Aliases: []string{"s"},
|
||||
Usage: "Starts server",
|
||||
EnvVars: []string{"SERVER"},
|
||||
EnvVars: []string{"SERVER"},
|
||||
Destination: &Server,
|
||||
},
|
||||
&cli.BoolFlag{
|
||||
Name: "UpdateServerList",
|
||||
Aliases: []string{"us"},
|
||||
Aliases: []string{"us"},
|
||||
Usage: "Update List of Server available based on servers iptables",
|
||||
EnvVars: []string{"UPDATE_SERVER_LIST"},
|
||||
EnvVars: []string{"UPDATE_SERVER_LIST"},
|
||||
Destination: &UpdateServerList,
|
||||
},
|
||||
&cli.BoolFlag{
|
||||
Name: "ListServers",
|
||||
Aliases: []string{"ls"},
|
||||
Aliases: []string{"ls"},
|
||||
Usage: "List servers which can render tasks",
|
||||
EnvVars: []string{"LIST_SERVERS"},
|
||||
EnvVars: []string{"LIST_SERVERS"},
|
||||
Destination: &ServerList,
|
||||
},
|
||||
&cli.StringFlag{
|
||||
Name: "AddServer",
|
||||
Aliases: []string{"as"},
|
||||
Aliases: []string{"as"},
|
||||
Usage: "Adds server IP address to iptables",
|
||||
EnvVars: []string{"ADD_SERVER"},
|
||||
EnvVars: []string{"ADD_SERVER"},
|
||||
Destination: &AddServer,
|
||||
},
|
||||
&cli.StringFlag{
|
||||
Name: "ViewImages",
|
||||
Aliases: []string{"vi"},
|
||||
Aliases: []string{"vi"},
|
||||
Usage: "View images available on the server IP address",
|
||||
EnvVars: []string{"VIEW_IMAGES"},
|
||||
EnvVars: []string{"VIEW_IMAGES"},
|
||||
Destination: &ViewImages,
|
||||
},
|
||||
&cli.StringFlag{
|
||||
Name: "CreateVM",
|
||||
Aliases: []string{"touch"},
|
||||
Aliases: []string{"touch"},
|
||||
Usage: "Creates Docker container on the selected server",
|
||||
EnvVars: []string{"CREATE_VM"},
|
||||
EnvVars: []string{"CREATE_VM"},
|
||||
Destination: &CreateVM,
|
||||
},
|
||||
&cli.StringFlag{
|
||||
Name: "ContainerName",
|
||||
Aliases: []string{"cn"},
|
||||
Aliases: []string{"cn"},
|
||||
Usage: "Specifying the container run on the server side",
|
||||
EnvVars: []string{"CONTAINER_NAME"},
|
||||
EnvVars: []string{"CONTAINER_NAME"},
|
||||
Destination: &ContainerName,
|
||||
},
|
||||
&cli.StringFlag{
|
||||
Name: "RemoveVM",
|
||||
Aliases: []string{"rm"},
|
||||
Aliases: []string{"rm"},
|
||||
Usage: "Stop and Remove Docker container",
|
||||
EnvVars: []string{"REMOVE_VM"},
|
||||
EnvVars: []string{"REMOVE_VM"},
|
||||
Destination: &RemoveVM,
|
||||
},
|
||||
&cli.StringFlag{
|
||||
Name: "ID",
|
||||
Aliases: []string{"id"},
|
||||
Aliases: []string{"id"},
|
||||
Usage: "Docker Container ID",
|
||||
EnvVars: []string{"ID"},
|
||||
EnvVars: []string{"ID"},
|
||||
Destination: &ID,
|
||||
},
|
||||
&cli.StringFlag{
|
||||
Name: "Ports",
|
||||
Aliases: []string{"p"},
|
||||
Aliases: []string{"p"},
|
||||
Usage: "Number of ports to open for the Docker Container",
|
||||
EnvVars: []string{"NUM_PORTS"},
|
||||
EnvVars: []string{"NUM_PORTS"},
|
||||
Destination: &Ports,
|
||||
},
|
||||
&cli.BoolFlag{
|
||||
Name: "GPU",
|
||||
Aliases: []string{"gpu"},
|
||||
Aliases: []string{"gpu"},
|
||||
Usage: "Create Docker Containers to access GPU",
|
||||
EnvVars: []string{"USE_GPU"},
|
||||
EnvVars: []string{"USE_GPU"},
|
||||
Destination: &GPU,
|
||||
},
|
||||
&cli.StringFlag{
|
||||
Name: "Specification",
|
||||
Aliases: []string{"specs"},
|
||||
Aliases: []string{"specs"},
|
||||
Usage: "Specs of the server node",
|
||||
EnvVars: []string{"SPECS"},
|
||||
EnvVars: []string{"SPECS"},
|
||||
Destination: &Specs,
|
||||
},
|
||||
&cli.BoolFlag{
|
||||
Name: "SetDefaultConfig",
|
||||
Aliases: []string{"dc"},
|
||||
Aliases: []string{"dc"},
|
||||
Usage: "Sets a default configuration file",
|
||||
EnvVars: []string{"SET_DEFAULT_CONFIG"},
|
||||
EnvVars: []string{"SET_DEFAULT_CONFIG"},
|
||||
Destination: &SetDefaultConfig,
|
||||
},
|
||||
&cli.BoolFlag{
|
||||
Name: "NetworkInterfaces",
|
||||
Aliases: []string{"ni"},
|
||||
Aliases: []string{"ni"},
|
||||
Usage: "Shows the network interface in your computer",
|
||||
EnvVars: []string{"NETWORK_INTERFACE"},
|
||||
EnvVars: []string{"NETWORK_INTERFACE"},
|
||||
Destination: &NetworkInterface,
|
||||
},
|
||||
&cli.BoolFlag{
|
||||
Name: "ViewPlugins",
|
||||
Aliases: []string{"vp"},
|
||||
Aliases: []string{"vp"},
|
||||
Usage: "Shows plugins available to be executed",
|
||||
EnvVars: []string{"VIEW_PLUGIN"},
|
||||
EnvVars: []string{"VIEW_PLUGIN"},
|
||||
Destination: &ViewPlugin,
|
||||
},
|
||||
&cli.BoolFlag{
|
||||
Name: "TrackedContainers",
|
||||
Name: "TrackedContainers",
|
||||
Aliases: []string{"tc"},
|
||||
Usage: "View containers which have " +
|
||||
"been created from the client side ",
|
||||
EnvVars: []string{"TRACKED_CONTAINERS"},
|
||||
Usage: "View containers which have " +
|
||||
"been created from the client side ",
|
||||
EnvVars: []string{"TRACKED_CONTAINERS"},
|
||||
Destination: &TrackedContainers,
|
||||
},
|
||||
&cli.StringFlag{
|
||||
Name: "ExecutePlugin",
|
||||
Aliases: []string{"plugin"},
|
||||
Aliases: []string{"plugin"},
|
||||
Usage: "Plugin which needs to be executed",
|
||||
EnvVars: []string{"EXECUTE_PLUGIN"},
|
||||
EnvVars: []string{"EXECUTE_PLUGIN"},
|
||||
Destination: &ExecutePlugin,
|
||||
},
|
||||
&cli.BoolFlag{
|
||||
Name: "CreateGroup",
|
||||
Aliases: []string{"cgroup"},
|
||||
Aliases: []string{"cgroup"},
|
||||
Usage: "Creates a new group",
|
||||
EnvVars: []string{"CREATE_GROUP"},
|
||||
EnvVars: []string{"CREATE_GROUP"},
|
||||
Destination: &CreateGroup,
|
||||
},
|
||||
&cli.StringFlag{
|
||||
Name: "Group",
|
||||
Aliases: []string{"group"},
|
||||
Aliases: []string{"group"},
|
||||
Usage: "group flag with argument group ID",
|
||||
EnvVars: []string{"GROUP"},
|
||||
EnvVars: []string{"GROUP"},
|
||||
Destination: &Group,
|
||||
},
|
||||
&cli.BoolFlag{
|
||||
Name: "Groups",
|
||||
Aliases: []string{"groups"},
|
||||
Aliases: []string{"groups"},
|
||||
Usage: "View all groups",
|
||||
EnvVars: []string{"GROUPS"},
|
||||
EnvVars: []string{"GROUPS"},
|
||||
Destination: &Groups,
|
||||
},
|
||||
&cli.BoolFlag{
|
||||
Name: "RemoveContainerGroup",
|
||||
Aliases: []string{"rmcgroup"},
|
||||
Aliases: []string{"rmcgroup"},
|
||||
Usage: "Remove specific container in the group",
|
||||
EnvVars: []string{"REMOVE_CONTAINER_GROUP"},
|
||||
EnvVars: []string{"REMOVE_CONTAINER_GROUP"},
|
||||
Destination: &RemoveContainerGroup,
|
||||
},
|
||||
&cli.StringFlag{
|
||||
Name: "RemoveGroup",
|
||||
Aliases: []string{"rmgroup"},
|
||||
Aliases: []string{"rmgroup"},
|
||||
Usage: "Removes the entire group",
|
||||
EnvVars: []string{"REMOVE_GROUP"},
|
||||
EnvVars: []string{"REMOVE_GROUP"},
|
||||
Destination: &RemoveGroup,
|
||||
},
|
||||
// Generate only allowed in dev release
|
||||
// -- REMOVE ON REGULAR RELEASE --
|
||||
&cli.StringFlag{
|
||||
Name: "Generate",
|
||||
Aliases: []string{"gen"},
|
||||
Aliases: []string{"gen"},
|
||||
Usage: "Generates a new copy of P2PRC which can be modified based on your needs",
|
||||
EnvVars: []string{"GENERATE"},
|
||||
EnvVars: []string{"GENERATE"},
|
||||
Destination: &Generate,
|
||||
},
|
||||
&cli.StringFlag{
|
||||
Name: "ModuleName",
|
||||
Aliases: []string{"mod"},
|
||||
Aliases: []string{"mod"},
|
||||
Usage: "New go project module name",
|
||||
EnvVars: []string{"MODULENAME"},
|
||||
EnvVars: []string{"MODULENAME"},
|
||||
Destination: &Modulename,
|
||||
},
|
||||
//&cli.BoolFlag{
|
||||
// Name: "FRPServerProxy",
|
||||
// Aliases: []string{"proxy"},
|
||||
// Usage: "Starts proxy for server",
|
||||
// EnvVars: []string{"FRPSERVERPROXY"},
|
||||
// Destination: &FRPProxy,
|
||||
//},
|
||||
//--------------------------------
|
||||
&cli.StringFlag{
|
||||
Name: "PullPlugin",
|
||||
Aliases: []string{"pp"},
|
||||
Aliases: []string{"pp"},
|
||||
Usage: "Pulls plugin from git repos",
|
||||
EnvVars: []string{"PULLPLUGIN"},
|
||||
EnvVars: []string{"PULLPLUGIN"},
|
||||
Destination: &PullPlugin,
|
||||
},
|
||||
&cli.StringFlag{
|
||||
Name: "RemovePlugin",
|
||||
Aliases: []string{"rp"},
|
||||
Aliases: []string{"rp"},
|
||||
Usage: "Removes plugin",
|
||||
EnvVars: []string{"REMOVEPLUGIN"},
|
||||
EnvVars: []string{"REMOVEPLUGIN"},
|
||||
Destination: &RemovePlugin,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7,25 +7,28 @@ import (
|
||||
)
|
||||
|
||||
var (
|
||||
defaultPath string
|
||||
defaults = map[string]interface{}{}
|
||||
configName = "config"
|
||||
configType = "json"
|
||||
configFile = "config.json"
|
||||
configPaths []string
|
||||
defaultPath string
|
||||
defaults = map[string]interface{}{}
|
||||
configName = "config"
|
||||
configType = "json"
|
||||
configFile = "config.json"
|
||||
configPaths []string
|
||||
defaultEnvName = "P2PRC"
|
||||
)
|
||||
|
||||
type Config struct {
|
||||
IPTable string
|
||||
DockerContainers string
|
||||
DefaultDockerFile string
|
||||
SpeedTestFile string
|
||||
IPV6Address string
|
||||
PluginPath string
|
||||
TrackContainersPath string
|
||||
ServerPort string
|
||||
MachineName string
|
||||
IPTable string
|
||||
DockerContainers string
|
||||
DefaultDockerFile string
|
||||
SpeedTestFile string
|
||||
IPV6Address string
|
||||
PluginPath string
|
||||
TrackContainersPath string
|
||||
ServerPort string
|
||||
GroupTrackContainersPath string
|
||||
FRPServerPort string
|
||||
BehindNAT string
|
||||
//NetworkInterface string
|
||||
//NetworkInterfaceIPV6Index int
|
||||
}
|
||||
@@ -64,7 +67,7 @@ func Copy(src, dst string) error {
|
||||
}
|
||||
|
||||
// GetPathP2PRC Getting P2PRC Directory from environment variable
|
||||
func GetPathP2PRC()(string,error) {
|
||||
func GetPathP2PRC() (string, error) {
|
||||
curDir := os.Getenv(defaultEnvName)
|
||||
return curDir + "/", nil
|
||||
}
|
||||
@@ -80,40 +83,38 @@ func SetEnvName(EnvName string) error {
|
||||
}
|
||||
|
||||
// GetCurrentPath Getting P2PRC Directory from environment variable
|
||||
func GetCurrentPath()(string,error) {
|
||||
func GetCurrentPath() (string, error) {
|
||||
curDir := os.Getenv("PWD")
|
||||
return curDir + "/", nil
|
||||
}
|
||||
|
||||
|
||||
// SetDefaults This function to be called only during a
|
||||
// make install
|
||||
func SetDefaults() error {
|
||||
//Setting current directory to default path
|
||||
defaultPath, err := GetPathP2PRC()
|
||||
if err != nil{
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
//Creates ip_table.json in the json directory
|
||||
err = Copy("p2p/ip_table.json","p2p/iptable/ip_table.json")
|
||||
err = Copy("p2p/ip_table.json", "p2p/iptable/ip_table.json")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
//Creates a copy of trackcontainers.json in the appropriate directory
|
||||
err = Copy("client/trackcontainers.json","client/trackcontainers/trackcontainers.json")
|
||||
err = Copy("client/trackcontainers.json", "client/trackcontainers/trackcontainers.json")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
//Creates a copy of trackcontainers.json in the appropriate directory
|
||||
err = Copy("client/grouptrackcontainers.json","client/trackcontainers/grouptrackcontainers.json")
|
||||
err = Copy("client/grouptrackcontainers.json", "client/trackcontainers/grouptrackcontainers.json")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
|
||||
//Setting default paths for the config file
|
||||
defaults["IPTable"] = defaultPath + "p2p/iptable/ip_table.json"
|
||||
defaults["DefaultDockerFile"] = defaultPath + "server/docker/containers/docker-ubuntu-sshd/"
|
||||
@@ -124,6 +125,15 @@ func SetDefaults() error {
|
||||
defaults["TrackContainersPath"] = defaultPath + "client/trackcontainers/trackcontainers.json"
|
||||
defaults["GroupTrackContainersPath"] = defaultPath + "client/trackcontainers/grouptrackcontainers.json"
|
||||
defaults["ServerPort"] = "8088"
|
||||
defaults["FRPServerPort"] = "0"
|
||||
defaults["BehindNAT"] = "True"
|
||||
// Random name generator
|
||||
hostname, err := os.Hostname()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
defaults["MachineName"] = hostname
|
||||
//defaults["NetworkInterface"] = "wlp0s20f3"
|
||||
//defaults["NetworkInterfaceIPV6Index"] = "2"
|
||||
|
||||
@@ -145,18 +155,18 @@ func SetDefaults() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func ConfigInit()(*Config,error) {
|
||||
func ConfigInit() (*Config, error) {
|
||||
|
||||
//Setting current directory to default path
|
||||
defaultPath, err := GetPathP2PRC()
|
||||
if err != nil{
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
//Paths to search for config file
|
||||
configPaths = append(configPaths, defaultPath)
|
||||
|
||||
//Add all possible configurations paths
|
||||
for _,v := range configPaths {
|
||||
for _, v := range configPaths {
|
||||
viper.AddConfigPath(v)
|
||||
}
|
||||
|
||||
@@ -164,23 +174,23 @@ func ConfigInit()(*Config,error) {
|
||||
if err := viper.ReadInConfig(); err != nil {
|
||||
// If the error thrown is config file not found
|
||||
//Sets default configuration to viper
|
||||
for k,v := range defaults {
|
||||
viper.SetDefault(k,v)
|
||||
for k, v := range defaults {
|
||||
viper.SetDefault(k, v)
|
||||
}
|
||||
viper.SetConfigName(configName)
|
||||
viper.SetConfigFile(configFile)
|
||||
viper.SetConfigType(configType)
|
||||
|
||||
if err = viper.WriteConfig(); err != nil {
|
||||
return nil,err
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
// Adds configuration to the struct
|
||||
var config Config
|
||||
if err := viper.Unmarshal(&config); err != nil {
|
||||
return nil,err
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &config,nil
|
||||
return &config, nil
|
||||
}
|
||||
|
||||
12
go.mod
12
go.mod
@@ -8,10 +8,11 @@ require (
|
||||
github.com/containerd/continuity v0.0.0-20210315143101-93e15499afd5 // indirect
|
||||
github.com/docker/docker v20.10.0-beta1.0.20201113105859-b6bfff2a628f+incompatible
|
||||
github.com/docker/go-connections v0.4.0
|
||||
github.com/fatedier/frp v0.45.0
|
||||
github.com/gin-gonic/gin v1.6.3
|
||||
github.com/go-git/go-git/v5 v5.4.2
|
||||
github.com/google/uuid v1.1.2
|
||||
github.com/gorilla/mux v1.8.0 // indirect
|
||||
github.com/google/uuid v1.3.0
|
||||
github.com/goombaio/namegenerator v0.0.0-20181006234301-989e774b106e
|
||||
github.com/lithammer/shortuuid v3.0.0+incompatible
|
||||
github.com/moby/sys/mount v0.2.0 // indirect
|
||||
github.com/moby/term v0.0.0-20201110203204-bea5bbe245bf // indirect
|
||||
@@ -19,14 +20,11 @@ require (
|
||||
github.com/otiai10/copy v1.6.0
|
||||
github.com/phayes/freeport v0.0.0-20180830031419-95f893ade6f2
|
||||
github.com/shirou/gopsutil/v3 v3.22.10
|
||||
github.com/spf13/viper v1.4.0
|
||||
github.com/spf13/viper v1.7.0
|
||||
github.com/urfave/cli/v2 v2.3.0
|
||||
gitlab.com/NebulousLabs/fastrand v0.0.0-20181126182046-603482d69e40 // indirect
|
||||
gitlab.com/NebulousLabs/go-upnp v0.0.0-20181011194642-3a71999ed0d3
|
||||
golang.org/x/mod v0.3.0
|
||||
golang.org/x/text v0.3.5 // indirect
|
||||
golang.org/x/time v0.0.0-20210220033141-f8bda1e9f3ba // indirect
|
||||
google.golang.org/grpc v1.35.0 // indirect
|
||||
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4
|
||||
gopkg.in/yaml.v2 v2.4.0
|
||||
gotest.tools/v3 v3.0.3 // indirect
|
||||
)
|
||||
|
||||
165
p2p/frp/client.go
Normal file
165
p2p/frp/client.go
Normal file
@@ -0,0 +1,165 @@
|
||||
package frp
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"git.sr.ht/~akilan1999/p2p-rendering-computation/server/docker"
|
||||
"github.com/fatedier/frp/client"
|
||||
"github.com/fatedier/frp/pkg/config"
|
||||
"github.com/phayes/freeport"
|
||||
"math/rand"
|
||||
"strconv"
|
||||
"time"
|
||||
)
|
||||
|
||||
// Client This struct stores
|
||||
// client information with server
|
||||
// proxy connected
|
||||
type Client struct {
|
||||
Name string
|
||||
Server *Server
|
||||
ClientMappings []ClientMapping
|
||||
}
|
||||
|
||||
// ClientMapping Stores client mapping ports
|
||||
// to proxy server
|
||||
type ClientMapping struct {
|
||||
LocalIP string
|
||||
LocalPort int
|
||||
RemotePort int
|
||||
}
|
||||
|
||||
// StartFRPClientForServer Starts Server using FRP server
|
||||
// returns back a port
|
||||
func StartFRPClientForServer(ipaddress string, port string, localport string) (string, error) {
|
||||
// Setup server information
|
||||
var s Server
|
||||
s.address = ipaddress
|
||||
// convert port to int
|
||||
portInt, err := strconv.Atoi(port)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
s.port = portInt
|
||||
|
||||
// Setup client information
|
||||
var c Client
|
||||
c.Name = "ServerPort"
|
||||
c.Server = &s
|
||||
|
||||
// converts localport to int
|
||||
portInt, err = strconv.Atoi(localport)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
//random port
|
||||
//randPort := rangeIn(10000, 99999)
|
||||
OpenPorts, err := freeport.GetFreePorts(1)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
c.ClientMappings = []ClientMapping{
|
||||
{
|
||||
LocalIP: "localhost",
|
||||
LocalPort: portInt,
|
||||
RemotePort: OpenPorts[0],
|
||||
},
|
||||
}
|
||||
|
||||
// Start client server
|
||||
go c.StartFRPClient()
|
||||
|
||||
return strconv.Itoa(OpenPorts[0]), nil
|
||||
|
||||
}
|
||||
|
||||
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
|
||||
// convert port to int
|
||||
portInt, err := strconv.Atoi(port)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
s.port = portInt
|
||||
|
||||
// Setup client information
|
||||
var c Client
|
||||
c.Name = "ServerPort"
|
||||
c.Server = &s
|
||||
|
||||
// set client mapping
|
||||
//var clientMappings []ClientMapping
|
||||
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
|
||||
}
|
||||
|
||||
//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
|
||||
}
|
||||
|
||||
Docker.Ports.PortSet[i].ExternalPort = portInt
|
||||
}
|
||||
|
||||
return Docker, nil
|
||||
|
||||
}
|
||||
|
||||
// StartFRPClient Starts FRP client
|
||||
func (c *Client) StartFRPClient() error {
|
||||
|
||||
cfg := config.GetDefaultClientConf()
|
||||
|
||||
var proxyConfs map[string]config.ProxyConf
|
||||
var visitorCfgs map[string]config.VisitorConf
|
||||
|
||||
proxyConfs = make(map[string]config.ProxyConf)
|
||||
|
||||
cfg.ServerAddr = c.Server.address
|
||||
cfg.ServerPort = c.Server.port
|
||||
|
||||
for i, _ := range c.ClientMappings {
|
||||
var tcpcnf config.TCPProxyConf
|
||||
tcpcnf.LocalIP = c.ClientMappings[i].LocalIP
|
||||
tcpcnf.LocalPort = c.ClientMappings[i].LocalPort
|
||||
tcpcnf.RemotePort = c.ClientMappings[i].RemotePort
|
||||
|
||||
proxyConfs[tcpcnf.ProxyName] = &tcpcnf
|
||||
}
|
||||
|
||||
cli, err := client.NewService(cfg, proxyConfs, visitorCfgs, "")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
cli.Run()
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// helper function to generate random
|
||||
// number in a certain range
|
||||
func rangeIn(low, hi int) int {
|
||||
return low + rand.Intn(hi-low)
|
||||
}
|
||||
81
p2p/frp/server.go
Normal file
81
p2p/frp/server.go
Normal file
@@ -0,0 +1,81 @@
|
||||
package frp
|
||||
|
||||
import (
|
||||
"github.com/fatedier/frp/pkg/config"
|
||||
"github.com/fatedier/frp/server"
|
||||
"github.com/phayes/freeport"
|
||||
"io/ioutil"
|
||||
"net/http"
|
||||
)
|
||||
|
||||
type Server struct {
|
||||
address string
|
||||
port int
|
||||
}
|
||||
|
||||
// StartFRPProxyFromRandom starts
|
||||
// reverse proxy server based on
|
||||
// a random port generated
|
||||
func StartFRPProxyFromRandom() (int, error) {
|
||||
// gets current configuration
|
||||
//config, err := configP2PRC.ConfigInit()
|
||||
//if err != nil {
|
||||
// return err
|
||||
//}
|
||||
|
||||
var s Server
|
||||
s.address = "0.0.0.0"
|
||||
|
||||
// use random port
|
||||
OpenPorts, err := freeport.GetFreePorts(1)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
|
||||
s.port = OpenPorts[0]
|
||||
|
||||
// start FRP server
|
||||
|
||||
go s.StartFRPServer()
|
||||
|
||||
return OpenPorts[0], nil
|
||||
|
||||
}
|
||||
|
||||
// StartFRPServer The initial plan is only support reverse proxy
|
||||
// for TCP ports
|
||||
// This function starts a server that can act as a reverse
|
||||
// proxy for nodes behind NAT.
|
||||
func (s *Server) StartFRPServer() error {
|
||||
baseConfig := config.GetDefaultServerConf()
|
||||
baseConfig.BindAddr = s.address
|
||||
|
||||
baseConfig.BindPort = s.port
|
||||
service, err := server.NewService(baseConfig)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
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
|
||||
}
|
||||
46
p2p/frp/server_test.go
Normal file
46
p2p/frp/server_test.go
Normal file
@@ -0,0 +1,46 @@
|
||||
package frp
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"testing"
|
||||
"time"
|
||||
)
|
||||
|
||||
// Testing scenario FRPServer
|
||||
func TestStartFRPServer(t *testing.T) {
|
||||
var s Server
|
||||
s.address = "127.0.0.1"
|
||||
s.port = 8808
|
||||
err := s.StartFRPServer()
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
t.Fail()
|
||||
}
|
||||
}
|
||||
|
||||
// Testing scenario FRPServer and FRPClient connection
|
||||
func TestStartFRPClient(t *testing.T) {
|
||||
var s Server
|
||||
s.address = "127.0.0.1"
|
||||
s.port = 8808
|
||||
go s.StartFRPServer()
|
||||
|
||||
time.Sleep(3 * time.Second)
|
||||
|
||||
// Sample test client
|
||||
var c Client
|
||||
c.Server = &s
|
||||
c.ClientMappings = []ClientMapping{
|
||||
{
|
||||
LocalIP: "127.0.0.1",
|
||||
LocalPort: 22,
|
||||
RemotePort: 3301,
|
||||
},
|
||||
}
|
||||
|
||||
err := c.StartFRPClient()
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
t.Fail()
|
||||
}
|
||||
}
|
||||
@@ -1,12 +1,13 @@
|
||||
{
|
||||
"ip_address": [
|
||||
{
|
||||
"ipv4": "139.162.246.221",
|
||||
"ipv6": "",
|
||||
"latency": 0,
|
||||
"download": 0,
|
||||
"upload": 0,
|
||||
"serverport": "8088"
|
||||
"Name": "Node1",
|
||||
"IPV4": "64.227.168.102",
|
||||
"IPV6": "",
|
||||
"Latency": 0,
|
||||
"ServerPort": "8088",
|
||||
"NAT": "False",
|
||||
"EscapeImplementation": "None"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
@@ -18,12 +18,15 @@ type IpAddresses struct {
|
||||
}
|
||||
|
||||
type IpAddress struct {
|
||||
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"`
|
||||
Name string `json:"Name"`
|
||||
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"`
|
||||
NAT string `json:"NAT"`
|
||||
EscapeImplementation string `json:"EscapeImplementation"`
|
||||
}
|
||||
|
||||
type IP struct {
|
||||
@@ -31,19 +34,18 @@ type IP struct {
|
||||
}
|
||||
|
||||
// ReadIpTable Read data from Ip tables from json file
|
||||
func ReadIpTable()(*IpAddresses ,error){
|
||||
// Get Path from config
|
||||
func ReadIpTable() (*IpAddresses, error) {
|
||||
// Get Path from config
|
||||
config, err := config.ConfigInit()
|
||||
if err != nil {
|
||||
return nil,err
|
||||
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
|
||||
return nil, err
|
||||
}
|
||||
|
||||
|
||||
// defer the closing of our jsonFile so that we can parse it later on
|
||||
defer jsonFile.Close()
|
||||
|
||||
@@ -71,6 +73,9 @@ func ReadIpTable()(*IpAddresses ,error){
|
||||
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)
|
||||
@@ -80,7 +85,7 @@ func ReadIpTable()(*IpAddresses ,error){
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &ipAddresses, nil
|
||||
return &ipAddresses, nil
|
||||
}
|
||||
|
||||
// WriteIpTable Write to IP table json file
|
||||
@@ -118,27 +123,38 @@ func PrintIpTable() error {
|
||||
}
|
||||
|
||||
for i := 0; i < len(table.IpAddress); i++ {
|
||||
fmt.Printf("\nIP Address: %s\nIPV6: %s\nLatency: %s\nServerPort: %s\n-----------" +
|
||||
"-----------------\n",table.IpAddress[i].Ipv4,table.IpAddress[i].Ipv6,
|
||||
table.IpAddress[i].Latency, table.IpAddress[i].ServerPort)
|
||||
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
|
||||
}
|
||||
|
||||
// RemoveDuplicates This is a temporary fix current functions failing to remove
|
||||
// Duplicate IP addresses from local IP table
|
||||
func (table *IpAddresses)RemoveDuplicates() error {
|
||||
func (table *IpAddresses) RemoveDuplicates() error {
|
||||
|
||||
var NoDuplicates IpAddresses
|
||||
for i, _:= range table.IpAddress {
|
||||
for i, _ := range table.IpAddress {
|
||||
Exists := false
|
||||
for k := range NoDuplicates.IpAddress {
|
||||
if (NoDuplicates.IpAddress[k].Ipv4 != "" && NoDuplicates.IpAddress[k].Ipv4 == table.IpAddress[i].Ipv4) || (NoDuplicates.IpAddress[k].Ipv6 != "" && NoDuplicates.IpAddress[k].Ipv6 == table.IpAddress[i].Ipv6) {
|
||||
// Statements checked for
|
||||
// - duplicate IPV4 addresses [<IPV4>:<Port No>]
|
||||
// - duplicate IPV6 addresses [<IPV6>]
|
||||
// - 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 == "True" && table.IpAddress[i].EscapeImplementation == "None" {
|
||||
Exists = true
|
||||
}
|
||||
if Exists {
|
||||
continue
|
||||
}
|
||||
@@ -151,16 +167,16 @@ func (table *IpAddresses)RemoveDuplicates() error {
|
||||
}
|
||||
|
||||
// CurrentPublicIP Get Current Public IP address
|
||||
func CurrentPublicIP() (string,error) {
|
||||
func CurrentPublicIP() (string, error) {
|
||||
req, err := http.Get("http://ip-api.com/json/")
|
||||
if err != nil {
|
||||
return "",err
|
||||
return "", err
|
||||
}
|
||||
defer req.Body.Close()
|
||||
|
||||
body, err := ioutil.ReadAll(req.Body)
|
||||
if err != nil {
|
||||
return "",err
|
||||
return "", err
|
||||
}
|
||||
|
||||
var ip IP
|
||||
@@ -171,10 +187,10 @@ func CurrentPublicIP() (string,error) {
|
||||
|
||||
// GetCurrentIPV6 gets the current IPV6 address based on the interface
|
||||
// specified in the config file
|
||||
func GetCurrentIPV6()(string,error){
|
||||
func GetCurrentIPV6() (string, error) {
|
||||
Config, err := config.ConfigInit()
|
||||
if err != nil {
|
||||
return "",err
|
||||
return "", err
|
||||
}
|
||||
|
||||
// Fix in future release
|
||||
@@ -223,7 +239,7 @@ func ViewNetworkInterface() error {
|
||||
}
|
||||
|
||||
// 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)
|
||||
// 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] {
|
||||
@@ -235,4 +251,15 @@ func Ip4or6(s string) string {
|
||||
}
|
||||
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)
|
||||
//}
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
package p2p
|
||||
|
||||
// SpeedTest Runs a speed test and does updates IP tables accordingly
|
||||
func (ip *IpAddresses)SpeedTest() error{
|
||||
func (ip *IpAddresses) SpeedTest() error {
|
||||
|
||||
//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 {
|
||||
|
||||
@@ -36,7 +36,6 @@ func (ip *IpAddresses)SpeedTest() error{
|
||||
//Set value to the list
|
||||
|
||||
ActiveIP.IpAddress = append(ActiveIP.IpAddress, value)
|
||||
|
||||
}
|
||||
|
||||
ip.IpAddress = ActiveIP.IpAddress
|
||||
@@ -50,7 +49,7 @@ func (ip *IpAddresses)SpeedTest() error{
|
||||
}
|
||||
|
||||
// SpeedTestUpdatedIPTable Called when ip tables from httpclient/server is also passed on
|
||||
func (ip *IpAddresses)SpeedTestUpdatedIPTable() error{
|
||||
func (ip *IpAddresses) SpeedTestUpdatedIPTable() error {
|
||||
targets, err := ReadIpTable()
|
||||
if err != nil {
|
||||
return err
|
||||
@@ -59,24 +58,24 @@ func (ip *IpAddresses)SpeedTestUpdatedIPTable() error{
|
||||
// To ensure struct has no duplicates IP addresses
|
||||
//DoNotRead := targets
|
||||
|
||||
// Appends all IP addresses
|
||||
// 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 {
|
||||
// // 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].Ipv6 != "" && ip.IpAddress[k].Ipv6 == targets.IpAddress[i].Ipv6) {
|
||||
// Exists = true
|
||||
// break
|
||||
// }
|
||||
//}
|
||||
//
|
||||
//// If the struct exists then continues
|
||||
//if Exists {
|
||||
// continue
|
||||
//}
|
||||
//To ensure that there are no duplicate IP addresses
|
||||
Exists := false
|
||||
for k := range ip.IpAddress {
|
||||
// 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 == "True") || (targets.IpAddress[i].Ipv6 != "" && ip.IpAddress[k].Ipv6 == targets.IpAddress[i].Ipv6) {
|
||||
Exists = true
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
// If the struct exists then continues
|
||||
if Exists {
|
||||
continue
|
||||
}
|
||||
|
||||
ip.IpAddress = append(ip.IpAddress, targets.IpAddress[i])
|
||||
}
|
||||
@@ -105,7 +104,6 @@ func LocalSpeedTestIpTable() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
|
||||
// Helper function to remove element from an array of a struct
|
||||
//func remove(s []IpAddress, i int) []IpAddress {
|
||||
// s[len(s)-1], s[i] = s[i], s[len(s)-1]
|
||||
|
||||
@@ -2,6 +2,7 @@ package p2p
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"errors"
|
||||
"git.sr.ht/~akilan1999/p2p-rendering-computation/config"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
@@ -12,8 +13,8 @@ import (
|
||||
"time"
|
||||
)
|
||||
|
||||
//var dlSizes = [...]int{350, 500, 750, 1000, 1500, 2000, 2500, 3000, 3500, 4000}
|
||||
//var ulSizes = [...]int{100, 300, 500, 800, 1000, 1500, 2500, 3000, 3500, 4000} //kB
|
||||
// var dlSizes = [...]int{350, 500, 750, 1000, 1500, 2000, 2500, 3000, 3500, 4000}
|
||||
// var ulSizes = [...]int{100, 300, 500, 800, 1000, 1500, 2500, 3000, 3500, 4000} //kB
|
||||
var httpclient = http.Client{}
|
||||
|
||||
// DownloadTest executes the test to measure download speed
|
||||
@@ -78,7 +79,7 @@ var httpclient = http.Client{}
|
||||
//}
|
||||
|
||||
// Download Speed
|
||||
func (s *IpAddress)DownloadSpeed() error {
|
||||
func (s *IpAddress) DownloadSpeed() error {
|
||||
start := time.Now()
|
||||
resp, err := httpclient.Get("http://" + s.Ipv4 + ":8088/50")
|
||||
if err != nil {
|
||||
@@ -89,11 +90,11 @@ func (s *IpAddress)DownloadSpeed() error {
|
||||
t := time.Since(start)
|
||||
//fmt.Println(s.Seconds())
|
||||
// size * time (seconds)
|
||||
s.Download = (50/t.Seconds())*8
|
||||
return nil
|
||||
s.Download = (50 / t.Seconds()) * 8
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *IpAddress)UploadSpeed() error {
|
||||
func (s *IpAddress) UploadSpeed() error {
|
||||
start := time.Now()
|
||||
|
||||
// Get upload file path from config file
|
||||
@@ -103,9 +104,9 @@ func (s *IpAddress)UploadSpeed() error {
|
||||
return err
|
||||
}
|
||||
|
||||
b, w := createMultipartFormData("file",config.SpeedTestFile)
|
||||
b, w := createMultipartFormData("file", config.SpeedTestFile)
|
||||
|
||||
req, err := http.NewRequest("GET", "http://" + s.Ipv4 + ":" + s.ServerPort + "/upload", &b)
|
||||
req, err := http.NewRequest("GET", "http://"+s.Ipv4+":"+s.ServerPort+"/upload", &b)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -116,12 +117,12 @@ func (s *IpAddress)UploadSpeed() error {
|
||||
t := time.Since(start)
|
||||
//fmt.Println(s.Seconds())
|
||||
// size * time (seconds)
|
||||
s.Upload = (50/t.Seconds())*8
|
||||
s.Upload = (50 / t.Seconds()) * 8
|
||||
return nil
|
||||
}
|
||||
|
||||
//Upload helper function for uploading
|
||||
//(https://stackoverflow.com/questions/20205796/post-data-using-the-content-type-multipart-form-data
|
||||
// Upload helper function for uploading
|
||||
// (https://stackoverflow.com/questions/20205796/post-data-using-the-content-type-multipart-form-data
|
||||
func createMultipartFormData(fieldName, fileName string) (bytes.Buffer, *multipart.Writer) {
|
||||
var b bytes.Buffer
|
||||
var err error
|
||||
@@ -142,7 +143,7 @@ func createMultipartFormData(fieldName, fileName string) (bytes.Buffer, *multipa
|
||||
func mustOpen(f string) *os.File {
|
||||
r, err := os.Open(f)
|
||||
if err != nil {
|
||||
log.Fatalf("Error with mustOpen: %v",err)
|
||||
log.Fatalf("Error with mustOpen: %v", err)
|
||||
}
|
||||
return r
|
||||
}
|
||||
@@ -163,8 +164,8 @@ func (s *IpAddress) PingTest() error {
|
||||
sTime := time.Now()
|
||||
resp, err := http.Get(pingURL)
|
||||
fTime := time.Now()
|
||||
if err != nil {
|
||||
return err
|
||||
if err != nil || resp.StatusCode != 200 {
|
||||
return errors.New("Node not found")
|
||||
}
|
||||
if fTime.Sub(sTime) < l {
|
||||
l = fTime.Sub(sTime)
|
||||
@@ -176,4 +177,3 @@ func (s *IpAddress) PingTest() error {
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
|
||||
106
p2p/upnp.go
106
p2p/upnp.go
@@ -1,76 +1,74 @@
|
||||
package p2p
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"fmt"
|
||||
"gitlab.com/NebulousLabs/go-upnp"
|
||||
)
|
||||
|
||||
// Port forwarding to the router
|
||||
func ForwardPort(port int) error{
|
||||
// connect to router
|
||||
d, err := upnp.Discover()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
func ForwardPort(port int) error {
|
||||
// connect to router
|
||||
d, err := upnp.Discover()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// discover external IP
|
||||
ip, err := d.ExternalIP()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
fmt.Println("Your external IP is:", ip)
|
||||
// discover external IP
|
||||
ip, err := d.ExternalIP()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
fmt.Println("Your external IP is:", ip)
|
||||
|
||||
// forward a port
|
||||
err = d.Forward(50498, "upnp test")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
// forward a port
|
||||
err = d.Forward(50498, "upnp test")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// record router's location
|
||||
loc := d.Location()
|
||||
// record router's location
|
||||
loc := d.Location()
|
||||
|
||||
// connect to router directly
|
||||
d, err = upnp.Load(loc)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
// connect to router directly
|
||||
d, err = upnp.Load(loc)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
return nil
|
||||
}
|
||||
|
||||
// unForwardPort from router
|
||||
func UnForwardPort(port int) error{
|
||||
// connect to router
|
||||
d, err := upnp.Discover()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
// UnForwardPort from router
|
||||
func UnForwardPort(port int) error {
|
||||
// connect to router
|
||||
d, err := upnp.Discover()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// discover external IP
|
||||
ip, err := d.ExternalIP()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// discover external IP
|
||||
ip, err := d.ExternalIP()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
fmt.Println("Your external IP is:", ip)
|
||||
|
||||
fmt.Println("Your external IP is:", ip)
|
||||
// un-forward a port
|
||||
err = d.Clear(50498)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// record router's location
|
||||
loc := d.Location()
|
||||
|
||||
// un-forward a port
|
||||
err = d.Clear(50498)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
// connect to router directly
|
||||
d, err = upnp.Load(loc)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// record router's location
|
||||
loc := d.Location()
|
||||
|
||||
// connect to router directly
|
||||
d, err = upnp.Load(loc)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
return nil
|
||||
|
||||
}
|
||||
|
||||
15
p2p/upnp_test.go
Normal file
15
p2p/upnp_test.go
Normal file
@@ -0,0 +1,15 @@
|
||||
package p2p
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"testing"
|
||||
)
|
||||
|
||||
// Tests if the current has UPNP support
|
||||
func TestForwardUPNPPort(t *testing.T) {
|
||||
err := ForwardPort(6586)
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
t.Fail()
|
||||
}
|
||||
}
|
||||
BIN
server/50.bin
BIN
server/50.bin
Binary file not shown.
120
server/server.go
120
server/server.go
@@ -3,29 +3,39 @@ package server
|
||||
import (
|
||||
"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{
|
||||
func Server() error {
|
||||
r := gin.Default()
|
||||
|
||||
//Get Server port based on the config file
|
||||
config, err := config.ConfigInit()
|
||||
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
|
||||
|
||||
// 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){
|
||||
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)
|
||||
})
|
||||
|
||||
@@ -71,7 +81,7 @@ func Server() error{
|
||||
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)
|
||||
@@ -83,7 +93,7 @@ func Server() error{
|
||||
}
|
||||
|
||||
// Reads IP addresses from ip table
|
||||
IpAddresses,err := p2p.ReadIpTable()
|
||||
IpAddresses, err := p2p.ReadIpTable()
|
||||
if err != nil {
|
||||
c.String(http.StatusOK, fmt.Sprint(err))
|
||||
}
|
||||
@@ -91,31 +101,40 @@ func Server() error{
|
||||
c.JSON(http.StatusOK, IpAddresses)
|
||||
})
|
||||
|
||||
// Starts docker container in server
|
||||
// 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
|
||||
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)
|
||||
|
||||
// Creates container and returns-back result to
|
||||
// access container
|
||||
resp, err := docker.BuildRunContainer(PortsInt,GPU,ContainerName)
|
||||
resp, err := docker.BuildRunContainer(PortsInt, GPU, ContainerName)
|
||||
|
||||
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))
|
||||
}
|
||||
fmt.Println(resp)
|
||||
}
|
||||
|
||||
c.JSON(http.StatusOK, resp)
|
||||
})
|
||||
|
||||
//Remove container
|
||||
r.GET("/RemoveContainer", func(c *gin.Context) {
|
||||
ID := c.DefaultQuery("id","0")
|
||||
ID := c.DefaultQuery("id", "0")
|
||||
if err := docker.StopAndRemoveContainer(ID); err != nil {
|
||||
c.String(http.StatusInternalServerError, fmt.Sprintf("error: %s", err))
|
||||
}
|
||||
@@ -131,10 +150,73 @@ func Server() error{
|
||||
c.JSON(http.StatusOK, resp)
|
||||
})
|
||||
|
||||
//Get Server port based on the config file
|
||||
config, err := config.ConfigInit()
|
||||
if err != nil {
|
||||
return 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))
|
||||
})
|
||||
|
||||
// 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
|
||||
}
|
||||
|
||||
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]
|
||||
}
|
||||
}
|
||||
|
||||
// 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.Name = config.MachineName
|
||||
ProxyIpAddr.NAT = "False"
|
||||
ProxyIpAddr.EscapeImplementation = "FRP"
|
||||
|
||||
// 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
|
||||
|
||||
Reference in New Issue
Block a user