added auto reverse proxy detection and applicable for docker container

This commit is contained in:
2022-12-01 05:37:15 +00:00
parent 7c0ddc79c9
commit 4921a6345d
8 changed files with 1136 additions and 908 deletions

View File

@@ -1,294 +1,304 @@
package cmd
import (
"fmt"
"git.sr.ht/~akilan1999/p2p-rendering-computation/client"
"git.sr.ht/~akilan1999/p2p-rendering-computation/config"
"git.sr.ht/~akilan1999/p2p-rendering-computation/generate"
"git.sr.ht/~akilan1999/p2p-rendering-computation/p2p"
"git.sr.ht/~akilan1999/p2p-rendering-computation/plugin"
"git.sr.ht/~akilan1999/p2p-rendering-computation/server"
"github.com/urfave/cli/v2"
"fmt"
"git.sr.ht/~akilan1999/p2p-rendering-computation/client"
"git.sr.ht/~akilan1999/p2p-rendering-computation/config"
"git.sr.ht/~akilan1999/p2p-rendering-computation/generate"
"git.sr.ht/~akilan1999/p2p-rendering-computation/p2p"
"git.sr.ht/~akilan1999/p2p-rendering-computation/p2p/frp"
"git.sr.ht/~akilan1999/p2p-rendering-computation/plugin"
"git.sr.ht/~akilan1999/p2p-rendering-computation/server"
"github.com/urfave/cli/v2"
)
var CliAction = func(ctx *cli.Context) error {
if Server {
// TODO: with RPC calls
server.Server()
//server.Rpc()
}
if 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()
if err != nil {
fmt.Print(err)
}
// Reads from ip table and passes it
// on to struct print function
//Servers, err := p2p.ReadIpTable()
//if err != nil {
// return err
//}
//client.PrettyPrint(Servers)
p2p.PrintIpTable()
}
//Listing servers and also updates IP tables (Default 3 hops)
if UpdateServerList {
err := client.UpdateIpTableListClient()
if err != nil {
fmt.Print(err)
}
// Reads from ip table and passes it
// on to struct print function
//Servers, err := p2p.ReadIpTable()
//if err != nil {
// return err
//}
//client.PrettyPrint(Servers)
p2p.PrintIpTable()
}
// Displays the IP table
if ServerList {
// Reads from ip table and passes it
// on to struct print function
//Servers, err := p2p.ReadIpTable()
//if err != nil {
// return err
//}
p2p.PrintIpTable()
}
// Displays the IP table
if ServerList {
// Reads from ip table and passes it
// on to struct print function
//Servers, err := p2p.ReadIpTable()
//if err != nil {
// return err
//}
p2p.PrintIpTable()
}
// Add provided IP to the IP table
if AddServer != "" {
res, err := p2p.ReadIpTable()
if err != nil {
fmt.Println(err)
}
// Add provided IP to the IP table
if AddServer != "" {
res, err := p2p.ReadIpTable()
if err != nil {
fmt.Println(err)
}
//Create variable of type IpAddress and set IP address
// to it
var IpAddr p2p.IpAddress
//Create variable of type IpAddress and set IP address
// to it
var IpAddr p2p.IpAddress
//Checking if the address is a ipv4
// or ipv6 address
ip4Orip6 := p2p.Ip4or6(AddServer)
if ip4Orip6 == "version 6" {
IpAddr.Ipv6 = AddServer
} else {
IpAddr.Ipv4 = AddServer
}
//Checking if the address is a ipv4
// or ipv6 address
ip4Orip6 := p2p.Ip4or6(AddServer)
if ip4Orip6 == "version 6" {
IpAddr.Ipv6 = AddServer
} else {
IpAddr.Ipv4 = AddServer
}
// If a server port is provided then set it
if Ports != "" {
IpAddr.ServerPort = Ports
} else {
IpAddr.ServerPort = "8088"
}
// Append IP address to variable result which
// is a list
res.IpAddress = append(res.IpAddress, IpAddr)
// Adds the new server IP to the iptable
res.WriteIpTable()
// If a server port is provided then set it
if Ports != "" {
IpAddr.ServerPort = Ports
} else {
IpAddr.ServerPort = "8088"
}
// Append IP address to variable result which
// is a list
res.IpAddress = append(res.IpAddress, IpAddr)
// Adds the new server IP to the iptable
res.WriteIpTable()
}
}
// Displays all images available on the server side
if ViewImages != "" {
imageRes, err := client.ViewContainers(ViewImages)
// Displays all images available on the server side
if ViewImages != "" {
imageRes, err := client.ViewContainers(ViewImages)
if err != nil {
fmt.Print(err)
}
client.PrettyPrint(imageRes)
}
if err != nil {
fmt.Print(err)
}
client.PrettyPrint(imageRes)
}
// Function called to stop and remove server from Docker
if RemoveVM != "" && ID != "" {
err := client.RemoveContianer(RemoveVM, ID)
if err != nil {
fmt.Print(err)
}
}
// Function called to stop and remove server from Docker
if RemoveVM != "" && ID != "" {
err := client.RemoveContianer(RemoveVM,ID)
if err != nil {
fmt.Print(err)
}
}
//Call function to create Docker container
if CreateVM != "" {
//Call function to create Docker container
if CreateVM != "" {
var PortsInt int
var PortsInt int
if Ports != "" {
// Convert Get Request value to int
fmt.Sscanf(Ports, "%d", &PortsInt)
}
if Ports != "" {
// Convert Get Request value to int
fmt.Sscanf(Ports, "%d", &PortsInt)
}
// Calls function to do Api call to start the container on the server side
imageRes, err := client.StartContainer(CreateVM, PortsInt, GPU, ContainerName)
// Calls function to do Api call to start the container on the server side
imageRes, err := client.StartContainer(CreateVM,PortsInt,GPU,ContainerName)
if err != nil {
fmt.Print(err)
}
client.PrettyPrint(imageRes)
}
if err != nil {
fmt.Print(err)
}
client.PrettyPrint(imageRes)
}
//Call if specs flag is called
if Specs != "" {
specs, err := client.GetSpecs(Specs)
if err != nil {
return err
}
//Call if specs flag is called
if Specs != "" {
specs, err := client.GetSpecs(Specs)
if err != nil {
return err
}
// Pretty print
client.PrettyPrint(specs)
}
// Pretty print
client.PrettyPrint(specs)
}
//Sets default paths to the config file
if SetDefaultConfig {
err := config.SetDefaults()
if err != nil {
fmt.Print(err)
}
}
//Sets default paths to the config file
if SetDefaultConfig {
err := config.SetDefaults()
if err != nil {
fmt.Print(err)
}
}
//If the network interface flag is called
// Then all the network interfaces are displayed
if NetworkInterface {
err := p2p.ViewNetworkInterface()
if err != nil {
fmt.Print(err)
}
}
//If the network interface flag is called
// Then all the network interfaces are displayed
if NetworkInterface {
err := p2p.ViewNetworkInterface()
if err != nil {
fmt.Print(err)
}
}
// If the view plugin flag is called then display all
// plugins available
if ViewPlugin {
plugins, err := plugin.DetectPlugins()
if err != nil {
fmt.Print(err)
}
client.PrettyPrint(plugins)
}
// If the view plugin flag is called then display all
// plugins available
if ViewPlugin {
plugins ,err := plugin.DetectPlugins()
if err != nil {
fmt.Print(err)
}
client.PrettyPrint(plugins)
}
// If the flag Tracked Container is called or the flag
// --tc
if TrackedContainers {
err, trackedContainers := client.ViewTrackedContainers()
if err != nil {
fmt.Print(err)
}
client.PrettyPrint(trackedContainers)
}
// If the flag Tracked Container is called or the flag
// --tc
if TrackedContainers {
err, trackedContainers := client.ViewTrackedContainers()
if err != nil {
fmt.Print(err)
}
client.PrettyPrint(trackedContainers)
}
//Executing plugin when the plugin flag is called
// --plugin
if ExecutePlugin != "" {
// To execute plugin requires the container ID or group ID provided when being executed
if ID != "" {
err := plugin.CheckRunPlugin(ExecutePlugin, ID)
if err != nil {
fmt.Println(err)
} else {
fmt.Println("Success")
}
} else {
fmt.Println("provide container ID")
}
//Executing plugin when the plugin flag is called
// --plugin
if ExecutePlugin != "" {
// To execute plugin requires the container ID or group ID provided when being executed
if ID != "" {
err := plugin.CheckRunPlugin(ExecutePlugin, ID)
if err != nil {
fmt.Println(err)
} else {
fmt.Println("Success")
}
} else {
fmt.Println("provide container ID")
}
}
}
// Executing function to create new group
// Creates new group and outputs JSON file
if CreateGroup {
group, err := client.CreateGroup()
if err != nil {
return err
}
client.PrettyPrint(group)
}
// Executing function to create new group
// Creates new group and outputs JSON file
if CreateGroup {
group, err := client.CreateGroup()
if err != nil {
return err
}
client.PrettyPrint(group)
}
// Actions to be performed when the
// group flag is called
// --group <Group ID>
if Group != "" {
// Remove container from group based on group ID provided
// --rmcgroup --id <contianer id>
if RemoveContainerGroup && ID != "" {
group, err := client.RemoveContainerGroup(ID, Group)
if err != nil {
fmt.Println(err)
} else {
client.PrettyPrint(group)
}
} else if ID != "" { // Add container to group based on group ID provided
// --id <Container ID>
group, err := client.AddContainerToGroup(ID, Group)
if err != nil {
fmt.Println(err)
} else {
client.PrettyPrint(group)
}
} else { // View all information about current group
group, err := client.GetGroup(Group)
if err != nil {
fmt.Println(err)
} else {
client.PrettyPrint(group)
}
}
}
// Actions to be performed when the
// group flag is called
// --group <Group ID>
if Group != "" {
// Remove container from group based on group ID provided
// --rmcgroup --id <contianer id>
if RemoveContainerGroup && ID != "" {
group, err := client.RemoveContainerGroup(ID, Group)
if err != nil {
fmt.Println(err)
} else {
client.PrettyPrint(group)
}
} else if ID != "" { // Add container to group based on group ID provided
// --id <Container ID>
group, err := client.AddContainerToGroup(ID,Group)
if err != nil {
fmt.Println(err)
} else {
client.PrettyPrint(group)
}
} else { // View all information about current group
group, err := client.GetGroup(Group)
if err != nil {
fmt.Println(err)
} else {
client.PrettyPrint(group)
}
}
}
// Execute function to remove entire group
// when remove group flag is called
// --rmgroup
if RemoveGroup != "" {
err := client.RemoveGroup(RemoveGroup)
if err != nil {
fmt.Println(err)
} else {
fmt.Println("Group Removed")
}
}
// Execute function to remove entire group
// when remove group flag is called
// --rmgroup
if RemoveGroup != "" {
err := client.RemoveGroup(RemoveGroup)
if err != nil {
fmt.Println(err)
} else {
fmt.Println("Group Removed")
}
}
// Execute Function to view all groups
if Groups {
groups, err := client.ReadGroup()
if err != nil {
fmt.Println(err)
} else {
client.PrettyPrint(groups)
}
}
// Execute Function to view all groups
if Groups {
groups, err := client.ReadGroup()
if err != nil {
fmt.Println(err)
} else {
client.PrettyPrint(groups)
}
}
// -- REMOVE ON REGULAR RELEASE --
// when flag --gen is called an extension
// of the project is created to repurpose
// the project for custom purpose
if Generate != "" {
var err error
// If the module name is provided
if Modulename != "" {
err = generate.GenerateNewProject(Generate,Modulename)
} else {
err = generate.GenerateNewProject(Generate,Generate)
}
if err != nil {
fmt.Println(err)
} else {
fmt.Println("Created new folder: " + Generate)
fmt.Println("1. Enter inside " + Generate + " directory")
fmt.Println("2. git remote add " + Generate + " <PATH to the github repo>")
fmt.Println("3. git push " + Generate + " <PATH to the github repo>")
fmt.Println("4. go mod tidy")
fmt.Println("5. sh install.sh " + Generate)
fmt.Println("6. ./" + Generate + " -h (This is to test if the binary is working)")
}
}
//--------------------------------
// Starts server as a reverse proxy so that
// nodes can connect to each other behind NAT
if FRPProxy {
err := frp.StartFRPProxyFromConfig()
if err != nil {
fmt.Println(err)
}
}
if PullPlugin != "" {
err := plugin.DownloadPlugin(PullPlugin)
if err != nil {
fmt.Println(err)
} else {
fmt.Println("Success")
}
}
// -- REMOVE ON REGULAR RELEASE --
// when flag --gen is called an extension
// of the project is created to repurpose
// the project for custom purpose
if Generate != "" {
var err error
// If the module name is provided
if Modulename != "" {
err = generate.GenerateNewProject(Generate, Modulename)
} else {
err = generate.GenerateNewProject(Generate, Generate)
}
if err != nil {
fmt.Println(err)
} else {
fmt.Println("Created new folder: " + Generate)
fmt.Println("1. Enter inside " + Generate + " directory")
fmt.Println("2. git remote add " + Generate + " <PATH to the github repo>")
fmt.Println("3. git push " + Generate + " <PATH to the github repo>")
fmt.Println("4. go mod tidy")
fmt.Println("5. sh install.sh " + Generate)
fmt.Println("6. ./" + Generate + " -h (This is to test if the binary is working)")
}
}
//--------------------------------
if RemovePlugin != "" {
err := plugin.DeletePlugin(RemovePlugin)
if err != nil {
fmt.Println(err)
} else {
fmt.Println("Success")
}
}
if PullPlugin != "" {
err := plugin.DownloadPlugin(PullPlugin)
if err != nil {
fmt.Println(err)
} else {
fmt.Println("Success")
}
}
if RemovePlugin != "" {
err := plugin.DeletePlugin(RemovePlugin)
if err != nil {
fmt.Println(err)
} else {
fmt.Println("Success")
}
}
return nil
return nil
}

