added python reference implementation

This commit is contained in:
2025-01-02 01:27:07 +00:00
parent 9d9c484d07
commit 9692fce5b2
6 changed files with 184 additions and 0 deletions

3
python/.gitignore vendored Normal file
View File

@@ -0,0 +1,3 @@
p2prc-virtualenv/
SharedObjects/
__pycache__/

View File

@@ -0,0 +1 @@
lsof -i tcp:8084 | awk 'NR!=1 {print $2}' | xargs kill

View File

@@ -0,0 +1 @@
python3 -m http.server 8084

135
python/library.py Normal file
View File

@@ -0,0 +1,135 @@
import ctypes
from ctypes import Structure, c_char_p, c_int, cdll
from dataclasses import dataclass, astuple
import time
import json
from urllib.parse import urlparse
from typing import List
import subprocess
import uuid
import dacite
import os
p2prc = ctypes.CDLL("SharedObjects/p2prc.so")
p2prc.Init("")
# Global variable
# A global variable will be populated on runtime.
# It is read from P2PRC directly or from a local
# database.
# Node information
# Generated using: https://jsonformatter.org/json-to-python
@dataclass
class Node:
Name: str
MachineUsername: str
IPV4: str
IPV6: str
Latency: int
Download: int
Upload: int
ServerPort: str
BareMetalSSHPort: str
NAT: str
EscapeImplementation: str
ProxyServer: str
UnSafeMode: bool
PublicKey: str
CustomInformation: str
@dataclass
class IPAddress:
ip_address: List[Node]
# ----------------------------------------------------------------------------
# ----------------------------- Helper functions -----------------------------
# ----------------------------------------------------------------------------
def StartServer():
# Starting P2PRC as a server mode
p2prc.Server()
for _ in iter(int, 1):
pass
# Class to create string to pass as string function
# parameter to shared object file
class go_string(Structure):
_fields_ = [
("p", c_char_p),
("n", c_int)]
# Local port intended to ensure that
def P2PRCMapPort(port="",domainname="",serveraddress=""):
# Local Port intended to be escaped outside NAT
# Converting to the appropirate datatype to be
# passed as a string to GoLang.
port = go_string(c_char_p(port.encode('utf-8')), len(port))
domainname = go_string(c_char_p(domainname.encode('utf-8')), len(domainname))
serveraddress = go_string(c_char_p(serveraddress.encode('utf-8')), len(serveraddress))
# Defining the response type of the GoLang function
# function
p2prc.MapPort.restype = c_char_p
# Calling the Go function
address = p2prc.MapPort(port,domainname,serveraddress)
res = str(address).strip("b'")
return res
def ListNodes():
# View IP Table information
p2prc.ViewIPTable.restype = c_char_p
ipTable = p2prc.ViewIPTable()
# View IP Table as
ipTableObject = json.loads((str(ipTable).strip("b'")))
dat: IPAddress = dacite.from_dict(IPAddress,ipTableObject)
return dat
# -----------------------------------------------------------------------------------
# ----------------------------- End of helper functions -----------------------------
# -----------------------------------------------------------------------------------
def infinity():
while True:
yield
# Process datatype
@dataclass
class Process:
ID: str
InternalPortNo: str
ExternalAddress: str
NodeInfo: Node
TaskName: str
CommandToRunScript: str
CommandToKillScript: str
Status: bool
DomainName: str
# Initial defined functions
# Exposed functions
def SpinProcess(process: Process):
# Starts P2PRC process
os.system(process.CommandToRunScript)
process.ExternalAddress = P2PRCMapPort(port=process.InternalPortNo,domainname=process.DomainName,serveraddress=process.NodeInfo.ip_address.IPV4 + ":" + process.NodeInfo.ip_address.ServerPort)
process.ID = str(uuid.uuid4())
process.Status = True
return process
# Kill process based on the process provided
def KillProcess(process: Process):
os.system(process.CommandToKillScript)
process.Status = False
return process
# def ProcessInformation():
# def ListProcess():

1
python/requirements.txt Normal file
View File

@@ -0,0 +1 @@
dacite

43
python/test.py Normal file
View File

@@ -0,0 +1,43 @@
from library import *
if __name__ == "__main__":
P2PRCNodes = ListNodes()
# Create sample process
sample_process = Process(
ID="",
TaskName="TestServer",
InternalPortNo="8084",
NodeInfo=IPAddress(P2PRCNodes.ip_address[2]),
CommandToRunScript="sh SamplePythonTestServer/server.sh &",
CommandToKillScript="sh SamplePythonTestServer/killserver.sh",
DomainName="",
Status=False,
ExternalAddress=""
)
print("------------ Starting process -------------")
# Spin process
sample_process = SpinProcess(sample_process)
print("------------ Process Public address -------------")
# Prints status of the current process
print(sample_process.ExternalAddress)
print("------------ Process kept waiting for 20 seconds -------------")
# Runs the process for 20 seconds
time.sleep(20)
print("------------ Process getting killed -------------")
# Kills the process
KillProcess(sample_process)
print("------------ Process current process -------------")
# Prints process status
print(sample_process.Status)