fixed pass through custom information

This commit is contained in:
2025-06-04 15:51:07 +01:00
parent 6a24da74ef
commit 3c3cfac5e2
5 changed files with 744 additions and 726 deletions

View File

@@ -31,9 +31,11 @@ P2PRC_instances() {
p2prc --as 0.0.0.0 -p "$NEW_PORT"
# Replace the ServerPort in config
# test-$counter
sed -i.bak "s/\"ServerPort\": \"[0-9]*\"/\"ServerPort\": \"$NEW_PORT\"/" "./config.json"
sed -i.bak "s/\"Test\": false/\"Test\": true/" "./config.json"
sed -i.bak "s/\"BehindNAT\": true/\"BehindNAT\": false/" "./config.json"
# sed -i.bak "s/\"MachineName\": "Akilans-MacBook-Pro.local-J2UbbkF"/\"MachineName\": \"test-$counter\"/" "./config.json"
cat config.json
@@ -92,6 +94,15 @@ Update_All_IP_Tables() {
done
}
# Test function for the root to custom information
# through the network
Send_Information() {
ls
cd test-2/
p2prc --amd "test message"
cd ..
}
# ---------------- Work flow test ---------------
@@ -104,6 +115,12 @@ P2PRC_instances 3
## Start instances
Start_all_instances 3
# Send test information from node 1
sleep 10
Send_Information
sleep 10
## List ip tables of nodes started
IP_Tables_after_Started 3
#
@@ -112,3 +129,4 @@ Remove_all_test_files
## Kill all instances
Kill_all_instances

View File

@@ -1,40 +1,40 @@
package clientIPTable
import (
"errors"
"github.com/Akilan1999/p2p-rendering-computation/config"
"github.com/Akilan1999/p2p-rendering-computation/p2p"
"errors"
"github.com/Akilan1999/p2p-rendering-computation/config"
"github.com/Akilan1999/p2p-rendering-computation/p2p"
)
func AddCustomInformationToIPTable(text string) error {
// Get config information
Config, err := config.ConfigInit(nil, nil)
if err != nil {
return err
}
// Get config information
Config, err := config.ConfigInit(nil, nil)
if err != nil {
return err
}
// Get IPTable information
table, err := p2p.ReadIpTable()
if err != nil {
return err
}
// Get IPTable information
table, err := p2p.ReadIpTable()
if err != nil {
return err
}
found := false
found := false
for i, _ := range table.IpAddress {
if table.IpAddress[i].Name == Config.MachineName {
table.IpAddress[i].CustomInformation = text
found = true
}
}
for i, _ := range table.IpAddress {
if table.IpAddress[i].Name == Config.MachineName {
table.IpAddress[i].CustomInformation = text
found = true
}
}
if found {
table.WriteIpTable()
// update IPTable after modified entry
go UpdateIpTableListClient()
} else {
return errors.New("start server with p2prc -s as the server is currently not running")
}
if found {
table.WriteIpTable()
// update IPTable after modified entry
UpdateIpTableListClient()
} else {
return errors.New("start server with p2prc -s as the server is currently not running")
}
return nil
return nil
}

View File

@@ -1,296 +1,297 @@
package p2p
import (
"bytes"
"crypto/sha256"
"encoding/json"
"fmt"
"github.com/Akilan1999/p2p-rendering-computation/config"
"io/ioutil"
"net"
"net/http"
"os"
"time"
"bytes"
"crypto/sha256"
"encoding/json"
"fmt"
"github.com/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 {
Name string `json:"Name"`
MachineUsername string `json:"MachineUsername"`
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"`
BareMetalSSHPort string `json:"BareMetalSSHPort"`
NAT bool `json:"NAT"`
EscapeImplementation string `json:"EscapeImplementation"`
ProxyServer bool `json:"ProxyServer"`
UnSafeMode bool `json:"UnSafeMode"`
PublicKey string `json:"PublicKey"`
CustomInformation string `json:"CustomInformation"`
//CustomInformationKey []byte `json:"CustomInformationKey"`
Name string `json:"Name"`
MachineUsername string `json:"MachineUsername"`
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"`
BareMetalSSHPort string `json:"BareMetalSSHPort"`
NAT bool `json:"NAT"`
EscapeImplementation string `json:"EscapeImplementation"`
ProxyServer bool `json:"ProxyServer"`
UnSafeMode bool `json:"UnSafeMode"`
PublicKey string `json:"PublicKey"`
CustomInformation string `json:"CustomInformation"`
//CustomInformationKey []byte `json:"CustomInformationKey"`
}
type IP struct {
Query string
Query string
}
var Test = false
// ReadIpTable Read data from Ip tables from json file
func ReadIpTable() (*IpAddresses, error) {
// Get Path from config
config, err := config.ConfigInit(nil, nil)
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
}
// Get Path from config
config, err := config.ConfigInit(nil, nil)
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
PublicIP.Name = config.MachineName
PublicIP.NAT = config.BehindNAT
PublicIP.EscapeImplementation = "None"
ip, err := CurrentPublicIP()
if err != nil {
return nil, err
}
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)
// 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
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(nil, nil)
if err != nil {
return err
}
// Get Path from config
config, err := config.ConfigInit(nil, nil)
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()
//
if err != nil {
return err
}
//
//for i := 0; i < len(table.IpAddress); i++ {
// 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)
table, err := ReadIpTable()
//
if err != nil {
return err
}
//
//for i := 0; i < len(table.IpAddress); i++ {
// 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
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 {
var NoDuplicates IpAddresses
for i, _ := range table.IpAddress {
Exists := false
for k := range NoDuplicates.IpAddress {
// 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
}
}
var NoDuplicates IpAddresses
for i, _ := range table.IpAddress {
Exists := false
for k := range NoDuplicates.IpAddress {
// 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 && table.IpAddress[i].EscapeImplementation == "None" {
Exists = true
}
if table.IpAddress[i].NAT && table.IpAddress[i].EscapeImplementation == "None" {
Exists = true
}
if Exists {
continue
}
NoDuplicates.IpAddress = append(NoDuplicates.IpAddress, table.IpAddress[i])
}
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) {
// Get configs
Config, err := config.ConfigInit(nil, nil)
if err != nil {
return "", err
}
// If test mode is on then return local address
if Config.Test {
return "0.0.0.0", nil
}
// Get configs
Config, err := config.ConfigInit(nil, nil)
if err != nil {
return "", err
}
// If test mode is on then return local address
if Config.Test {
return "0.0.0.0", nil
}
req, err := http.Get("http://ip-api.com/json/")
if err != nil {
return "", err
}
defer req.Body.Close()
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(nil, nil)
if err != nil {
return "", err
}
Config, err := config.ConfigInit(nil, nil)
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"
}
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)
var p []byte
// var err := error
p, err := json.MarshalIndent(data, "", "\t")
if err != nil {
fmt.Println(err)
return
}
fmt.Printf("%s \n", p)
}
func GenerateHashSHA256(text string) []byte {
h := sha256.New()
h.Write([]byte(text))
h := sha256.New()
h.Write([]byte(text))
return h.Sum(nil)
return h.Sum(nil)
}
// ValidateHashSHA256 CustomInformationKey the text and check if the text and
@@ -299,12 +300,12 @@ func GenerateHashSHA256(text string) []byte {
// SHA256 is the current hashing algorthm
// used.
func ValidateHashSHA256(text string, Hash []byte) bool {
h := sha256.New()
h.Write([]byte(text))
h := sha256.New()
h.Write([]byte(text))
textHash := h.Sum(nil)
if bytes.Equal(textHash, Hash) {
return true
}
return false
textHash := h.Sum(nil)
if bytes.Equal(textHash, Hash) {
return true
}
return false
}

View File

@@ -1,136 +1,137 @@
package p2p
import (
"github.com/Akilan1999/p2p-rendering-computation/config"
"github.com/Akilan1999/p2p-rendering-computation/config"
)
// SpeedTest Runs a speed test and does updates IP tables accordingly
func (ip *IpAddresses) SpeedTest() error {
//temp variable to store elements IP addresses and other information
// of IP addresses that are pingable
var ActiveIP IpAddresses
//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 {
// Index to remove from struct
for _, value := range ip.IpAddress {
var err error
//if len(ip.IpAddress) == 1 {
// i = 0
//}
var err error
//if len(ip.IpAddress) == 1 {
// i = 0
//}
// Ping Test
err = value.PingTest()
// Ping Test
err = value.PingTest()
if err != nil {
continue
}
if err != nil {
continue
}
//Upload Speed Test
//err = value.UploadSpeed()
//if err != nil {
// return err
//}
//
//err = value.DownloadSpeed()
//if err != nil {
// return err
//}
//Upload Speed Test
//err = value.UploadSpeed()
//if err != nil {
// return err
//}
//
//err = value.DownloadSpeed()
//if err != nil {
// return err
//}
//Set value to the list
//Set value to the list
ActiveIP.IpAddress = append(ActiveIP.IpAddress, value)
}
ActiveIP.IpAddress = append(ActiveIP.IpAddress, value)
}
ip.IpAddress = ActiveIP.IpAddress
ip.IpAddress = ActiveIP.IpAddress
err := ip.WriteIpTable()
if err != nil {
return err
}
err := ip.WriteIpTable()
if err != nil {
return err
}
return nil
return nil
}
// SpeedTestUpdatedIPTable Called when ip tables from httpclient/server is also passed on
func (ip *IpAddresses) SpeedTestUpdatedIPTable() error {
Config, err := config.ConfigInit(nil, nil)
if err != nil {
return err
}
Config, err := config.ConfigInit(nil, nil)
if err != nil {
return err
}
targets, err := ReadIpTable()
if err != nil {
return err
}
targets, err := ReadIpTable()
if err != nil {
return err
}
// Checks if baremetal mode and unsafe mode
// is enabled. If it is enabled it adds the
// the propagated public key to the list.
// Checks if baremetal mode and unsafe mode
// is enabled. If it is enabled it adds the
// the propagated public key to the list.
AddPublicKey := false
if Config.BareMetal && Config.UnsafeMode {
AddPublicKey = true
}
AddPublicKey := false
if Config.BareMetal && Config.UnsafeMode {
AddPublicKey = true
}
// To ensure struct has no duplicates IP addresses
//DoNotRead := targets
// To ensure struct has no duplicates IP addresses
//DoNotRead := targets
// Appends all IP addresses
for i, _ := range targets.IpAddress {
// 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 {
if AddPublicKey && ip.IpAddress[k].PublicKey != "" {
// This function call (AddAuthorisationKey) is inefficient but to be optimised later on.
// This is because when if the user is running on as unsafe mode the authorization file
// is opened from the SSH directory and then iterates through every single SSH entry
// to find out if the SSH entry exists or not. This will incur multiple CPU cycles
// for no reason. A better approach would be to have been to store the states on memory and only
// add when needed based on the memory location. This is something is to be discussed
// and look upon later on.
AddAuthorisationKey(ip.IpAddress[k].PublicKey)
}
// 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) || (targets.IpAddress[i].Ipv6 != "" && ip.IpAddress[k].Ipv6 == targets.IpAddress[i].Ipv6) {
Exists = true
break
}
}
//To ensure that there are no duplicate IP addresses
Exists := false
for k := range ip.IpAddress {
if AddPublicKey && ip.IpAddress[k].PublicKey != "" {
// This function call (AddAuthorisationKey) is inefficient but to be optimised later on.
// This is because when if the user is running on as unsafe mode the authorization file
// is opened from the SSH directory and then iterates through every single SSH entry
// to find out if the SSH entry exists or not. This will incur multiple CPU cycles
// for no reason. A better approach would be to have been to store the states on memory and only
// add when needed based on the memory location. This is something is to be discussed
// and look upon later on.
AddAuthorisationKey(ip.IpAddress[k].PublicKey)
}
targets.IpAddress[i].CustomInformation = ip.IpAddress[k].CustomInformation
// 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) || (targets.IpAddress[i].Ipv6 != "" && ip.IpAddress[k].Ipv6 == targets.IpAddress[i].Ipv6) {
Exists = true
break
}
}
// If the struct exists then continues
if Exists {
continue
}
// If the struct exists then continues
if Exists {
continue
}
ip.IpAddress = append(ip.IpAddress, targets.IpAddress[i])
}
ip.IpAddress = append(ip.IpAddress, targets.IpAddress[i])
}
err = ip.SpeedTest()
err = ip.SpeedTest()
if err != nil {
return err
}
if err != nil {
return err
}
return nil
return nil
}
// LocalSpeedTestIpTable Runs speed test in iptables locally only
func LocalSpeedTestIpTable() error {
targets, err := ReadIpTable()
if err != nil {
return err
}
targets, err := ReadIpTable()
if err != nil {
return err
}
err = targets.SpeedTest()
if err != nil {
return err
}
err = targets.SpeedTest()
if err != nil {
return err
}
return nil
return nil
}
// Helper function to remove element from an array of a struct