View File

@@ -1,228 +1,236 @@
package cmd
import (
"github.com/urfave/cli/v2"
"github.com/urfave/cli/v2"
)
// 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
Groups bool
RemoveContainerGroup bool
RemoveGroup string
// Generate only allowed in dev release
// -- REMOVE ON REGULAR RELEASE --
Generate string
Modulename string
//--------------------------------
PullPlugin string
RemovePlugin 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
FRPProxy bool
// Generate only allowed in dev release
// -- REMOVE ON REGULAR RELEASE --
Generate string
Modulename string
//--------------------------------
PullPlugin string
RemovePlugin string
)
var AppConfigFlags = []cli.Flag{
// Deprecated to be implemented using GRPC
&cli.BoolFlag{
Name: "Server",
Aliases: []string{"s"},
Usage: "Starts server",
EnvVars: []string{"SERVER"},
Destination: &Server,
},
&cli.BoolFlag{
Name: "UpdateServerList",
Aliases: []string{"us"},
Usage: "Update List of Server available based on servers iptables",
EnvVars: []string{"UPDATE_SERVER_LIST"},
Destination: &UpdateServerList,
},
&cli.BoolFlag{
Name: "ListServers",
Aliases: []string{"ls"},
Usage: "List servers which can render tasks",
EnvVars: []string{"LIST_SERVERS"},
Destination: &ServerList,
},
&cli.StringFlag{
Name: "AddServer",
Aliases: []string{"as"},
Usage: "Adds server IP address to iptables",
EnvVars: []string{"ADD_SERVER"},
Destination: &AddServer,
},
&cli.StringFlag{
Name: "ViewImages",
Aliases: []string{"vi"},
Usage: "View images available on the server IP address",
EnvVars: []string{"VIEW_IMAGES"},
Destination: &ViewImages,
},
&cli.StringFlag{
Name: "CreateVM",
Aliases: []string{"touch"},
Usage: "Creates Docker container on the selected server",
EnvVars: []string{"CREATE_VM"},
Destination: &CreateVM,
},
&cli.StringFlag{
Name: "ContainerName",
Aliases: []string{"cn"},
Usage: "Specifying the container run on the server side",
EnvVars: []string{"CONTAINER_NAME"},
Destination: &ContainerName,
},
&cli.StringFlag{
Name: "RemoveVM",
Aliases: []string{"rm"},
Usage: "Stop and Remove Docker container",
EnvVars: []string{"REMOVE_VM"},
Destination: &RemoveVM,
},
&cli.StringFlag{
Name: "ID",
Aliases: []string{"id"},
Usage: "Docker Container ID",
EnvVars: []string{"ID"},
Destination: &ID,
},
&cli.StringFlag{
Name: "Ports",
Aliases: []string{"p"},
Usage: "Number of ports to open for the Docker Container",
EnvVars: []string{"NUM_PORTS"},
Destination: &Ports,
},
&cli.BoolFlag{
Name: "GPU",
Aliases: []string{"gpu"},
Usage: "Create Docker Containers to access GPU",
EnvVars: []string{"USE_GPU"},
Destination: &GPU,
},
&cli.StringFlag{
Name: "Specification",
Aliases: []string{"specs"},
Usage: "Specs of the server node",
EnvVars: []string{"SPECS"},
Destination: &Specs,
},
&cli.BoolFlag{
Name: "SetDefaultConfig",
Aliases: []string{"dc"},
Usage: "Sets a default configuration file",
EnvVars: []string{"SET_DEFAULT_CONFIG"},
Destination: &SetDefaultConfig,
},
&cli.BoolFlag{
Name: "NetworkInterfaces",
Aliases: []string{"ni"},
Usage: "Shows the network interface in your computer",
EnvVars: []string{"NETWORK_INTERFACE"},
Destination: &NetworkInterface,
},
&cli.BoolFlag{
Name: "ViewPlugins",
Aliases: []string{"vp"},
Usage: "Shows plugins available to be executed",
EnvVars: []string{"VIEW_PLUGIN"},
Destination: &ViewPlugin,
},
&cli.BoolFlag{
Name: "TrackedContainers",
Aliases: []string{"tc"},
Usage: "View containers which have " +
"been created from the client side ",
EnvVars: []string{"TRACKED_CONTAINERS"},
Destination: &TrackedContainers,
},
&cli.StringFlag{
Name: "ExecutePlugin",
Aliases: []string{"plugin"},
Usage: "Plugin which needs to be executed",
EnvVars: []string{"EXECUTE_PLUGIN"},
Destination: &ExecutePlugin,
},
&cli.BoolFlag{
Name: "CreateGroup",
Aliases: []string{"cgroup"},
Usage: "Creates a new group",
EnvVars: []string{"CREATE_GROUP"},
Destination: &CreateGroup,
},
&cli.StringFlag{
Name: "Group",
Aliases: []string{"group"},
Usage: "group flag with argument group ID",
EnvVars: []string{"GROUP"},
Destination: &Group,
},
&cli.BoolFlag{
Name: "Groups",
Aliases: []string{"groups"},
Usage: "View all groups",
EnvVars: []string{"GROUPS"},
Destination: &Groups,
},
&cli.BoolFlag{
Name: "RemoveContainerGroup",
Aliases: []string{"rmcgroup"},
Usage: "Remove specific container in the group",
EnvVars: []string{"REMOVE_CONTAINER_GROUP"},
Destination: &RemoveContainerGroup,
},
&cli.StringFlag{
Name: "RemoveGroup",
Aliases: []string{"rmgroup"},
Usage: "Removes the entire group",
EnvVars: []string{"REMOVE_GROUP"},
Destination: &RemoveGroup,
},
// Generate only allowed in dev release
// -- REMOVE ON REGULAR RELEASE --
&cli.StringFlag{
Name: "Generate",
Aliases: []string{"gen"},
Usage: "Generates a new copy of P2PRC which can be modified based on your needs",
EnvVars: []string{"GENERATE"},
Destination: &Generate,
},
&cli.StringFlag{
Name: "ModuleName",
Aliases: []string{"mod"},
Usage: "New go project module name",
EnvVars: []string{"MODULENAME"},
Destination: &Modulename,
},
//--------------------------------
&cli.StringFlag{
Name: "PullPlugin",
Aliases: []string{"pp"},
Usage: "Pulls plugin from git repos",
EnvVars: []string{"PULLPLUGIN"},
Destination: &PullPlugin,
},
&cli.StringFlag{
Name: "RemovePlugin",
Aliases: []string{"rp"},
Usage: "Removes plugin",
EnvVars: []string{"REMOVEPLUGIN"},
Destination: &RemovePlugin,
},
}
// Deprecated to be implemented using GRPC
&cli.BoolFlag{
Name: "Server",
Aliases: []string{"s"},
Usage: "Starts server",
EnvVars: []string{"SERVER"},
Destination: &Server,
},
&cli.BoolFlag{
Name: "UpdateServerList",
Aliases: []string{"us"},
Usage: "Update List of Server available based on servers iptables",
EnvVars: []string{"UPDATE_SERVER_LIST"},
Destination: &UpdateServerList,
},
&cli.BoolFlag{
Name: "ListServers",
Aliases: []string{"ls"},
Usage: "List servers which can render tasks",
EnvVars: []string{"LIST_SERVERS"},
Destination: &ServerList,
},
&cli.StringFlag{
Name: "AddServer",
Aliases: []string{"as"},
Usage: "Adds server IP address to iptables",
EnvVars: []string{"ADD_SERVER"},
Destination: &AddServer,
},
&cli.StringFlag{
Name: "ViewImages",
Aliases: []string{"vi"},
Usage: "View images available on the server IP address",
EnvVars: []string{"VIEW_IMAGES"},
Destination: &ViewImages,
},
&cli.StringFlag{
Name: "CreateVM",
Aliases: []string{"touch"},
Usage: "Creates Docker container on the selected server",
EnvVars: []string{"CREATE_VM"},
Destination: &CreateVM,
},
&cli.StringFlag{
Name: "ContainerName",
Aliases: []string{"cn"},
Usage: "Specifying the container run on the server side",
EnvVars: []string{"CONTAINER_NAME"},
Destination: &ContainerName,
},
&cli.StringFlag{
Name: "RemoveVM",
Aliases: []string{"rm"},
Usage: "Stop and Remove Docker container",
EnvVars: []string{"REMOVE_VM"},
Destination: &RemoveVM,
},
&cli.StringFlag{
Name: "ID",
Aliases: []string{"id"},
Usage: "Docker Container ID",
EnvVars: []string{"ID"},
Destination: &ID,
},
&cli.StringFlag{
Name: "Ports",
Aliases: []string{"p"},
Usage: "Number of ports to open for the Docker Container",
EnvVars: []string{"NUM_PORTS"},
Destination: &Ports,
},
&cli.BoolFlag{
Name: "GPU",
Aliases: []string{"gpu"},
Usage: "Create Docker Containers to access GPU",
EnvVars: []string{"USE_GPU"},
Destination: &GPU,
},
&cli.StringFlag{
Name: "Specification",
Aliases: []string{"specs"},
Usage: "Specs of the server node",
EnvVars: []string{"SPECS"},
Destination: &Specs,
},
&cli.BoolFlag{
Name: "SetDefaultConfig",
Aliases: []string{"dc"},
Usage: "Sets a default configuration file",
EnvVars: []string{"SET_DEFAULT_CONFIG"},
Destination: &SetDefaultConfig,
},
&cli.BoolFlag{
Name: "NetworkInterfaces",
Aliases: []string{"ni"},
Usage: "Shows the network interface in your computer",
EnvVars: []string{"NETWORK_INTERFACE"},
Destination: &NetworkInterface,
},
&cli.BoolFlag{
Name: "ViewPlugins",
Aliases: []string{"vp"},
Usage: "Shows plugins available to be executed",
EnvVars: []string{"VIEW_PLUGIN"},
Destination: &ViewPlugin,
},
&cli.BoolFlag{
Name: "TrackedContainers",
Aliases: []string{"tc"},
Usage: "View containers which have " +
"been created from the client side ",
EnvVars: []string{"TRACKED_CONTAINERS"},
Destination: &TrackedContainers,
},
&cli.StringFlag{
Name: "ExecutePlugin",
Aliases: []string{"plugin"},
Usage: "Plugin which needs to be executed",
EnvVars: []string{"EXECUTE_PLUGIN"},
Destination: &ExecutePlugin,
},
&cli.BoolFlag{
Name: "CreateGroup",
Aliases: []string{"cgroup"},
Usage: "Creates a new group",
EnvVars: []string{"CREATE_GROUP"},
Destination: &CreateGroup,
},
&cli.StringFlag{
Name: "Group",
Aliases: []string{"group"},
Usage: "group flag with argument group ID",
EnvVars: []string{"GROUP"},
Destination: &Group,
},
&cli.BoolFlag{
Name: "Groups",
Aliases: []string{"groups"},
Usage: "View all groups",
EnvVars: []string{"GROUPS"},
Destination: &Groups,
},
&cli.BoolFlag{
Name: "RemoveContainerGroup",
Aliases: []string{"rmcgroup"},
Usage: "Remove specific container in the group",
EnvVars: []string{"REMOVE_CONTAINER_GROUP"},
Destination: &RemoveContainerGroup,
},
&cli.StringFlag{
Name: "RemoveGroup",
Aliases: []string{"rmgroup"},
Usage: "Removes the entire group",
EnvVars: []string{"REMOVE_GROUP"},
Destination: &RemoveGroup,
},
// Generate only allowed in dev release
// -- REMOVE ON REGULAR RELEASE --
&cli.StringFlag{
Name: "Generate",
Aliases: []string{"gen"},
Usage: "Generates a new copy of P2PRC which can be modified based on your needs",
EnvVars: []string{"GENERATE"},
Destination: &Generate,
},
&cli.StringFlag{
Name: "ModuleName",
Aliases: []string{"mod"},
Usage: "New go project module name",
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"},
Usage: "Pulls plugin from git repos",
EnvVars: []string{"PULLPLUGIN"},
Destination: &PullPlugin,
},
&cli.StringFlag{
Name: "RemovePlugin",
Aliases: []string{"rp"},
Usage: "Removes plugin",
EnvVars: []string{"REMOVEPLUGIN"},
Destination: &RemovePlugin,
},
}