View File

@@ -1,479 +1,477 @@
package server
import (
b64 "encoding/base64"
"encoding/json"
"errors"
"fmt"
"github.com/Akilan1999/p2p-rendering-computation/client/clientIPTable"
"github.com/Akilan1999/p2p-rendering-computation/config"
"github.com/Akilan1999/p2p-rendering-computation/p2p"
"github.com/Akilan1999/p2p-rendering-computation/p2p/frp"
"github.com/Akilan1999/p2p-rendering-computation/server/docker"
"github.com/gin-gonic/gin"
"io/ioutil"
"net/http"
"os/user"
"strconv"
"time"
b64 "encoding/base64"
"encoding/json"
"errors"
"fmt"
"github.com/Akilan1999/p2p-rendering-computation/client/clientIPTable"
"github.com/Akilan1999/p2p-rendering-computation/config"
"github.com/Akilan1999/p2p-rendering-computation/p2p"
"github.com/Akilan1999/p2p-rendering-computation/p2p/frp"
"github.com/Akilan1999/p2p-rendering-computation/server/docker"
"github.com/gin-gonic/gin"
"io/ioutil"
"net/http"
"os/user"
"strconv"
"time"
)
type ReverseProxy struct {
IPAddress string
Port string
IPAddress string
Port string
}
// ReverseProxies Reverse to the map such as ReverseProxies[<domain nane>]ReverseProxy type
var ReverseProxies map[string]ReverseProxy
func Server() (*gin.Engine, error) {
r := gin.Default()
r := gin.Default()
// "The make function allocates and initializes a hash map data
//structure and returns a map value that points to it.
//The specifics of that data structure are an implementation
//detail of the runtime and are not specified by the language itself."
// source: https://go.dev/blog/maps
ReverseProxies = make(map[string]ReverseProxy)
// "The make function allocates and initializes a hash map data
//structure and returns a map value that points to it.
//The specifics of that data structure are an implementation
//detail of the runtime and are not specified by the language itself."
// source: https://go.dev/blog/maps
ReverseProxies = make(map[string]ReverseProxy)
//Get Server port based on the config file
config, err := config.ConfigInit(nil, nil)
if err != nil {
return nil, err
}
//Get Server port based on the config file
config, err := config.ConfigInit(nil, nil)
if err != nil {
return nil, err
}
// update IPTable with new port and ip address and update ip table
var ProxyIpAddr p2p.IpAddress
var lowestLatencyIpAddress p2p.IpAddress
// update IPTable with new port and ip address and update ip table
var ProxyIpAddr p2p.IpAddress
var lowestLatencyIpAddress p2p.IpAddress
// Gets default information of the server
r.GET("/server_info", func(c *gin.Context) {
c.JSON(http.StatusOK, ServerInfo())
})
// Gets default information of the server
r.GET("/server_info", func(c *gin.Context) {
c.JSON(http.StatusOK, ServerInfo())
})
// Speed test with 50 mbps
r.GET("/50", func(c *gin.Context) {
// Get Path from config
c.File(config.SpeedTestFile)
})
// Speed test with 50 mbps
r.GET("/50", func(c *gin.Context) {
// Get Path from config
c.File(config.SpeedTestFile)
})
// Route build to do a speed test
r.GET("/upload", func(c *gin.Context) {
file, _ := c.FormFile("file")
// Route build to do a speed test
r.GET("/upload", func(c *gin.Context) {
file, _ := c.FormFile("file")
// Upload the file to specific dst.
// c.SaveUploadedFile(file, dst)
// Upload the file to specific dst.
// c.SaveUploadedFile(file, dst)
c.String(http.StatusOK, fmt.Sprintf("'%s' uploaded!", file.Filename))
})
c.String(http.StatusOK, fmt.Sprintf("'%s' uploaded!", file.Filename))
})
//Gets Ip Table from server node
r.POST("/IpTable", func(c *gin.Context) {
// Getting IPV4 address of client
//var ClientHost p2p.IpAddress
//
//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
//
//if p2p.Ip4or6(c.ClientIP()) == "version 6" {
// ClientHost.Ipv6 = c.ClientIP()
//} else {
// ClientHost.Ipv4 = c.ClientIP()
//}
// Variable to store IP table information
var IPTable p2p.IpAddresses
// Variable to store IP table information
var IPTable p2p.IpAddresses
// Receive file from POST request
body, err := c.FormFile("json")
if err != nil {
c.String(http.StatusOK, fmt.Sprint(err))
}
// Receive file from POST request
body, err := c.FormFile("json")
if err != nil {
c.String(http.StatusOK, fmt.Sprint(err))
}
// Open file
open, err := body.Open()
if err != nil {
c.String(http.StatusOK, fmt.Sprint(err))
}
// Open file
open, err := body.Open()
if err != nil {
c.String(http.StatusOK, fmt.Sprint(err))
}
// Open received file
file, err := ioutil.ReadAll(open)
if err != nil {
c.String(http.StatusOK, fmt.Sprint(err))
}
// Open received file
file, err := ioutil.ReadAll(open)
if err != nil {
c.String(http.StatusOK, fmt.Sprint(err))
}
json.Unmarshal(file, &IPTable)
json.Unmarshal(file, &IPTable)
//Add Client IP address to IPTable struct
//IPTable.IpAddress = append(IPTable.IpAddress, ClientHost)
//Add Client IP address to IPTable struct
//IPTable.IpAddress = append(IPTable.IpAddress, ClientHost)
// Runs speed test to return only servers in the IP table pingable
err = IPTable.SpeedTestUpdatedIPTable()
if err != nil {
c.String(http.StatusOK, fmt.Sprint(err))
}
// Runs speed test to return only servers in the IP table pingable
err = IPTable.SpeedTestUpdatedIPTable()
if err != nil {
c.String(http.StatusOK, fmt.Sprint(err))
}
// Reads IP addresses from ip table
IpAddresses, err := p2p.ReadIpTable()
if err != nil {
c.String(http.StatusOK, fmt.Sprint(err))
}
// Reads IP addresses from ip table
IpAddresses, err := p2p.ReadIpTable()
if err != nil {
c.String(http.StatusOK, fmt.Sprint(err))
}
c.JSON(http.StatusOK, IpAddresses)
})
c.JSON(http.StatusOK, IpAddresses)
})
// Starts docker container in server
r.GET("/startcontainer", func(c *gin.Context) {
// Get Number of ports to open and whether to use GPU or not
Ports := c.DefaultQuery("ports", "0")
GPU := c.DefaultQuery("GPU", "false")
ContainerName := c.DefaultQuery("ContainerName", "")
BaseImage := c.DefaultQuery("BaseImage", "")
PublicKey := c.DefaultQuery("PublicKey", "")
var PortsInt int
// Starts docker container in server
r.GET("/startcontainer", func(c *gin.Context) {
// Get Number of ports to open and whether to use GPU or not
Ports := c.DefaultQuery("ports", "0")
GPU := c.DefaultQuery("GPU", "false")
ContainerName := c.DefaultQuery("ContainerName", "")
BaseImage := c.DefaultQuery("BaseImage", "")
PublicKey := c.DefaultQuery("PublicKey", "")
var PortsInt int
if PublicKey == "" {
c.String(http.StatusInternalServerError, fmt.Sprintf("error: %s", "Publickey not passed"))
}
if PublicKey == "" {
c.String(http.StatusInternalServerError, fmt.Sprintf("error: %s", "Publickey not passed"))
}
PublicKeyDecoded, err := b64.StdEncoding.DecodeString(PublicKey)
if err != nil {
c.String(http.StatusInternalServerError, fmt.Sprintf("error: %s", err))
}
PublicKeyDecoded, err := b64.StdEncoding.DecodeString(PublicKey)
if err != nil {
c.String(http.StatusInternalServerError, fmt.Sprintf("error: %s", err))
}
// Convert Get Request value to int
fmt.Sscanf(Ports, "%d", &PortsInt)
// Convert Get Request value to int
fmt.Sscanf(Ports, "%d", &PortsInt)
fmt.Println(string(PublicKeyDecoded[:]))
// Creates container and returns-back result to
// access container
resp, err := docker.BuildRunContainer(PortsInt, GPU, ContainerName, BaseImage, string(PublicKeyDecoded[:]))
// Creates container and returns-back result to
// access container
resp, err := docker.BuildRunContainer(PortsInt, GPU, ContainerName, BaseImage, string(PublicKeyDecoded[:]))
if err != nil {
c.String(http.StatusInternalServerError, fmt.Sprintf("error: %s", err))
}
if err != nil {
c.String(http.StatusInternalServerError, fmt.Sprintf("error: %s", err))
}
// Ensures that FRP is triggered only if a proxy address is provided
if ProxyIpAddr.Ipv4 != "" && c.Request.Host != "localhost:"+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))
}
}
// 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))
}
}
c.JSON(http.StatusOK, resp)
})
c.JSON(http.StatusOK, resp)
})
//Remove container
r.GET("/RemoveContainer", func(c *gin.Context) {
ID := c.DefaultQuery("id", "0")
if err := docker.StopAndRemoveContainer(ID); err != nil {
c.String(http.StatusInternalServerError, fmt.Sprintf("error: %s", err))
}
c.String(http.StatusOK, "success")
})
//Remove container
r.GET("/RemoveContainer", func(c *gin.Context) {
ID := c.DefaultQuery("id", "0")
if err := docker.StopAndRemoveContainer(ID); err != nil {
c.String(http.StatusInternalServerError, fmt.Sprintf("error: %s", err))
}
c.String(http.StatusOK, "success")
})
//Show images available
r.GET("/ShowImages", func(c *gin.Context) {
resp, err := docker.ViewAllContainers()
if err != nil {
c.String(http.StatusInternalServerError, fmt.Sprintf("error: %s", err))
}
c.JSON(http.StatusOK, resp)
})
//Show images available
r.GET("/ShowImages", func(c *gin.Context) {
resp, err := docker.ViewAllContainers()
if err != nil {
c.String(http.StatusInternalServerError, fmt.Sprintf("error: %s", err))
}
c.JSON(http.StatusOK, resp)
})
// Request for port no from Server with address
r.GET("/FRPPort", func(c *gin.Context) {
port, err := frp.StartFRPProxyFromRandom()
if err != nil {
c.String(http.StatusInternalServerError, fmt.Sprintf("error: %s", err))
}
// Request for port no from Server with address
r.GET("/FRPPort", func(c *gin.Context) {
port, err := frp.StartFRPProxyFromRandom()
if err != nil {
c.String(http.StatusInternalServerError, fmt.Sprintf("error: %s", err))
}
c.String(http.StatusOK, strconv.Itoa(port))
})
c.String(http.StatusOK, strconv.Itoa(port))
})
r.GET("/MAPPort", func(c *gin.Context) {
Ports := c.DefaultQuery("port", "0")
DomainName := c.DefaultQuery("domain_name", "")
url, _, err := MapPort(Ports, DomainName)
if err != nil {
c.String(http.StatusInternalServerError, fmt.Sprintf("error: %s", err))
}
r.GET("/MAPPort", func(c *gin.Context) {
Ports := c.DefaultQuery("port", "0")
DomainName := c.DefaultQuery("domain_name", "")
url, _, err := MapPort(Ports, DomainName)
if err != nil {
c.String(http.StatusInternalServerError, fmt.Sprintf("error: %s", err))
}
c.String(http.StatusOK, url)
})
c.String(http.StatusOK, url)
})
r.GET("/AddProxy", func(c *gin.Context) {
DomainName := c.DefaultQuery("domain_name", "")
ip_address := c.DefaultQuery("ip_address", "")
Ports := c.DefaultQuery("port", "")
r.GET("/AddProxy", func(c *gin.Context) {
DomainName := c.DefaultQuery("domain_name", "")
ip_address := c.DefaultQuery("ip_address", "")
Ports := c.DefaultQuery("port", "")
if DomainName == "" || ip_address == "" || Ports == "" {
c.String(http.StatusInternalServerError, fmt.Sprintf("All get parameters npt provided"+
" do ensure domain_name, ip_Address and port no is provided"))
}
if DomainName == "" || ip_address == "" || Ports == "" {
c.String(http.StatusInternalServerError, fmt.Sprintf("All get parameters npt provided"+
" do ensure domain_name, ip_Address and port no is provided"))
}
err := SaveRegistration(DomainName, ip_address+":"+Ports)
if err != nil {
c.String(http.StatusInternalServerError, fmt.Sprintf(err.Error()))
}
err := SaveRegistration(DomainName, ip_address+":"+Ports)
if err != nil {
c.String(http.StatusInternalServerError, fmt.Sprintf(err.Error()))
}
//_, ok := ReverseProxies[DomainName]
//// To check if the subdomain entry exists
//if ok {
// c.String(http.StatusInternalServerError, fmt.Sprintf("The domain entry already exists as a reverse"+
// " proxy entry"))
//}
//
//// added proxy as a map entry
//ReverseProxies[DomainName] = ReverseProxy{IPAddress: ip_address, Port: Ports}
c.String(http.StatusOK, "Sucess")
//_, ok := ReverseProxies[DomainName]
//// To check if the subdomain entry exists
//if ok {
// c.String(http.StatusInternalServerError, fmt.Sprintf("The domain entry already exists as a reverse"+
// " proxy entry"))
//}
//
//// added proxy as a map entry
//ReverseProxies[DomainName] = ReverseProxy{IPAddress: ip_address, Port: Ports}
c.String(http.StatusOK, "Sucess")
})
})
//r.GET("/RemoveProxy", func(c *gin.Context) {
// DomainName := c.DefaultQuery("domain_name", "")
//
// _, ok := ReverseProxies[DomainName]
// if !ok {
// c.String(http.StatusInternalServerError, fmt.Sprintf("Domain name does exist in entries of proxies"))
// } else {
// delete(ReverseProxies, DomainName)
// }
//
//})
//r.GET("/RemoveProxy", func(c *gin.Context) {
// DomainName := c.DefaultQuery("domain_name", "")
//
// _, ok := ReverseProxies[DomainName]
// if !ok {
// c.String(http.StatusInternalServerError, fmt.Sprintf("Domain name does exist in entries of proxies"))
// } else {
// delete(ReverseProxies, DomainName)
// }
//
//})
// If there is a proxy port specified
// then starts the FRP server
//if config.FRPServerPort != "0" {
// go frp.StartFRPProxyFromRandom()
//}
// If there is a proxy port specified
// then starts the FRP server
//if config.FRPServerPort != "0" {
// go frp.StartFRPProxyFromRandom()
//}
// Remove nodes currently not pingable
clientIPTable.RemoveOfflineNodes()
// Remove nodes currently not pingable
clientIPTable.RemoveOfflineNodes()
table, err := p2p.ReadIpTable()
table, err := p2p.ReadIpTable()
// 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 {
if err != nil {
return nil, err
}
// TODO check if IPV6 or Proxy port is specified
// if not update current entry as proxy address
// with appropriate port on IP Table
if config.BehindNAT {
if err != nil {
return nil, err
}
var lowestLatency int64
// random large number
lowestLatency = 10000000
var lowestLatency int64
// random large number
lowestLatency = 10000000
for i, _ := range table.IpAddress {
// Checks if the ping is the lowest and if the following node is acting as a proxy
//if table.IpAddress[i].Latency.Milliseconds() < lowestLatency && table.IpAddress[i].ProxyPort != "" {
if table.IpAddress[i].Latency.Milliseconds() < lowestLatency && !table.IpAddress[i].NAT {
lowestLatency = table.IpAddress[i].Latency.Milliseconds()
lowestLatencyIpAddress = table.IpAddress[i]
}
}
for i, _ := range table.IpAddress {
// Checks if the ping is the lowest and if the following node is acting as a proxy
//if table.IpAddress[i].Latency.Milliseconds() < lowestLatency && table.IpAddress[i].ProxyPort != "" {
if table.IpAddress[i].Latency.Milliseconds() < lowestLatency && !table.IpAddress[i].NAT {
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 nil, 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 nil, err
}
// If there is an identified node
if lowestLatency != 10000000 {
serverPort, err := frp.GetFRPServerPort("http://" + lowestLatencyIpAddress.Ipv4 + ":" + lowestLatencyIpAddress.ServerPort)
if err != nil {
return nil, 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 nil, err
}
// updating with the current proxy address
ProxyIpAddr.Ipv4 = lowestLatencyIpAddress.Ipv4
ProxyIpAddr.ServerPort = proxyPort
ProxyIpAddr.Name = config.MachineName
ProxyIpAddr.NAT = false
ProxyIpAddr.ProxyServer = false
ProxyIpAddr.EscapeImplementation = "FRP"
// updating with the current proxy address
ProxyIpAddr.Ipv4 = lowestLatencyIpAddress.Ipv4
ProxyIpAddr.ServerPort = proxyPort
ProxyIpAddr.Name = config.MachineName
ProxyIpAddr.NAT = false
ProxyIpAddr.ProxyServer = false
ProxyIpAddr.EscapeImplementation = "FRP"
if config.BareMetal {
_, SSHPort, err := MapPort("22", "")
if err != nil {
return nil, err
}
ProxyIpAddr.BareMetalSSHPort = SSHPort
}
if config.BareMetal {
_, SSHPort, err := MapPort("22", "")
if err != nil {
return nil, err
}
ProxyIpAddr.BareMetalSSHPort = SSHPort
}
//ProxyIpAddr.CustomInformationKey = p2p.GenerateHashSHA256(config.IPTableKey)
// write information back to the IP Table
}
//ProxyIpAddr.CustomInformationKey = p2p.GenerateHashSHA256(config.IPTableKey)
// write information back to the IP Table
}
} else {
ProxyIpAddr.Ipv4, err = p2p.CurrentPublicIP()
if err != nil {
fmt.Println(err)
}
} else {
ProxyIpAddr.Ipv4, err = p2p.CurrentPublicIP()
if err != nil {
fmt.Println(err)
}
ProxyIpAddr.ServerPort = config.ServerPort
ProxyIpAddr.Name = config.MachineName
ProxyIpAddr.NAT = false
if config.ProxyPort != "" {
ProxyIpAddr.ProxyServer = true
}
ProxyIpAddr.EscapeImplementation = ""
if config.BareMetal {
ProxyIpAddr.BareMetalSSHPort = "22"
}
ProxyIpAddr.ServerPort = config.ServerPort
ProxyIpAddr.Name = config.MachineName
ProxyIpAddr.NAT = false
if config.ProxyPort != "" {
ProxyIpAddr.ProxyServer = true
}
ProxyIpAddr.EscapeImplementation = ""
if config.BareMetal {
ProxyIpAddr.BareMetalSSHPort = "22"
}
}
}
// Get machine username
currentUser, err := user.Current()
if err != nil {
return nil, err
}
// Add username p2prc binary is being run under
ProxyIpAddr.MachineUsername = currentUser.Username
ProxyIpAddr.UnSafeMode = config.UnsafeMode
// Adds the public key information to the IPTable
// improving transmission of IPTables without the
// entire public key is future work to be improved
// in the P2PRC protocol level (Improving by adding
// UDP with TCP reliability layer).
ProxyIpAddr.PublicKey, err = config.GetPublicKey()
// Get machine username
currentUser, err := user.Current()
if err != nil {
return nil, err
}
// Add username p2prc binary is being run under
ProxyIpAddr.MachineUsername = currentUser.Username
ProxyIpAddr.UnSafeMode = config.UnsafeMode
// Adds the public key information to the IPTable
// improving transmission of IPTables without the
// entire public key is future work to be improved
// in the P2PRC protocol level (Improving by adding
// UDP with TCP reliability layer).
ProxyIpAddr.PublicKey, err = config.GetPublicKey()
if err != nil {
return nil, err
}
if err != nil {
return nil, err
}
// append the following to the ip table
table.IpAddress = append(table.IpAddress, ProxyIpAddr)
// append the following to the ip table
table.IpAddress = append(table.IpAddress, ProxyIpAddr)
// Writing results to the IPTable
err = table.WriteIpTable()
if err != nil {
return nil, err
}
// Writing results to the IPTable
err = table.WriteIpTable()
if err != nil {
return nil, err
}
// update ip table
go func() error {
err := clientIPTable.UpdateIpTableListClient()
if err != nil {
fmt.Println(err)
return err
}
return nil
}()
// update ip table
go func() error {
err := clientIPTable.UpdateIpTableListClient()
if err != nil {
fmt.Println(err)
return err
}
return nil
}()
if config.ProxyPort != "" {
go ProxyRun(config.ProxyPort)
}
if config.ProxyPort != "" {
go ProxyRun(config.ProxyPort)
}
// Run gin server on the specified port
go r.Run(":" + config.ServerPort)
// Run gin server on the specified port
go r.Run(":" + config.ServerPort)
return r, nil
return r, nil
}
func MapPort(port string, domainName string) (string, string, error) {
// if server address is provided to do call RESTAPI to remotely open port.
//if serverAddress != "" {
// requestURL := fmt.Sprintf("http://%v/MAPPort?port=%v&domain_name=%v", serverAddress, port, domainName)
// req, err := http.NewRequest(http.MethodGet, requestURL, nil)
// if err != nil {
// return "", "", err
// }
//
// res, err := http.DefaultClient.Do(req)
// if err != nil {
// return "", "", err
// }
//
// resBody, err := io.ReadAll(res.Body)
// if err != nil {
// return "", "", err
// }
//
// _, Exposedport, err := net.SplitHostPort(string(resBody))
// if err != nil {
// return "", "", err
// }
//
// return string(resBody), Exposedport, nil
//}
// if server address is provided to do call RESTAPI to remotely open port.
//if serverAddress != "" {
// requestURL := fmt.Sprintf("http://%v/MAPPort?port=%v&domain_name=%v", serverAddress, port, domainName)
// req, err := http.NewRequest(http.MethodGet, requestURL, nil)
// if err != nil {
// return "", "", err
// }
//
// res, err := http.DefaultClient.Do(req)
// if err != nil {
// return "", "", err
// }
//
// resBody, err := io.ReadAll(res.Body)
// if err != nil {
// return "", "", err
// }
//
// _, Exposedport, err := net.SplitHostPort(string(resBody))
// if err != nil {
// return "", "", err
// }
//
// return string(resBody), Exposedport, nil
//}
//Get Server port based on the config file
config, err := config.ConfigInit(nil, nil)
if err != nil {
return "", "", err
}
//Get Server port based on the config file
config, err := config.ConfigInit(nil, nil)
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
// update IPTable with new port and ip address and update ip table
var ProxyIpAddr p2p.IpAddress
var lowestLatencyIpAddress p2p.IpAddress
clientIPTable.RemoveOfflineNodes()
clientIPTable.RemoveOfflineNodes()
table, err := p2p.ReadIpTable()
if err != nil {
return "", "", err
}
table, err := p2p.ReadIpTable()
if err != nil {
return "", "", err
}
var lowestLatency int64
// random large number
lowestLatency = 10000000
var lowestLatency int64
// random large number
lowestLatency = 10000000
for i, _ := range table.IpAddress {
// Checks if the ping is the lowest and if the following node is acting as a proxy
//if table.IpAddress[i].Latency.Milliseconds() < lowestLatency && table.IpAddress[i].ProxyPort != "" {
if table.IpAddress[i].Latency.Milliseconds() < lowestLatency && !table.IpAddress[i].NAT {
// Filter based on nodes with proxy enabled
if domainName != "" && table.IpAddress[i].ProxyServer {
lowestLatency = table.IpAddress[i].Latency.Milliseconds()
lowestLatencyIpAddress = table.IpAddress[i]
continue
}
lowestLatency = table.IpAddress[i].Latency.Milliseconds()
lowestLatencyIpAddress = table.IpAddress[i]
}
}
for i, _ := range table.IpAddress {
// Checks if the ping is the lowest and if the following node is acting as a proxy
//if table.IpAddress[i].Latency.Milliseconds() < lowestLatency && table.IpAddress[i].ProxyPort != "" {
if table.IpAddress[i].Latency.Milliseconds() < lowestLatency && !table.IpAddress[i].NAT {
// Filter based on nodes with proxy enabled
if domainName != "" && table.IpAddress[i].ProxyServer {
lowestLatency = table.IpAddress[i].Latency.Milliseconds()
lowestLatencyIpAddress = table.IpAddress[i]
continue
}
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, port, "")
if err != nil {
return "", "", err
}
// If there is an identified node
if lowestLatency != 10000000 {
serverPort, err := frp.GetFRPServerPort("http://" + lowestLatencyIpAddress.Ipv4 + ":" + lowestLatencyIpAddress.ServerPort)
if err != nil {
return "", "", err
}
// Create 3 second delay to allow FRP server to start
time.Sleep(1 * time.Second)
// Starts FRP as a client with
proxyPort, err := frp.StartFRPClientForServer(lowestLatencyIpAddress.Ipv4, serverPort, port, "")
if err != nil {
return "", "", err
}
// Doing the proxy mapping for the domain name
if domainName != "" {
fmt.Println("http://" + lowestLatencyIpAddress.Ipv4 + ":" + lowestLatencyIpAddress.ServerPort + "/AddProxy?port=" + proxyPort + "&domain_name=" + domainName + "&ip_address=" + lowestLatencyIpAddress.Ipv4)
URL := "http://" + lowestLatencyIpAddress.Ipv4 + ":" + lowestLatencyIpAddress.ServerPort + "/AddProxy?port=" + proxyPort + "&domain_name=" + domainName + "&ip_address=" + lowestLatencyIpAddress.Ipv4
//} else {
// URL = "http://" + IP + ":" + serverPort + "/server_info"
//}
http.Get(URL)
//SaveRegistration(domainName, lowestLatencyIpAddress.Ipv4+":"+proxyPort)
}
// Doing the proxy mapping for the domain name
if domainName != "" {
fmt.Println("http://" + lowestLatencyIpAddress.Ipv4 + ":" + lowestLatencyIpAddress.ServerPort + "/AddProxy?port=" + proxyPort + "&domain_name=" + domainName + "&ip_address=" + lowestLatencyIpAddress.Ipv4)
URL := "http://" + lowestLatencyIpAddress.Ipv4 + ":" + lowestLatencyIpAddress.ServerPort + "/AddProxy?port=" + proxyPort + "&domain_name=" + domainName + "&ip_address=" + lowestLatencyIpAddress.Ipv4
//} else {
// URL = "http://" + IP + ":" + serverPort + "/server_info"
//}
http.Get(URL)
//SaveRegistration(domainName, lowestLatencyIpAddress.Ipv4+":"+proxyPort)
}
// updating with the current proxy address
ProxyIpAddr.Ipv4 = lowestLatencyIpAddress.Ipv4
ProxyIpAddr.ServerPort = proxyPort
ProxyIpAddr.Name = config.MachineName
ProxyIpAddr.NAT = false
ProxyIpAddr.EscapeImplementation = "FRP"
// updating with the current proxy address
ProxyIpAddr.Ipv4 = lowestLatencyIpAddress.Ipv4
ProxyIpAddr.ServerPort = proxyPort
ProxyIpAddr.Name = config.MachineName
ProxyIpAddr.NAT = false
ProxyIpAddr.EscapeImplementation = "FRP"
//ProxyIpAddr.CustomInformationKey = p2p.GenerateHashSHA256(config.IPTableKey)
} else {
return "", "", errors.New("proxy IP not found")
}
//ProxyIpAddr.CustomInformationKey = p2p.GenerateHashSHA256(config.IPTableKey)
} else {
return "", "", errors.New("proxy IP not found")
}
return ProxyIpAddr.Ipv4 + ":" + ProxyIpAddr.ServerPort, ProxyIpAddr.ServerPort, nil
return ProxyIpAddr.Ipv4 + ":" + ProxyIpAddr.ServerPort, ProxyIpAddr.ServerPort, nil
}