View File

@@ -1,72 +1,73 @@
package config
import (
"github.com/spf13/viper"
"io"
"os"
"github.com/spf13/viper"
"io"
"os"
)
var (
defaultPath string
defaults = map[string]interface{}{}
configName = "config"
configType = "json"
configFile = "config.json"
configPaths []string
defaultEnvName = "P2PRC"
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
GroupTrackContainersPath string
//NetworkInterface string
//NetworkInterfaceIPV6Index int
IPTable string
DockerContainers string
DefaultDockerFile string
SpeedTestFile string
IPV6Address string
PluginPath string
TrackContainersPath string
ServerPort string
GroupTrackContainersPath string
FRPServerPort string
//NetworkInterface string
//NetworkInterfaceIPV6Index int
}
// Exists reports whether the named file or directory exists.
func fileExists(name string) bool {
if _, err := os.Stat(name); err != nil {
if os.IsNotExist(err) {
return false
}
}
return true
if _, err := os.Stat(name); err != nil {
if os.IsNotExist(err) {
return false
}
}
return true
}
// Copy the src file to dst. Any existing file will be overwritten and will not
// copy file attributes.
// Source: https://stackoverflow.com/questions/21060945/simple-way-to-copy-a-file
func Copy(src, dst string) error {
in, err := os.Open(src)
if err != nil {
return err
}
defer in.Close()
in, err := os.Open(src)
if err != nil {
return err
}
defer in.Close()
out, err := os.Create(dst)
if err != nil {
return err
}
defer out.Close()
out, err := os.Create(dst)
if err != nil {
return err
}
defer out.Close()
_, err = io.Copy(out, in)
if err != nil {
return err
}
return out.Close()
_, err = io.Copy(out, in)
if err != nil {
return err
}
return out.Close()
}
// GetPathP2PRC Getting P2PRC Directory from environment variable
func GetPathP2PRC()(string,error) {
curDir := os.Getenv(defaultEnvName)
return curDir + "/", nil
func GetPathP2PRC() (string, error) {
curDir := os.Getenv(defaultEnvName)
return curDir + "/", nil
}
// SetEnvName Sets the environment name
@@ -74,113 +75,112 @@ func GetPathP2PRC()(string,error) {
// your environment variable
// This is useful when extending the use case of P2PRC
func SetEnvName(EnvName string) error {
defaultEnvName = EnvName
// Handling error to be implemented only if needed
return nil
defaultEnvName = EnvName
// Handling error to be implemented only if needed
return nil
}
// GetCurrentPath Getting P2PRC Directory from environment variable
func GetCurrentPath()(string,error) {
curDir := os.Getenv("PWD")
return curDir + "/", nil
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{
return err
}
//Setting current directory to default path
defaultPath, err := GetPathP2PRC()
if err != nil {
return err
}
//Creates ip_table.json in the json directory
err = Copy("p2p/ip_table.json","p2p/iptable/ip_table.json")
if err != nil {
return err
}
//Creates ip_table.json in the json directory
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")
if err != nil {
return err
}
//Creates a copy of trackcontainers.json in the appropriate directory
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")
if err != nil {
return err
}
//Creates a copy of trackcontainers.json in the appropriate directory
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/"
defaults["DockerContainers"] = defaultPath + "server/docker/containers/"
defaults["SpeedTestFile"] = defaultPath + "p2p/50.bin"
defaults["IPV6Address"] = ""
defaults["PluginPath"] = defaultPath + "plugin/deploy"
defaults["TrackContainersPath"] = defaultPath + "client/trackcontainers/trackcontainers.json"
defaults["GroupTrackContainersPath"] = defaultPath + "client/trackcontainers/grouptrackcontainers.json"
defaults["ServerPort"] = "8088"
defaults["FRPServerPort"] = "0"
//defaults["NetworkInterface"] = "wlp0s20f3"
//defaults["NetworkInterfaceIPV6Index"] = "2"
//Setting default paths for the config file
defaults["IPTable"] = defaultPath + "p2p/iptable/ip_table.json"
defaults["DefaultDockerFile"] = defaultPath + "server/docker/containers/docker-ubuntu-sshd/"
defaults["DockerContainers"] = defaultPath + "server/docker/containers/"
defaults["SpeedTestFile"] = defaultPath + "p2p/50.bin"
defaults["IPV6Address"] = ""
defaults["PluginPath"] = defaultPath + "plugin/deploy"
defaults["TrackContainersPath"] = defaultPath + "client/trackcontainers/trackcontainers.json"
defaults["GroupTrackContainersPath"] = defaultPath + "client/trackcontainers/grouptrackcontainers.json"
defaults["ServerPort"] = "8088"
//defaults["NetworkInterface"] = "wlp0s20f3"
//defaults["NetworkInterfaceIPV6Index"] = "2"
//Paths to search for config file
configPaths = append(configPaths, defaultPath)
//Paths to search for config file
configPaths = append(configPaths, defaultPath)
if fileExists(defaultPath + "config.json") {
err := os.Remove(defaultPath + "config.json")
if err != nil {
return err
}
}
if fileExists(defaultPath + "config.json") {
err := os.Remove(defaultPath + "config.json")
if err != nil {
return err
}
}
//Calling configuration file
_, err = ConfigInit()
if err != nil {
return err
}
return nil
//Calling configuration file
_, err = ConfigInit()
if err != nil {
return err
}
return nil
}
func ConfigInit()(*Config,error) {
func ConfigInit() (*Config, error) {
//Setting current directory to default path
defaultPath, err := GetPathP2PRC()
if err != nil{
return nil, err
}
//Paths to search for config file
configPaths = append(configPaths, defaultPath)
//Setting current directory to default path
defaultPath, err := GetPathP2PRC()
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 {
viper.AddConfigPath(v)
}
//Add all possible configurations paths
for _, v := range configPaths {
viper.AddConfigPath(v)
}
//Read config file
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)
}
viper.SetConfigName(configName)
viper.SetConfigFile(configFile)
viper.SetConfigType(configType)
//Read config file
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)
}
viper.SetConfigName(configName)
viper.SetConfigFile(configFile)
viper.SetConfigType(configType)
if err = viper.WriteConfig(); err != nil {
return nil,err
}
}
if err = viper.WriteConfig(); err != nil {
return nil, err
}
}
// Adds configuration to the struct
var config Config
if err := viper.Unmarshal(&config); err != nil {
return nil,err
}
// Adds configuration to the struct
var config Config
if err := viper.Unmarshal(&config); err != nil {
return nil, err
}
return &config,nil
return &config, nil
}

View File

@@ -1,33 +1,121 @@
package frp
import (
"git.sr.ht/~akilan1999/p2p-rendering-computation/server/docker"
"github.com/fatedier/frp/client"
"github.com/fatedier/frp/pkg/config"
"math/rand"
"strconv"
)
// Starts FRP client
func StartFRPClient(address string, port int) error {
// Client This struct stores
// client information with server
// proxy connected
type Client struct {
Name string
Server *Server
ClientMappings []ClientMapping
}
cfg := config.GetDefaultClientConf()
//var cfg config.ClientCommonConf
var visitorCfgs map[string]config.VisitorConf
//
cfg.ServerAddr = address
cfg.ServerPort = port
// ClientMapping Stores client mapping ports
// to proxy server
type ClientMapping struct {
LocalIP string
LocalPort int
RemotePort int
}
var tcpcnf config.TCPProxyConf
tcpcnf.LocalIP = "0.0.0.0"
tcpcnf.LocalPort = 22
tcpcnf.RemotePort = 3000
// StartFRPClientForServer Starts Server using FRP server
// returns back a port
func StartFRPClientForServer(ipaddress string, port 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
proxyConfs := map[string]config.ProxyConf{
tcpcnf.ProxyName: &tcpcnf,
// Setup client information
var c Client
c.Name = "ServerPort"
c.Server = &s
//random port
randPort := rangeIn(10000, 99999)
c.ClientMappings = []ClientMapping{
{
LocalIP: ipaddress,
LocalPort: randPort,
RemotePort: randPort,
},
}
//cfg.ClientConfig = auth.GetDefaultClientConf()
//cfg.Protocol = "tcp"
// Start client server
go c.StartFRPClient()
//pxyCfgs, visitorCfgs, _ = config.LoadAllProxyConfsFromIni(cfg.User, nil, cfg.Start)
return strconv.Itoa(randPort), nil
}
func StartFRPCDockerContainer(ipaddress string, port string, docker *docker.DockerVM) 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
// 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.LocalPort = portMap
clientMapping.RemotePort = portMap
// Append to array
clientMappings = append(clientMappings, clientMapping)
}
// Start client server
go c.StartFRPClient()
return 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 {
@@ -38,3 +126,9 @@ func StartFRPClient(address string, port int) error {
return nil
}
// helper function to generate random
// number in a certain range
func rangeIn(low, hi int) int {
return low + rand.Intn(hi-low)
}

View File

@@ -1,21 +1,58 @@
package frp
import (
configP2PRC "git.sr.ht/~akilan1999/p2p-rendering-computation/config"
"github.com/fatedier/frp/pkg/config"
"github.com/fatedier/frp/server"
"strconv"
)
type ServerFRPConf struct {
// TODO: Implement a way to
// check if ports are taken
type Server struct {
address string
port int
}
// StartFRPProxyFromConfig starts
// reverse proxy server based on
// the port provided in the config file
// field FRPServerPort.
func StartFRPProxyFromConfig() error {
// gets current configuration
config, err := configP2PRC.ConfigInit()
if err != nil {
return err
}
var s Server
s.address = "0.0.0.0"
// Converting config port to int
port, err := strconv.Atoi(config.FRPServerPort)
if err != nil {
return err
}
s.port = port
// start FRP server
err = s.StartFRPServer()
if err != nil {
return err
}
return 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 StartFRPServer(address string, port int) error {
func (s *Server) StartFRPServer() error {
baseConfig := config.GetDefaultServerConf()
baseConfig.BindAddr = address
baseConfig.BindAddr = s.address
//TODO look into later for dashboard
//baseConfig.DashboardAddr = "127.0.0.1"
@@ -24,7 +61,7 @@ func StartFRPServer(address string, port int) error {
//baseConfig.DashboardPwd = "admin"
// todo change to make it a dynamic port
baseConfig.BindPort = port
baseConfig.BindPort = s.port
service, err := server.NewService(baseConfig)
if err != nil {
return err

View File

@@ -6,24 +6,39 @@ import (
"time"
)
// Testing scenario FRPServer
func TestStartFRPServer(t *testing.T) {
err := StartFRPServer("127.0.0.1", 8808)
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) {
go StartFRPServer("127.0.0.1", 8808)
//if err != nil {
// fmt.Println(err)
// t.Fail()
//}
var s Server
s.address = "127.0.0.1"
s.port = 8808
go s.StartFRPServer()
time.Sleep(3 * time.Second)
err := StartFRPClient("127.0.0.1", 8808)
// 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()

View File

@@ -1,238 +1,241 @@
package p2p
import (
"encoding/json"
"fmt"
"git.sr.ht/~akilan1999/p2p-rendering-computation/config"
"io/ioutil"
"net"
"net/http"
"os"
"time"
"encoding/json"
"fmt"
"git.sr.ht/~akilan1999/p2p-rendering-computation/config"
"io/ioutil"
"net"
"net/http"
"os"
"time"
)
// Get IP table Data
type IpAddresses struct {
IpAddress []IpAddress `json:"ip_address"`
IpAddress []IpAddress `json:"ip_address"`
}
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"`
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"`
ProxyPort string `json:"proxyport"`
}
type IP struct {
Query string
Query string
}
// ReadIpTable Read data from Ip tables from json file
func ReadIpTable()(*IpAddresses ,error){
func ReadIpTable() (*IpAddresses, error) {
// Get Path from config
config, err := config.ConfigInit()
if err != nil {
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
}
config, err := config.ConfigInit()
if err != nil {
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
}
// defer the closing of our jsonFile so that we can parse it later on
defer jsonFile.Close()
// defer the closing of our jsonFile so that we can parse it later on
defer jsonFile.Close()
// read our opened xmlFile as a byte array.
byteValue, _ := ioutil.ReadAll(jsonFile)
// read our opened xmlFile as a byte array.
byteValue, _ := ioutil.ReadAll(jsonFile)
// we initialize our Users array
var ipAddresses IpAddresses
// we initialize our Users array
var ipAddresses IpAddresses
// we unmarshal our byteArray which contains our
// jsonFile's content into 'users' which we defined above
json.Unmarshal(byteValue, &ipAddresses)
// we unmarshal our byteArray which contains our
// jsonFile's content into 'users' which we defined above
json.Unmarshal(byteValue, &ipAddresses)
var PublicIP IpAddress
var PublicIP IpAddress
ipv6, err := GetCurrentIPV6()
if err != nil {
return nil, err
}
ipv6, err := GetCurrentIPV6()
if err != nil {
return nil, err
}
ip, err := CurrentPublicIP()
if err != nil {
return nil, err
}
PublicIP.Ipv4 = ip
PublicIP.Ipv6 = ipv6
PublicIP.ServerPort = config.ServerPort
if config.FRPServerPort != "0" {
PublicIP.ProxyPort = config.FRPServerPort
}
ip, err := CurrentPublicIP()
if err != nil {
return nil, err
}
PublicIP.Ipv4 = ip
PublicIP.Ipv6 = ipv6
PublicIP.ServerPort = config.ServerPort
// Updates current machine IP address to the IP table
ipAddresses.IpAddress = append(ipAddresses.IpAddress, PublicIP)
// Updates current machine IP address to the IP table
ipAddresses.IpAddress = append(ipAddresses.IpAddress, PublicIP)
//before writing to iptable ensures the duplicates are removed
if err = ipAddresses.RemoveDuplicates(); err != nil {
return nil, err
}
//before writing to iptable ensures the duplicates are removed
if err = ipAddresses.RemoveDuplicates(); err != nil {
return nil, err
}
return &ipAddresses, nil
}
// WriteIpTable Write to IP table json file
func (i *IpAddresses) WriteIpTable() error {
//before writing to iptable ensures the duplicates are removed
if err := i.RemoveDuplicates(); err != nil {
return err
}
//before writing to iptable ensures the duplicates are removed
if err := i.RemoveDuplicates(); err != nil {
return err
}
file, err := json.MarshalIndent(i, "", " ")
if err != nil {
return err
}
file, err := json.MarshalIndent(i, "", " ")
if err != nil {
return err
}
// Get Path from config
config, err := config.ConfigInit()
if err != nil {
return err
}
// Get Path from config
config, err := config.ConfigInit()
if err != nil {
return err
}
err = ioutil.WriteFile(config.IPTable, file, 0644)
if err != nil {
return err
}
err = ioutil.WriteFile(config.IPTable, file, 0644)
if err != nil {
return err
}
return nil
return nil
}
// PrintIpTable Print Ip table data for Cli
func PrintIpTable() error {
table, err := ReadIpTable()
table, err := ReadIpTable()
if err != nil {
return err
}
if err != nil {
return err
}
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)
}
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)
}
return nil
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 {
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) {
Exists = true
break
}
}
if Exists {
continue
}
NoDuplicates.IpAddress = append(NoDuplicates.IpAddress, table.IpAddress[i])
}
var NoDuplicates IpAddresses
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) {
Exists = true
break
}
}
if Exists {
continue
}
NoDuplicates.IpAddress = append(NoDuplicates.IpAddress, table.IpAddress[i])
}
table.IpAddress = NoDuplicates.IpAddress
table.IpAddress = NoDuplicates.IpAddress
return nil
return nil
}
// CurrentPublicIP Get Current Public IP address
func CurrentPublicIP() (string,error) {
req, err := http.Get("http://ip-api.com/json/")
if err != nil {
return "",err
}
defer req.Body.Close()
func CurrentPublicIP() (string, error) {
req, err := http.Get("http://ip-api.com/json/")
if err != nil {
return "", err
}
defer req.Body.Close()
body, err := ioutil.ReadAll(req.Body)
if err != nil {
return "",err
}
body, err := ioutil.ReadAll(req.Body)
if err != nil {
return "", err
}
var ip IP
json.Unmarshal(body, &ip)
var ip IP
json.Unmarshal(body, &ip)
return ip.Query, nil
return ip.Query, nil
}
// GetCurrentIPV6 gets the current IPV6 address based on the interface
// specified in the config file
func GetCurrentIPV6()(string,error){
Config, err := config.ConfigInit()
if err != nil {
return "",err
}
func GetCurrentIPV6() (string, error) {
Config, err := config.ConfigInit()
if err != nil {
return "", err
}
// Fix in future release
//byNameInterface, err := net.InterfaceByName(Config.NetworkInterface)
//if err != nil {
// return "",err
//}
//addresses, err := byNameInterface.Addrs()
//if err != nil {
// return "",err
//}
//if addresses[1].String() == "" {
// return "",errors.New("IPV6 address not detected")
//}
//IP,_,err := net.ParseCIDR(addresses[Config.NetworkInterfaceIPV6Index].String())
//if err != nil {
// return "",err
//}
// Fix in future release
//byNameInterface, err := net.InterfaceByName(Config.NetworkInterface)
//if err != nil {
// return "",err
//}
//addresses, err := byNameInterface.Addrs()
//if err != nil {
// return "",err
//}
//if addresses[1].String() == "" {
// return "",errors.New("IPV6 address not detected")
//}
//IP,_,err := net.ParseCIDR(addresses[Config.NetworkInterfaceIPV6Index].String())
//if err != nil {
// return "",err
//}
return Config.IPV6Address, nil
return Config.IPV6Address, nil
}
// ViewNetworkInterface This function is created to view the network interfaces available
func ViewNetworkInterface() error {
ifaces, err := net.Interfaces()
if err != nil {
return err
}
for _, i := range ifaces {
addrs, err := i.Addrs()
if err != nil {
return err
}
for index, a := range addrs {
switch v := a.(type) {
case *net.IPAddr:
fmt.Printf("(%v) %v : %s (%s)\n", index, i.Name, v, v.IP.DefaultMask())
ifaces, err := net.Interfaces()
if err != nil {
return err
}
for _, i := range ifaces {
addrs, err := i.Addrs()
if err != nil {
return err
}
for index, a := range addrs {
switch v := a.(type) {
case *net.IPAddr:
fmt.Printf("(%v) %v : %s (%s)\n", index, i.Name, v, v.IP.DefaultMask())
case *net.IPNet:
fmt.Printf("(%v) %v : %s \n", index, i.Name, v)
}
case *net.IPNet:
fmt.Printf("(%v) %v : %s \n", index, i.Name, v)
}
}
}
return nil
}
}
return nil
}
// 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)
func Ip4or6(s string) string {
for i := 0; i < len(s); i++ {
switch s[i] {
case '.':
return "version 4"
case ':':
return "version 6"
}
}
return "version 6"
for i := 0; i < len(s); i++ {
switch s[i] {
case '.':
return "version 4"
case ':':
return "version 6"
}
}
return "version 6"
}
}

View File

@@ -1,147 +1,208 @@
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/server/docker"
"github.com/gin-gonic/gin"
"io/ioutil"
"net/http"
"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"
)
func Server() error{
r := gin.Default()
func Server() error {
r := gin.Default()
// Gets default information of the server
r.GET("/server_info", func(c *gin.Context) {
c.JSON(http.StatusOK, ServerInfo())
})
// update IPTable with new port and ip address and update ip table
var ProxyIpAddr p2p.IpAddress
// 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)
})
// Gets default information of the server
r.GET("/server_info", func(c *gin.Context) {
c.JSON(http.StatusOK, ServerInfo())
})
// Route build to do a speed test
r.GET("/upload", func(c *gin.Context) {
file, _ := c.FormFile("file")
// 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)
})
// Upload the file to specific dst.
// c.SaveUploadedFile(file, dst)
// Route build to do a speed test
r.GET("/upload", func(c *gin.Context) {
file, _ := c.FormFile("file")
c.String(http.StatusOK, fmt.Sprintf("'%s' uploaded!", file.Filename))
})
// Upload the file to specific dst.
// c.SaveUploadedFile(file, dst)
//Gets Ip Table from server node
r.POST("/IpTable", func(c *gin.Context) {
// Getting IPV4 address of client
var ClientHost p2p.IpAddress
c.String(http.StatusOK, fmt.Sprintf("'%s' uploaded!", file.Filename))
})
if p2p.Ip4or6(c.ClientIP()) == "version 6" {
ClientHost.Ipv6 = c.ClientIP()
} else {
ClientHost.Ipv4 = c.ClientIP()
}
//Gets Ip Table from server node
r.POST("/IpTable", func(c *gin.Context) {
// Getting IPV4 address of client
var ClientHost p2p.IpAddress
// Variable to store IP table information
var IPTable p2p.IpAddresses
if p2p.Ip4or6(c.ClientIP()) == "version 6" {
ClientHost.Ipv6 = c.ClientIP()
} else {
ClientHost.Ipv4 = c.ClientIP()
}
// Receive file from POST request
body, err := c.FormFile("json")
if err != nil {
c.String(http.StatusOK, fmt.Sprint(err))
}
// Variable to store IP table information
var IPTable p2p.IpAddresses
// Open file
open, err := body.Open()
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 received file
file, err := ioutil.ReadAll(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))
}
json.Unmarshal(file,&IPTable)
// Open received file
file, err := ioutil.ReadAll(open)
if err != nil {
c.String(http.StatusOK, fmt.Sprint(err))
}
//Add Client IP address to IPTable struct
IPTable.IpAddress = append(IPTable.IpAddress, ClientHost)
json.Unmarshal(file, &IPTable)
// 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))
}
//Add Client IP address to IPTable struct
IPTable.IpAddress = append(IPTable.IpAddress, ClientHost)
// Reads IP addresses from ip table
IpAddresses,err := p2p.ReadIpTable()
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))
}
c.JSON(http.StatusOK, IpAddresses)
})
// 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)
})
// 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","")
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 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)
})
if err != nil {
c.String(http.StatusInternalServerError, fmt.Sprintf("error: %s", err))
}
//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")
})
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)
})
//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")
})
//Get Server port based on the config file
config, err := config.ConfigInit()
if err != nil {
return err
}
//Show images available
r.GET("/ShowImages", func(c *gin.Context) {
resp, err := docker.ViewAllContainers()
if err != nil {
c.String(http.StatusInternalServerError, fmt.Sprintf("error: %s", err))
}
c.JSON(http.StatusOK, resp)
})
// Run gin server on the specified port
err = r.Run(":" + config.ServerPort)
if err != nil {
return err
}
//Get Server port based on the config file
config, err := config.ConfigInit()
if err != nil {
return err
}
return nil
// If there is a proxy port specified
// then starts the FRP server
if config.FRPServerPort != "0" {
go frp.StartFRPProxyFromConfig()
}
// 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.IPV6Address == "" || config.FRPServerPort == "0" {
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]
}
}
// If there is an identified node
if lowestLatency != 10000000 {
// Starts FRP as a client with
proxyPort, err := frp.StartFRPClientForServer(lowestLatencyIpAddress.Ipv4, lowestLatencyIpAddress.ProxyPort)
if err != nil {
return err
}
// updating with the current proxy address
ProxyIpAddr.Ipv4 = lowestLatencyIpAddress.Ipv4
ProxyIpAddr.ServerPort = proxyPort
ProxyIpAddr.ProxyPort = lowestLatencyIpAddress.ProxyPort
// 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.SpeedTestUpdatedIPTable()
}
}
// Run gin server on the specified port
err = r.Run(":" + config.ServerPort)
if err != nil {
return err
}
return nil
}