├── .DS_Store ├── .github ├── FUNDING.yml └── release-drafter.yml ├── .gitignore ├── .goreleaser.yml ├── Bindings ├── Client.go ├── Haskell │ ├── .dev_run.sh │ ├── .gen_docs.sh │ ├── .gitignore │ ├── .mhsi │ ├── README.md │ ├── cabal.project │ ├── flake.lock │ ├── flake.nix │ ├── lib │ │ ├── API.hs │ │ ├── CLI.hs │ │ ├── Engine.hs │ │ ├── Error.hs │ │ ├── JSON.hs │ │ └── P2PRC.hs │ ├── p2prc.cabal │ ├── project.nix │ └── src │ │ └── Main.hs ├── docs.md └── python │ ├── .DS_Store │ ├── library.py │ ├── requirements.txt │ └── test.py ├── CITATION.cff ├── CNAME ├── CONTRIBUTE.md ├── Docs ├── .gitignore ├── Colored-On-Light-Image.png ├── DocsDeprecated │ ├── Abstractions.md │ ├── Abstractions.org │ ├── Bindings.md │ ├── Bindings.org │ ├── CliImplementation.md │ ├── CliImplementation.org │ ├── Client.md │ ├── Client.org │ ├── ClientArchitecture.md │ ├── ClientArchitecture.org │ ├── ClientImplementation.md │ ├── ClientImplementation.org │ ├── ConfigImplementation.md │ ├── ConfigImplementation.org │ ├── DesignArchtectureIntro.md │ ├── DesignArchtectureIntro.org │ ├── DomainNameMappingsImplementation.md │ ├── DomainNameMappingsImplementation.org │ ├── Implementation.md │ ├── Implementation.org │ ├── Installation.md │ ├── Installation.org │ ├── Introduction.md │ ├── Introduction.org │ ├── NAT-Traveral.md │ ├── NAT-Traveral.org │ ├── P2P-testing.md │ ├── P2P-testing.org │ ├── P2P.md │ ├── P2P.org │ ├── P2PArchitecture.md │ ├── P2PArchitecture.org │ ├── P2PImplementation.md │ ├── P2PImplementation.org │ ├── PluginImplementation.md │ ├── PluginImplementation.org │ ├── README.md │ ├── README.org │ ├── ServerArchitecture.md │ ├── ServerArchitecture.md.org │ ├── ServerImplementation.md │ ├── ServerImplementation.md.org │ ├── Virtualization │ └── docs.org ├── diagrams │ └── P2PRCRemoteNodes.drawio ├── haskell │ ├── P2PRC.html │ ├── README.md │ ├── doc-index.html │ ├── haddock-bundle.min.js │ ├── index.html │ ├── linuwial.css │ ├── meta.json │ ├── p2prc.haddock │ ├── quick-jump.css │ └── synopsis.png ├── images │ ├── NumOfHops.png │ ├── P2PRCRemoteNodes.png │ ├── clientmoduleArch.png │ ├── p2pmoduleArch.png │ ├── p2prclogo.png │ └── servermoduleArch.png ├── index.html ├── index.org ├── kill-docs.sh ├── run-docs.sh ├── staticServer.go └── style.css ├── LICENSE ├── Makefile ├── README.md ├── Simulation └── simulation.sh ├── _config.yml ├── abstractions ├── base.go └── docs.md ├── artwork ├── .DS_Store ├── README.md ├── embed.svg ├── index.html └── p2prc-logos │ ├── .DS_Store │ ├── Black-Image.png │ ├── Black-Vector.svg │ ├── Colored-Image.png │ ├── Colored-On-Dark-Image.png │ ├── Colored-On-Dark-Vector.svg │ ├── Colored-On-Light-Image.png │ ├── Colored-On-Light-Vector.svg │ ├── Colored-Vector.svg │ ├── P2PRCHaskell.png │ ├── White-Image.png │ └── White-Vector.svg ├── build-bindings.sh ├── build-haskell.sh ├── build-python-package.sh ├── client ├── GroupTrackContainer.go ├── GroupTrackContainer_test.go ├── MAPPort.go ├── ServerSpecs.go ├── TrackContainers.go ├── TrackContianers_test.go ├── clientIPTable │ ├── AddCustomInformationToIPTable.go │ ├── Iptable.go │ ├── docs.md │ └── iptable_test.go ├── container.go ├── docs.md ├── grouptrackcontainers.json └── trackcontainers.json ├── cmd ├── action.go ├── docs.md └── flags.go ├── config ├── config.go ├── docs.md └── generate │ ├── config_test.go │ ├── docs.md │ ├── generate.go │ ├── generateCertificate.go │ ├── generateFiles.go │ ├── gernerate_test.go │ └── helperFunctions.go ├── default.nix ├── flake.lock ├── flake.nix ├── go.mod ├── go.sum ├── gomod2nix.toml ├── install-binary.bat ├── install-binary.sh ├── install.bat ├── install.sh ├── main.go ├── main.md ├── nix ├── overlays │ └── bindings.nix └── templates │ └── haskell │ ├── flake.lock │ └── flake.nix ├── p2p ├── README ├── docs.md ├── frp │ ├── client.go │ ├── docs.md │ ├── server.go │ └── server_test.go ├── ip_table.json ├── iptable.go ├── iptable_test.go ├── speedtest.go ├── speedtest_test.go ├── ssh_autorisation.go ├── testingMetrics.go ├── upnp.go └── upnp_test.go ├── plugin ├── .dockerignore ├── .gitignore ├── README.md ├── TestAnsible │ ├── description.txt │ ├── hosts │ └── site.yml ├── docs.md ├── generate_test_case.sh ├── packageManager.go ├── plugin.go └── plugin_test.go ├── server ├── .DS_Store ├── ReverseProxy.go ├── docker │ ├── .DS_Store │ ├── Makefile │ ├── README │ ├── docker.go │ ├── docker_test.go │ ├── dockprom │ │ ├── LICENSE │ │ ├── README.md │ │ ├── alertmanager │ │ │ └── config.yml │ │ ├── caddy │ │ │ └── Caddyfile │ │ ├── config │ │ ├── docker-compose.exporters.yml │ │ ├── docker-compose.yml │ │ ├── grafana │ │ │ └── provisioning │ │ │ │ ├── dashboards │ │ │ │ ├── dashboard.yml │ │ │ │ ├── docker_containers.json │ │ │ │ ├── docker_host.json │ │ │ │ ├── monitor_services.json │ │ │ │ └── nginx_container.json │ │ │ │ └── datasources │ │ │ │ └── datasource.yml │ │ ├── helpers │ │ │ └── aws │ │ │ │ ├── README.md │ │ │ │ ├── cadvisor_ecs_task_definition.json │ │ │ │ ├── node_exporter_task_definition.json │ │ │ │ └── prometheus.yml │ │ ├── prometheus │ │ │ ├── alert.rules │ │ │ └── prometheus.yml │ │ └── screens │ │ │ ├── Grafana_Docker_Containers.png │ │ │ ├── Grafana_Docker_Host.png │ │ │ ├── Grafana_Prometheus.png │ │ │ └── Slack_Notifications.png │ ├── docs.md │ └── kill-containers.sh ├── docs.md ├── gopsutil.go ├── gpu.go ├── gpu_test.go ├── server.go └── upload_file.go ├── shell.nix └── wasm └── p2prc.wasm /.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Akilan1999/p2p-rendering-computation/36930be8e480877414fec654169b9b2969168db0/.DS_Store -------------------------------------------------------------------------------- /.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | # These are supported funding model platforms 2 | 3 | github: # Replace with up to 4 GitHub Sponsors-enabled usernames e.g., [user1, user2] 4 | patreon: # Replace with a single Patreon username 5 | open_collective: # Replace with a single Open Collective username 6 | ko_fi: akilan1999 7 | tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel 8 | community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry 9 | liberapay: # Replace with a single Liberapay username 10 | issuehunt: # Replace with a single IssueHunt username 11 | otechie: # Replace with a single Otechie username 12 | custom: # Replace with up to 4 custom sponsorship URLs e.g., ['link1', 'link2'] 13 | -------------------------------------------------------------------------------- /.github/release-drafter.yml: -------------------------------------------------------------------------------- 1 | name: Release Drafter 2 | 3 | on: 4 | push: 5 | # branches to consider in the event; optional, defaults to all 6 | branches: 7 | - master 8 | # pull_request event is required only for autolabeler 9 | pull_request: 10 | # Only following types are handled by the action, but one can default to all as well 11 | types: [opened, reopened, synchronize] 12 | 13 | jobs: 14 | update_release_draft: 15 | runs-on: ubuntu-latest 16 | steps: 17 | # (Optional) GitHub Enterprise requires GHE_HOST variable set 18 | #- name: Set GHE_HOST 19 | # run: | 20 | # echo "GHE_HOST=${GITHUB_SERVER_URL##https:\/\/}" >> $GITHUB_ENV 21 | 22 | # Drafts your next Release notes as Pull Requests are merged into "master" 23 | - uses: release-drafter/release-drafter@v5 24 | # (Optional) specify config name to use, relative to .github/. Default: release-drafter.yml 25 | # with: 26 | # config-name: my-config.yml 27 | # disable-autolabeler: true 28 | env: 29 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 30 | 31 | name-template: 'v$RESOLVED_VERSION' 32 | tag-template: 'v$RESOLVED_VERSION' 33 | categories: 34 | - title: '🚀 Features' 35 | labels: 36 | - 'feature' 37 | - 'enhancement' 38 | - title: '🐛 Bug Fixes' 39 | labels: 40 | - 'fix' 41 | - 'bugfix' 42 | - 'bug' 43 | - title: '🧰 Maintenance' 44 | label: 'chore' 45 | 46 | change-template: '- $TITLE @$AUTHOR (#$NUMBER)' 47 | change-title-escapes: '\<*_&' # You can add # and @ to disable mentions, and add ` to disable code blocks. 48 | version-resolver: 49 | major: 50 | labels: 51 | - 'major' 52 | minor: 53 | labels: 54 | - 'minor' 55 | patch: 56 | labels: 57 | - 'patch' 58 | default: patch 59 | template: | 60 | ## Changes 61 | 62 | $CHANGES 63 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .idea 2 | vendor/ 3 | bin/ 4 | p2p-rendering/ 5 | main 6 | server/docker/__pycache__ 7 | p2p-rendering-computation 8 | p2prc 9 | config.json 10 | .vscode/ 11 | 12 | #ignore generated iptables 13 | p2p/iptable/ 14 | #ignore plugins added 15 | plugin/deploy/ 16 | #ignore track container file 17 | client/trackcontainers/ 18 | # Test generated files 19 | generate/p2prctest 20 | generate/Test 21 | #ignore windows exe files 22 | *.exe 23 | dist/ 24 | # Ignore any sort of logs 25 | logs/ 26 | 27 | # ignore docker image files 28 | server/docker/containers/ 29 | *.h 30 | *.so 31 | 32 | # generic folder to ignore 33 | export/ 34 | exports/ 35 | 36 | # Any testing file 37 | *test 38 | 39 | # Ignore public and private keys 40 | p2prc.publicKey 41 | p2prc.privateKey 42 | p2prc.PublicKeyBareMetal 43 | 44 | # Ignore pem files 45 | *.pem 46 | 47 | # ignore virtual env file 48 | venv 49 | 50 | # Nix and Nix flake files 51 | result 52 | result-* 53 | -------------------------------------------------------------------------------- /.goreleaser.yml: -------------------------------------------------------------------------------- 1 | # This is an example .goreleaser.yml file with some sensible defaults. 2 | # Make sure to check the documentation at https://goreleaser.com 3 | before: 4 | hooks: 5 | # You may remove this if you don't use go modules. 6 | - go mod tidy 7 | # you may remove this if you don't need go generate 8 | - go generate ./... 9 | builds: 10 | - env: 11 | - CGO_ENABLED=0 12 | goos: 13 | - linux 14 | - windows 15 | - darwin 16 | archives: 17 | - replacements: 18 | darwin: Darwin 19 | linux: Linux 20 | windows: Windows 21 | 386: i386 22 | amd64: x86_64 23 | checksum: 24 | name_template: 'checksums.txt' 25 | snapshot: 26 | name_template: "{{ incpatch .Version }}-next" 27 | changelog: 28 | sort: asc 29 | filters: 30 | exclude: 31 | - '^docs:' 32 | - '^test:' 33 | -------------------------------------------------------------------------------- /Bindings/Haskell/.dev_run.sh: -------------------------------------------------------------------------------- 1 | rm -rf *pem client/ plugin/ server/ p2p/ p2prc.[pP]* config.json dist-newstyle/ &&\ 2 | cabal clean &&\ 3 | cabal run 4 | -------------------------------------------------------------------------------- /Bindings/Haskell/.gen_docs.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | rm -rf dist-newstyle/ 4 | 5 | cabal haddock 6 | 7 | rm -rf ../../Docs/haskell 8 | 9 | cp -r \ 10 | ./dist-newstyle/build/x86_64-linux/ghc-9.6.6/p2prc-0.1.0.0/doc/html/p2prc/ \ 11 | ../../Docs/haskell 12 | -------------------------------------------------------------------------------- /Bindings/Haskell/.gitignore: -------------------------------------------------------------------------------- 1 | CHANGELOG.md 2 | client 3 | config.json 4 | dist-newstyle 5 | p2p 6 | p2prc.privateKey 7 | p2prc.PublicKeyBareMetal 8 | plugin 9 | server 10 | 11 | haddocks/ 12 | 13 | key.pem 14 | cert.pem 15 | cabal.project.local 16 | -------------------------------------------------------------------------------- /Bindings/Haskell/.mhsi: -------------------------------------------------------------------------------- 1 | exit 2 | Exit 3 | -------------------------------------------------------------------------------- /Bindings/Haskell/README.md: -------------------------------------------------------------------------------- 1 |
2 | 3 | p2prc-0.1.0.0: P2PRC haskell library 4 | 5 | - [Contents](index.html) 6 | - [Index](doc-index.html) 7 | 8 |
9 | 10 |
11 | 12 |
13 | 14 | | | | 15 | |--------------|-----------------------------------------| 16 | | Copyright | Copyright (C) 2006-2024 John MacFarlane | 17 | | License | GNU GPL, version 2 or above | 18 | | Stability | alpha | 19 | | Portability | portable | 20 | | Safe Haskell | Safe-Inferred | 21 | | Language | GHC2021 | 22 | 23 | P2PRC 24 | 25 |
26 | 27 |
28 | 29 | Description 30 | 31 |
32 | 33 | This helper module exports the main writers, readers, and data structure 34 | definitions from the Pandoc libraries. 35 | 36 | A typical application will chain together a reader and a writer to 37 | convert strings from one format to another. For example, the following 38 | simple program will act as a filter converting markdown fragments to 39 | reStructuredText, using reference-style links instead of inline links: 40 | 41 | module Main where 42 | import Text.Pandoc 43 | import Data.Text (Text) 44 | import qualified Data.Text.IO as T 45 | 46 | mdToRST :: Text -> IO Text 47 | mdToRST txt = runIOorExplode $ 48 | readMarkdown def txt 49 | >>= writeRST def{ writerReferenceLinks = True } 50 | 51 | main :: IO () 52 | main = do 53 | T.getContents >>= mdToRST >>= T.putStrLn 54 | 55 |
56 | 57 |
58 | 59 |
60 | 61 | Synopsis 62 | 63 | - [runP2PRC](#v:runP2PRC) :: 64 | [MapPortRequest](P2PRC.html#t:MapPortRequest "P2PRC") -\> 65 | [IO]($%7Bpkgroot%7D/../../../../dcnyq1a8qi8x59n5p53d0dx42cl8hf8x-ghc-9.6.5-doc/share/doc/ghc/html/libraries/base-4.18.2.1/System-IO.html#t:IO "System.IO") 66 | () 67 | - data [MapPortRequest](#t:MapPortRequest) 68 | = [MkMapPortRequest](#v:MkMapPortRequest) 69 | [Int]($%7Bpkgroot%7D/../../../../dcnyq1a8qi8x59n5p53d0dx42cl8hf8x-ghc-9.6.5-doc/share/doc/ghc/html/libraries/base-4.18.2.1/Data-Int.html#t:Int "Data.Int") 70 | [String]($%7Bpkgroot%7D/../../../../dcnyq1a8qi8x59n5p53d0dx42cl8hf8x-ghc-9.6.5-doc/share/doc/ghc/html/libraries/base-4.18.2.1/Data-String.html#t:String "Data.String") 71 | 72 |
73 | 74 |
75 | 76 | # Documentation 77 | 78 |
79 | 80 | runP2PRC :: 81 | [MapPortRequest](P2PRC.html#t:MapPortRequest "P2PRC") -\> 82 | [IO]($%7Bpkgroot%7D/../../../../dcnyq1a8qi8x59n5p53d0dx42cl8hf8x-ghc-9.6.5-doc/share/doc/ghc/html/libraries/base-4.18.2.1/System-IO.html#t:IO "System.IO") 83 | () # 84 | 85 |
86 | 87 | Hello World 88 | 89 |
90 | 91 |
92 | 93 |
94 | 95 | data MapPortRequest 97 | # 98 | 99 |
100 | 101 | Constructors 102 | 103 | | | | 104 | |-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|-----| 105 | | MkMapPortRequest [Int]($%7Bpkgroot%7D/../../../../dcnyq1a8qi8x59n5p53d0dx42cl8hf8x-ghc-9.6.5-doc/share/doc/ghc/html/libraries/base-4.18.2.1/Data-Int.html#t:Int "Data.Int") [String]($%7Bpkgroot%7D/../../../../dcnyq1a8qi8x59n5p53d0dx42cl8hf8x-ghc-9.6.5-doc/share/doc/ghc/html/libraries/base-4.18.2.1/Data-String.html#t:String "Data.String") |   | 106 | 107 |
108 | 109 |
110 | 111 |
112 | 113 |
114 | 115 | 120 | -------------------------------------------------------------------------------- /Bindings/Haskell/cabal.project: -------------------------------------------------------------------------------- 1 | 2 | packages: ./p2prc.cabal 3 | 4 | index-state: 2024-11-09T17:56:52Z 5 | -------------------------------------------------------------------------------- /Bindings/Haskell/flake.lock: -------------------------------------------------------------------------------- 1 | { 2 | "nodes": { 3 | "flake-utils": { 4 | "inputs": { 5 | "systems": "systems" 6 | }, 7 | "locked": { 8 | "lastModified": 1731533236, 9 | "narHash": "sha256-l0KFg5HjrsfsO/JpG+r7fRrqm12kzFHyUHqHCVpMMbI=", 10 | "owner": "numtide", 11 | "repo": "flake-utils", 12 | "rev": "11707dc2f618dd54ca8739b309ec4fc024de578b", 13 | "type": "github" 14 | }, 15 | "original": { 16 | "owner": "numtide", 17 | "repo": "flake-utils", 18 | "type": "github" 19 | } 20 | }, 21 | "flake-utils_2": { 22 | "inputs": { 23 | "systems": "systems_2" 24 | }, 25 | "locked": { 26 | "lastModified": 1731533236, 27 | "narHash": "sha256-l0KFg5HjrsfsO/JpG+r7fRrqm12kzFHyUHqHCVpMMbI=", 28 | "owner": "numtide", 29 | "repo": "flake-utils", 30 | "rev": "11707dc2f618dd54ca8739b309ec4fc024de578b", 31 | "type": "github" 32 | }, 33 | "original": { 34 | "owner": "numtide", 35 | "repo": "flake-utils", 36 | "type": "github" 37 | } 38 | }, 39 | "gomod2nix": { 40 | "inputs": { 41 | "flake-utils": [ 42 | "p2prc-main", 43 | "flake-utils" 44 | ], 45 | "nixpkgs": [ 46 | "p2prc-main", 47 | "nixpkgs" 48 | ] 49 | }, 50 | "locked": { 51 | "lastModified": 1745875161, 52 | "narHash": "sha256-0YkWCS13jpoo3+sX/3kcgdxBNt1VZTmvF+FhZb4rFKI=", 53 | "owner": "nix-community", 54 | "repo": "gomod2nix", 55 | "rev": "2cbd7fdd6eeab65c494cc426e18f4e4d2a5e35c0", 56 | "type": "github" 57 | }, 58 | "original": { 59 | "owner": "nix-community", 60 | "repo": "gomod2nix", 61 | "type": "github" 62 | } 63 | }, 64 | "nixpkgs": { 65 | "locked": { 66 | "lastModified": 0, 67 | "narHash": "sha256-m/lh6hYMIWDYHCAsn81CDAiXoT3gmxXI9J987W5tZrE=", 68 | "path": "/nix/store/wj2qla569hnxwqfc26imv5hqbxc1rc27-source", 69 | "type": "path" 70 | }, 71 | "original": { 72 | "id": "nixpkgs", 73 | "type": "indirect" 74 | } 75 | }, 76 | "nixpkgs_2": { 77 | "locked": { 78 | "lastModified": 1748026106, 79 | "narHash": "sha256-6m1Y3/4pVw1RWTsrkAK2VMYSzG4MMIj7sqUy7o8th1o=", 80 | "owner": "NixOS", 81 | "repo": "nixpkgs", 82 | "rev": "063f43f2dbdef86376cc29ad646c45c46e93234c", 83 | "type": "github" 84 | }, 85 | "original": { 86 | "owner": "NixOS", 87 | "ref": "nixos-unstable", 88 | "repo": "nixpkgs", 89 | "type": "github" 90 | } 91 | }, 92 | "p2prc-main": { 93 | "inputs": { 94 | "flake-utils": "flake-utils_2", 95 | "gomod2nix": "gomod2nix", 96 | "nixpkgs": "nixpkgs_2" 97 | }, 98 | "locked": { 99 | "lastModified": 0, 100 | "narHash": "sha256-5qbaxawuLsg8iu9076zlAbLtTFSNJaTz7WERS5rWRxU=", 101 | "path": "/nix/store/lg694r23fzc6v5ai3qqcszq1fp44djg2-source", 102 | "type": "path" 103 | }, 104 | "original": { 105 | "path": "/nix/store/lg694r23fzc6v5ai3qqcszq1fp44djg2-source", 106 | "type": "path" 107 | } 108 | }, 109 | "root": { 110 | "inputs": { 111 | "flake-utils": "flake-utils", 112 | "nixpkgs": "nixpkgs", 113 | "p2prc-main": "p2prc-main" 114 | } 115 | }, 116 | "systems": { 117 | "locked": { 118 | "lastModified": 1681028828, 119 | "narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=", 120 | "owner": "nix-systems", 121 | "repo": "default", 122 | "rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e", 123 | "type": "github" 124 | }, 125 | "original": { 126 | "owner": "nix-systems", 127 | "repo": "default", 128 | "type": "github" 129 | } 130 | }, 131 | "systems_2": { 132 | "locked": { 133 | "lastModified": 1681028828, 134 | "narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=", 135 | "owner": "nix-systems", 136 | "repo": "default", 137 | "rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e", 138 | "type": "github" 139 | }, 140 | "original": { 141 | "owner": "nix-systems", 142 | "repo": "default", 143 | "type": "github" 144 | } 145 | } 146 | }, 147 | "root": "root", 148 | "version": 7 149 | } 150 | -------------------------------------------------------------------------------- /Bindings/Haskell/flake.nix: -------------------------------------------------------------------------------- 1 | { 2 | description = "Nix flake for P2PRC Haskell library"; 3 | inputs = { 4 | flake-utils.url = "github:numtide/flake-utils"; 5 | p2prc-main.url = "../../"; 6 | }; 7 | 8 | outputs = { nixpkgs, flake-utils, p2prc-main, ... }: 9 | flake-utils.lib.eachDefaultSystem (system: 10 | let 11 | pkgs = nixpkgs.legacyPackages.${system}; 12 | in 13 | { 14 | 15 | packages.default = pkgs.haskellPackages.callPackage ./project.nix {}; 16 | 17 | devShell = pkgs.mkShell { 18 | buildInputs = with pkgs; [ 19 | cabal2nix 20 | cabal-install 21 | ghc 22 | zlib.dev 23 | p2prc-main.packages.${system}.default 24 | ]; 25 | }; 26 | } 27 | ); 28 | } 29 | -------------------------------------------------------------------------------- /Bindings/Haskell/lib/CLI.hs: -------------------------------------------------------------------------------- 1 | module CLI where 2 | 3 | import System.Process 4 | ( readProcessWithExitCode 5 | , proc 6 | , createProcess 7 | , terminateProcess 8 | , ProcessHandle 9 | ) 10 | 11 | import System.Exit 12 | ( ExitCode(ExitFailure) 13 | ) 14 | 15 | import Error 16 | ( IOEitherError 17 | , Error(..) 18 | , assignError 19 | ) 20 | 21 | import Data.Aeson 22 | ( FromJSON 23 | , eitherDecode 24 | ) 25 | 26 | import qualified Data.ByteString.Lazy.Char8 as LBC8 27 | 28 | 29 | 30 | data StdInput 31 | = MkEmptyStdInput 32 | | MkStdInputVal String 33 | 34 | 35 | instance Show StdInput where 36 | show MkEmptyStdInput = "" 37 | show (MkStdInputVal v) = v 38 | 39 | 40 | data CLIOpt 41 | = MkEmptyOpts 42 | | MkOptAtomic String 43 | | MkOptTuple (String, String) 44 | 45 | type CLIOptsInput = [String] 46 | type CLICmd = String 47 | 48 | 49 | eitherExecProcessParser :: 50 | FromJSON a => 51 | CLICmd -> [CLIOpt] -> StdInput -> IOEitherError a 52 | eitherExecProcessParser p2prcCmd opts stdInput = 53 | do 54 | val <- eitherExecProcess p2prcCmd opts stdInput 55 | 56 | pure $ case val of 57 | (Right v) -> eitherErrDecode v 58 | (Left e) -> Left e 59 | 60 | 61 | eitherErrDecode :: 62 | FromJSON a => 63 | String -> Either Error a 64 | eitherErrDecode = eitherErrorDecode . eitherDecode . LBC8.pack 65 | 66 | 67 | eitherExecProcess :: CLICmd -> [CLIOpt] -> StdInput -> IOEitherError String 68 | eitherExecProcess cmd opts input = 69 | do 70 | (code, out, err) <- 71 | readProcessWithExitCode 72 | cmd 73 | (optsToCLI opts) 74 | (show input) 75 | 76 | pure $ case code of 77 | ExitFailure i -> Left $ MkCLISystemError i cmd err 78 | _ -> Right out 79 | 80 | optsToCLI :: [CLIOpt] -> CLIOptsInput 81 | optsToCLI = concatMap _optToCLI 82 | where 83 | 84 | _optToCLI :: CLIOpt -> CLIOptsInput 85 | _optToCLI MkEmptyOpts = [] 86 | _optToCLI (MkOptAtomic o) = [o] 87 | _optToCLI (MkOptTuple (o, v)) = [o, v] 88 | 89 | 90 | spawnProcP2PRC :: CLICmd -> [CLIOpt] -> IOEitherError ProcessHandle 91 | spawnProcP2PRC cmd opts = 92 | do 93 | let prc = proc cmd $ optsToCLI opts 94 | 95 | creationResult <- createProcess prc 96 | 97 | let (_, _, _, ph) = creationResult 98 | 99 | case creationResult of 100 | (_, _, Just _, _) -> do 101 | 102 | terminateProcess ph 103 | 104 | pure $ Left $ MkErrorSpawningProcess cmd 105 | 106 | _-> pure $ Right ph 107 | 108 | 109 | eitherErrorDecode :: Either String a -> Either Error a 110 | eitherErrorDecode esa = 111 | case esa of 112 | (Left s) -> Left $ assignError s 113 | (Right v) -> Right v 114 | 115 | 116 | -- assumes the program is ran inside the haskell module in p2prc's repo 117 | -- assumes that last path segment is "haskell" and that p2prc binary's name is "p2p-rendering-computation" 118 | p2prcCmdName :: String 119 | p2prcCmdName = "p2p-rendering-computation" 120 | 121 | -------------------------------------------------------------------------------- /Bindings/Haskell/lib/Engine.hs: -------------------------------------------------------------------------------- 1 | {-# LANGUAGE OverloadedStrings #-} 2 | 3 | module Engine 4 | ( runP2PRC 5 | , fn 6 | ) 7 | where 8 | 9 | 10 | import Control.Concurrent 11 | import Data.Char (toLower) 12 | import System.IO 13 | import Control.Monad (when) 14 | 15 | 16 | import System.Process ( terminateProcess ) 17 | 18 | 19 | import API 20 | ( P2PRCapi(..) 21 | , MapPortRequest(..) 22 | , p2prcAPI, P2PRCommands 23 | ) 24 | 25 | 26 | -- URGENT TASKS 27 | -- 28 | -- 29 | -- TODO: add Haddock documentation 30 | -- 31 | -- TODO: P2PRC setup 32 | -- check version P2PRC: only run if version if above a certain value 33 | -- setup p2prc command 34 | -- check if p2prc command is available in environment first 35 | -- otherwise check folder above 36 | -- 37 | -- TODO: Fix API TODOS 38 | -- 39 | -- TODO: Fix JSON TODOS 40 | -- 41 | -- create DSL to start and orchestrate network 42 | -- 43 | -- TODO: publish haskell library 44 | -- 45 | 46 | {-| 47 | This function starts and bootstraps the P2PRC runtime that associates the a specific host's machine port to a DNS address to expose a certain application to the P2PRC network. You will only need to also import the 'MkMapPortRequest' data constructor to represent the this port request. 48 | 49 | ==== __Example__ 50 | 51 | This example demonstrates how it can be ran on the IO context: 52 | 53 | @ 54 | example :: IO () 55 | example = do 56 | runP2PRC 57 | ( MkMapPortRequest 8080 "jose.akilan.io" 58 | ) 59 | @ 60 | -} 61 | runP2PRC 62 | :: [P2PRCommands] -- ^ TCP Port Request 63 | -> IO () 64 | runP2PRC [] = putStrLn "" 65 | runP2PRC nonEmpty@(_:_) = 66 | let 67 | 68 | -- 69 | -- TODO: add quickcheck testing (quickchecking-dynamic) 70 | -- 71 | -- TODO: Change Standard Library 72 | -- TODO: add GDTA syntax to data types 73 | -- 74 | -- TODO: need monad transformers to refactor the code 75 | -- 76 | -- 77 | -- TODO: parse IO arguments; 78 | -- TODO: create DSL from the standard input 79 | -- 80 | -- TODO: add use case examples (extra-source_files) 81 | -- 82 | -- TODO: setup nix flake package 83 | -- Nix p2prc runtime packaging 84 | -- Perhaps create internal script to run P2PRC from nix flake 85 | -- "nix flake run ..." 86 | -- simplify packaging 87 | -- 88 | -- Extra: 89 | -- 90 | -- TODO: Error 91 | -- assign error: should parse other error 92 | 93 | ( MkP2PRCapi 94 | { startServer = startServer 95 | -- , execInitConfig = execInitConfig 96 | , execListServers = execListServers 97 | , execMapPort = execMapPort 98 | , execAddCustomInformation = _ 99 | } 100 | ) = p2prcAPI 101 | 102 | in do 103 | let 104 | 105 | 106 | -- configValue <- execInitConfig 107 | 108 | -- TODO: get name of host server from config json 109 | 110 | -- print configValue 111 | -- putStrLn "\n\n\n" 112 | 113 | eitherStartProcessHandle <- startServer 114 | 115 | 116 | case eitherStartProcessHandle of 117 | (Right startProcessHandle) -> 118 | do 119 | 120 | let sleepNSecs i = threadDelay (i * 1000000) 121 | 122 | sleepNSecs 5 123 | 124 | outputStr <- execListServers 125 | print outputStr 126 | 127 | -- mapPortOut <- execMapPort $ MkMapPortRequest portNumber domainName 128 | mapPortOut <- execMapPort $ MkMapPortRequest undefined undefined 129 | 130 | case mapPortOut of 131 | (Right v) -> print v 132 | (Left e) -> print e 133 | 134 | 135 | -- TODO: work on looping function 136 | -- 137 | -- Loop (Run replica of haskell program on different $NODES) 138 | -- - Start server 139 | -- - wait 4 seconds 140 | -- - Identify new node running p2prc with SSH external port exposed 141 | -- - SSH into machine 142 | -- - Use simple File transfer to setup files 143 | -- - Run server 144 | -- - Use remote machine p2prc cmd to map a port using --mp 145 | -- - Return back the exposed public IP and port number back to stdout 146 | 147 | exitOnQ $ terminateProcess startProcessHandle 148 | 149 | 150 | (Left err) -> print err 151 | 152 | 153 | where 154 | 155 | exitOnQ :: IO () -> IO () 156 | exitOnQ exitF = do 157 | hSetBuffering stdin NoBuffering 158 | c <- getChar 159 | when (toLower c /= 'q') $ exitOnQ exitF 160 | exitF 161 | 162 | 163 | 164 | fn :: undefined 165 | fn = undefined -------------------------------------------------------------------------------- /Bindings/Haskell/lib/Error.hs: -------------------------------------------------------------------------------- 1 | module Error 2 | ( Error(..) 3 | , IOEitherError 4 | , assignError 5 | ) where 6 | 7 | 8 | {- | 9 | Haskell-side Error value. This type is designed to parse and track System and P2PRC's error signals in a safe and effective manner. 10 | 11 | It does have an 'MkUnknownError' value which is meant to be warn about new kinds of error not yet accounted in this client. Github issues and pull requests are very welcome to improve error handling by parsing more types of errors. 12 | 13 | -} 14 | data Error 15 | = MkCLISystemError -- ^ This is a CLI System Error 16 | Int -- ^ System error code 17 | String -- ^ Command name executed 18 | String -- ^ Error output 19 | | MkErrorSpawningProcess -- ^ Spawing process error 20 | String -- ^ Spawning executable name 21 | | MkUnknownError -- ^ This is an unparsed P2PRC's error 22 | String -- ^ Unparsed error message 23 | deriving Show 24 | 25 | -- | Type synonym for an IO action with either returns an Error or a parsed value 26 | type IOEitherError a = IO ( Either Error a) 27 | 28 | assignError :: String -> Error 29 | assignError = MkUnknownError 30 | -- 31 | -- TODO: add megaparsec to parse Error Messages 32 | -- 33 | -- TODO: add error when internet connection is off 34 | -- 35 | -- Left (MkUnknownError "Unexpected end-of-input, expecting JSON value") 36 | -- MkSystemError 1 "/home/xecarlox/Desktop/p2p-rendering-computation/p2p-rendering-computation" "2024/11/09 21:08:06 Get \"http://0.0.0.0:8088/MAPPort?port=3333&domain_name=\": dial tcp 0.0.0.0:8088: connect: connection refused\n" 37 | -------------------------------------------------------------------------------- /Bindings/Haskell/lib/P2PRC.hs: -------------------------------------------------------------------------------- 1 | {-# OPTIONS_HADDOCK show-extensions #-} 2 | 3 | 4 | {- | 5 | Module : P2PRC 6 | Copyright : Copyright (C) 2024-2024 Jose Fernandes 7 | License : GNU GPL, version 2 or above 8 | Maintainer : Jose Fernandes 9 | Stability : beta 10 | Portability : portable 11 | 12 | This library provides an interface to the P2Prc runtime. 13 | 14 | This Module intends to export the main functions and data type definitions necessary to get started with the P2PRC api. 15 | 16 | A minimal application will require the import of 'runP2PRC' function that accepts a 'MapPortRequest' value that exposes a specific port number and associates it with a domain name in the internet. 17 | 18 | This is a small template to get quickly get started with this interface. We assume the user has already an application listening on the tcp socket "8080". 19 | 20 | > module Main where 21 | > 22 | > import P2PRC 23 | > ( runP2PRC 24 | > , MapPortRequest(MkMapPortRequest) 25 | > ) 26 | > 27 | > main :: IO () 28 | > main = 29 | > runP2PRC 30 | > ( MkMapPortRequest 8080 "jose.akilan.io" 31 | > ) 32 | 33 | -} 34 | 35 | 36 | module P2PRC 37 | ( 38 | -- * Functions 39 | {- | These are the available functions available to interact with the P2Prc environment, at a lower level of abstraction. 40 | It is intended this way to give freedom to the developer to implement their own orchestration strategies. 41 | -} 42 | runP2PRC 43 | , p2prcAPI 44 | 45 | -- * Data Types 46 | {- | This section describes and explains the library's type system, more specifically, the interfaces and primitive types. 47 | -} 48 | 49 | -- ** Interface data types 50 | -- | This section gives an overview on the runtime and host machine interfaces. 51 | , P2PRCapi(..) 52 | , P2PRCConfig(..) 53 | , MapPortRequest(..) 54 | , MapPortResponse(..) 55 | , P2PRCommands(..) 56 | 57 | -- ** Primitive data types 58 | -- | These types represent the core data that is communicated between requests and the runtime. 59 | , IPAddressTable(..) 60 | , ServerInfo(..) 61 | , IPAddress(..) 62 | , Error(..) 63 | 64 | -- ** Type Synonyms 65 | -- | This section is reserved to some useful type synonyms that add significant ergonomics. 66 | , IOEitherError 67 | ) 68 | where 69 | 70 | 71 | import Engine 72 | ( runP2PRC 73 | ) 74 | 75 | import JSON 76 | ( IPAddressTable(..) 77 | , ServerInfo(..) 78 | , IPAddress(..) 79 | , MapPortResponse(..) 80 | , P2PRCConfig(..) 81 | ) 82 | 83 | import API 84 | ( MapPortRequest(..) 85 | , P2PRCapi(..) 86 | , p2prcAPI 87 | , P2PRCommands(..) 88 | ) 89 | 90 | 91 | import Error 92 | ( Error(..) 93 | , IOEitherError 94 | ) 95 | 96 | 97 | -------------------------------------------------------------------------------- /Bindings/Haskell/p2prc.cabal: -------------------------------------------------------------------------------- 1 | cabal-version: 3.0 2 | 3 | name: p2prc 4 | 5 | -- See the Haskell package versioning policy (PVP) for standards 6 | -- guiding when and how versions should be incremented. 7 | -- https://pvp.haskell.org 8 | -- PVP summary: +-+------- breaking API changes 9 | -- | | +----- non-breaking API additions 10 | -- | | | +--- code changes with no API change 11 | version: 0.1.0.0 12 | 13 | synopsis: P2PRC haskell library 14 | 15 | description: Implements a client interface to the P2PRC networking runtime 16 | 17 | author: xecarlox94 18 | 19 | maintainer: jf94.uk@gmail.com 20 | 21 | category: Network 22 | build-type: Simple 23 | 24 | extra-doc-files: README.md 25 | 26 | 27 | common warnings 28 | ghc-options: -Wall 29 | 30 | executable p2prc 31 | 32 | import: warnings 33 | 34 | hs-source-dirs: src 35 | 36 | main-is: Main.hs 37 | 38 | other-extensions: OverloadedStrings 39 | 40 | build-depends: base 41 | , p2prc 42 | 43 | default-language: GHC2021 44 | 45 | library 46 | 47 | import: warnings 48 | 49 | build-depends: base 50 | , text 51 | , aeson 52 | , process 53 | , bytestring 54 | , directory 55 | 56 | hs-source-dirs: lib 57 | 58 | exposed-modules: P2PRC 59 | 60 | other-modules: API 61 | , Engine 62 | , CLI 63 | , JSON 64 | , Error 65 | 66 | default-language: GHC2021 67 | -------------------------------------------------------------------------------- /Bindings/Haskell/project.nix: -------------------------------------------------------------------------------- 1 | { mkDerivation, aeson, base, bytestring, directory, lib, process 2 | , text 3 | }: 4 | mkDerivation { 5 | pname = "p2prc"; 6 | version = "0.1.0.0"; 7 | src = ./.; 8 | libraryHaskellDepends = [ 9 | aeson base bytestring directory process text 10 | ]; 11 | description = "P2PRC haskell library"; 12 | license = "unknown"; 13 | } 14 | -------------------------------------------------------------------------------- /Bindings/Haskell/src/Main.hs: -------------------------------------------------------------------------------- 1 | module Main where 2 | 3 | import P2PRC 4 | ( runP2PRC 5 | , MapPortRequest(MkMapPortRequest) 6 | , P2PRCommands(MapPort) 7 | ) 8 | 9 | main :: IO () 10 | main =let 11 | in 12 | runP2PRC 13 | [ 14 | ( MapPort $ MkMapPortRequest 8080 "jose.akilan.io") 15 | ] 16 | 17 | -------------------------------------------------------------------------------- /Bindings/docs.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | # Bindings 4 | 5 | ```go 6 | import "github.com/Akilan1999/p2p-rendering-computation/Bindings" 7 | ``` 8 | 9 | ## Index 10 | 11 | - [func ConvertStructToJSONString\(Struct interface\{\}\) \*C.char](<#ConvertStructToJSONString>) 12 | - [func EscapeFirewall\(HostOutsideNATIP string, HostOutsideNATPort string, internalPort string\) \(output \*C.char\)](<#EscapeFirewall>) 13 | - [func GetSpecs\(IP string\) \(output \*C.char\)](<#GetSpecs>) 14 | - [func Init\(customConfig string\) \(output \*C.char\)](<#Init>) 15 | - [func MapPort\(Port string, DomainName string, ServerAddress string\) \*C.char](<#MapPort>) 16 | - [func RemoveContainer\(IP string, ID string\) \(output \*C.char\)](<#RemoveContainer>) 17 | - [func Server\(\) \(output \*C.char\)](<#Server>) 18 | - [func StartContainer\(IP string\) \(output \*C.char\)](<#StartContainer>) 19 | - [func UpdateIPTable\(\) \(output \*C.char\)](<#UpdateIPTable>) 20 | - [func ViewIPTable\(\) \(output \*C.char\)](<#ViewIPTable>) 21 | 22 | 23 | 24 | ## func [ConvertStructToJSONString]() 25 | 26 | ```go 27 | func ConvertStructToJSONString(Struct interface{}) *C.char 28 | ``` 29 | 30 | 31 | 32 | 33 | ## func [EscapeFirewall]() 34 | 35 | ```go 36 | func EscapeFirewall(HostOutsideNATIP string, HostOutsideNATPort string, internalPort string) (output *C.char) 37 | ``` 38 | 39 | 40 | 41 | 42 | ## func [GetSpecs]() 43 | 44 | ```go 45 | func GetSpecs(IP string) (output *C.char) 46 | ``` 47 | 48 | 49 | 50 | 51 | ## func [Init]() 52 | 53 | ```go 54 | func Init(customConfig string) (output *C.char) 55 | ``` 56 | 57 | 58 | 59 | 60 | ## func [MapPort]() 61 | 62 | ```go 63 | func MapPort(Port string, DomainName string, ServerAddress string) *C.char 64 | ``` 65 | 66 | 67 | 68 | 69 | ## func [RemoveContainer]() 70 | 71 | ```go 72 | func RemoveContainer(IP string, ID string) (output *C.char) 73 | ``` 74 | 75 | 76 | 77 | 78 | ## func [Server]() 79 | 80 | ```go 81 | func Server() (output *C.char) 82 | ``` 83 | 84 | 85 | 86 | 87 | ## func [StartContainer]() 88 | 89 | ```go 90 | func StartContainer(IP string) (output *C.char) 91 | ``` 92 | 93 | 94 | 95 | 96 | ## func [UpdateIPTable]() 97 | 98 | ```go 99 | func UpdateIPTable() (output *C.char) 100 | ``` 101 | 102 | 103 | 104 | 105 | ## func [ViewIPTable]() 106 | 107 | ```go 108 | func ViewIPTable() (output *C.char) 109 | ``` 110 | 111 | 112 | 113 | Generated by [gomarkdoc]() 114 | -------------------------------------------------------------------------------- /Bindings/python/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Akilan1999/p2p-rendering-computation/36930be8e480877414fec654169b9b2969168db0/Bindings/python/.DS_Store -------------------------------------------------------------------------------- /Bindings/python/library.py: -------------------------------------------------------------------------------- 1 | import ctypes 2 | from ctypes import Structure, c_char_p, c_int, cdll 3 | from dataclasses import dataclass, astuple 4 | import time 5 | import json 6 | from urllib.parse import urlparse 7 | from typing import List 8 | import subprocess 9 | import uuid 10 | import dacite 11 | import os 12 | import sqlalchemy 13 | import dataclasses 14 | from typing import Union 15 | import schedule 16 | import threading 17 | import requests 18 | 19 | p2prc = ctypes.CDLL("SharedObjects/p2prc.so") 20 | 21 | p2prc.Init("") 22 | 23 | # Start running schedule 24 | schedule.run_pending() 25 | 26 | # # Create Sqlite database to track processes 27 | # engine=sqlalchemy.create_engine(f'sqlite:///homeserver.db') 28 | 29 | # Global variable 30 | # A global variable will be populated on runtime. 31 | # It is read from P2PRC directly or from a local 32 | # database. 33 | 34 | # Node information 35 | # Generated using: https://jsonformatter.org/json-to-python 36 | @dataclass 37 | class Node: 38 | Name: str 39 | MachineUsername: str 40 | IPV4: str 41 | IPV6: str 42 | Latency: int 43 | Download: int 44 | Upload: int 45 | ServerPort: str 46 | BareMetalSSHPort: str 47 | NAT: bool 48 | EscapeImplementation: str 49 | ProxyServer: bool 50 | UnSafeMode: bool 51 | PublicKey: str 52 | CustomInformation: str 53 | 54 | @dataclass 55 | class IPAddress: 56 | ip_address: List[Node] 57 | 58 | 59 | # ---------------------------------------------------------------------------- 60 | # ----------------------------- Helper functions ----------------------------- 61 | # ---------------------------------------------------------------------------- 62 | 63 | def StartServer(): 64 | # Starting P2PRC as a server mode 65 | p2prc.Server() 66 | 67 | # Class to create string to pass as string function 68 | # parameter to shared object file 69 | class go_string(Structure): 70 | _fields_ = [ 71 | ("p", c_char_p), 72 | ("n", c_int)] 73 | 74 | # Ensuring local port can escape NAT and responds 75 | # with the public ip and port no. 76 | # If the domain name is specified then the public IP 77 | # can be used as an A name entry. 78 | def P2PRCMapPort(port="",domainname="",serveraddress=""): 79 | port = go_string(c_char_p(port.encode('utf-8')), len(port)) 80 | domainname = go_string(c_char_p(domainname.encode('utf-8')), len(domainname)) 81 | serveraddress = go_string(c_char_p(serveraddress.encode('utf-8')), len(serveraddress)) 82 | 83 | # Defining the response type of the GoLang function 84 | # function 85 | p2prc.MapPort.restype = c_char_p 86 | # Calling the Go function 87 | address = p2prc.MapPort(port,domainname,serveraddress) 88 | res = str(address).strip("b'") 89 | return res 90 | 91 | # Lists all avaliable nodes in the network 92 | def ListNodes(): 93 | # View IP Table information 94 | p2prc.ViewIPTable.restype = c_char_p 95 | ipTable = p2prc.ViewIPTable() 96 | # View IP Table as 97 | ipTableObject = json.loads((str(ipTable).strip("b'"))) 98 | dat: IPAddress = dacite.from_dict(IPAddress,ipTableObject) 99 | return dat 100 | 101 | # Add a root node to P2RRC and overwrites all other nodes. 102 | # To be only added before the network started and with 103 | # the intention of a fresh protocol. 104 | def AddRootNode(ip="", port="") -> bool: 105 | ip = go_string(c_char_p(ip.encode('utf-8')), len(ip)) 106 | port = go_string(c_char_p(port.encode('utf-8')), len(port)) 107 | 108 | p2prc.AddRootNode.restype = c_char_p 109 | res = p2prc.AddRootNode(ip, port) 110 | if str(res).strip("b'") == "Success": 111 | return True 112 | return False 113 | 114 | 115 | 116 | # python function to pass-through custom 117 | # information to interpret which can be 118 | # interpreted as a DSL. 119 | def AddCustomInformation(message="") -> bool: 120 | message = go_string(c_char_p(message.encode('utf-8')), len(message)) 121 | 122 | p2prc.CustomInformation.restype = c_char_p 123 | status = p2prc.CustomInformation(message) 124 | if str(status).strip("b'") == "Success": 125 | return True 126 | return False 127 | 128 | 129 | 130 | -------------------------------------------------------------------------------- /Bindings/python/requirements.txt: -------------------------------------------------------------------------------- 1 | dacite 2 | schedule 3 | sqlalchemy 4 | requests 5 | -------------------------------------------------------------------------------- /Bindings/python/test.py: -------------------------------------------------------------------------------- 1 | from library import * 2 | 3 | 4 | if __name__ == "__main__": 5 | P2PRCNodes = ListNodes() 6 | # Print nodes in the network 7 | print(P2PRCNodes) 8 | 9 | # Add custom information to the network 10 | if AddCustomInformation("Test"): 11 | print("It worked") 12 | 13 | if AddRootNode("0.0.0.0", "8081"): 14 | print("It worked for adding root node") 15 | -------------------------------------------------------------------------------- /CITATION.cff: -------------------------------------------------------------------------------- 1 | cff-version: 1.0.0 2 | message: "If you use this software, please cite it as below." 3 | authors: 4 | - family-names: Selvacoumar 5 | given-names: Akilan 6 | title: P2PRC 7 | license: "GPL-2.0" 8 | version: 2.0.0 9 | date-released: 2023-06-08 10 | -------------------------------------------------------------------------------- /CNAME: -------------------------------------------------------------------------------- 1 | p2prc.akilan.io -------------------------------------------------------------------------------- /CONTRIBUTE.md: -------------------------------------------------------------------------------- 1 | # Contributing 2 | When contributing to this repository, please first discuss the change you wish to make via issue, email, or any other method with the owners of this repository before making a change. 3 | 4 | Please note we have a code of conduct, please follow it in all your interactions with the project. 5 | 6 | ## Pull Request Process 7 | 8 | 1. Ensure any install or build dependencies are removed before the end of the layer when doing a build. 9 | 2. Update the appropriate docs before stating the changes you did. 10 | 3. You may merge the Pull Request in once you have the approval of CODEOWNER, or if you do not have permission to do that, you may request the second reviewer to merge it for you. 11 | 12 | ## Code of conduct 13 | All projects(including mailing lists) at HWTechClub is required to follow [The Lunduke Code of Conduct](https://lunduke.com/pages/codeofconduct/). 14 | 15 | ### The Lunduke Code of Conduct 16 | 17 | > #### “Be Excellent to Each Other.” 18 | 19 | ##### FAQ 20 | 21 | **Q**: Wait. That's it? 22 | 23 | A: Yup. 24 | 25 | **Q**: But… but… it's only 5 words! 26 | 27 | A: It is? Cool! 28 | 29 | **Q**: Isn't that too short to be a viable Code of Conduct? 30 | 31 | A: Nah. 32 | 33 | **Q**: It's too vague! How would you enforce this?!? 34 | 35 | A: By being excellent to each other. 36 | 37 | **Q**: What if someone violates this Code of Conduct? 38 | 39 | A: I trust you to figure it out. 40 | 41 | **Q**: What if someone talks about politics I disagree with?!?!!? 42 | 43 | A: I know a guy who votes for Papa Smurf in every Presidential election. He's a pretty cool dude. 44 | 45 | **Q**: I'm super angry about something! And a person likes the thing making me angry! What do I do? 46 | 47 | A: I dunno. Try *hugs*? 48 | 49 | **Q**: Are virtual hugs (such as *“hugs”* and animated .GIFs of teddy bears hugging) excellent? 50 | 51 | A: Most excellent. 52 | 53 | **Q**: Huh. Seems so simple! 54 | 55 | A: I know, right? 56 | 57 | **Q**: I like you! 58 | 59 | A: I like you, too! 60 | 61 | *The Lunduke Code of Conduct is free for you to use however you like.* 62 | 63 | 64 | **Source**: [The Lunduke Code of Conduct](https://lunduke.com/pages/codeofconduct/) 65 | -------------------------------------------------------------------------------- /Docs/.gitignore: -------------------------------------------------------------------------------- 1 | # Don't bother tracking a bunch of stuff when building and installing 2 | # Org from the master git repository. 3 | 4 | # ...by ignoring everything created by 'make', 'make doc', `make info' 5 | # `make html_manual', `make release' 6 | 7 | *.aux 8 | *.bak 9 | *.cp 10 | *.cps 11 | *.diff 12 | *.dvi 13 | *.elc 14 | *.fn 15 | *.fns 16 | *.info 17 | *.ky 18 | *.kys 19 | *.log 20 | *.patch 21 | *.pdf 22 | *.pg 23 | *.pgs 24 | *.ps 25 | *.toc 26 | *.tex 27 | *.tp 28 | *.vr 29 | *.vrs 30 | orgcard_letter.tex 31 | orgcard.txt 32 | org 33 | org-loaddefs.el 34 | org-version.el 35 | doc/org-version.inc 36 | org-*.tar* 37 | orgplus-*.tar* 38 | org-*.zip 39 | version.mk 40 | manual 41 | org_dual_license.texi 42 | ORGWEBPAGE/Changes.txt 43 | local*.mk 44 | .gitattributes 45 | mk/x11idle 46 | 47 | # texi2pdf --tidy 48 | 49 | doc/*.t2d 50 | 51 | # aspell word and replacement lists 52 | .aspell.org.pws 53 | .aspell.org.prepl 54 | 55 | # allow tmp and test directories that will not be tracked 56 | 57 | test 58 | t 59 | auto 60 | tmp 61 | TODO 62 | 63 | # and collateral damage from Emacs 64 | 65 | *~ 66 | .DS_Store 67 | *# 68 | .#* 69 | 70 | # 71 | # Local variables: 72 | # End: 73 | -------------------------------------------------------------------------------- /Docs/Colored-On-Light-Image.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Akilan1999/p2p-rendering-computation/36930be8e480877414fec654169b9b2969168db0/Docs/Colored-On-Light-Image.png -------------------------------------------------------------------------------- /Docs/DocsDeprecated/Abstractions.md: -------------------------------------------------------------------------------- 1 | # Abstractions 2 | 3 | | [◀ Previous](Installation.md) | [Next ▶](Implementation.md) | 4 | |:-----------:|---------| 5 | 6 | The Abstractions package consists of black-boxed functions for P2PRC. 7 | 8 | ## Functions 9 | - ```Init()```: Initializes P2PRC with all the needed configurations. 10 | - ```Start()```: Starts p2prc as a server and makes it possible to extend by adding other routes and functionality to P2PRC. 11 | - ```MapPort()```: On the local machine the port you want to export to world. 12 | - ```StartContainer()```: The machine on the p2p network where you want to spin up a docker container. 13 | - ```RemoveContainer(,)```: Terminate container based on the IP address and container name. 14 | - ```GetSpecs()```: Get specs of a machine on the network based on the IP address. 15 | - ```ViewIPTable()```: View the IP table which about nodes in the network. 16 | - ```UpdateIPTable()```: Force update IP table to learn about new nodes faster. 17 | 18 | --- 19 | 20 | ### Next Chapter: [Implementation](Implementation.md) -------------------------------------------------------------------------------- /Docs/DocsDeprecated/Abstractions.org: -------------------------------------------------------------------------------- 1 | * Abstractions 2 | :PROPERTIES: 3 | :CUSTOM_ID: abstractions 4 | :END: 5 | | [[file:Installation.md][◀ Previous]] | [[file:Implementation.md][Next ▶]] | 6 | |--------------------------------------+------------------------------------| 7 | 8 | The Abstractions package consists of black-boxed functions for P2PRC. 9 | 10 | ** Functions 11 | :PROPERTIES: 12 | :CUSTOM_ID: functions 13 | :END: 14 | - =Init()=: Initializes P2PRC with all the needed 15 | configurations. 16 | - =Start()=: Starts p2prc as a server and makes it possible to extend by 17 | adding other routes and functionality to P2PRC. 18 | - =MapPort()=: On the local machine the port you want to export 19 | to world. 20 | - =StartContainer()=: The machine on the p2p network where 21 | you want to spin up a docker container. 22 | - =RemoveContainer(,)=: Terminate container 23 | based on the IP address and container name. 24 | - =GetSpecs()=: Get specs of a machine on the network based 25 | on the IP address. 26 | - =ViewIPTable()=: View the IP table which about nodes in the network. 27 | - =UpdateIPTable()=: Force update IP table to learn about new nodes 28 | faster. 29 | 30 | -------------- 31 | 32 | *** Next Chapter: [[file:Implementation.org][Implementation]] 33 | :PROPERTIES: 34 | :CUSTOM_ID: next-chapter-implementation 35 | :END: 36 | -------------------------------------------------------------------------------- /Docs/DocsDeprecated/Bindings.md: -------------------------------------------------------------------------------- 1 | # Language Bindings 2 | [Language bindings](https://en.wikipedia.org/wiki/Language_binding) refers to wrappers to bridge 2 programming languages. This is used in P2PRC to extend calling P2PRC functions in other programming languages. Currently this is done by generating ```.so``` and ```.h``` from the Go compiler. 3 | 4 |
5 | 6 | ## How to build shared object files 7 | #### The easier way 8 | ```bash 9 | # Run 10 | make sharedObjects 11 | ``` 12 | #### Or the direct way 13 | ```bash 14 | # Run 15 | cd Bindings && go build -buildmode=c-shared -o p2prc.so 16 | ``` 17 | #### If successfully built: 18 | ```bash 19 | # Enter into the Bindings directory 20 | cd Bindings 21 | # List files 22 | ls 23 | # Find files 24 | p2prc.h p2prc.so 25 | ``` 26 |
27 | 28 | ## Workings under the hood 29 | Below are a sample set of commands to 30 | open the bindings implementation. 31 | ``` 32 | # run 33 | cd Bindings/ 34 | # list files 35 | ls 36 | # search for file 37 | Client.go 38 | ``` 39 | ### In Client go 40 | There a few things to notice which are different from 41 | your standard Go programs: 42 | 43 | #### 1. We import "C" which means [Cgo](https://pkg.go.dev/cmd/cgo) is required. 44 | ```go 45 | import "C" 46 | ``` 47 | #### 2. All functions which are required to be called from other programming languages have comment such as. 48 | ```go 49 | //export 50 | 51 | // ------------ Example ---------------- 52 | // The function below allows to externally 53 | // to call the P2PRC function to start containers 54 | // in a specific node in the know list of nodes 55 | // in the p2p network. 56 | // Note: the comment "//export StartContainer". 57 | 58 | //export StartContainer 59 | func StartContainer(IP string) (output *C.char) { 60 | container, err := client.StartContainer(IP, 0, false, "", "") 61 | if err != nil { 62 | return C.CString(err.Error()) 63 | } 64 | return ConvertStructToJSONString(container) 65 | } 66 | ``` 67 | #### 3. While looking through the file (If 2 files are compared it is pretty trivial to notice a common structure). 68 | ```go 69 | // --------- Example ------------ 70 | 71 | //export StartContainer 72 | func StartContainer(IP string) (output *C.char) { 73 | container, err := client.StartContainer(IP, 0, false, "", "") 74 | if err != nil { 75 | return C.CString(err.Error()) 76 | } 77 | return ConvertStructToJSONString(container) 78 | } 79 | 80 | //export ViewPlugin 81 | func ViewPlugin() (output *C.char) { 82 | plugins, err := plugin.DetectPlugins() 83 | if err != nil { 84 | return C.CString(err.Error()) 85 | } 86 | return ConvertStructToJSONString(plugins) 87 | } 88 | 89 | ``` 90 | #### It is easy to notice that: 91 | - ```ConvertStructToJSONString()```: This is a helper function that convert 92 | a go object to JSON string initially and converts it to ```CString```. 93 | - ```(output *C.char)```: This is the return type for most of the functions. 94 | 95 | #### A Pseudo code to refer to the common function implementation shape could be represented as: 96 | ``` 97 | func (output *C.char) { 98 | , := () 99 | if != nil { 100 | return C.CString(.Error()) 101 | } 102 | return ConvertStructToJSONString() 103 | } 104 | ``` 105 | 106 | 107 |
108 | 109 | 110 | ## Current languages supported 111 | - Python 112 | 113 | ### Build sample python program 114 | The easier way 115 | ```bash 116 | # Run 117 | make python 118 | # Expected ouput 119 | Output is in the Directory Bindings/python/export/ 120 | # Run 121 | cd Bindings/python/export/ 122 | # list files 123 | ls 124 | # Expected output 125 | SharedObjects/ p2prc.py 126 | ``` 127 | Above shows a generated folder which consists of a folder 128 | called "SharedObjects/" which consists of ```p2prc.so``` 129 | and ```p2prc.h``` files. ```p2prc.py``` refers to a 130 | sample python script calling P2PRC go functions. 131 | To start an any project to extend P2PRC with python, 132 | This generated folder can copied and created as a new 133 | git repo for P2PRC extensions scripted or used a reference 134 | point as proof of concept that P2PRC can be called from 135 | other programming languages. 136 | 137 | 138 | 139 | 140 | -------------------------------------------------------------------------------- /Docs/DocsDeprecated/CliImplementation.md: -------------------------------------------------------------------------------- 1 | # Cli module 2 | 3 | The Cli (i.e Command Line Interface) is the only one in which the user can directly interact with the 4 | modules in the project. The objective when building the Cli was to have the least amount of 5 | commands as possible. The cli was built using the library called urfave cli v2 . They were 2 6 | major files created named as flags.go and actions.go. 7 | ### Flags.go 8 | The flags .go file is responsible to create the appropriate flags for the cli. There are 2 types of flags 9 | called boolean and string. Each of the flags outputs are assigned to a 10 | variable to be handled. The flags can also detect environment variables set. This feature is useful 11 | because if the user wants to call certain flags in a repeated sequence it only has to be initialized 12 | once. 13 | 14 | ### Actions.go 15 | The actions.go file is implemented to call the appropriate functions when the flags are called. It 16 | interacts directly with the modules in the project. Action.go checks if variables 17 | are not empty string or the boolean value is true. 18 | -------------------------------------------------------------------------------- /Docs/DocsDeprecated/CliImplementation.org: -------------------------------------------------------------------------------- 1 | * Cli module 2 | :PROPERTIES: 3 | :CUSTOM_ID: cli-module 4 | :END: 5 | The Cli (i.e Command Line Interface) is the only one in which the user 6 | can directly interact with the modules in the project. The objective 7 | when building the Cli was to have the least amount of commands as 8 | possible. The cli was built using the library called urfave cli v2 . 9 | They were 2 major files created named as flags.go and actions.go. ### 10 | Flags.go The flags .go file is responsible to create the appropriate 11 | flags for the cli. There are 2 types of flags called boolean and string. 12 | Each of the flags outputs are assigned to a variable to be handled. The 13 | flags can also detect environment variables set. This feature is useful 14 | because if the user wants to call certain flags in a repeated sequence 15 | it only has to be initialized once. 16 | 17 | *** Actions.go 18 | :PROPERTIES: 19 | :CUSTOM_ID: actions.go 20 | :END: 21 | The actions.go file is implemented to call the appropriate functions 22 | when the flags are called. It interacts directly with the modules in the 23 | project. Action.go checks if variables are not empty string or the 24 | boolean value is true. 25 | -------------------------------------------------------------------------------- /Docs/DocsDeprecated/Client.md: -------------------------------------------------------------------------------- 1 | # Client Module 2 | This module is incharge of communicating with the server and receiving the appropriate information back from the server. 3 | 4 | ## Functions of the Client Module 5 | 6 | - [Decision maker on how the ip table is created or updated](#decision-maker-on-how-the-ip-table-is-created-or-updated) 7 | 8 | ## Decision maker on how the IP table is created or updated 9 | - Does a local speedtest to verify and see if the server IP's in the IP table 10 | are pingable. 11 | - Tries to ping the servers IP Table addresses. 12 | - If it's pingable then it's added as a new entry in the IP table. 13 | - The following steps occurs in the clients IP table. 14 | - To ensure that the same servers are not being called to update the IP table. There is 15 | a temporary list of IP address which have already been called in relation to updating the 16 | IP table. 17 | - Based on the current implementation there will 3 hops done to update the IP table. 18 | -------------------------------------------------------------------------------- /Docs/DocsDeprecated/Client.org: -------------------------------------------------------------------------------- 1 | * Client Module 2 | :PROPERTIES: 3 | :CUSTOM_ID: client-module 4 | :END: 5 | This module is incharge of communicating with the server and receiving 6 | the appropriate information back from the server. 7 | 8 | ** Functions of the Client Module 9 | :PROPERTIES: 10 | :CUSTOM_ID: functions-of-the-client-module 11 | :END: 12 | 13 | #+begin_html 14 | 15 | #+end_html 16 | 17 | - [[#decision-maker-on-how-the-ip-table-is-created-or-updated][Decision 18 | maker on how the ip table is created or updated]] 19 | 20 | ** Decision maker on how the IP table is created or updated 21 | :PROPERTIES: 22 | :CUSTOM_ID: decision-maker-on-how-the-ip-table-is-created-or-updated 23 | :END: 24 | - Does a local speedtest to verify and see if the server IP's in the IP 25 | table are pingable. 26 | - Tries to ping the servers IP Table addresses. 27 | - If it's pingable then it's added as a new entry in the IP table. 28 | - The following steps occurs in the clients IP table. 29 | - To ensure that the same servers are not being called to update the IP 30 | table. There is a temporary list of IP address which have already been 31 | called in relation to updating the IP table. 32 | - Based on the current implementation there will 3 hops done to update 33 | the IP table. 34 | -------------------------------------------------------------------------------- /Docs/DocsDeprecated/ClientArchitecture.md: -------------------------------------------------------------------------------- 1 | # Client Module Architecture 2 | 3 | The Client Module interacts with the P2P module and Server Module. It is responsible for 4 | interacting with the server module and appropriately updating the IP table on the client side. It 5 | connects to the server using the server's REST Apis. It is also the primary decision maker on how 6 | the IP table is updated is on the client side. This is because each user can have requirements like 7 | how many number of hops they would want to do to update their IP table. Hops is the number of 8 | times the client is going to download the IP table from different servers ,once it gets the IP tables 9 | from the previous servers. 10 | 11 | ![Visual demonstration of hops](images/NumOfHops.png) 12 | ![UML diagram of client module](images/clientmoduleArch.png) -------------------------------------------------------------------------------- /Docs/DocsDeprecated/ClientArchitecture.org: -------------------------------------------------------------------------------- 1 | * Client Module Architecture 2 | :PROPERTIES: 3 | :CUSTOM_ID: client-module-architecture 4 | :END: 5 | The Client Module interacts with the P2P module and Server Module. It is 6 | responsible for interacting with the server module and appropriately 7 | updating the IP table on the client side. It connects to the server 8 | using the server's REST Apis. It is also the primary decision maker on 9 | how the IP table is updated is on the client side. This is because each 10 | user can have requirements like how many number of hops they would want 11 | to do to update their IP table. Hops is the number of times the client 12 | is going to download the IP table from different servers ,once it gets 13 | the IP tables from the previous servers. 14 | 15 | [[file:images/NumOfHops.png]] [[file:images/clientmoduleArch.png]] 16 | -------------------------------------------------------------------------------- /Docs/DocsDeprecated/ConfigImplementation.md: -------------------------------------------------------------------------------- 1 | # Config Implementation 2 | 3 | The configuration module is responsible to store basic information of absolute paths of files being 4 | called in the Go code. In a full-fledged Cli the configuration file can be found in the directory 5 | /etc/ and from there points to location such as where the IP table file is located. In 6 | the future implementation the config file will have information such as number of hops and other 7 | parameters to tweak and to improve the effectiveness of the peer to peer network. The 8 | configuration module was implemented using the library Viper. The Viper library automates 9 | features such as searching in default paths to find out if the configuration file is present. If the 10 | configuration file is not present in the default paths then it auto generates the configuration file. 11 | The configurations file can be in any format. In this project the configuration file was generated using 12 | JSON format. 13 | 14 | ```json 15 | { 16 | "MachineName": "pc-74-120.customer.ask4.lan", 17 | "IPTable": "/Users/akilan/Documents/p2p-rendering-computation/p2p/iptable/ip_table.json", 18 | "DockerContainers": "/Users/akilan/Documents/p2p-rendering-computation/server/docker/containers/", 19 | "DefaultDockerFile": "/Users/akilan/Documents/p2p-rendering-computation/server/docker/containers/docker-ubuntu-sshd/", 20 | "SpeedTestFile": "/Users/akilan/Documents/p2p-rendering-computation/p2p/50.bin", 21 | "IPV6Address": "", 22 | "PluginPath": "/Users/akilan/Documents/p2p-rendering-computation/plugin/deploy", 23 | "TrackContainersPath": "/Users/akilan/Documents/p2p-rendering-computation/client/trackcontainers/trackcontainers.json", 24 | "ServerPort": "8088", 25 | "GroupTrackContainersPath": "/Users/akilan/Documents/p2p-rendering-computation/client/trackcontainers/grouptrackcontainers.json", 26 | "FRPServerPort": "True", 27 | "BehindNAT": "True", 28 | "CustomConfig": null 29 | } 30 | ``` 31 | 32 | -------------------------------------------------------------------------------- /Docs/DocsDeprecated/ConfigImplementation.org: -------------------------------------------------------------------------------- 1 | * Config Implementation 2 | :PROPERTIES: 3 | :CUSTOM_ID: config-implementation 4 | :END: 5 | The configuration module is responsible to store basic information of 6 | absolute paths of files being called in the Go code. In a full-fledged 7 | Cli the configuration file can be found in the directory /etc/ and from 8 | there points to location such as where the IP table file is located. In 9 | the future implementation the config file will have information such as 10 | number of hops and other parameters to tweak and to improve the 11 | effectiveness of the peer to peer network. The configuration module was 12 | implemented using the library Viper. The Viper library automates 13 | features such as searching in default paths to find out if the 14 | configuration file is present. If the configuration file is not present 15 | in the default paths then it auto generates the configuration file. The 16 | configurations file can be in any format. In this project the 17 | configuration file was generated using JSON format. 18 | 19 | #+begin_src json 20 | { 21 | "MachineName": "pc-74-120.customer.ask4.lan", 22 | "IPTable": "/Users/akilan/Documents/p2p-rendering-computation/p2p/iptable/ip_table.json", 23 | "DockerContainers": "/Users/akilan/Documents/p2p-rendering-computation/server/docker/containers/", 24 | "DefaultDockerFile": "/Users/akilan/Documents/p2p-rendering-computation/server/docker/containers/docker-ubuntu-sshd/", 25 | "SpeedTestFile": "/Users/akilan/Documents/p2p-rendering-computation/p2p/50.bin", 26 | "IPV6Address": "", 27 | "PluginPath": "/Users/akilan/Documents/p2p-rendering-computation/plugin/deploy", 28 | "TrackContainersPath": "/Users/akilan/Documents/p2p-rendering-computation/client/trackcontainers/trackcontainers.json", 29 | "ServerPort": "8088", 30 | "GroupTrackContainersPath": "/Users/akilan/Documents/p2p-rendering-computation/client/trackcontainers/grouptrackcontainers.json", 31 | "FRPServerPort": "True", 32 | "BehindNAT": "True", 33 | "CustomConfig": null 34 | } 35 | #+end_src 36 | -------------------------------------------------------------------------------- /Docs/DocsDeprecated/DesignArchtectureIntro.md: -------------------------------------------------------------------------------- 1 | # Design Architecture 2 | 3 | This chapter focuses on architecture of the dissertation. The objective would be to have a good 4 | understanding on the purpose of each module and how they interact with each other. The design 5 | architecture was inspired and based on the linux kernel design. The project is segmented into 6 | various modules. Each module is responsible for certain tasks in the project. The modules are 7 | highly dependent on each other hence the entire codebase can be considered as a huge monolithic 8 | chuck which acts as its own library. The following sub topics below talk about the main modules 9 | and how they function with appropriate diagrams. 10 | 11 | ### 1. [Client Module](ClientArchitecture.md) 12 | ### 2. [P2P Module](P2PArchitecture.md) 13 | ### 3. [Server Module](ServerArchitecture.md) 14 | 15 | -------------------------------------------------------------------------------- /Docs/DocsDeprecated/DesignArchtectureIntro.org: -------------------------------------------------------------------------------- 1 | * Design Architecture 2 | :PROPERTIES: 3 | :CUSTOM_ID: design-architecture 4 | :END: 5 | This chapter focuses on architecture of the dissertation. The objective 6 | would be to have a good understanding on the purpose of each module and 7 | how they interact with each other. The design architecture was inspired 8 | and based on the linux kernel design. The project is segmented into 9 | various modules. Each module is responsible for certain tasks in the 10 | project. The modules are highly dependent on each other hence the entire 11 | codebase can be considered as a huge monolithic chuck which acts as its 12 | own library. The following sub topics below talk about the main modules 13 | and how they function with appropriate diagrams. 14 | 15 | *** 1. [[file:ClientArchitecture.md][Client Module]] 16 | :PROPERTIES: 17 | :CUSTOM_ID: client-module 18 | :END: 19 | *** 2. [[file:P2PArchitecture.md][P2P Module]] 20 | :PROPERTIES: 21 | :CUSTOM_ID: p2p-module 22 | :END: 23 | *** 3. [[file:ServerArchitecture.md][Server Module]] 24 | :PROPERTIES: 25 | :CUSTOM_ID: server-module 26 | :END: 27 | -------------------------------------------------------------------------------- /Docs/DocsDeprecated/DomainNameMappingsImplementation.md: -------------------------------------------------------------------------------- 1 | # Domain name mappings 2 | This -------------------------------------------------------------------------------- /Docs/DocsDeprecated/DomainNameMappingsImplementation.org: -------------------------------------------------------------------------------- 1 | * Domain name mappings 2 | :PROPERTIES: 3 | :CUSTOM_ID: domain-name-mappings 4 | :END: 5 | 6 | Todo be written. 7 | -------------------------------------------------------------------------------- /Docs/DocsDeprecated/Implementation.md: -------------------------------------------------------------------------------- 1 | # Implementation 2 | | [◀ Previous](Introduction.md) | [Back to TOC](README.md) | 3 | |:-----------:|---------| 4 | 5 | This chapter describes how the project was built. It talks in depth of the implementation 6 | performed to give a better understanding of the project. 7 | 8 | ## Programming langauge used 9 | The programming language used for this project was [Golang](https://go.dev/). The reason Go lang was chosen was 10 | because it is a compiled language.
11 | The entire codebase is just a single binary file. When 12 | distributing to other linux distributing the only requirement would be the binary file to run the 13 | code. It is easy to write independant modules and be monolithic at the sametime using Go.
14 | Using Go.mod makes it very easy to handle external libraries and modularise code. The go.mod name for 15 | the project is [git.sr.ht/~akilan1999/p2p-rendering-computation](https://git.sr.ht/~akilan1999/p2p-rendering-computation). 16 | 17 | - ## [Cli Module](CliImplementation.md) 18 | - ## [Config Module](ConfigImplementation.md) 19 | - ## [Server Module](ServerImplementation.md) 20 | - ## [Client Module](ClientImplementation.md) 21 | - ## [P2P Module](P2PImplementation.md) 22 | - ## [Plugin Module](PluginImplementation.md) 23 | - ## [Generate Module](GenerateImplementation.md) -------------------------------------------------------------------------------- /Docs/DocsDeprecated/Implementation.org: -------------------------------------------------------------------------------- 1 | * Implementation 2 | :PROPERTIES: 3 | :CUSTOM_ID: implementation 4 | :END 5 | This chapter describes how the project was built. It talks in depth of 6 | the implementation performed to give a better understanding of the 7 | project. 8 | 9 | ** Programming language used 10 | :PROPERTIES: 11 | :CUSTOM_ID: programming-langauge-used 12 | :END: 13 | The programming language used for this project was 14 | [[https://go.dev/][Golang]]. The reason Go lang was chosen was because 15 | it is a compiled language. The entire codebase is just a single binary 16 | file. When distributing to other linux distributing the only requirement 17 | would be the binary file to run the code. It is easy to write 18 | independant modules and be monolithic at the sametime using Go. Using 19 | Go.mod makes it very easy to handle external libraries and modularise 20 | code. The go.mod name for the project is 21 | [[https://git.sr.ht/~akilan1999/p2p-rendering-computation][git.sr.ht/~akilan1999/p2p-rendering-computation]]. 22 | -------------------------------------------------------------------------------- /Docs/DocsDeprecated/Introduction.md: -------------------------------------------------------------------------------- 1 | # Chapter 1: Introduction 2 | 3 | | [◀ Back to TOC](README.md) | [Next ▶](Installation.md) | 4 | |:-----------:|---------| 5 | 6 | ## Abstract 7 | This project focuses on creating a framework on running heavy tasks that a regular computer 8 | cannot run easily such as graphically demanding video games, rendering 3D animations , protein 9 | folding simulations. In this project the major focus will not be on the financial incentive part. A peer 10 | to peer network will be created to help run tasks decentrally, increasing bandwidth for running 11 | tasks. To ensure the tasks in the peer to peer network do not corrupt the server 0S (Operating 12 | System), they will be executed in a virtual environment in the server. 13 | 14 | The main aim of this project was to create a custom peer to peer network. The user acting as the 15 | client has total flexibility on how to batch the tasks and the user acting as the server has complete 16 | flexibility on tracking the container's usages and killing the containers at any point of time. 17 | 18 | ## Motivation 19 | Many of the users rely on our PC / Laptop or servers that belong to a server farm to run heavy 20 | tasks and with the demand of high creativity requires higher computing power. Buying a powerful 21 | computer every few years to run a bunch of heavy tasks which are not executed as frequently to 22 | reap the benefits can be inefficient utilization of hardware. On the other end, renting servers to 23 | run these heavy tasks can be really useful. Ethically speaking this is leading to monopolisation of 24 | computing power similar to what is happening in the web server area. By using peer to peer 25 | principles it is possible to remove the monopolisation factor and increase the bandwidth between 26 | the client and server. 27 | 40 | 41 | --- 42 | 43 | ### Next Chapter: [Installation](Installation.md) -------------------------------------------------------------------------------- /Docs/DocsDeprecated/Introduction.org: -------------------------------------------------------------------------------- 1 | * Chapter 1: Introduction 2 | :PROPERTIES: 3 | :CUSTOM_ID: chapter-1-introduction 4 | :END: 5 | 6 | ** Abstract 7 | :PROPERTIES: 8 | :CUSTOM_ID: abstract 9 | :END: 10 | This project focuses on creating a framework on running heavy tasks that 11 | a regular computer cannot run easily such as graphically demanding video 12 | games, rendering 3D animations , protein folding simulations. In this 13 | project the major focus will not be on the financial incentive part. A 14 | peer to peer network will be created to help run tasks decentrally, 15 | increasing bandwidth for running tasks. To ensure the tasks in the peer 16 | to peer network do not corrupt the server 0S (Operating System), they 17 | will be executed in a virtual environment in the server. 18 | 19 | The main aim of this project was to create a custom peer to peer 20 | network. The user acting as the client has total flexibility on how to 21 | batch the tasks and the user acting as the server has complete 22 | flexibility on tracking the container's usages and killing the 23 | containers at any point of time. 24 | 25 | ** Motivation 26 | :PROPERTIES: 27 | :CUSTOM_ID: motivation 28 | :END: 29 | Many of the users rely on our PC / Laptop or servers that belong to a 30 | server farm to run heavy tasks and with the demand of high creativity 31 | requires higher computing power. Buying a powerful computer every few 32 | years to run a bunch of heavy tasks which are not executed as frequently 33 | to reap the benefits can be inefficient utilization of hardware. On the 34 | other end, renting servers to run these heavy tasks can be really 35 | useful. Ethically speaking this is leading to monopolisation of 36 | computing power similar to what is happening in the web server area. By 37 | using peer to peer principles it is possible to remove the 38 | monopolisation factor and increase the bandwidth between the client and 39 | server. -------------------------------------------------------------------------------- /Docs/DocsDeprecated/NAT-Traveral.md: -------------------------------------------------------------------------------- 1 | # NAT Traversal 2 | P2PRC currently supports TURN for NAT traversal. 3 | 4 | ## TURN 5 | The current TURN implementation used is FRP. The TURN server is also required when 6 | a P2PRC node is acting as a Server. The TURN server is determined based on the Node 7 | with the least amount of latency based on the Nodes available on the IPTable. 8 | Once a TURN server is determined there are 2 actions performed. The first one is 9 | ```/FRPPort``` to the TURN server to receive a port which is used to generate the external 10 | port from the TURN server. The flow below describes the workflow. 11 | 12 | ### Client mode 13 | - Call ```/FRPPort``` 14 | ``` 15 | http://:/FRPport 16 | ``` 17 | - Call the TURN server in the following manner. The following is a sample code snippet below. 18 | ```go 19 | import ( 20 | "github.com/Akilan1999/p2p-rendering-computation/p2p/frp" 21 | ) 22 | 23 | func main() { 24 | serverPort, err := frp.GetFRPServerPort("http://" + + ":" + lowestLatencyIpAddress.ServerPort) 25 | if err != nil { 26 | return nil, err 27 | } 28 | // Create 1 second delay to allow FRP server to start 29 | time.Sleep(1 * time.Second) 30 | // Starts FRP as a client with 31 | proxyPort, err := frp.StartFRPClientForServer(, serverPort, ) 32 | if err != nil { 33 | return nil, err 34 | } 35 | } 36 | ``` 37 | 38 | -------------------------------------------------------------------------------- /Docs/DocsDeprecated/NAT-Traveral.org: -------------------------------------------------------------------------------- 1 | * NAT Traversal 2 | :PROPERTIES: 3 | :CUSTOM_ID: nat-traversal 4 | :END: 5 | P2PRC currently supports TURN for NAT traversal. 6 | 7 | ** TURN 8 | :PROPERTIES: 9 | :CUSTOM_ID: turn 10 | :END: 11 | The current TURN implementation used is FRP. The TURN server is also 12 | required when a P2PRC node is acting as a Server. The TURN server is 13 | determined based on the Node with the least amount of latency based on 14 | the Nodes available on the IPTable. Once a TURN server is determined 15 | there are 2 actions performed. The first one is =/FRPPort= to the TURN 16 | server to receive a port which is used to generate the external port 17 | from the TURN server. The flow below describes the workflow. 18 | 19 | *** Client mode 20 | :PROPERTIES: 21 | :CUSTOM_ID: client-mode 22 | :END: 23 | - Call =/FRPPort= 24 | 25 | #+begin_example 26 | http://:/FRPport 27 | #+end_example 28 | 29 | - Call the TURN server in the following manner. The following is a 30 | sample code snippet below. 31 | 32 | #+begin_src go 33 | import ( 34 | "github.com/Akilan1999/p2p-rendering-computation/p2p/frp" 35 | ) 36 | 37 | func main() { 38 | serverPort, err := frp.GetFRPServerPort("http://" + + ":" + lowestLatencyIpAddress.ServerPort) 39 | if err != nil { 40 | return nil, err 41 | } 42 | // Create 1 second delay to allow FRP server to start 43 | time.Sleep(1 * time.Second) 44 | // Starts FRP as a client with 45 | proxyPort, err := frp.StartFRPClientForServer(, serverPort, ) 46 | if err != nil { 47 | return nil, err 48 | } 49 | } 50 | #+end_src 51 | -------------------------------------------------------------------------------- /Docs/DocsDeprecated/P2P-testing.md: -------------------------------------------------------------------------------- 1 | # Testing P2P network 2 | 3 | The objective would be to test the p2p network, and the effectiveness of updating 4 | the ip tables. The objective of would be to give the impression to the client and 5 | server of a Zero configuration setting. For testing there will be a 6 | test network set. In the testing scenario all will be client and 7 | server because the IP table does not store clients IP addresses. At current 8 | number of hopes would be 3 as default. 9 | 10 | ### Test Network Scenario 1 11 | The test network consists of 5 nodes acting as a client and server. 12 | The objective would be to have the entire IP table Updated in each node 13 | with interacting with only 1 node once. Each node has knowledge of 14 | one node only. 15 | 16 | ![p2pscenario1](https://user-images.githubusercontent.com/31743758/115069627-e4aa8c80-9f04-11eb-8402-706a3407f0e8.png) 17 | Fig 1.0 Visual Representation of testnet scenario 1 18 | 19 | #### Result 20 | All nodes except node 1 where able to have information of IP addresses in the test net. This was due to the reason of 3 hops 21 | set as default. Node 1 had in it's IP table IP addresses of Node 2, Node 3, Node 4. Once the number of hops was set to 4 objective 22 | of the test was acheived. 23 | 24 | 25 | ### Test Network Scenario 2 26 | The second test network has a scenario of a single peer which all the 27 | other nodes connect too. The scenario being when the other nodes 28 | connect to the single server they download information about nodes 29 | that have connected to the server node before. 30 | 31 | ### Testing Broadcast Module 32 | For testing the broadcast module 2 types of servers will be 33 | tested. One with a CPU only , another one with a CPU and GPU. 34 | The expected result being that the appropriate results are 35 | visible. 36 | 37 | #### Results (CPU and GPU): 38 | ``` 39 | { 40 | "Hostname": "akilan-Lenovo-IdeaPad-Y510P", 41 | "Platform": "ubuntu", 42 | "CPU": "Intel(R) Core(TM) i7-4700MQ CPU @ 2.40GHz", 43 | "RAM": 7872, 44 | "Disk": 937367, 45 | "GPU": { 46 | "DriveVersion": "390.141", 47 | "Gpu": { 48 | "GpuName": "GeForce GT 755M", 49 | "BiosVersion": "80.07.A8.00.0F", 50 | "FanSpeed": "N/A", 51 | "Utilization": { 52 | "GpuUsage": "N/A", 53 | "MemoryUsage": "N/A" 54 | }, 55 | "Temperature": { 56 | "GpuTemp": "66 C" 57 | }, 58 | "Clock": { 59 | "GpuClock": "N/A", 60 | "GpuMemClock": "N/A" 61 | } 62 | } 63 | } 64 | } 65 | ``` 66 | At the moment of the current implementation v1.0. Nvidia GPU 67 | are only compatible. As the Go code calls the command ``nvidia-smi`` 68 | to get information about the GPU available. 69 | 70 | #### Results (CPU only) 71 | ``` 72 | { 73 | "Hostname": "sv-t1.small.x86-01", 74 | "Platform": "ubuntu", 75 | "CPU": "Intel(R) Atom(TM) CPU C2750 @ 2.40GHz", 76 | "RAM": 7944, 77 | "Disk": 138793, 78 | "GPU": null 79 | } 80 | ``` 81 | As the ``nvidia-smi`` interface was not detected it only broadcasts 82 | the CPU specs available. 83 | 84 | ### SpeedTests 85 | The speed test has 3 parameters which are Ping , upload and download. The tests check if 86 | the results returned are approximately correct. The ping at the moment returns the correct 87 | result. The upload and download returned are inccorect at the moment, This is due incorrect 88 | implementation in for timer and will be patched in future versions. 89 | 90 | ### Unit tests 91 | All functions implemented on the P2P module returns type error. 92 | The units test call certain functions and check if the functions 93 | return an error or not. This proved sufficient as the point of 94 | the units tests was code coverage to check if certain functions 95 | return an error. 96 | 97 | #### Functions tested 98 | This sections talks about the function called and represents 99 | code coverage. 100 | 101 | 1. ``TestServer_SpeedTest``: Function called LocalSpeedTestIpTable() 102 | 2. ``TestReadIpTable``: Function called ReadIpTable() 103 | 104 | The P2P module has a 100% code coverage in unit tests as both the unit 105 | tests call directly or call within the function all the functions used 106 | in the P2P module. 107 | 108 | -------------------------------------------------------------------------------- /Docs/DocsDeprecated/P2P-testing.org: -------------------------------------------------------------------------------- 1 | * Testing P2P network 2 | :PROPERTIES: 3 | :CUSTOM_ID: testing-p2p-network 4 | :END: 5 | The objective would be to test the p2p network, and the effectiveness of 6 | updating the ip tables. The objective of would be to give the impression 7 | to the client and server of a Zero configuration setting. For testing 8 | there will be a test network set. In the testing scenario all will be 9 | client and server because the IP table does not store clients IP 10 | addresses. At current number of hopes would be 3 as default. 11 | 12 | *** Test Network Scenario 1 13 | :PROPERTIES: 14 | :CUSTOM_ID: test-network-scenario-1 15 | :END: 16 | The test network consists of 5 nodes acting as a client and server. The 17 | objective would be to have the entire IP table Updated in each node with 18 | interacting with only 1 node once. Each node has knowledge of one node 19 | only. 20 | 21 | [[https://user-images.githubusercontent.com/31743758/115069627-e4aa8c80-9f04-11eb-8402-706a3407f0e8.png]] 22 | Fig 1.0 Visual Representation of testnet scenario 1 23 | 24 | **** Result 25 | :PROPERTIES: 26 | :CUSTOM_ID: result 27 | :END: 28 | All nodes except node 1 where able to have information of IP addresses 29 | in the test net. This was due to the reason of 3 hops set as default. 30 | Node 1 had in it's IP table IP addresses of Node 2, Node 3, Node 4. Once 31 | the number of hops was set to 4 objective of the test was acheived. 32 | 33 | *** Test Network Scenario 2 34 | :PROPERTIES: 35 | :CUSTOM_ID: test-network-scenario-2 36 | :END: 37 | The second test network has a scenario of a single peer which all the 38 | other nodes connect too. The scenario being when the other nodes connect 39 | to the single server they download information about nodes that have 40 | connected to the server node before. 41 | 42 | *** Testing Broadcast Module 43 | :PROPERTIES: 44 | :CUSTOM_ID: testing-broadcast-module 45 | :END: 46 | For testing the broadcast module 2 types of servers will be tested. One 47 | with a CPU only , another one with a CPU and GPU. The expected result 48 | being that the appropriate results are visible. 49 | 50 | **** Results (CPU and GPU): 51 | :PROPERTIES: 52 | :CUSTOM_ID: results-cpu-and-gpu 53 | :END: 54 | #+begin_example 55 | { 56 | "Hostname": "akilan-Lenovo-IdeaPad-Y510P", 57 | "Platform": "ubuntu", 58 | "CPU": "Intel(R) Core(TM) i7-4700MQ CPU @ 2.40GHz", 59 | "RAM": 7872, 60 | "Disk": 937367, 61 | "GPU": { 62 | "DriveVersion": "390.141", 63 | "Gpu": { 64 | "GpuName": "GeForce GT 755M", 65 | "BiosVersion": "80.07.A8.00.0F", 66 | "FanSpeed": "N/A", 67 | "Utilization": { 68 | "GpuUsage": "N/A", 69 | "MemoryUsage": "N/A" 70 | }, 71 | "Temperature": { 72 | "GpuTemp": "66 C" 73 | }, 74 | "Clock": { 75 | "GpuClock": "N/A", 76 | "GpuMemClock": "N/A" 77 | } 78 | } 79 | } 80 | } 81 | #+end_example 82 | 83 | At the moment of the current implementation v1.0. Nvidia GPU are only 84 | compatible. As the Go code calls the command =nvidia-smi= to get 85 | information about the GPU available. 86 | 87 | **** Results (CPU only) 88 | :PROPERTIES: 89 | :CUSTOM_ID: results-cpu-only 90 | :END: 91 | #+begin_example 92 | { 93 | "Hostname": "sv-t1.small.x86-01", 94 | "Platform": "ubuntu", 95 | "CPU": "Intel(R) Atom(TM) CPU C2750 @ 2.40GHz", 96 | "RAM": 7944, 97 | "Disk": 138793, 98 | "GPU": null 99 | } 100 | #+end_example 101 | 102 | As the =nvidia-smi= interface was not detected it only broadcasts the 103 | CPU specs available. 104 | 105 | *** SpeedTests 106 | :PROPERTIES: 107 | :CUSTOM_ID: speedtests 108 | :END: 109 | The speed test has 3 parameters which are Ping , upload and download. 110 | The tests check if the results returned are approximately correct. The 111 | ping at the moment returns the correct result. The upload and download 112 | returned are inccorect at the moment, This is due incorrect 113 | implementation in for timer and will be patched in future versions. 114 | 115 | *** Unit tests 116 | :PROPERTIES: 117 | :CUSTOM_ID: unit-tests 118 | :END: 119 | All functions implemented on the P2P module returns type error. The 120 | units test call certain functions and check if the functions return an 121 | error or not. This proved sufficient as the point of the units tests was 122 | code coverage to check if certain functions return an error. 123 | 124 | **** Functions tested 125 | :PROPERTIES: 126 | :CUSTOM_ID: functions-tested 127 | :END: 128 | This sections talks about the function called and represents code 129 | coverage. 130 | 131 | 1. =TestServer_SpeedTest=: Function called LocalSpeedTestIpTable() 132 | 2. =TestReadIpTable=: Function called ReadIpTable() 133 | 134 | The P2P module has a 100% code coverage in unit tests as both the unit 135 | tests call directly or call within the function all the functions used 136 | in the P2P module. 137 | -------------------------------------------------------------------------------- /Docs/DocsDeprecated/P2P.md: -------------------------------------------------------------------------------- 1 | # P2P (Peer to Peer module) 2 | In this repository the P2P module has been designed from sratch at the point of this implementation. 3 | [More about function implementation](https://pkg.go.dev/git.sr.ht/~akilan1999/p2p-rendering-computation@v0.0.0-20210404191839-6a046babcb02/p2p) 4 | 5 | ## Terminology 6 | 1. IPTable: Refers to a json file which stores information about the current servers avaliable with the speedtest results ran from the Node that triggered it. 7 | ``` 8 | { 9 | "ip_address": [ 10 | { 11 | "ipv4": "localhost", 12 | "latency": 14981051, 13 | "download": 8142.122540206258, 14 | "upload": 3578.766512629995, 15 | } 16 | ] 17 | } 18 | ``` 19 | 20 | 21 | ## Responsibility 22 | - To ensure the IP table has nodes which are pingable 23 | - Taking to nodes behind NAT. [More about the implementation](NAT-Traversal)... 24 | 25 | 26 | > [!NOTE] 27 | > If you are running in server mode it is recommended to use [DMZ](https://routerguide.net/when-and-how-to-setup-dmz-host-for-home-use/) to bypass the [NAT](https://en.wikipedia.org/wiki/Network_address_translation). 28 | -------------------------------------------------------------------------------- /Docs/DocsDeprecated/P2P.org: -------------------------------------------------------------------------------- 1 | * P2P (Peer to Peer module) 2 | :PROPERTIES: 3 | :CUSTOM_ID: p2p-peer-to-peer-module 4 | :END: 5 | In this repository the P2P module has been designed from sratch at the 6 | point of this implementation. 7 | [[https://pkg.go.dev/git.sr.ht/~akilan1999/p2p-rendering-computation@v0.0.0-20210404191839-6a046babcb02/p2p][More 8 | about function implementation]] 9 | 10 | ** Terminology 11 | :PROPERTIES: 12 | :CUSTOM_ID: terminology 13 | :END: 14 | 1. IPTable: Refers to a json file which stores information about the 15 | current servers avaliable with the speedtest results ran from the 16 | Node that triggered it. 17 | 18 | #+begin_example 19 | { 20 | "ip_address": [ 21 | { 22 | "ipv4": "localhost", 23 | "latency": 14981051, 24 | "download": 8142.122540206258, 25 | "upload": 3578.766512629995, 26 | } 27 | ] 28 | } 29 | #+end_example 30 | 31 | ** Responsibility 32 | :PROPERTIES: 33 | :CUSTOM_ID: responsibility 34 | :END: 35 | - To ensure the IP table has nodes which are pingable 36 | - Taking to nodes behind NAT. [[file:NAT-Traversal][More about the 37 | implementation]]... 38 | 39 | #+begin_quote 40 | [!NOTE] If you are running in server mode it is recommended to use 41 | [[https://routerguide.net/when-and-how-to-setup-dmz-host-for-home-use/][DMZ]] 42 | to bypass the 43 | [[https://en.wikipedia.org/wiki/Network_address_translation][NAT]]. 44 | 45 | #+end_quote 46 | -------------------------------------------------------------------------------- /Docs/DocsDeprecated/P2PArchitecture.md: -------------------------------------------------------------------------------- 1 | # P2P Module Architecture 2 | 3 | The P2P module (i.e Peer to Peer Module) is responsible for storing the IP table and interacting 4 | with the IP table. In the following implementation of the P2P module ,the IP table stores 5 | information about servers available in the network. The other functionality the P2P module takes 6 | care of is doing the appropriate speed tests to the servers in the IP table. This is for informing the 7 | users about nodes which are close by and nodes which have quicker uploads and downloads 8 | speeds. The module is responsible to ensure that there are no duplicate server IPs in the IP table 9 | and to remove all server IPs which are not pingable. 10 | 11 | ![UML diagram of P2P module](images/p2pmoduleArch.png) -------------------------------------------------------------------------------- /Docs/DocsDeprecated/P2PArchitecture.org: -------------------------------------------------------------------------------- 1 | * P2P Module Architecture 2 | :PROPERTIES: 3 | :CUSTOM_ID: p2p-module-architecture 4 | :END: 5 | The P2P module (i.e Peer to Peer Module) is responsible for storing the 6 | IP table and interacting with the IP table. In the following 7 | implementation of the P2P module ,the IP table stores information about 8 | servers available in the network. The other functionality the P2P module 9 | takes care of is doing the appropriate speed tests to the servers in the 10 | IP table. This is for informing the users about nodes which are close by 11 | and nodes which have quicker uploads and downloads speeds. The module is 12 | responsible to ensure that there are no duplicate server IPs in the IP 13 | table and to remove all server IPs which are not pingable. 14 | 15 | #+caption: UML diagram of P2P module 16 | [[file:images/p2pmoduleArch.png]] 17 | -------------------------------------------------------------------------------- /Docs/DocsDeprecated/P2PImplementation.md: -------------------------------------------------------------------------------- 1 | # P2P Module Implementation 2 | 3 | The P2P module (i.e Peer to Peer Module) is responsible for storing the IP table and interacting 4 | with the IP table. In the following implementation of the P2P module ,the IP table stores 5 | information about servers available in the network. The other functionality the P2P module takes 6 | care of is doing the appropriate speed tests to the servers in the IP table. This is for informing the 7 | users about nodes which are close by and nodes which have quicker uploads and downloads 8 | speeds. The module is responsible to ensure that there are no duplicate server IPs in the IP table 9 | and to remove all server IPs which are not pingable. 10 | 11 | ![UML diagram of P2P module](images/p2pmoduleArch.png) 12 | 13 | The peer to peer implementation was built from scratch. This is because other peer to peer 14 | libraries were on the implementation of the Distributed hash table. At the current moment all 15 | those heavy features are not needed because the objective is to search and list all possible servers 16 | available. The limitation being that to be a part of the network the user has to know at least 1 17 | server. The advantage of building from scratch makes the module super light and 18 | possibility for custom functions and structs. The sub topics below will mention the 19 | implementations of each functionality in depth. 20 | 21 | ## IP Table 22 | The ip table file is a json as the format with a list of servers ip addresses, latencies, downloads and 23 | uploads speeds. The functions implemented include read 24 | file, write file and remove duplicate IP addresses. The remove duplicate IP address function exists 25 | because sometimes servers IP tables can have the same ip addresses as what the client has. The 26 | path of the IP table json file is received from the configuration module. 27 | 28 | ```json 29 | { 30 | "ip_address": [ 31 | { 32 | "ipv4": "", 33 | "latency": "", 34 | "download": "", 35 | "upload": "" 36 | "port no": "", 37 | } 38 | ] 39 | } 40 | ``` 41 | 42 | ### Latency 43 | The latency is measured in milliseconds. The route /server_info is called from the 44 | server and time it takes to provide a json response is recorded. 45 | 46 | ## NAT Traversal 47 | P2PRC currently supports TURN for NAT traversal. 48 | 49 | 50 | 51 | ## TURN 52 | The current TURN implementation used is FRP. The TURN server is also required when 53 | a P2PRC node is acting as a Server. The TURN server is determined based on the Node 54 | with the least amount of latency based on the Nodes available on the IPTable. 55 | Once a TURN server is determined there are 2 actions performed. The first one is 56 | ```/FRPPort``` to the TURN server to receive a port which is used to generate the external 57 | port from the TURN server. The flow below describes the workflow. 58 | 59 | ### Client mode 60 | - Call ```/FRPPort``` 61 | ``` 62 | http://:/FRPport 63 | ``` 64 | - Call the TURN server in the following manner. The following is a sample code snippet below. 65 | ```go 66 | import ( 67 | "github.com/Akilan1999/p2p-rendering-computation/p2p/frp" 68 | ) 69 | 70 | func main() { 71 | serverPort, err := frp.GetFRPServerPort("http://" + + ":" + lowestLatencyIpAddress.ServerPort) 72 | if err != nil { 73 | return nil, err 74 | } 75 | // Create 1 second delay to allow FRP server to start 76 | time.Sleep(1 * time.Second) 77 | // Starts FRP as a client with 78 | proxyPort, err := frp.StartFRPClientForServer(, serverPort, ) 79 | if err != nil { 80 | return nil, err 81 | } 82 | } 83 | ``` 84 | 85 | 86 | -------------------------------------------------------------------------------- /Docs/DocsDeprecated/P2PImplementation.org: -------------------------------------------------------------------------------- 1 | * P2P Module Implementation 2 | :PROPERTIES: 3 | :CUSTOM_ID: p2p-module-implementation 4 | :END: 5 | The P2P module (i.e Peer to Peer Module) is responsible for storing the 6 | IP table and interacting with the IP table. In the following 7 | implementation of the P2P module ,the IP table stores information about 8 | servers available in the network. The other functionality the P2P module 9 | takes care of is doing the appropriate speed tests to the servers in the 10 | IP table. This is for informing the users about nodes which are close by 11 | and nodes which have quicker uploads and downloads speeds. The module is 12 | responsible to ensure that there are no duplicate server IPs in the IP 13 | table and to remove all server IPs which are not pingable. 14 | 15 | #+caption: UML diagram of P2P module 16 | [[file:images/p2pmoduleArch.png]] 17 | 18 | The peer to peer implementation was built from scratch. This is because 19 | other peer to peer libraries were on the implementation of the 20 | Distributed hash table. At the current moment all those heavy features 21 | are not needed because the objective is to search and list all possible 22 | servers available. The limitation being that to be a part of the network 23 | the user has to know at least 1 server. The advantage of building from 24 | scratch makes the module super light and possibility for custom 25 | functions and structs. The sub topics below will mention the 26 | implementations of each functionality in depth. 27 | 28 | ** IP Table 29 | :PROPERTIES: 30 | :CUSTOM_ID: ip-table 31 | :END: 32 | The ip table file is a json as the format with a list of servers ip 33 | addresses, latencies, downloads and uploads speeds. The functions 34 | implemented include read file, write file and remove duplicate IP 35 | addresses. The remove duplicate IP address function exists because 36 | sometimes servers IP tables can have the same ip addresses as what the 37 | client has. The path of the IP table json file is received from the 38 | configuration module. 39 | 40 | #+begin_src json 41 | { 42 | "ip_address": [ 43 | { 44 | "ipv4": "", 45 | "latency": "", 46 | "download": "", 47 | "upload": "" 48 | "port no": "", 49 | } 50 | ] 51 | } 52 | #+end_src 53 | 54 | *** Latency 55 | :PROPERTIES: 56 | :CUSTOM_ID: latency 57 | :END: 58 | The latency is measured in milliseconds. The route /server_info is 59 | called from the server and time it takes to provide a json response is 60 | recorded. 61 | 62 | ** NAT Traversal 63 | :PROPERTIES: 64 | :CUSTOM_ID: nat-traversal 65 | :END: 66 | P2PRC currently supports TURN for NAT traversal. 67 | 68 | ** TURN 69 | :PROPERTIES: 70 | :CUSTOM_ID: turn 71 | :END: 72 | The current TURN implementation used is FRP. The TURN server is also 73 | required when a P2PRC node is acting as a Server. The TURN server is 74 | determined based on the Node with the least amount of latency based on 75 | the Nodes available on the IPTable. Once a TURN server is determined 76 | there are 2 actions performed. The first one is =/FRPPort= to the TURN 77 | server to receive a port which is used to generate the external port 78 | from the TURN server. The flow below describes the workflow. 79 | 80 | *** Client mode 81 | :PROPERTIES: 82 | :CUSTOM_ID: client-mode 83 | :END: 84 | - Call =/FRPPort= 85 | 86 | #+begin_example 87 | http://:/FRPport 88 | #+end_example 89 | 90 | - Call the TURN server in the following manner. The following is a 91 | sample code snippet below. 92 | 93 | #+begin_src go 94 | import ( 95 | "github.com/Akilan1999/p2p-rendering-computation/p2p/frp" 96 | ) 97 | 98 | func main() { 99 | serverPort, err := frp.GetFRPServerPort("http://" + + ":" + lowestLatencyIpAddress.ServerPort) 100 | if err != nil { 101 | return nil, err 102 | } 103 | // Create 1 second delay to allow FRP server to start 104 | time.Sleep(1 * time.Second) 105 | // Starts FRP as a client with 106 | proxyPort, err := frp.StartFRPClientForServer(, serverPort, ) 107 | if err != nil { 108 | return nil, err 109 | } 110 | } 111 | #+end_src 112 | -------------------------------------------------------------------------------- /Docs/DocsDeprecated/README.org: -------------------------------------------------------------------------------- 1 | * Table of contents 2 | :PROPERTIES: 3 | :CUSTOM_ID: table-of-contents 4 | :END: 5 | 1.[[file:Introduction.org][ Introduction]] 6 | 2. [[file:Installation.org][Installation]] 7 | 3. [[file:Abstractions.org][Abstractions]] 8 | 4. [[file:Implementation.org][Implementation]] 9 | 1. [[file:ClientImplementation.org][Client Module]] 10 | 2. [[file:P2PImplementation.org][P2P Module]] 11 | 3. [[file:ServerImplementation.org][Server Module]] 12 | 4. [[file:ConfigImplementation.org][Config Module]] 13 | 5. [[file:CliImplementation.org][Cli Module]] 14 | 6. [[file:PluginImplementation.org][Plugin Module]] 15 | 7. [[file:Bindings.org][Language bindings]] 16 | 8. [[file:Bindings.org][Domain name mappings]] 17 | 5. Language bindings 18 | 1. [[file:haskell/][Haskell]] 19 | -------------------------------------------------------------------------------- /Docs/DocsDeprecated/ServerArchitecture.md: -------------------------------------------------------------------------------- 1 | # Server Module Architecture 2 | The server module takes care of setting and removing the virtualization environment (i.e 3 | containers) for accessing and doing the appropriate computation. It also interacts with the peer to 4 | peer module to update the IP table on the server side. The server module 5 | accesses information regarding CPU and GPU specifications of the machine running the server 6 | module. To do Speed tests the server has routes which allows it to upload and download a 50mb. 7 | 8 | ![UML diagram of server module](images/servermoduleArch.png) -------------------------------------------------------------------------------- /Docs/DocsDeprecated/ServerArchitecture.md.org: -------------------------------------------------------------------------------- 1 | * Server Module Architecture 2 | :PROPERTIES: 3 | :CUSTOM_ID: server-module-architecture 4 | :END: 5 | The server module takes care of setting and removing the virtualization 6 | environment (i.e containers) for accessing and doing the appropriate 7 | computation. It also interacts with the peer to peer module to update 8 | the IP table on the server side. The server module accesses information 9 | regarding CPU and GPU specifications of the machine running the server 10 | module. To do Speed tests the server has routes which allows it to 11 | upload and download a 50mb. 12 | 13 | #+caption: UML diagram of server module 14 | [[file:images/servermoduleArch.png]] 15 | -------------------------------------------------------------------------------- /Docs/DocsDeprecated/Virtualization: -------------------------------------------------------------------------------- 1 | 2 | Virtualization Design 3 | ====================== 4 | 5 | The virtualization tool will be treated as a separate module. In our implementation 6 | we will use docker as it's easier to configure and set. 7 | 8 | Methods to be created 9 | - Build OS Image from DockerFile 10 | - Run Image Built 11 | - Possibility to kill image by server admin or client side user. 12 | - Track stats of the docker container by server admin or client side user. 13 | -------------------------------------------------------------------------------- /Docs/haskell/README.md: -------------------------------------------------------------------------------- 1 |
2 | 3 | p2prc-0.1.0.0: P2PRC haskell library 4 | 5 | - [Contents](index.html) 6 | - [Index](doc-index.html) 7 | 8 |
9 | 10 |
11 | 12 |
13 | 14 | | | | 15 | |--------------|-----------------------------------------| 16 | | Copyright | Copyright (C) 2006-2024 John MacFarlane | 17 | | License | GNU GPL, version 2 or above | 18 | | Maintainer | John MacFarlane \ | 19 | | Stability | alpha | 20 | | Portability | portable | 21 | | Safe Haskell | Safe-Inferred | 22 | | Language | GHC2021 | 23 | 24 | P2PRC 25 | 26 |
27 | 28 |
29 | 30 | Description 31 | 32 |
33 | 34 | This helper module exports the main writers, readers, and data structure 35 | definitions from the Pandoc libraries. 36 | 37 | A typical application will chain together a reader and a writer to 38 | convert strings from one format to another. For example, the following 39 | simple program will act as a filter converting markdown fragments to 40 | reStructuredText, using reference-style links instead of inline links: 41 | 42 | module Main where 43 | import Text.Pandoc 44 | import Data.Text (Text) 45 | import qualified Data.Text.IO as T 46 | 47 | mdToRST :: Text -> IO Text 48 | mdToRST txt = runIOorExplode $ 49 | readMarkdown def txt 50 | >>= writeRST def{ writerReferenceLinks = True } 51 | 52 | main :: IO () 53 | main = do 54 | T.getContents >>= mdToRST >>= T.putStrLn 55 | 56 |
57 | 58 |
59 | 60 |
61 | 62 | Synopsis 63 | 64 | - [runP2PRC](#v:runP2PRC) :: 65 | [MapPortRequest](P2PRC.html#t:MapPortRequest "P2PRC") -\> 66 | [IO]($%7Bpkgroot%7D/../../../../dcnyq1a8qi8x59n5p53d0dx42cl8hf8x-ghc-9.6.5-doc/share/doc/ghc/html/libraries/base-4.18.2.1/System-IO.html#t:IO "System.IO") 67 | () 68 | - data [MapPortRequest](#t:MapPortRequest) 69 | = [MkMapPortRequest](#v:MkMapPortRequest) 70 | [Int]($%7Bpkgroot%7D/../../../../dcnyq1a8qi8x59n5p53d0dx42cl8hf8x-ghc-9.6.5-doc/share/doc/ghc/html/libraries/base-4.18.2.1/Data-Int.html#t:Int "Data.Int") 71 | [String]($%7Bpkgroot%7D/../../../../dcnyq1a8qi8x59n5p53d0dx42cl8hf8x-ghc-9.6.5-doc/share/doc/ghc/html/libraries/base-4.18.2.1/Data-String.html#t:String "Data.String") 72 | 73 |
74 | 75 |
76 | 77 | # Documentation 78 | 79 |
80 | 81 | runP2PRC :: 82 | [MapPortRequest](P2PRC.html#t:MapPortRequest "P2PRC") -\> 83 | [IO]($%7Bpkgroot%7D/../../../../dcnyq1a8qi8x59n5p53d0dx42cl8hf8x-ghc-9.6.5-doc/share/doc/ghc/html/libraries/base-4.18.2.1/System-IO.html#t:IO "System.IO") 84 | () # 85 | 86 |
87 | 88 | Hello World 89 | 90 |
91 | 92 |
93 | 94 |
95 | 96 | data MapPortRequest 98 | # 99 | 100 |
101 | 102 | Constructors 103 | 104 | | | | 105 | |-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|-----| 106 | | MkMapPortRequest [Int]($%7Bpkgroot%7D/../../../../dcnyq1a8qi8x59n5p53d0dx42cl8hf8x-ghc-9.6.5-doc/share/doc/ghc/html/libraries/base-4.18.2.1/Data-Int.html#t:Int "Data.Int") [String]($%7Bpkgroot%7D/../../../../dcnyq1a8qi8x59n5p53d0dx42cl8hf8x-ghc-9.6.5-doc/share/doc/ghc/html/libraries/base-4.18.2.1/Data-String.html#t:String "Data.String") |   | 107 | 108 |
109 | 110 |
111 | 112 |
113 | 114 |
115 | 116 | 121 | -------------------------------------------------------------------------------- /Docs/haskell/index.html: -------------------------------------------------------------------------------- 1 | p2prc-0.1.0.0: P2PRC haskell library
p2prc-0.1.0.0: P2PRC haskell library

p2prc-0.1.0.0: P2PRC haskell library

Implements a client interface to the P2PRC networking runtime

Modules

p2prc-0.1.0.0

-------------------------------------------------------------------------------- /Docs/haskell/meta.json: -------------------------------------------------------------------------------- 1 | {"haddock_version":"2.29.2"} -------------------------------------------------------------------------------- /Docs/haskell/p2prc.haddock: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Akilan1999/p2p-rendering-computation/36930be8e480877414fec654169b9b2969168db0/Docs/haskell/p2prc.haddock -------------------------------------------------------------------------------- /Docs/haskell/quick-jump.css: -------------------------------------------------------------------------------- 1 | /* @group Fundamentals */ 2 | 3 | .hidden { 4 | display: none; 5 | } 6 | 7 | /* @end */ 8 | 9 | /* @group Search box layout */ 10 | 11 | #search { 12 | position: fixed; 13 | top: 3.2em; 14 | bottom: 0; 15 | left: calc(50% - 22em); 16 | width: 44em; 17 | z-index: 1000; 18 | overflow-y: auto; 19 | } 20 | 21 | @media only screen and (max-width: 999px) { 22 | #search { 23 | top: 5.7em; 24 | } 25 | } 26 | 27 | #search-form, #search-results { 28 | box-shadow: 2px 2px 6px rgb(199, 204, 208); 29 | pointer-events: all; 30 | } 31 | 32 | #search-form input { 33 | font-size: 1.25em; line-height: 2.3em; height: 2.4em; 34 | display: block; 35 | box-sizing: border-box; 36 | width: 100%; 37 | margin: 0; 38 | padding: 0 0.75em; 39 | border: 0.05em solid rgb(151, 179, 202); 40 | } 41 | 42 | #search input:focus { 43 | outline: none; 44 | } 45 | 46 | #search p.error { 47 | color: rgb(107, 24, 24); 48 | font-weight: bold; 49 | } 50 | 51 | #search-results { 52 | box-sizing: border-box; 53 | border: 0.05em solid #b2d5fb; 54 | background: #e8f3ff; 55 | max-height: 80%; 56 | overflow: scroll; 57 | } 58 | 59 | #search-form input + #search-results { 60 | border-top: none; 61 | top: 3em; 62 | max-height: calc(100% - 3em); 63 | } 64 | 65 | /* @end */ 66 | 67 | /* @group search results */ 68 | 69 | #search-results > ul { 70 | margin: 0; 71 | list-style: none; 72 | } 73 | 74 | #search-results > ul > li, 75 | #search-results > p, 76 | #search-results > table { 77 | padding: 0.5em 1em; 78 | margin: 0; 79 | } 80 | 81 | #search-results > ul > li { 82 | border-bottom: 1px solid #b2d5fb; 83 | } 84 | 85 | #search-results > ul > li > ul { 86 | list-style: none; 87 | } 88 | 89 | .search-module h4 { 90 | margin: 0; 91 | } 92 | 93 | .search-module > ul { 94 | margin: 0.5em 0 0.5em 2em; 95 | } 96 | 97 | .search-module > ul > li > a[href] { 98 | display: block; 99 | color: inherit; 100 | padding: 0.25em 0.5em; 101 | } 102 | 103 | .search-module > ul > li > a[href].active-link { 104 | background: #faf9dc; 105 | } 106 | 107 | .search-module a[href]:hover { 108 | text-decoration: none; 109 | } 110 | 111 | .search-result a a { 112 | pointer-events: none; 113 | } 114 | 115 | .search-result ul.subs { 116 | display: inline-block; 117 | margin: 0; padding: 0; 118 | } 119 | 120 | .search-result ul.subs li { 121 | display: none; 122 | } 123 | 124 | .search-result ul.subs::after { 125 | display: inline-block; 126 | content: "..."; 127 | color: rgb(78,98,114); 128 | margin: 0 0.25em; 129 | } 130 | 131 | .more-results { 132 | color: rgb(99, 141, 173); 133 | position: relative; 134 | } 135 | 136 | .more-results::before { 137 | content: "+"; 138 | display: inline-block; 139 | color: #b2d5fb; 140 | font-weight: bold; 141 | font-size: 1.25em; line-height: inherit; 142 | position: absolute; 143 | left: -1em; 144 | } 145 | 146 | /* @end */ 147 | 148 | /* @group Keyboard shortcuts table */ 149 | 150 | .keyboard-shortcuts { 151 | line-height: 1.6em; 152 | } 153 | 154 | .keyboard-shortcuts th { 155 | color: rgb(78,98,114); 156 | } 157 | 158 | .keyboard-shortcuts td:first-child, 159 | .keyboard-shortcuts th:first-child { 160 | text-align: right; 161 | padding-right: 0.6em; 162 | } 163 | 164 | .key { 165 | display: inline-block; 166 | font-size: 0.9em; 167 | min-width: 0.8em; line-height: 1.2em; 168 | text-align: center; 169 | background: #b2d5fb; 170 | border: 1px solid #74a3d6; 171 | padding: 0 0.2em; 172 | margin: 0 0.1em; 173 | } 174 | 175 | /* @end */ 176 | 177 | /* @group Dropdown menus */ 178 | 179 | /* Based on #search styling above. */ 180 | 181 | .dropdown-menu { 182 | position: fixed; 183 | /* Not robust to window size changes. */ 184 | top: 3.2em; 185 | right: 0; 186 | /* To display on top of synopsis menu on right side. */ 187 | z-index: 1000; 188 | border: 0.05em solid #b2d5fb; 189 | background: #e8f3ff; 190 | } 191 | 192 | @media only screen and (max-width: 999px) { 193 | .dropdown-menu { 194 | top: 5.7em; 195 | } 196 | } 197 | 198 | .dropdown-menu * { 199 | margin: 0.1em; 200 | } 201 | 202 | .dropdown-menu button { 203 | border: 1px #5E5184 solid; 204 | border-radius: 3px; 205 | background: #5E5184; 206 | padding: 3px; 207 | color: #f4f4f4; 208 | min-width: 6em; 209 | } 210 | 211 | .dropdown-menu button:hover { 212 | color: #5E5184; 213 | background: #f4f4f4; 214 | } 215 | 216 | .dropdown-menu button:active { 217 | color: #f4f4f4; 218 | background: #5E5184; 219 | } 220 | 221 | /* @end */ 222 | -------------------------------------------------------------------------------- /Docs/haskell/synopsis.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Akilan1999/p2p-rendering-computation/36930be8e480877414fec654169b9b2969168db0/Docs/haskell/synopsis.png -------------------------------------------------------------------------------- /Docs/images/NumOfHops.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Akilan1999/p2p-rendering-computation/36930be8e480877414fec654169b9b2969168db0/Docs/images/NumOfHops.png -------------------------------------------------------------------------------- /Docs/images/P2PRCRemoteNodes.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Akilan1999/p2p-rendering-computation/36930be8e480877414fec654169b9b2969168db0/Docs/images/P2PRCRemoteNodes.png -------------------------------------------------------------------------------- /Docs/images/clientmoduleArch.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Akilan1999/p2p-rendering-computation/36930be8e480877414fec654169b9b2969168db0/Docs/images/clientmoduleArch.png -------------------------------------------------------------------------------- /Docs/images/p2pmoduleArch.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Akilan1999/p2p-rendering-computation/36930be8e480877414fec654169b9b2969168db0/Docs/images/p2pmoduleArch.png -------------------------------------------------------------------------------- /Docs/images/p2prclogo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Akilan1999/p2p-rendering-computation/36930be8e480877414fec654169b9b2969168db0/Docs/images/p2prclogo.png -------------------------------------------------------------------------------- /Docs/images/servermoduleArch.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Akilan1999/p2p-rendering-computation/36930be8e480877414fec654169b9b2969168db0/Docs/images/servermoduleArch.png -------------------------------------------------------------------------------- /Docs/kill-docs.sh: -------------------------------------------------------------------------------- 1 | kill -9 $(lsof -t -i:8083) 2 | -------------------------------------------------------------------------------- /Docs/run-docs.sh: -------------------------------------------------------------------------------- 1 | go run staticServer.go & 2 | -------------------------------------------------------------------------------- /Docs/staticServer.go: -------------------------------------------------------------------------------- 1 | /* 2 | Serve is a very simple static file server in go 3 | Usage: 4 | 5 | -p="8100": port to serve on 6 | -d=".": the directory of static files to host 7 | 8 | Navigating to http://localhost:8100 will display the index.html or directory 9 | listing file. 10 | */ 11 | package main 12 | 13 | import ( 14 | "flag" 15 | "log" 16 | "net/http" 17 | ) 18 | 19 | func main() { 20 | port := flag.String("p", "8083", "port to serve on") 21 | directory := flag.String("d", ".", "the directory of static file to host") 22 | flag.Parse() 23 | 24 | http.Handle("/", http.FileServer(http.Dir(*directory))) 25 | 26 | log.Printf("Serving %s on HTTP port: %s\n", *directory, *port) 27 | log.Fatal(http.ListenAndServe(":"+*port, nil)) 28 | } 29 | -------------------------------------------------------------------------------- /Docs/style.css: -------------------------------------------------------------------------------- 1 | #table-of-contents h2{ 2 | z-index: 200; 3 | background-color: #b96c29; 4 | text-align: center; 5 | padding: 0.809em; 6 | display: block; 7 | color: #fcfcfc; 8 | font-size: 100%; 9 | margin-bottom: 0.809em; 10 | } 11 | 12 | #search-results li { 13 | background-color: #b96c29; 14 | color: white; 15 | margin-bottom: 5px; 16 | padding: 5px; 17 | border-radius: 4px; 18 | cursor: pointer; 19 | font-size: 14px; 20 | } 21 | 22 | h4,h5,h6{ 23 | color: #b96c29; 24 | font-weight:300; 25 | } 26 | 27 | .video { 28 | box-shadow: 10px 10px 25px rgba(0, 0, 0, 0.3); 29 | } 30 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | 2 | install: 3 | sh install.sh p2prc 4 | 5 | testcases: 6 | sh plugin/generate_test_case.sh 7 | 8 | run: 9 | go run main.go 10 | 11 | sharedObjects: 12 | sh build-bindings.sh 13 | 14 | python: 15 | sh build-python-package.sh 16 | 17 | haskell: 18 | sh build-haskell.sh 19 | 20 | clean: 21 | go clean -modcache 22 | rm -fr .go-build vendor result* 23 | -------------------------------------------------------------------------------- /Simulation/simulation.sh: -------------------------------------------------------------------------------- 1 | # Unset P2PRC 2 | unset P2PRC 3 | 4 | # Create P2PRC instances 5 | # Parameters: 6 | # 1. Number of nodes 7 | P2PRC_instances() { 8 | local rootPort="" 9 | for (( counter=0; counter<$1; counter++ )); do 10 | mkdir test-$counter/ 11 | cd test-$counter/ 12 | 13 | # Generate a new random port 14 | NEW_PORT=$(shuf -i 2000-65000 -n 1) 15 | 16 | # Initialize node 17 | p2prc --dc 18 | 19 | # Save rootPort from the first node 20 | if [[ $counter -eq 0 ]]; then 21 | rootPort=$NEW_PORT 22 | fi 23 | 24 | echo "Root port: $rootPort" 25 | echo "This node's port: $NEW_PORT" 26 | 27 | # Set root port 28 | p2prc --arn --ip 0.0.0.0 -p "$rootPort" 29 | 30 | # add current node 31 | p2prc --as 0.0.0.0 -p "$NEW_PORT" 32 | 33 | # Replace the ServerPort in config 34 | # test-$counter 35 | sed -i.bak "s/\"ServerPort\": \"[0-9]*\"/\"ServerPort\": \"$NEW_PORT\"/" "./config.json" 36 | sed -i.bak "s/\"Test\": false/\"Test\": true/" "./config.json" 37 | sed -i.bak "s/\"BehindNAT\": true/\"BehindNAT\": false/" "./config.json" 38 | # sed -i.bak "s/\"MachineName\": "Akilans-MacBook-Pro.local-J2UbbkF"/\"MachineName\": \"test-$counter\"/" "./config.json" 39 | 40 | cat config.json 41 | 42 | # List services 43 | p2prc --ls 44 | 45 | cd .. 46 | done 47 | 48 | # remove all instances after testing (optional — might want to comment this during testing) 49 | # rm -rf test-* 50 | } 51 | 52 | # Arrays of process IDs 53 | pids=() 54 | 55 | # Calls all the P2PRC instances created for testing 56 | Start_all_instances() { 57 | for (( counter=0; counter<$1; counter++ )); do 58 | cd test-$counter/ 59 | # Start P2PRC as background process 60 | p2prc -s & 61 | pids+=($!) 62 | sleep 3 63 | cd .. 64 | done 65 | } 66 | 67 | # Kills all P2PRC instances 68 | Kill_all_instances() { 69 | for pid in "${pids[@]}"; do 70 | kill "$pid" 71 | echo "Killed process $pid" 72 | done 73 | } 74 | 75 | # Removes all test files created 76 | Remove_all_test_files() { 77 | rm -rf test-* 78 | } 79 | 80 | # List ip tables of all nodes started 81 | IP_Tables_after_Started() { 82 | for (( counter=0; counter<$1; counter++ )); do 83 | cd test-$counter/ 84 | p2prc --ls 85 | cd .. 86 | done 87 | } 88 | 89 | Update_All_IP_Tables() { 90 | for (( counter=0; counter<$1; counter++ )); do 91 | cd test-$counter/ 92 | p2prc --us 93 | cd .. 94 | done 95 | } 96 | 97 | # Test function for the root to custom information 98 | # through the network 99 | Send_Information() { 100 | ls 101 | cd test-2/ 102 | p2prc --amd "test message" 103 | cd .. 104 | } 105 | 106 | 107 | # ---------------- Work flow test --------------- 108 | 109 | # Unset default P2PRC env path 110 | unset P2PRC 111 | 112 | # Run with 2 nodes 113 | P2PRC_instances 3 114 | 115 | ## Start instances 116 | Start_all_instances 3 117 | 118 | 119 | # Send test information from node 1 120 | sleep 10 121 | Send_Information 122 | 123 | sleep 10 124 | ## List ip tables of nodes started 125 | IP_Tables_after_Started 3 126 | # 127 | ## Remove test files created 128 | Remove_all_test_files 129 | 130 | ## Kill all instances 131 | Kill_all_instances 132 | 133 | -------------------------------------------------------------------------------- /_config.yml: -------------------------------------------------------------------------------- 1 | remote_theme: abhinavs/moonwalk 2 | 3 | favicon: "favicon-32x32.png" # relative path to site's favicon 4 | 5 | theme_config: 6 | appearance: "dark" # can be "light", "dark" or "auto" 7 | appearance_toggle: true # if appearance can be switched by user 8 | show_navbar: false 9 | show_footer: false 10 | -------------------------------------------------------------------------------- /abstractions/base.go: -------------------------------------------------------------------------------- 1 | package abstractions 2 | 3 | import ( 4 | "github.com/Akilan1999/p2p-rendering-computation/client" 5 | "github.com/Akilan1999/p2p-rendering-computation/client/clientIPTable" 6 | Config "github.com/Akilan1999/p2p-rendering-computation/config" 7 | "github.com/Akilan1999/p2p-rendering-computation/config/generate" 8 | "github.com/Akilan1999/p2p-rendering-computation/p2p" 9 | "github.com/Akilan1999/p2p-rendering-computation/server" 10 | "github.com/Akilan1999/p2p-rendering-computation/server/docker" 11 | "github.com/gin-gonic/gin" 12 | "os" 13 | ) 14 | 15 | // Init Initialises p2prc 16 | func Init(customConfig interface{}) (config *Config.Config, err error) { 17 | 18 | // Get config file path 19 | // Checks P2PRC path initially 20 | // - Get PATH if environment varaible 21 | path, err := Config.GetPathP2PRC("P2PRC") 22 | if err != nil { 23 | return 24 | } 25 | // check if the config file exists 26 | if _, err = os.Stat(path + "config.json"); err != nil { 27 | // Initialize with base p2prc config files 28 | // set the config file with default paths 29 | config, err = generate.SetDefaults("P2PRC", false, customConfig, false) 30 | if err != nil { 31 | return 32 | } 33 | } else { 34 | // If the configs are available then use them over generating new ones. 35 | config, err = Config.ConfigInit(nil, nil) 36 | if err != nil { 37 | return 38 | } 39 | } 40 | 41 | return 42 | } 43 | 44 | // Start p2prc in a server mode 45 | func Start() (*gin.Engine, error) { 46 | engine, err := server.Server() 47 | if err != nil { 48 | return nil, err 49 | } 50 | return engine, nil 51 | } 52 | 53 | // MapPort Creates a reverse proxy connection and maps the appropriate port 54 | func MapPort(port string, domainName string, serverAddress string) (response *client.ResponseMAPPort, err error) { 55 | response, err = client.MAPPort(port, domainName, serverAddress) 56 | return 57 | } 58 | 59 | // StartContainer Starts docker container on the remote machine 60 | func StartContainer(IP string) (container *docker.DockerVM, err error) { 61 | container, err = client.StartContainer(IP, 0, false, "", "") 62 | return 63 | } 64 | 65 | // RemoveContainer Removes docker container based on the IP address and ID 66 | // provided 67 | func RemoveContainer(IP string, ID string) error { 68 | return client.RemoveContianer(IP, ID) 69 | } 70 | 71 | // GetSpecs Get spec information about the remote server 72 | func GetSpecs(IP string) (specs *server.SysInfo, err error) { 73 | specs, err = client.GetSpecs(IP) 74 | return 75 | } 76 | 77 | // ViewIPTable View information of nodes in the network 78 | func ViewIPTable() (table *p2p.IpAddresses, err error) { 79 | table, err = p2p.ReadIpTable() 80 | return 81 | } 82 | 83 | // UpdateIPTable Force updates IP tables based on new 84 | // new nodes discovered in the network 85 | func UpdateIPTable() (err error) { 86 | return clientIPTable.UpdateIpTableListClient() 87 | } 88 | 89 | // AddCustomInformation allows to pass custom information 90 | // through the network to which can be listened on 91 | // all peers in the network to execute a task. 92 | func AddCustomInformation(information string) error { 93 | return clientIPTable.AddCustomInformationToIPTable(information) 94 | } 95 | 96 | // AddRootNode Adds root node to the network by using defaults except for 97 | // ip address and port no. Supports only IPV4 as of now. 98 | func AddRootNode(rootIP string, portNo string) error { 99 | var rootNode []p2p.IpAddress 100 | 101 | rootNode = append(rootNode, p2p.IpAddress{ 102 | Name: "", 103 | Ipv4: rootIP, 104 | ServerPort: portNo, 105 | NAT: false, 106 | }) 107 | return generate.GenerateIPTableFile(rootNode) 108 | } 109 | -------------------------------------------------------------------------------- /abstractions/docs.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | # abstractions 4 | 5 | ```go 6 | import "github.com/Akilan1999/p2p-rendering-computation/abstractions" 7 | ``` 8 | 9 | ## Index 10 | 11 | - [func GetSpecs\(IP string\) \(specs \*server.SysInfo, err error\)](<#GetSpecs>) 12 | - [func Init\(customConfig interface\{\}\) \(config \*Config.Config, err error\)](<#Init>) 13 | - [func MapPort\(port string, domainName string, serverAddress string\) \(entireAddress string, mapPort string, err error\)](<#MapPort>) 14 | - [func RemoveContainer\(IP string, ID string\) error](<#RemoveContainer>) 15 | - [func Start\(\) \(\*gin.Engine, error\)](<#Start>) 16 | - [func StartContainer\(IP string\) \(container \*docker.DockerVM, err error\)](<#StartContainer>) 17 | - [func UpdateIPTable\(\) \(err error\)](<#UpdateIPTable>) 18 | - [func ViewIPTable\(\) \(table \*p2p.IpAddresses, err error\)](<#ViewIPTable>) 19 | 20 | 21 | 22 | ## func [GetSpecs]() 23 | 24 | ```go 25 | func GetSpecs(IP string) (specs *server.SysInfo, err error) 26 | ``` 27 | 28 | GetSpecs Get spec information about the remote server 29 | 30 | 31 | ## func [Init]() 32 | 33 | ```go 34 | func Init(customConfig interface{}) (config *Config.Config, err error) 35 | ``` 36 | 37 | Init Initialises p2prc 38 | 39 | 40 | ## func [MapPort]() 41 | 42 | ```go 43 | func MapPort(port string, domainName string, serverAddress string) (entireAddress string, mapPort string, err error) 44 | ``` 45 | 46 | MapPort Creates a reverse proxy connection and maps the appropriate port 47 | 48 | 49 | ## func [RemoveContainer]() 50 | 51 | ```go 52 | func RemoveContainer(IP string, ID string) error 53 | ``` 54 | 55 | RemoveContainer Removes docker container based on the IP address and ID provided 56 | 57 | 58 | ## func [Start]() 59 | 60 | ```go 61 | func Start() (*gin.Engine, error) 62 | ``` 63 | 64 | Start p2prc in a server mode 65 | 66 | 67 | ## func [StartContainer]() 68 | 69 | ```go 70 | func StartContainer(IP string) (container *docker.DockerVM, err error) 71 | ``` 72 | 73 | StartContainer Starts docker container on the remote machine 74 | 75 | 76 | ## func [UpdateIPTable]() 77 | 78 | ```go 79 | func UpdateIPTable() (err error) 80 | ``` 81 | 82 | UpdateIPTable Force updates IP tables based on new new nodes discovered in the network 83 | 84 | 85 | ## func [ViewIPTable]() 86 | 87 | ```go 88 | func ViewIPTable() (table *p2p.IpAddresses, err error) 89 | ``` 90 | 91 | ViewIPTable View information of nodes in the network 92 | 93 | Generated by [gomarkdoc]() 94 | -------------------------------------------------------------------------------- /artwork/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Akilan1999/p2p-rendering-computation/36930be8e480877414fec654169b9b2969168db0/artwork/.DS_Store -------------------------------------------------------------------------------- /artwork/README.md: -------------------------------------------------------------------------------- 1 | 2 | # p2prc_logo 3 | 4 | ## Pure HTML Version of the p2prc Logo :) 5 | ![p2prc Logo](https://user-images.githubusercontent.com/55647468/204634868-07e94b6d-65f5-4446-a11f-7a14f11edff9.png) 6 | 7 | > [!NOTE] 8 | > To change the size of the logo simply edit the CSS variable of `--size` under the `style` tag! 9 | 10 | --- 11 | 12 | ### Embedding the HTML as a `foreignObject` element inside an SVG directly 13 | 14 | ![](embed.svg) 15 | -------------------------------------------------------------------------------- /artwork/p2prc-logos/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Akilan1999/p2p-rendering-computation/36930be8e480877414fec654169b9b2969168db0/artwork/p2prc-logos/.DS_Store -------------------------------------------------------------------------------- /artwork/p2prc-logos/Black-Image.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Akilan1999/p2p-rendering-computation/36930be8e480877414fec654169b9b2969168db0/artwork/p2prc-logos/Black-Image.png -------------------------------------------------------------------------------- /artwork/p2prc-logos/Colored-Image.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Akilan1999/p2p-rendering-computation/36930be8e480877414fec654169b9b2969168db0/artwork/p2prc-logos/Colored-Image.png -------------------------------------------------------------------------------- /artwork/p2prc-logos/Colored-On-Dark-Image.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Akilan1999/p2p-rendering-computation/36930be8e480877414fec654169b9b2969168db0/artwork/p2prc-logos/Colored-On-Dark-Image.png -------------------------------------------------------------------------------- /artwork/p2prc-logos/Colored-On-Light-Image.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Akilan1999/p2p-rendering-computation/36930be8e480877414fec654169b9b2969168db0/artwork/p2prc-logos/Colored-On-Light-Image.png -------------------------------------------------------------------------------- /artwork/p2prc-logos/P2PRCHaskell.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Akilan1999/p2p-rendering-computation/36930be8e480877414fec654169b9b2969168db0/artwork/p2prc-logos/P2PRCHaskell.png -------------------------------------------------------------------------------- /artwork/p2prc-logos/White-Image.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Akilan1999/p2p-rendering-computation/36930be8e480877414fec654169b9b2969168db0/artwork/p2prc-logos/White-Image.png -------------------------------------------------------------------------------- /build-bindings.sh: -------------------------------------------------------------------------------- 1 | cd Bindings 2 | go build -buildmode=c-shared -o p2prc.so 3 | # mkdir p2prc-mac-amd64 4 | # CGO_ENABLED=1 GOOS=darwin GOARCH=amd64 go build -buildmode=c-shared -o p2prc-mac-amd64/p2prc.so 5 | # mkdir p2prc-mac-arm64 6 | # CGO_ENABLED=1 GOOS=darwin GOARCH=arm64 go build -buildmode=c-shared -o p2prc-mac-arm64/p2prc.so 7 | # mkdir p2prc-windows-arm64 8 | # CGO_ENABLED=1 GOOS=windows GOARCH=arm64 go build -buildmode=c-shared -o p2prc-windows-arm64/p2prc.so 9 | # mkdir p2prc-windows-amd64 10 | # CGO_ENABLED=1 GOOS=windows GOARCH=amd64 go build -buildmode=c-shared -o p2prc-windows-amd64/p2prc.so 11 | # mkdir p2prc-windows-amd64 12 | # CGO_ENABLED=1 GOOS=windows GOARCH=amd64 go build -buildmode=c-shared -o p2prc-windows-amd64/p2prc.so 13 | # mkdir p2prc-windows-arm 14 | # CGO_ENABLED=1 GOOS=windows GOARCH=arm go build -buildmode=c-shared -o p2prc-windows-arm/p2prc.so 15 | # mkdir p2prc-windows-arm 16 | # CGO_ENABLED=1 GOOS=windows GOARCH=arm go build -buildmode=c-shared -o p2prc-windows-arm/p2prc.so 17 | # mkdir p2prc-linux-386 18 | # CGO_ENABLED=1 GOOS=linux GOARCH=386 go build -buildmode=c-shared -o p2prc-linux-386/p2prc.so 19 | 20 | # linux/386 21 | # linux/amd64 22 | # linux/arm 23 | # linux/arm64 24 | # linux/loong64 25 | # linux/mips 26 | # linux/mips64 27 | # linux/mips64le 28 | # linux/mipsle 29 | # linux/ppc64 30 | # linux/ppc64le 31 | # linux/riscv64 32 | # linux/s390x 33 | 34 | -------------------------------------------------------------------------------- /build-haskell.sh: -------------------------------------------------------------------------------- 1 | # This bash script consists of the manaul build script of haskell 2 | go build . 3 | 4 | # Unset p2prc path 5 | unset p2prc 6 | 7 | # Enter the haskell project 8 | cd Bindings/haskell 9 | # Remove exsisting export build 10 | rm -rf exports 11 | # Create exports directory 12 | mkdir exports 13 | # Copy current haskell project into the folder 14 | cp -rf . exports/ 15 | # Copy p2prc binary inside haskell folder 16 | cp ../../p2p-rendering-computation exports/ 17 | 18 | cd exports 19 | # remove exports directory copied inside exports 20 | rm -rf exports/ 21 | 22 | # Set p2prc variable 23 | echo export P2PRC=$PWD 24 | 25 | export P2PRC=$PWD 26 | 27 | ./p2p-rendering-computation --dc 28 | 29 | echo "Run the following commands in the directory: ${PWD}" 30 | echo "To build: cabal build" 31 | echo "To run sample program: cabal run" 32 | -------------------------------------------------------------------------------- /build-python-package.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/bash 2 | 3 | # Create export directory for python 4 | mkdir Bindings/python/export 5 | 6 | # Creating SharedObjects directory for python 7 | mkdir Bindings/python/export/SharedObjects 8 | 9 | # Builds p2prc.h and p2prc.so file 10 | # as apart of Go FFI to interacted 11 | # with later on. 12 | sh build-bindings.sh 13 | 14 | # Copy the shared object files as well to ensure 15 | # that python can interact with the latest snapshot 16 | # of P2PRC 17 | cp Bindings/p2prc.h Bindings/python/export/SharedObjects/ 18 | cp Bindings/p2prc.so Bindings/python/export/SharedObjects/ 19 | 20 | # Copy python library and tests as export as well 21 | cp Bindings/python/* Bindings/python/export/ 22 | 23 | echo "Output is in the Directory Bindings/python/export/" 24 | 25 | # Architectures for Linux 26 | #archs=(amd64 arm64) 27 | # 28 | #for arch in ${archs[@]} 29 | #do 30 | # mkdir Bindings/python/export/SharedObjects/linux-${arch} 31 | # cd Bindings/ 32 | # env GOOS=linux GOARCH=${arch} go build -buildmode=c-shared -o python/export/SharedObjects/linux-${arch}/p2prc.so 33 | # echo "GOOS=linux GOARCH=${arch} go build -buildmode=c-shared -o python/export/SharedObjects/linux-${arch}/p2prc.so" 34 | # cd .. 35 | #done 36 | -------------------------------------------------------------------------------- /client/MAPPort.go: -------------------------------------------------------------------------------- 1 | package client 2 | 3 | import ( 4 | "github.com/Akilan1999/p2p-rendering-computation/config" 5 | "io/ioutil" 6 | "net" 7 | "net/http" 8 | ) 9 | 10 | type ResponseMAPPort struct { 11 | IPAddress string 12 | PortNo string 13 | EntireAddress string 14 | } 15 | 16 | func MAPPort(port string, domainName string, ServerAddress string) (*ResponseMAPPort, error) { 17 | Config, err := config.ConfigInit(nil, nil) 18 | if err != nil { 19 | return nil, err 20 | } 21 | 22 | URL := "http://0.0.0.0:" + Config.ServerPort 23 | 24 | if ServerAddress != "" { 25 | URL = "http://" + ServerAddress 26 | } 27 | 28 | //if version == "version 6" { 29 | URL = URL + "/MAPPort?port=" + port + "&domain_name=" + domainName 30 | //} else { 31 | // URL = "http://" + IP + ":" + serverPort + "/server_info" 32 | //} 33 | resp, err := http.Get(URL) 34 | if err != nil { 35 | return nil, err 36 | } 37 | 38 | // Convert response to byte value 39 | byteValue, err := ioutil.ReadAll(resp.Body) 40 | if err != nil { 41 | return nil, err 42 | } 43 | 44 | host, Exposedport, err := net.SplitHostPort(string(byteValue)) 45 | if err != nil { 46 | return nil, err 47 | } 48 | 49 | var response ResponseMAPPort 50 | response.IPAddress = host 51 | response.PortNo = Exposedport 52 | response.EntireAddress = string(byteValue) 53 | 54 | return &response, nil 55 | } 56 | -------------------------------------------------------------------------------- /client/ServerSpecs.go: -------------------------------------------------------------------------------- 1 | package client 2 | 3 | import ( 4 | "encoding/json" 5 | "fmt" 6 | "github.com/Akilan1999/p2p-rendering-computation/server" 7 | "io/ioutil" 8 | "net/http" 9 | ) 10 | 11 | // GetSpecs Gets Specs from the server such CPU, GPU usage 12 | // and other basic information which helps set a 13 | // cluster of computer 14 | func GetSpecs(IP string) (*server.SysInfo, error) { 15 | var URL string 16 | //version := p2p.Ip4or6(IP) 17 | 18 | //Get port number of the server 19 | //serverPort, err := GetServerPort(IP) 20 | //if err != nil { 21 | // return nil, err 22 | //} 23 | 24 | //if version == "version 6" { 25 | URL = "http://" + IP + "/server_info" 26 | //} else { 27 | // URL = "http://" + IP + ":" + serverPort + "/server_info" 28 | //} 29 | resp, err := http.Get(URL) 30 | if err != nil { 31 | return nil, err 32 | } 33 | 34 | // Convert response to byte value 35 | byteValue, err := ioutil.ReadAll(resp.Body) 36 | if err != nil { 37 | return nil, err 38 | } 39 | 40 | // Create variable for result response type 41 | var serverSpecsResult server.SysInfo 42 | 43 | // Adds byte value to docker.DockerVM struct 44 | json.Unmarshal(byteValue, &serverSpecsResult) 45 | if err != nil { 46 | return nil, err 47 | } 48 | 49 | return &serverSpecsResult, nil 50 | } 51 | 52 | // PrettyPrint print the contents of the obj ( 53 | // Reference: https://stackoverflow.com/questions/24512112/how-to-print-struct-variables-in-console 54 | func PrettyPrint(data interface{}) { 55 | var p []byte 56 | // var err := error 57 | p, err := json.MarshalIndent(data, "", "\t") 58 | if err != nil { 59 | fmt.Println(err) 60 | return 61 | } 62 | fmt.Printf("%s \n", p) 63 | } 64 | -------------------------------------------------------------------------------- /client/TrackContianers_test.go: -------------------------------------------------------------------------------- 1 | package client 2 | 3 | import ( 4 | "fmt" 5 | "github.com/Akilan1999/p2p-rendering-computation/server/docker" 6 | "testing" 7 | ) 8 | 9 | // Tests a scenario where the container are getting tracked 10 | func TestAddTrackContainer(t *testing.T) { 11 | // Create docker container and get SSH port 12 | container1, err := docker.BuildRunContainer(0, "false", "") 13 | if err != nil { 14 | fmt.Println(err) 15 | t.Fail() 16 | } 17 | // Testing the AddTrackContainer Function 18 | err = AddTrackContainer(container1, "0.0.0.0") 19 | if err != nil { 20 | // Killing docker container created 21 | err = docker.StopAndRemoveContainer(container1.ID) 22 | if err != nil { 23 | fmt.Println(err) 24 | t.Fail() 25 | } 26 | fmt.Println(err) 27 | t.Fail() 28 | } 29 | // Killing docker container created 30 | err = docker.StopAndRemoveContainer(container1.ID) 31 | if err != nil { 32 | fmt.Println(err) 33 | t.Fail() 34 | } 35 | } 36 | 37 | // Testing the remove container function 38 | // NOTE: This test can also be considered as a whole flow on the process of 39 | // tracked containers 40 | func TestRemoveTrackedContainer(t *testing.T) { 41 | container1, err := docker.BuildRunContainer(0, "false", "") 42 | if err != nil { 43 | fmt.Println(err) 44 | t.Fail() 45 | } 46 | 47 | container2, err := docker.BuildRunContainer(0, "false", "") 48 | if err != nil { 49 | fmt.Println(err) 50 | t.Fail() 51 | } 52 | 53 | // Testing the AddTrackContainer Function and adding the first container created 54 | err = AddTrackContainer(container1, "0.0.0.0") 55 | if err != nil { 56 | // Killing docker container created 57 | err = docker.StopAndRemoveContainer(container1.ID) 58 | if err != nil { 59 | fmt.Println(err) 60 | t.Fail() 61 | } 62 | fmt.Println(err) 63 | t.Fail() 64 | } 65 | // Killing docker container created 66 | err = docker.StopAndRemoveContainer(container1.ID) 67 | if err != nil { 68 | fmt.Println(err) 69 | t.Fail() 70 | } 71 | 72 | // Testing the AddTrackContainer Function and the adding the second container created 73 | err = AddTrackContainer(container2, "0.0.0.0") 74 | if err != nil { 75 | // Killing docker container created 76 | err = docker.StopAndRemoveContainer(container2.ID) 77 | if err != nil { 78 | fmt.Println(err) 79 | t.Fail() 80 | } 81 | fmt.Println(err) 82 | t.Fail() 83 | } 84 | // Killing docker container created 85 | err = docker.StopAndRemoveContainer(container2.ID) 86 | if err != nil { 87 | fmt.Println(err) 88 | t.Fail() 89 | } 90 | 91 | // Removing container 1 from the tracked list 92 | err = RemoveTrackedContainer(container1.ID) 93 | if err != nil { 94 | fmt.Println(err) 95 | t.Fail() 96 | } 97 | 98 | // Removing container 2 from the tracked list 99 | err = RemoveTrackedContainer(container2.ID) 100 | if err != nil { 101 | fmt.Println(err) 102 | t.Fail() 103 | } 104 | } 105 | 106 | // Test function that checks if the ID belongs to 107 | // a group or container running 108 | func TestCheckID(t *testing.T) { 109 | id := "grp123" 110 | checkID, err := CheckID(id) 111 | if err != nil { 112 | fmt.Println(err) 113 | t.Fail() 114 | } 115 | if checkID == "group" { 116 | fmt.Println("pass") 117 | } else { 118 | t.Fail() 119 | } 120 | } 121 | -------------------------------------------------------------------------------- /client/clientIPTable/AddCustomInformationToIPTable.go: -------------------------------------------------------------------------------- 1 | package clientIPTable 2 | 3 | import ( 4 | "errors" 5 | "github.com/Akilan1999/p2p-rendering-computation/config" 6 | "github.com/Akilan1999/p2p-rendering-computation/p2p" 7 | ) 8 | 9 | func AddCustomInformationToIPTable(text string) error { 10 | // Get config information 11 | Config, err := config.ConfigInit(nil, nil) 12 | if err != nil { 13 | return err 14 | } 15 | 16 | // Get IPTable information 17 | table, err := p2p.ReadIpTable() 18 | if err != nil { 19 | return err 20 | } 21 | 22 | found := false 23 | 24 | for i, _ := range table.IpAddress { 25 | if table.IpAddress[i].Name == Config.MachineName { 26 | table.IpAddress[i].CustomInformation = text 27 | found = true 28 | } 29 | } 30 | 31 | if found { 32 | table.WriteIpTable() 33 | // update IPTable after modified entry 34 | UpdateIpTableListClient() 35 | } else { 36 | return errors.New("start server with p2prc -s as the server is currently not running") 37 | } 38 | 39 | return nil 40 | } 41 | -------------------------------------------------------------------------------- /client/clientIPTable/docs.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | # clientIPTable 4 | 5 | ```go 6 | import "github.com/Akilan1999/p2p-rendering-computation/client/clientIPTable" 7 | ``` 8 | 9 | ## Index 10 | 11 | - [func AddCustomInformationToIPTable\(text string\) error](<#AddCustomInformationToIPTable>) 12 | - [func RemoveOfflineNodes\(\) error](<#RemoveOfflineNodes>) 13 | - [func UpdateIpTable\(IpAddress string, serverPort string, wg \*sync.WaitGroup\) error](<#UpdateIpTable>) 14 | - [func UpdateIpTableListClient\(\) error](<#UpdateIpTableListClient>) 15 | - [func UploadMultipartFile\(client http.Client, uri, key, path string\) \(\[\]byte, error\)](<#UploadMultipartFile>) 16 | 17 | 18 | 19 | ## func [AddCustomInformationToIPTable]() 20 | 21 | ```go 22 | func AddCustomInformationToIPTable(text string) error 23 | ``` 24 | 25 | 26 | 27 | 28 | ## func [RemoveOfflineNodes]() 29 | 30 | ```go 31 | func RemoveOfflineNodes() error 32 | ``` 33 | 34 | 35 | 36 | 37 | ## func [UpdateIpTable]() 38 | 39 | ```go 40 | func UpdateIpTable(IpAddress string, serverPort string, wg *sync.WaitGroup) error 41 | ``` 42 | 43 | UpdateIpTable Does the following to update it's IP table 44 | 45 | 46 | ## func [UpdateIpTableListClient]() 47 | 48 | ```go 49 | func UpdateIpTableListClient() error 50 | ``` 51 | 52 | UpdateIpTableListClient updates IP tables \(Default 3 hops\) based on server information available on the ip tables 53 | 54 | 55 | ## func [UploadMultipartFile]() 56 | 57 | ```go 58 | func UploadMultipartFile(client http.Client, uri, key, path string) ([]byte, error) 59 | ``` 60 | 61 | 62 | 63 | Generated by [gomarkdoc]() 64 | -------------------------------------------------------------------------------- /client/clientIPTable/iptable_test.go: -------------------------------------------------------------------------------- 1 | package clientIPTable 2 | 3 | import ( 4 | "testing" 5 | ) 6 | 7 | func TestUpdateIpTableListClient(t *testing.T) { 8 | err := UpdateIpTableListClient() 9 | 10 | if err != nil { 11 | t.Error(err) 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /client/grouptrackcontainers.json: -------------------------------------------------------------------------------- 1 | {} -------------------------------------------------------------------------------- /client/trackcontainers.json: -------------------------------------------------------------------------------- 1 | {} -------------------------------------------------------------------------------- /config/docs.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | # config 4 | 5 | ```go 6 | import "github.com/Akilan1999/p2p-rendering-computation/config" 7 | ``` 8 | 9 | ## Index 10 | 11 | - [func GetCurrentPath\(\) \(string, error\)](<#GetCurrentPath>) 12 | - [func GetEnvName\(\) string](<#GetEnvName>) 13 | - [func GetPathP2PRC\(Envname string\) \(string, error\)](<#GetPathP2PRC>) 14 | - [func SetEnvName\(EnvName string\) error](<#SetEnvName>) 15 | - [type Config](<#Config>) 16 | - [func ConfigInit\(defaultsParameter map\[string\]interface\{\}, CustomConfig interface\{\}, envNameOptional ...string\) \(\*Config, error\)](<#ConfigInit>) 17 | - [func \(c \*Config\) GetPublicKey\(\) \(string, error\)](<#Config.GetPublicKey>) 18 | - [func \(c \*Config\) WriteConfig\(\) error](<#Config.WriteConfig>) 19 | 20 | 21 | 22 | ## func [GetCurrentPath]() 23 | 24 | ```go 25 | func GetCurrentPath() (string, error) 26 | ``` 27 | 28 | GetCurrentPath Getting P2PRC Directory from environment variable 29 | 30 | 31 | ## func [GetEnvName]() 32 | 33 | ```go 34 | func GetEnvName() string 35 | ``` 36 | 37 | 38 | 39 | 40 | ## func [GetPathP2PRC]() 41 | 42 | ```go 43 | func GetPathP2PRC(Envname string) (string, error) 44 | ``` 45 | 46 | GetPathP2PRC Getting P2PRC Directory from environment variable 47 | 48 | 49 | ## func [SetEnvName]() 50 | 51 | ```go 52 | func SetEnvName(EnvName string) error 53 | ``` 54 | 55 | SetEnvName Sets the environment name This is to ensure that the Path of your project is detected from your environment variable This is useful when extending the use case of P2PRC 56 | 57 | 58 | ## type [Config]() 59 | 60 | 61 | 62 | ```go 63 | type Config struct { 64 | MachineName string 65 | IPTable string 66 | DockerContainers string 67 | DefaultDockerFile string 68 | DockerRunLogs string 69 | SpeedTestFile string 70 | IPV6Address string 71 | PluginPath string 72 | TrackContainersPath string 73 | ServerPort string 74 | ProxyPort string 75 | GroupTrackContainersPath string 76 | FRPServerPort string 77 | BehindNAT string 78 | IPTableKey string 79 | PublicKeyFile string 80 | PrivateKeyFile string 81 | PemFile string 82 | KeyFile string 83 | BareMetal bool 84 | UnsafeMode bool 85 | CustomConfig interface{} 86 | } 87 | ``` 88 | 89 | 90 | ### func [ConfigInit]() 91 | 92 | ```go 93 | func ConfigInit(defaultsParameter map[string]interface{}, CustomConfig interface{}, envNameOptional ...string) (*Config, error) 94 | ``` 95 | 96 | ConfigInit Pass environment name as an optional parameter 97 | 98 | 99 | ### func \(\*Config\) [GetPublicKey]() 100 | 101 | ```go 102 | func (c *Config) GetPublicKey() (string, error) 103 | ``` 104 | 105 | GetPublicKey Gets public key of the current machine based on the path provided on the config file 106 | 107 | 108 | ### func \(\*Config\) [WriteConfig]() 109 | 110 | ```go 111 | func (c *Config) WriteConfig() error 112 | ``` 113 | 114 | 115 | 116 | Generated by [gomarkdoc]() 117 | -------------------------------------------------------------------------------- /config/generate/config_test.go: -------------------------------------------------------------------------------- 1 | package generate 2 | 3 | import ( 4 | "fmt" 5 | "github.com/Akilan1999/p2p-rendering-computation/config" 6 | "os" 7 | "testing" 8 | ) 9 | 10 | // func TestConfigInit(t *testing.T) { 11 | // _, err := config.ConfigInit(nil) 12 | // if err != nil { 13 | // t.Error(err) 14 | // } 15 | // } 16 | 17 | // func TestSetDefaults(t *testing.T) { 18 | // _, err := SetDefaults("", false) 19 | // if err != nil { 20 | // t.Error(err) 21 | // } 22 | // } 23 | 24 | func TestGetCurrentPath(t *testing.T) { 25 | path, err := GetCurrentPath() 26 | if err != nil { 27 | fmt.Println(err) 28 | t.Error(err) 29 | } 30 | fmt.Println(path) 31 | } 32 | 33 | func TestGetPathP2PRC(t *testing.T) { 34 | path, err := config.GetPathP2PRC("") 35 | if err != nil { 36 | fmt.Println(err) 37 | t.Error(err) 38 | } 39 | fmt.Println(path) 40 | } 41 | 42 | func TestSetEnvName(t *testing.T) { 43 | // Create an Env variable TEST with the value "lol" 44 | err := os.Setenv("TEST", "lol") 45 | if err != nil { 46 | fmt.Println(err) 47 | t.Error(err) 48 | } 49 | // Sets the environment variable as the default to read 50 | // for P2PRC 51 | err = config.SetEnvName("TEST") 52 | if err != nil { 53 | fmt.Println(err) 54 | t.Error(err) 55 | } 56 | 57 | // Checks if the output for the default read is "lol" 58 | path, err := config.GetPathP2PRC("") 59 | if err != nil { 60 | fmt.Println(err) 61 | t.Error(err) 62 | } 63 | fmt.Println(path) 64 | } 65 | -------------------------------------------------------------------------------- /config/generate/gernerate_test.go: -------------------------------------------------------------------------------- 1 | package generate 2 | 3 | import ( 4 | "fmt" 5 | "github.com/Akilan1999/p2p-rendering-computation/config" 6 | "testing" 7 | ) 8 | 9 | type CustomConfig struct { 10 | Test string 11 | } 12 | 13 | // Test case to generate defaults with custom data-structure 14 | func TestSetDefaults(t *testing.T) { 15 | setDefaults, err := SetDefaults("", true, &CustomConfig{Test: "lol"}, true) 16 | if err != nil { 17 | fmt.Println(err) 18 | t.Fail() 19 | return 20 | } 21 | 22 | fmt.Println(setDefaults) 23 | 24 | var c CustomConfig 25 | 26 | _, err = config.ConfigInit(nil, &c) 27 | if err != nil { 28 | fmt.Println(err) 29 | t.Fail() 30 | return 31 | } 32 | 33 | fmt.Println(c) 34 | 35 | } 36 | 37 | // Test case to generate public and private keys 38 | func TestGeneratePublicAndPrivateKeys(t *testing.T) { 39 | MakeSSHKeyPair("test.pub", "test.prv") 40 | } 41 | -------------------------------------------------------------------------------- /config/generate/helperFunctions.go: -------------------------------------------------------------------------------- 1 | package generate 2 | 3 | import ( 4 | "io" 5 | "os" 6 | ) 7 | 8 | // Exists reports whether the named file or directory exists. 9 | func fileExists(name string) bool { 10 | if _, err := os.Stat(name); err != nil { 11 | if os.IsNotExist(err) { 12 | return false 13 | } 14 | } 15 | return true 16 | } 17 | 18 | // Copy the src file to dst. Any existing file will be overwritten and will not 19 | // copy file attributes. 20 | // Source: https://stackoverflow.com/questions/21060945/simple-way-to-copy-a-file 21 | func Copy(src, dst string) error { 22 | in, err := os.Open(src) 23 | if err != nil { 24 | return err 25 | } 26 | defer in.Close() 27 | 28 | out, err := os.Create(dst) 29 | if err != nil { 30 | return err 31 | } 32 | defer out.Close() 33 | 34 | _, err = io.Copy(out, in) 35 | if err != nil { 36 | return err 37 | } 38 | return out.Close() 39 | } 40 | -------------------------------------------------------------------------------- /default.nix: -------------------------------------------------------------------------------- 1 | { pkgs ? ( 2 | let 3 | inherit (builtins) fetchTree fromJSON readFile; 4 | inherit ((fromJSON (readFile ./flake.lock)).nodes) nixpkgs gomod2nix; 5 | in 6 | import (fetchTree nixpkgs.locked) { 7 | overlays = [ 8 | (import "${fetchTree gomod2nix.locked}/overlay.nix") 9 | ]; 10 | } 11 | ) 12 | }: 13 | 14 | pkgs.buildGoApplication { 15 | pname = "p2p-rendering-computation"; 16 | version = "2.0.0"; 17 | pwd = ./.; 18 | src = ./.; 19 | modules = ./gomod2nix.toml; 20 | doCheck = false; 21 | } 22 | -------------------------------------------------------------------------------- /flake.lock: -------------------------------------------------------------------------------- 1 | { 2 | "nodes": { 3 | "flake-utils": { 4 | "inputs": { 5 | "systems": "systems" 6 | }, 7 | "locked": { 8 | "lastModified": 1731533236, 9 | "narHash": "sha256-l0KFg5HjrsfsO/JpG+r7fRrqm12kzFHyUHqHCVpMMbI=", 10 | "owner": "numtide", 11 | "repo": "flake-utils", 12 | "rev": "11707dc2f618dd54ca8739b309ec4fc024de578b", 13 | "type": "github" 14 | }, 15 | "original": { 16 | "owner": "numtide", 17 | "repo": "flake-utils", 18 | "type": "github" 19 | } 20 | }, 21 | "gomod2nix": { 22 | "inputs": { 23 | "flake-utils": [ 24 | "flake-utils" 25 | ], 26 | "nixpkgs": [ 27 | "nixpkgs" 28 | ] 29 | }, 30 | "locked": { 31 | "lastModified": 1745875161, 32 | "narHash": "sha256-0YkWCS13jpoo3+sX/3kcgdxBNt1VZTmvF+FhZb4rFKI=", 33 | "owner": "nix-community", 34 | "repo": "gomod2nix", 35 | "rev": "2cbd7fdd6eeab65c494cc426e18f4e4d2a5e35c0", 36 | "type": "github" 37 | }, 38 | "original": { 39 | "owner": "nix-community", 40 | "repo": "gomod2nix", 41 | "type": "github" 42 | } 43 | }, 44 | "nixpkgs": { 45 | "locked": { 46 | "lastModified": 1748460289, 47 | "narHash": "sha256-7doLyJBzCllvqX4gszYtmZUToxKvMUrg45EUWaUYmBg=", 48 | "owner": "NixOS", 49 | "repo": "nixpkgs", 50 | "rev": "96ec055edbe5ee227f28cdbc3f1ddf1df5965102", 51 | "type": "github" 52 | }, 53 | "original": { 54 | "owner": "NixOS", 55 | "ref": "nixos-unstable", 56 | "repo": "nixpkgs", 57 | "type": "github" 58 | } 59 | }, 60 | "root": { 61 | "inputs": { 62 | "flake-utils": "flake-utils", 63 | "gomod2nix": "gomod2nix", 64 | "nixpkgs": "nixpkgs" 65 | } 66 | }, 67 | "systems": { 68 | "locked": { 69 | "lastModified": 1681028828, 70 | "narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=", 71 | "owner": "nix-systems", 72 | "repo": "default", 73 | "rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e", 74 | "type": "github" 75 | }, 76 | "original": { 77 | "owner": "nix-systems", 78 | "repo": "default", 79 | "type": "github" 80 | } 81 | } 82 | }, 83 | "root": "root", 84 | "version": 7 85 | } 86 | -------------------------------------------------------------------------------- /flake.nix: -------------------------------------------------------------------------------- 1 | { 2 | description = "P2PRC nix flake"; 3 | 4 | inputs = { 5 | 6 | nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable"; 7 | 8 | flake-utils = { 9 | url = "github:numtide/flake-utils"; 10 | }; 11 | 12 | gomod2nix = { 13 | url = "github:nix-community/gomod2nix"; 14 | inputs.nixpkgs.follows = "nixpkgs"; 15 | inputs.flake-utils.follows = "flake-utils"; 16 | }; 17 | 18 | }; 19 | 20 | outputs = 21 | { 22 | nixpkgs, 23 | flake-utils, 24 | gomod2nix, 25 | ... 26 | }: 27 | let 28 | 29 | bindingsOverlay = import ./nix/overlays/bindings.nix; 30 | coreOverlay = (final: prev: { 31 | p2prc = final.callPackage ./. { }; 32 | }); 33 | 34 | in 35 | (flake-utils.lib.eachDefaultSystem (system: 36 | let 37 | 38 | pkgs = import nixpkgs { 39 | inherit system; 40 | overlays = [ 41 | gomod2nix.overlays.default 42 | coreOverlay 43 | bindingsOverlay 44 | ]; 45 | }; 46 | 47 | # The current default sdk for macOS fails to compile go projects, so we use a newer one for now. 48 | # This has no effect on other platforms. 49 | callPackage = pkgs.darwin.apple_sdk_11_0.callPackage or pkgs.callPackage; 50 | 51 | p2prcDefault = callPackage ./. { }; 52 | 53 | in 54 | { 55 | packages.default = p2prcDefault; 56 | 57 | devShells.default = pkgs.mkShell { 58 | buildInputs = with pkgs; [ 59 | go 60 | gopls 61 | gotools 62 | go-tools 63 | gomod2nix.packages.${system}.default 64 | sqlite-interactive 65 | ]; 66 | }; 67 | 68 | packages.initHaskellProject = pkgs.writeShellApplication { 69 | name = "initHaskellProject"; 70 | runtimeInputs = with pkgs; [ 71 | ghc 72 | cabal2nix 73 | cabal-install 74 | git 75 | p2prcDefault 76 | ]; 77 | text = 78 | '' 79 | clear 80 | 81 | if [ "$#" -eq 0 ]; then 82 | echo "No arguments provided." 83 | echo "Please provide the name of your project" 84 | echo "nix run git+https://github:akilan1999/p2p-rendering-computation#initHaskellProject -- " 85 | exit 1; 86 | fi 87 | 88 | PROJECT_DIR="$1" 89 | 90 | mkdir "$PROJECT_DIR" 91 | 92 | cd "$PROJECT_DIR" 93 | 94 | git init . 95 | clear 96 | 97 | cabal init --exe --simple 98 | 99 | sed -i 's/base.*$/base, p2prc/' "$PROJECT_DIR".cabal 100 | 101 | cabal2nix . > ./cabal.nix; 102 | 103 | git add . 104 | 105 | clear 106 | 107 | echo -e "run the following commands to finish nix development and production environment:\n\n" 108 | 109 | echo -e "cd $PROJECT_DIR" 110 | echo -e "nix flake init -t github:akilan1999/p2p-rendering-computation#haskell" 111 | echo -e "nix develop" 112 | echo -e "nix run" 113 | echo -e "\n\n" 114 | 115 | ''; 116 | }; 117 | } 118 | )) // 119 | { 120 | overlays = { 121 | default = coreOverlay; 122 | bindings = bindingsOverlay; 123 | }; 124 | templates.haskell = { 125 | path = ./nix/templates/haskell; 126 | description = "Haskell Bindings to p2prc protocol"; 127 | }; 128 | }; 129 | } 130 | -------------------------------------------------------------------------------- /install-binary.bat: -------------------------------------------------------------------------------- 1 | setx PATH "%PATH%;%cd%" 2 | setx P2PRC "%cd%" 3 | 4 | p2p-rendering-computation.exe --dc -------------------------------------------------------------------------------- /install-binary.sh: -------------------------------------------------------------------------------- 1 | # This script setups up the project P2PRC 2 | echo '# Add the following paths to .bashrc or .zshrc based on the configuration you have set' 3 | echo export P2PRC=$PWD 4 | echo export PATH=$PWD:\${PATH} 5 | export P2PRC=${PWD} 6 | export PATH=${PWD}:${PATH} 7 | 8 | ./p2p-rendering-computation --dc -------------------------------------------------------------------------------- /install.bat: -------------------------------------------------------------------------------- 1 | go build -o p2prc.exe 2 | 3 | setx PATH "%PATH%;%cd%" 4 | setx P2PRC "%cd%" 5 | 6 | p2prc --dc -------------------------------------------------------------------------------- /install.sh: -------------------------------------------------------------------------------- 1 | # This script setups up the project P2PRC 2 | # Call: sh install.sh 3 | echo '# Add the following paths to .bashrc or .zshrc based on the configuration you have set' 4 | echo export P2PRC=$PWD 5 | echo export PATH=$PWD:\${PATH} 6 | export P2PRC=${PWD} 7 | export PATH=${PWD}:${PATH} 8 | 9 | # Expects an argument of the name of the binary 10 | go build -o ${1} 11 | ./p2prc --dc -------------------------------------------------------------------------------- /main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "log" 5 | "os" 6 | "os/signal" 7 | "syscall" 8 | 9 | "github.com/Akilan1999/p2p-rendering-computation/cmd" 10 | "github.com/urfave/cli/v2" 11 | ) 12 | 13 | // VERSION specifies the version of the platform 14 | var VERSION = "3.0.0" 15 | var mode string 16 | 17 | // Varaibles if mode is client 18 | var OS, Pull_location, Run_script string 19 | var List_servers, Ip_table bool 20 | 21 | // To be implemented later on 22 | func getFireSignalsChannel() chan os.Signal { 23 | 24 | c := make(chan os.Signal, 1) 25 | signal.Notify(c, 26 | // https://www.gnu.org/software/libc/manual/html_node/Termination-Signals.html 27 | syscall.SIGTERM, // "the normal way to politely ask a program to terminate" 28 | syscall.SIGINT, // Ctrl+C 29 | syscall.SIGQUIT, // Ctrl-\ 30 | syscall.SIGKILL, // "always fatal", "SIGKILL and SIGSTOP may not be caught by a program" 31 | syscall.SIGHUP, // "terminal is disconnected" 32 | ) 33 | return c 34 | 35 | } 36 | 37 | func main() { 38 | app := cli.NewApp() 39 | app.Name = "p2p-rendering-computation" 40 | app.Usage = "p2p cli application to create and access VMs in other servers" 41 | app.Version = VERSION 42 | app.Flags = cmd.AppConfigFlags 43 | app.Action = cmd.CliAction 44 | 45 | err := app.Run(os.Args) 46 | if err != nil { 47 | log.Fatal(err) 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /main.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | # p2p\-rendering\-computation 4 | 5 | ```go 6 | import "github.com/Akilan1999/p2p-rendering-computation" 7 | ``` 8 | 9 | ## Index 10 | 11 | - [Variables](<#variables>) 12 | 13 | 14 | ## Variables 15 | 16 | 17 | 18 | ```go 19 | var List_servers, Ip_table bool 20 | ``` 21 | 22 | Varaibles if mode is client 23 | 24 | ```go 25 | var OS, Pull_location, Run_script string 26 | ``` 27 | 28 | VERSION specifies the version of the platform 29 | 30 | ```go 31 | var VERSION = "2.0.0" 32 | ``` 33 | 34 | Generated by [gomarkdoc]() 35 | -------------------------------------------------------------------------------- /nix/overlays/bindings.nix: -------------------------------------------------------------------------------- 1 | final: prev: { 2 | haskellPackages = prev.haskellPackages.override { 3 | overrides = hfinal: hprev: { 4 | p2prc = hfinal.callPackage ../../Bindings/Haskell/project.nix { }; 5 | }; 6 | }; 7 | } 8 | -------------------------------------------------------------------------------- /nix/templates/haskell/flake.nix: -------------------------------------------------------------------------------- 1 | { 2 | description = "Start of Haskell P2PRC flake"; 3 | 4 | inputs = 5 | { 6 | nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable"; 7 | 8 | flake-util.url = "github:numtide/flake-utils"; 9 | 10 | p2prc-flake.url = "github:akilan1999/p2p-rendering-computation"; 11 | }; 12 | 13 | outputs = { nixpkgs, p2prc-flake, flake-utils, ... }: 14 | (flake-utils.lib.eachDefaultSystem (system: 15 | let 16 | 17 | pkgs = import nixpkgs { 18 | inherit system; 19 | overlays = [ 20 | p2prc-flake.overlays.default 21 | p2prc-flake.overlays.bindings 22 | ]; 23 | }; 24 | 25 | in { 26 | 27 | packages.default = pkgs.haskellPackages.callPackage ./cabal.nix { }; 28 | 29 | devShells.default = pkgs.haskellPackages.shellFor { 30 | 31 | packages = p: [ 32 | (p.callPackage ./cabal.nix { }) 33 | ]; 34 | 35 | buildInputs = with pkgs; [ 36 | p2prc-flake.packages.${system}.default 37 | ghc 38 | cabal2nix 39 | cabal-install 40 | ]; 41 | 42 | shellHook = '' 43 | cabal2nix . > ./cabal.nix 44 | ''; 45 | }; 46 | } 47 | )); 48 | } 49 | -------------------------------------------------------------------------------- /p2p/README: -------------------------------------------------------------------------------- 1 | P2P module 2 | =========== 3 | (Techniques to get over NAT) 4 | - UPNP implementation 5 | - DMZ to be used if UPNP does not work 6 | - Port forwarding for future release 7 | 8 | (Discovery of Nodes) 9 | - Connect to reliable connection (that has some knowledge) 10 | - Check if the connection is still open (If not instruct the server to remove from table) 11 | - According speed tests 12 | - Send list of servers connection open 13 | - default 100 MB (to store tables of ip records) 14 | -------------------------------------------------------------------------------- /p2p/frp/docs.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | # frp 4 | 5 | ```go 6 | import "github.com/Akilan1999/p2p-rendering-computation/p2p/frp" 7 | ``` 8 | 9 | ## Index 10 | 11 | - [func GetFRPServerPort\(host string\) \(string, error\)](<#GetFRPServerPort>) 12 | - [func StartFRPCDockerContainer\(ipaddress string, port string, Docker \*docker.DockerVM\) \(\*docker.DockerVM, error\)](<#StartFRPCDockerContainer>) 13 | - [func StartFRPClientForServer\(ipaddress string, port string, localport string, remoteport string\) \(string, error\)](<#StartFRPClientForServer>) 14 | - [func StartFRPProxyFromRandom\(\) \(int, error\)](<#StartFRPProxyFromRandom>) 15 | - [type Client](<#Client>) 16 | - [func \(c \*Client\) StartFRPClient\(\) error](<#Client.StartFRPClient>) 17 | - [type ClientMapping](<#ClientMapping>) 18 | - [type Server](<#Server>) 19 | - [func \(s \*Server\) StartFRPServer\(\) error](<#Server.StartFRPServer>) 20 | 21 | 22 | 23 | ## func [GetFRPServerPort]() 24 | 25 | ```go 26 | func GetFRPServerPort(host string) (string, error) 27 | ``` 28 | 29 | GetFRPServerPort Gets the port no from the FRPServer to establish the FRP connection needed. 30 | 31 | 32 | ## func [StartFRPCDockerContainer]() 33 | 34 | ```go 35 | func StartFRPCDockerContainer(ipaddress string, port string, Docker *docker.DockerVM) (*docker.DockerVM, error) 36 | ``` 37 | 38 | 39 | 40 | 41 | ## func [StartFRPClientForServer]() 42 | 43 | ```go 44 | func StartFRPClientForServer(ipaddress string, port string, localport string, remoteport string) (string, error) 45 | ``` 46 | 47 | StartFRPClientForServer Starts Server using FRP server returns back a port remote port is a custom external port a user would want to open. This under the assumption the user knows the exact port available in server doing the TURN connection. 48 | 49 | 50 | ## func [StartFRPProxyFromRandom]() 51 | 52 | ```go 53 | func StartFRPProxyFromRandom() (int, error) 54 | ``` 55 | 56 | StartFRPProxyFromRandom starts reverse proxy server based on a random port generated 57 | 58 | 59 | ## type [Client]() 60 | 61 | Client This struct stores client information with server proxy connected 62 | 63 | ```go 64 | type Client struct { 65 | Name string 66 | Server *Server 67 | ClientMappings []ClientMapping 68 | } 69 | ``` 70 | 71 | 72 | ### func \(\*Client\) [StartFRPClient]() 73 | 74 | ```go 75 | func (c *Client) StartFRPClient() error 76 | ``` 77 | 78 | StartFRPClient Starts FRP client 79 | 80 | 81 | ## type [ClientMapping]() 82 | 83 | ClientMapping Stores client mapping ports to proxy server 84 | 85 | ```go 86 | type ClientMapping struct { 87 | LocalIP string 88 | LocalPort int 89 | RemotePort int 90 | } 91 | ``` 92 | 93 | 94 | ## type [Server]() 95 | 96 | 97 | 98 | ```go 99 | type Server struct { 100 | // contains filtered or unexported fields 101 | } 102 | ``` 103 | 104 | 105 | ### func \(\*Server\) [StartFRPServer]() 106 | 107 | ```go 108 | func (s *Server) StartFRPServer() error 109 | ``` 110 | 111 | 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. 112 | 113 | Generated by [gomarkdoc]() 114 | -------------------------------------------------------------------------------- /p2p/frp/server.go: -------------------------------------------------------------------------------- 1 | package frp 2 | 3 | import ( 4 | "github.com/fatedier/frp/pkg/config" 5 | "github.com/fatedier/frp/server" 6 | "github.com/phayes/freeport" 7 | "io/ioutil" 8 | "net/http" 9 | ) 10 | 11 | type Server struct { 12 | address string 13 | port int 14 | } 15 | 16 | // StartFRPProxyFromRandom starts 17 | // reverse proxy server based on 18 | // a random port generated 19 | func StartFRPProxyFromRandom() (int, error) { 20 | // gets current configuration 21 | //config, err := configP2PRC.ConfigInit() 22 | //if err != nil { 23 | // return err 24 | //} 25 | 26 | var s Server 27 | s.address = "0.0.0.0" 28 | 29 | // use random port 30 | OpenPorts, err := freeport.GetFreePorts(1) 31 | if err != nil { 32 | return 0, err 33 | } 34 | 35 | s.port = OpenPorts[0] 36 | 37 | // start FRP server 38 | 39 | go s.StartFRPServer() 40 | 41 | return OpenPorts[0], nil 42 | 43 | } 44 | 45 | // StartFRPServer The initial plan is only support reverse proxy 46 | // for TCP ports 47 | // This function starts a server that can act as a reverse 48 | // proxy for nodes behind NAT. 49 | func (s *Server) StartFRPServer() error { 50 | baseConfig := config.GetDefaultServerConf() 51 | baseConfig.BindAddr = s.address 52 | 53 | baseConfig.BindPort = s.port 54 | service, err := server.NewService(baseConfig) 55 | if err != nil { 56 | return err 57 | } 58 | 59 | service.Run() 60 | return nil 61 | } 62 | 63 | // GetFRPServerPort Gets the port no from the FRPServer to establish 64 | // the FRP connection needed. 65 | func GetFRPServerPort(host string) (string, error) { 66 | resp, err := http.Get(host + "/FRPPort") 67 | 68 | if err != nil { 69 | return "", err 70 | } 71 | 72 | defer resp.Body.Close() 73 | 74 | body, err := ioutil.ReadAll(resp.Body) 75 | 76 | if err != nil { 77 | return "", err 78 | } 79 | 80 | return string(body), nil 81 | } 82 | -------------------------------------------------------------------------------- /p2p/frp/server_test.go: -------------------------------------------------------------------------------- 1 | package frp 2 | 3 | import ( 4 | "fmt" 5 | "testing" 6 | "time" 7 | ) 8 | 9 | // Testing scenario FRPServer 10 | func TestStartFRPServer(t *testing.T) { 11 | var s Server 12 | s.address = "127.0.0.1" 13 | s.port = 8808 14 | err := s.StartFRPServer() 15 | if err != nil { 16 | fmt.Println(err) 17 | t.Fail() 18 | } 19 | } 20 | 21 | // Testing scenario FRPServer and FRPClient connection 22 | func TestStartFRPClient(t *testing.T) { 23 | var s Server 24 | s.address = "127.0.0.1" 25 | s.port = 8808 26 | go s.StartFRPServer() 27 | 28 | time.Sleep(3 * time.Second) 29 | 30 | // Sample test client 31 | var c Client 32 | c.Server = &s 33 | c.ClientMappings = []ClientMapping{ 34 | { 35 | LocalIP: "127.0.0.1", 36 | LocalPort: 22, 37 | RemotePort: 3301, 38 | }, 39 | } 40 | 41 | err := c.StartFRPClient() 42 | if err != nil { 43 | fmt.Println(err) 44 | t.Fail() 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /p2p/ip_table.json: -------------------------------------------------------------------------------- 1 | { 2 | "ip_address": [ 3 | { 4 | "Name": "Node1", 5 | "IPV4": "139.59.162.154", 6 | "IPV6": "", 7 | "Latency": 0, 8 | "Download": 0, 9 | "Upload": 0, 10 | "ServerPort": "8078", 11 | "NAT": "False", 12 | "EscapeImplementation": "", 13 | "CustomInformation": null 14 | } 15 | ] 16 | } -------------------------------------------------------------------------------- /p2p/iptable_test.go: -------------------------------------------------------------------------------- 1 | package p2p 2 | 3 | import ( 4 | "fmt" 5 | "testing" 6 | ) 7 | 8 | func TestReadIpTable(t *testing.T) { 9 | json, err := ReadIpTable() 10 | if err != nil { 11 | t.Fatal(err) 12 | } 13 | 14 | err = json.WriteIpTable() 15 | if err != nil { 16 | t.Fatal(err) 17 | } 18 | 19 | err = PrintIpTable() 20 | if err != nil { 21 | t.Fatal(err) 22 | } 23 | } 24 | 25 | // Testing is a IPV6 address is returned 26 | func TestGetCurrentIPV6(t *testing.T) { 27 | res, err := GetCurrentIPV6() 28 | 29 | if err != nil { 30 | t.Error(err) 31 | } 32 | 33 | fmt.Println(res) 34 | } 35 | 36 | // This test ensures that the duplicate function works as intended 37 | func TestIpAddresses_RemoveDuplicates(t *testing.T) { 38 | var testduplicates IpAddresses 39 | var duplicateaddress1 IpAddress 40 | var duplicateaddress2 IpAddress 41 | 42 | duplicateaddress1.Ipv6="2001:8f8:172d:ee93:7588:ad57:c351:3309" 43 | duplicateaddress1.Ipv4="0.0.0.0" 44 | 45 | duplicateaddress2.Ipv6="2001:8f8:172d:ee93:7588:ad57:c351:3309" 46 | duplicateaddress2.Ipv4="0.0.0.0" 47 | 48 | testduplicates.IpAddress = append(testduplicates.IpAddress, duplicateaddress1) 49 | testduplicates.IpAddress = append(testduplicates.IpAddress, duplicateaddress2) 50 | 51 | err := testduplicates.RemoveDuplicates() 52 | if err != nil { 53 | t.Error(err) 54 | } 55 | 56 | if len(testduplicates.IpAddress) == 2 { 57 | t.Fail() 58 | } 59 | 60 | } 61 | 62 | func TestViewNetworkInterface(t *testing.T) { 63 | err := ViewNetworkInterface() 64 | if err != nil { 65 | t.Error() 66 | } 67 | } 68 | 69 | func TestIp4or6(t *testing.T) { 70 | // This test ensures that the ipv6 address gets detected 71 | test := "2001:8f8:172d:7e27:4f23:ae4:bce5:e037" 72 | res := Ip4or6(test) 73 | if res != "version 6" { 74 | t.Fail() 75 | } 76 | 77 | } 78 | -------------------------------------------------------------------------------- /p2p/speedtest.go: -------------------------------------------------------------------------------- 1 | package p2p 2 | 3 | import ( 4 | "github.com/Akilan1999/p2p-rendering-computation/config" 5 | ) 6 | 7 | // SpeedTest Runs a speed test and does updates IP tables accordingly 8 | func (ip *IpAddresses) SpeedTest() error { 9 | 10 | //temp variable to store elements IP addresses and other information 11 | // of IP addresses that are pingable 12 | var ActiveIP IpAddresses 13 | 14 | // Index to remove from struct 15 | for _, value := range ip.IpAddress { 16 | 17 | var err error 18 | //if len(ip.IpAddress) == 1 { 19 | // i = 0 20 | //} 21 | 22 | // Ping Test 23 | err = value.PingTest() 24 | 25 | if err != nil { 26 | continue 27 | } 28 | 29 | //Upload Speed Test 30 | //err = value.UploadSpeed() 31 | //if err != nil { 32 | // return err 33 | //} 34 | // 35 | //err = value.DownloadSpeed() 36 | //if err != nil { 37 | // return err 38 | //} 39 | 40 | //Set value to the list 41 | 42 | ActiveIP.IpAddress = append(ActiveIP.IpAddress, value) 43 | } 44 | 45 | ip.IpAddress = ActiveIP.IpAddress 46 | 47 | err := ip.WriteIpTable() 48 | if err != nil { 49 | return err 50 | } 51 | 52 | return nil 53 | } 54 | 55 | // SpeedTestUpdatedIPTable Called when ip tables from httpclient/server is also passed on 56 | func (ip *IpAddresses) SpeedTestUpdatedIPTable() error { 57 | 58 | Config, err := config.ConfigInit(nil, nil) 59 | if err != nil { 60 | return err 61 | } 62 | 63 | targets, err := ReadIpTable() 64 | if err != nil { 65 | return err 66 | } 67 | 68 | // Checks if baremetal mode and unsafe mode 69 | // is enabled. If it is enabled it adds the 70 | // the propagated public key to the list. 71 | 72 | AddPublicKey := false 73 | if Config.BareMetal && Config.UnsafeMode { 74 | AddPublicKey = true 75 | } 76 | 77 | // To ensure struct has no duplicates IP addresses 78 | //DoNotRead := targets 79 | 80 | // Appends all IP addresses 81 | for i, _ := range targets.IpAddress { 82 | 83 | //To ensure that there are no duplicate IP addresses 84 | Exists := false 85 | for k := range ip.IpAddress { 86 | if AddPublicKey && ip.IpAddress[k].PublicKey != "" { 87 | // This function call (AddAuthorisationKey) is inefficient but to be optimised later on. 88 | // This is because when if the user is running on as unsafe mode the authorization file 89 | // is opened from the SSH directory and then iterates through every single SSH entry 90 | // to find out if the SSH entry exists or not. This will incur multiple CPU cycles 91 | // for no reason. A better approach would be to have been to store the states on memory and only 92 | // add when needed based on the memory location. This is something is to be discussed 93 | // and look upon later on. 94 | AddAuthorisationKey(ip.IpAddress[k].PublicKey) 95 | } 96 | targets.IpAddress[i].CustomInformation = ip.IpAddress[k].CustomInformation 97 | // Checks if both the IPV4 addresses are the same or the IPV6 address is not 98 | // an empty string and IPV6 address are the same 99 | 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) { 100 | Exists = true 101 | break 102 | } 103 | } 104 | 105 | // If the struct exists then continues 106 | if Exists { 107 | continue 108 | } 109 | 110 | ip.IpAddress = append(ip.IpAddress, targets.IpAddress[i]) 111 | } 112 | 113 | err = ip.SpeedTest() 114 | 115 | if err != nil { 116 | return err 117 | } 118 | 119 | return nil 120 | } 121 | 122 | // LocalSpeedTestIpTable Runs speed test in iptables locally only 123 | func LocalSpeedTestIpTable() error { 124 | targets, err := ReadIpTable() 125 | if err != nil { 126 | return err 127 | } 128 | 129 | err = targets.SpeedTest() 130 | if err != nil { 131 | return err 132 | } 133 | 134 | return nil 135 | } 136 | 137 | // Helper function to remove element from an array of a struct 138 | //func remove(s []IpAddress, i int) []IpAddress { 139 | // s[len(s)-1], s[i] = s[i], s[len(s)-1] 140 | // return s[:len(s)-1] 141 | //} 142 | -------------------------------------------------------------------------------- /p2p/speedtest_test.go: -------------------------------------------------------------------------------- 1 | package p2p 2 | 3 | import ( 4 | "testing" 5 | ) 6 | 7 | // To run this test ip_table.json must be populated 8 | func TestServer_SpeedTest(t *testing.T) { 9 | err := LocalSpeedTestIpTable() 10 | if err != nil { 11 | t.Fatal(err) 12 | } 13 | 14 | //HumaidTest("http://localhost:8088/50") 15 | //HumaidTest("http://ipv4.download.thinkbroadband.com/50MB.zip") 16 | } 17 | -------------------------------------------------------------------------------- /p2p/ssh_autorisation.go: -------------------------------------------------------------------------------- 1 | // NOTE: Most of the code snippet was generated using ChatGPT 2 | // Prompt used: "generate go program to read and populate ssh authorization file" 3 | 4 | package p2p 5 | 6 | import ( 7 | "bufio" 8 | "errors" 9 | "fmt" 10 | "os" 11 | "path/filepath" 12 | "strings" 13 | ) 14 | 15 | // GetAuthorizedKeysPath returns the path to the authorized_keys file 16 | func GetAuthorizedKeysPath() (string, error) { 17 | homeDir, err := os.UserHomeDir() 18 | if err != nil { 19 | return "", fmt.Errorf("could not find home directory: %v", err) 20 | } 21 | return filepath.Join(homeDir, ".ssh", "authorized_keys"), nil 22 | } 23 | 24 | // ReadAuthorizedKeys reads and returns the current contents of the authorized_keys file as a map 25 | func ReadAuthorizedKeys(path string) (map[string]bool, error) { 26 | file, err := os.Open(path) 27 | if err != nil { 28 | return nil, fmt.Errorf("could not open authorized_keys file: %v", err) 29 | } 30 | defer file.Close() 31 | 32 | keys := make(map[string]bool) 33 | scanner := bufio.NewScanner(file) 34 | for scanner.Scan() { 35 | line := strings.TrimSpace(scanner.Text()) 36 | // Skip empty lines and comments 37 | if line != "" && !strings.HasPrefix(line, "#") { 38 | keys[line] = true 39 | } 40 | } 41 | if err := scanner.Err(); err != nil { 42 | return nil, fmt.Errorf("error reading authorized_keys file: %v", err) 43 | } 44 | return keys, nil 45 | } 46 | 47 | // AddKeyToAuthorizedKeys adds a new key to the authorized_keys file if it doesn’t already exist 48 | func AddKeyToAuthorizedKeys(path, newKey string) error { 49 | keys, err := ReadAuthorizedKeys(path) 50 | if err != nil { 51 | return err 52 | } 53 | 54 | // Check if the key already exists in the map 55 | if keys[newKey] { 56 | return errors.New("key already exists in authorized_keys") 57 | } 58 | 59 | // Append the new key 60 | file, err := os.OpenFile(path, os.O_APPEND|os.O_WRONLY|os.O_CREATE, 0600) 61 | if err != nil { 62 | return fmt.Errorf("could not open authorized_keys file for writing: %v", err) 63 | } 64 | defer file.Close() 65 | 66 | if _, err := file.WriteString(newKey + "\n"); err != nil { 67 | return fmt.Errorf("could not write to authorized_keys file: %v", err) 68 | } 69 | return nil 70 | } 71 | 72 | func RemoveKeyFromAuthorizedKeys(path, keyToRemove string) error { 73 | keys, err := ReadAuthorizedKeys(path) 74 | if err != nil { 75 | return err 76 | } 77 | 78 | // Check if the key exists in the map 79 | if !keys[keyToRemove] { 80 | return errors.New("key not found in authorized_keys") 81 | } 82 | 83 | // Delete the key from the map 84 | delete(keys, keyToRemove) 85 | 86 | // Write updated keys back to the authorized_keys file 87 | file, err := os.OpenFile(path, os.O_TRUNC|os.O_WRONLY|os.O_CREATE, 0600) 88 | if err != nil { 89 | return fmt.Errorf("could not open authorized_keys file for writing: %v", err) 90 | } 91 | defer file.Close() 92 | 93 | for key := range keys { 94 | if _, err := file.WriteString(key + "\n"); err != nil { 95 | return fmt.Errorf("could not write to authorized_keys file: %v", err) 96 | } 97 | } 98 | 99 | return nil 100 | } 101 | 102 | // AddAuthorisationKey Adds public key provided to the 103 | // authorization file so that nodes can SSH into 104 | // the 105 | func AddAuthorisationKey(PublicKey string) error { 106 | path, err := GetAuthorizedKeysPath() 107 | if err != nil { 108 | return err 109 | } 110 | 111 | // Display existing keys 112 | _, err = ReadAuthorizedKeys(path) 113 | if err != nil { 114 | return err 115 | } 116 | 117 | err = AddKeyToAuthorizedKeys(path, PublicKey) 118 | if err != nil { 119 | return err 120 | } 121 | 122 | return nil 123 | } 124 | -------------------------------------------------------------------------------- /p2p/upnp.go: -------------------------------------------------------------------------------- 1 | package p2p 2 | 3 | import ( 4 | "fmt" 5 | "gitlab.com/NebulousLabs/go-upnp" 6 | ) 7 | 8 | // Port forwarding to the router 9 | func ForwardPort(port int) error { 10 | // connect to router 11 | d, err := upnp.Discover() 12 | if err != nil { 13 | return err 14 | } 15 | 16 | // discover external IP 17 | ip, err := d.ExternalIP() 18 | if err != nil { 19 | return err 20 | } 21 | fmt.Println("Your external IP is:", ip) 22 | 23 | // forward a port 24 | err = d.Forward(50498, "upnp test") 25 | if err != nil { 26 | return err 27 | } 28 | 29 | // record router's location 30 | loc := d.Location() 31 | 32 | // connect to router directly 33 | d, err = upnp.Load(loc) 34 | if err != nil { 35 | return err 36 | } 37 | 38 | return nil 39 | } 40 | 41 | // UnForwardPort from router 42 | func UnForwardPort(port int) error { 43 | // connect to router 44 | d, err := upnp.Discover() 45 | if err != nil { 46 | return err 47 | } 48 | 49 | // discover external IP 50 | ip, err := d.ExternalIP() 51 | if err != nil { 52 | return err 53 | } 54 | 55 | fmt.Println("Your external IP is:", ip) 56 | 57 | // un-forward a port 58 | err = d.Clear(50498) 59 | if err != nil { 60 | return err 61 | } 62 | 63 | // record router's location 64 | loc := d.Location() 65 | 66 | // connect to router directly 67 | d, err = upnp.Load(loc) 68 | if err != nil { 69 | return err 70 | } 71 | 72 | return nil 73 | 74 | } 75 | -------------------------------------------------------------------------------- /p2p/upnp_test.go: -------------------------------------------------------------------------------- 1 | package p2p 2 | 3 | import ( 4 | "fmt" 5 | "testing" 6 | ) 7 | 8 | // Tests if the current has UPNP support 9 | func TestForwardUPNPPort(t *testing.T) { 10 | err := ForwardPort(6586) 11 | if err != nil { 12 | fmt.Println(err) 13 | t.Fail() 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /plugin/.dockerignore: -------------------------------------------------------------------------------- 1 | .idea 2 | .DS_Store 3 | Dockerfile 4 | -------------------------------------------------------------------------------- /plugin/.gitignore: -------------------------------------------------------------------------------- 1 | .idea 2 | .DS_Store 3 | -------------------------------------------------------------------------------- /plugin/README.md: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /plugin/TestAnsible/description.txt: -------------------------------------------------------------------------------- 1 | Test if it's detected -------------------------------------------------------------------------------- /plugin/TestAnsible/hosts: -------------------------------------------------------------------------------- 1 | --- 2 | all: 3 | vars: 4 | ansible_python_interpreter: /usr/bin/python3 5 | main: 6 | hosts: 7 | host1: 8 | ansible_host: 0.0.0.0 # Replace with your remote IP 9 | ansible_port: 44003 # Replace with your remote SSH port 10 | ansible_user: master # Replace wtih your username 11 | ansible_ssh_pass: password 12 | ansible_sudo_pass: password -------------------------------------------------------------------------------- /plugin/TestAnsible/site.yml: -------------------------------------------------------------------------------- 1 | --- 2 | 3 | - hosts: all 4 | 5 | tasks: 6 | - name: simple-ansibleplaybook 7 | debug: 8 | msg: Your are running 'simple-ansibleplaybook' example 9 | -------------------------------------------------------------------------------- /plugin/generate_test_case.sh: -------------------------------------------------------------------------------- 1 | cp -r plugin/TestAnsible/ plugin/deploy/ 2 | -------------------------------------------------------------------------------- /plugin/packageManager.go: -------------------------------------------------------------------------------- 1 | package plugin 2 | 3 | import ( 4 | "github.com/Akilan1999/p2p-rendering-computation/config" 5 | "github.com/go-git/go-git/v5" 6 | "net/url" 7 | "os" 8 | "strings" 9 | ) 10 | 11 | // DownloadPlugin This functions downloads package from 12 | // a git repo. 13 | func DownloadPlugin(pluginurl string) error { 14 | // paring plugin url 15 | u, err := url.Parse(pluginurl) 16 | if err != nil { 17 | return err 18 | } 19 | path := u.Path 20 | // Trim first character of the string 21 | path = path[1:] 22 | // trim last element of the string 23 | path = path[:len(path)-1] 24 | // Replaces / with _ 25 | folder := strings.Replace(path, "/", "_", -1) 26 | // Reads plugin path from the config path 27 | config, err := config.ConfigInit(nil, nil) 28 | if err != nil { 29 | return err 30 | } 31 | // clones a repo and stores it at the plugin directory 32 | _, err = git.PlainClone(config.PluginPath+"/"+folder, false, &git.CloneOptions{ 33 | URL: pluginurl, 34 | Progress: os.Stdout, 35 | }) 36 | // returns error if raised 37 | if err != nil { 38 | return err 39 | } 40 | 41 | return nil 42 | } 43 | 44 | // DeletePlugin The following function deletes a plugin based on 45 | // the plugin name provided. 46 | func DeletePlugin(pluginname string) error { 47 | config, err := config.ConfigInit(nil, nil) 48 | if err != nil { 49 | return err 50 | } 51 | 52 | plugin, err := SearchPlugin(pluginname) 53 | if err != nil { 54 | return err 55 | } 56 | 57 | // Delete the directory holding the plugin 58 | err = os.RemoveAll(config.PluginPath + "/" + plugin.FolderName) 59 | if err != nil { 60 | return err 61 | } 62 | 63 | return nil 64 | } 65 | -------------------------------------------------------------------------------- /server/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Akilan1999/p2p-rendering-computation/36930be8e480877414fec654169b9b2969168db0/server/.DS_Store -------------------------------------------------------------------------------- /server/ReverseProxy.go: -------------------------------------------------------------------------------- 1 | // source:https://github.com/afoley587/go-rev-proxy/tree/main 2 | package server 3 | 4 | import ( 5 | "fmt" 6 | "github.com/Akilan1999/p2p-rendering-computation/config" 7 | "github.com/gin-gonic/gin" 8 | "log" 9 | "net/http" 10 | "net/http/httputil" 11 | "net/url" 12 | ) 13 | 14 | var ( 15 | //RunPort = 2002 // The server port to run on 16 | //ReverseServerAddr = fmt.Sprint("0.0.0.0:", RunPort) // this is our reverse server ip address 17 | //InsideProxyHostname = fmt.Sprint("proxy:", RunPort) // Requests from private network 18 | //OutsideProxyHostname = fmt.Sprint("registration.localhost:", RunPort) // Requests from public network 19 | KnownAddresses = map[string]string{} // Known Addresses 20 | ) 21 | 22 | type RegistrationRequest struct { 23 | OutsideHost string // Outside host address. The hostname or IP on the public network. For example foo.bar.com or foo.localhost 24 | InsideHost string // Inside host address. The hostname or IP on the internal network. For example 192.168.10.5 25 | } 26 | 27 | // This function checks if TLS was enabled on the request 28 | // and translates it to the proper scheme (http or https) 29 | func GetScheme(c *gin.Context) string { 30 | if c.Request.TLS != nil { 31 | return "https" 32 | } else { 33 | return "http" 34 | } 35 | } 36 | 37 | // IsRegistrationRequest checks if an incoming request is meant to register 38 | // a new inside/outside hostname pair by checking if the hostname and 39 | // path match a specific combination. 40 | // If the host is our registration.localhost or proxy hostname 41 | // AND if the path is /register, we will register a new endpoint 42 | //func IsRegistrationRequest(c *gin.Context) bool { 43 | // isRR := ((c.Request.Host == InsideProxyHostname || c.Request.Host == OutsideProxyHostname) && 44 | // c.Request.URL.String() == "/register") 45 | // return isRR 46 | //} 47 | // 48 | //// SaveRegistrationRequest saves an inside/outside hostname pairing 49 | //// to our KnownAddresses map so we can use it later. Effectively 50 | //// registering a new endpoint for us 51 | //func SaveRegistrationRequest(c *gin.Context) error { 52 | // var rr RegistrationRequest 53 | // log.Println(c.Request.Body) 54 | // err := c.BindJSON(&rr) 55 | // 56 | // if err != nil { 57 | // return err 58 | // } 59 | // 60 | // log.Println("Registering", rr.OutsideHost, "to", rr.InsideHost) 61 | // KnownAddresses[rr.OutsideHost] = rr.InsideHost 62 | // return nil 63 | //} 64 | 65 | // SaveRegistration Creates registration of proxy node 66 | func SaveRegistration(OutsideHost string, InsideHost string) error { 67 | //_, ok := KnownAddresses[OutsideHost] 68 | //if !ok { 69 | // return errors.New("domain name provided already exists") 70 | //} 71 | KnownAddresses[OutsideHost] = InsideHost 72 | 73 | fmt.Println(OutsideHost) 74 | fmt.Println(InsideHost) 75 | fmt.Println(KnownAddresses[OutsideHost]) 76 | 77 | return nil 78 | } 79 | 80 | // Proxy runs the actual proxy and will look at the 81 | // hostnames requested from the received request. It will 82 | // then translate that to the inside hostname and forward the 83 | // request 84 | func Proxy(c *gin.Context) { 85 | 86 | // Get if HTTP or HTTPS 87 | scheme := GetScheme(c) 88 | 89 | log.Println(scheme, c.Request.Host, c.Request.URL.String()) 90 | 91 | // Translate the outside hostname to the inside hostname 92 | forwardTo, ok := KnownAddresses[c.Request.Host] 93 | 94 | if !ok { 95 | log.Printf("Unkown Host: %v", c.Request.Host) 96 | c.String(400, "Unkown Host") 97 | return 98 | } 99 | 100 | rUrl := fmt.Sprintf("%v://%v%v", "http", forwardTo, c.Request.URL) 101 | 102 | remote, err := url.Parse(rUrl) 103 | 104 | if err != nil { 105 | log.Println(err) 106 | c.String(500, "Error Proxying Host") 107 | return 108 | } 109 | 110 | log.Println("Forwarding request to", remote) 111 | 112 | // Forward the request to the inside remote server 113 | // https://pkg.go.dev/net/http/httputil#NewSingleHostReverseProxy 114 | proxy := httputil.NewSingleHostReverseProxy(remote) 115 | 116 | // Director is a function which modifies 117 | // the request into a new request to be sent 118 | // https://pkg.go.dev/net/http/httputil#ReverseProxy 119 | proxy.Director = func(req *http.Request) { 120 | req.Header = c.Request.Header 121 | req.Host = remote.Host 122 | req.URL.Scheme = remote.Scheme 123 | req.URL.Host = remote.Host 124 | req.URL.Path = c.Param("path") 125 | } 126 | 127 | proxy.ServeHTTP(c.Writer, c.Request) 128 | } 129 | 130 | func ProxyRun(port string) { 131 | r := gin.Default() 132 | 133 | KnownAddresses = make(map[string]string) 134 | 135 | // Get config information 136 | Config, err := config.ConfigInit(nil, nil) 137 | if err != nil { 138 | log.Printf("Error: %v", err) 139 | } 140 | 141 | // all paths should be handled by Proxy() 142 | r.Any("/*path", Proxy) 143 | 144 | if err := r.RunTLS(fmt.Sprint("0.0.0.0:", port), Config.PemFile, Config.KeyFile); err != nil { 145 | log.Printf("Error: %v", err) 146 | } 147 | } 148 | -------------------------------------------------------------------------------- /server/docker/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Akilan1999/p2p-rendering-computation/36930be8e480877414fec654169b9b2969168db0/server/docker/.DS_Store -------------------------------------------------------------------------------- /server/docker/Makefile: -------------------------------------------------------------------------------- 1 | SHELL := /bin/bash 2 | 3 | .PHONY: set_virtualenv,install_docker_requirements,dockerproc 4 | 5 | set_virtualenv: 6 | virtualenv env 7 | 8 | install_docker_requirements: 9 | source env/bin/activate && pip install -r requirements.txt 10 | 11 | dockerproc: 12 | ADMIN_USER=admin ADMIN_PASSWORD=admin docker-compose -f dockprom/docker-compose.yml up -d -------------------------------------------------------------------------------- /server/docker/README: -------------------------------------------------------------------------------- 1 | Docker Module P2P-rendering-computation 2 | ======================================== 3 | 4 | This module is incharge to spin up docker contaianers , create 5 | SSH server and VNC server. This module is implemented using 6 | python. -------------------------------------------------------------------------------- /server/docker/docker_test.go: -------------------------------------------------------------------------------- 1 | package docker 2 | 3 | // import ( 4 | // "testing" 5 | // ) 6 | // 7 | // func TestDockerUbuntuSSHDProvided(t *testing.T) { 8 | // // Testing by providing default container name 9 | // _,err := BuildRunContainer(2,"false","docker-ubuntu-sshd") 10 | // 11 | // if err != nil { 12 | // t.Error(err) 13 | // } 14 | // 15 | // } 16 | // 17 | // func TestDockerDefaultContainer(t *testing.T) { 18 | // // Testing by providing without providing default container name 19 | // _,err := BuildRunContainer(2,"false","") 20 | // 21 | // if err != nil { 22 | // t.Error(err) 23 | // } 24 | // } 25 | // 26 | // func TestContainerHorovod(t *testing.T) { 27 | // // Testing by providing the horovod cpu image 28 | // _,err := BuildRunContainer(2,"false","cpuhorovod") 29 | // 30 | // if err != nil { 31 | // t.Error(err) 32 | // } 33 | // } 34 | // 35 | // func TestViewAllContainers(t *testing.T) { 36 | // _,err := ViewAllContainers() 37 | // 38 | // if err != nil { 39 | // t.Error(err) 40 | // } 41 | // 42 | // } 43 | -------------------------------------------------------------------------------- /server/docker/dockprom/LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2016 Stefan Prodan 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /server/docker/dockprom/alertmanager/config.yml: -------------------------------------------------------------------------------- 1 | route: 2 | receiver: 'slack' 3 | 4 | receivers: 5 | - name: 'slack' 6 | slack_configs: 7 | - send_resolved: true 8 | text: "{{ .CommonAnnotations.description }}" 9 | username: 'Prometheus' 10 | channel: '#' 11 | api_url: 'https://hooks.slack.com/services/' 12 | -------------------------------------------------------------------------------- /server/docker/dockprom/caddy/Caddyfile: -------------------------------------------------------------------------------- 1 | :9090 { 2 | proxy / prometheus:9090 { 3 | transparent 4 | } 5 | 6 | errors stderr 7 | tls off 8 | } 9 | 10 | :9093 { 11 | proxy / alertmanager:9093 { 12 | transparent 13 | } 14 | 15 | errors stderr 16 | tls off 17 | } 18 | 19 | :9091 { 20 | proxy / pushgateway:9091 { 21 | transparent 22 | } 23 | 24 | errors stderr 25 | tls off 26 | } 27 | 28 | :3000 { 29 | proxy / grafana:3000 { 30 | transparent 31 | websocket 32 | } 33 | 34 | errors stderr 35 | tls off 36 | } 37 | -------------------------------------------------------------------------------- /server/docker/dockprom/config: -------------------------------------------------------------------------------- 1 | GF_SECURITY_ADMIN_USER=admin 2 | GF_SECURITY_ADMIN_PASSWORD=changeme 3 | GF_USERS_ALLOW_SIGN_UP=false 4 | -------------------------------------------------------------------------------- /server/docker/dockprom/docker-compose.exporters.yml: -------------------------------------------------------------------------------- 1 | version: '2.1' 2 | 3 | services: 4 | 5 | nodeexporter: 6 | image: prom/node-exporter:v1.0.1 7 | container_name: nodeexporter 8 | volumes: 9 | - /proc:/host/proc:ro 10 | - /sys:/host/sys:ro 11 | - /:/rootfs:ro 12 | command: 13 | - '--path.procfs=/host/proc' 14 | - '--path.rootfs=/rootfs' 15 | - '--path.sysfs=/host/sys' 16 | - '--collector.filesystem.ignored-mount-points=^/(sys|proc|dev|host|etc)($$|/)' 17 | restart: unless-stopped 18 | network_mode: host 19 | labels: 20 | org.label-schema.group: "monitoring" 21 | 22 | cadvisor: 23 | image: gcr.io/cadvisor/cadvisor:v0.38.7 24 | container_name: cadvisor 25 | volumes: 26 | - /:/rootfs:ro 27 | - /var/run:/var/run:rw 28 | - /sys:/sys:ro 29 | - /var/lib/docker/:/var/lib/docker:ro 30 | - /cgroup:/cgroup:ro 31 | restart: unless-stopped 32 | network_mode: host 33 | labels: 34 | org.label-schema.group: "monitoring" 35 | 36 | 37 | -------------------------------------------------------------------------------- /server/docker/dockprom/docker-compose.yml: -------------------------------------------------------------------------------- 1 | version: '2.1' 2 | 3 | networks: 4 | monitor-net: 5 | driver: bridge 6 | 7 | volumes: 8 | prometheus_data: {} 9 | grafana_data: {} 10 | 11 | services: 12 | 13 | prometheus: 14 | image: prom/prometheus:v2.24.1 15 | container_name: prometheus 16 | volumes: 17 | - ./prometheus:/etc/prometheus 18 | - prometheus_data:/prometheus 19 | command: 20 | - '--config.file=/etc/prometheus/prometheus.yml' 21 | - '--storage.tsdb.path=/prometheus' 22 | - '--web.console.libraries=/etc/prometheus/console_libraries' 23 | - '--web.console.templates=/etc/prometheus/consoles' 24 | - '--storage.tsdb.retention.time=200h' 25 | - '--web.enable-lifecycle' 26 | restart: unless-stopped 27 | expose: 28 | - 9090 29 | ports: 30 | - "9090:9090" 31 | networks: 32 | - monitor-net 33 | labels: 34 | org.label-schema.group: "monitoring" 35 | 36 | alertmanager: 37 | image: prom/alertmanager:v0.21.0 38 | container_name: alertmanager 39 | volumes: 40 | - ./alertmanager:/etc/alertmanager 41 | command: 42 | - '--config.file=/etc/alertmanager/config.yml' 43 | - '--storage.path=/alertmanager' 44 | restart: unless-stopped 45 | expose: 46 | - 9093 47 | ports: 48 | - "9093:9093" 49 | networks: 50 | - monitor-net 51 | labels: 52 | org.label-schema.group: "monitoring" 53 | 54 | nodeexporter: 55 | image: prom/node-exporter:v1.0.1 56 | container_name: nodeexporter 57 | volumes: 58 | - /proc:/host/proc:ro 59 | - /sys:/host/sys:ro 60 | - /:/rootfs:ro 61 | command: 62 | - '--path.procfs=/host/proc' 63 | - '--path.rootfs=/rootfs' 64 | - '--path.sysfs=/host/sys' 65 | - '--collector.filesystem.ignored-mount-points=^/(sys|proc|dev|host|etc)($$|/)' 66 | restart: unless-stopped 67 | expose: 68 | - 9100 69 | ports: 70 | - "9100:9100" 71 | networks: 72 | - monitor-net 73 | labels: 74 | org.label-schema.group: "monitoring" 75 | 76 | cadvisor: 77 | image: gcr.io/cadvisor/cadvisor:v0.38.7 78 | container_name: cadvisor 79 | volumes: 80 | - /:/rootfs:ro 81 | - /var/run:/var/run:rw 82 | - /sys:/sys:ro 83 | - /var/lib/docker:/var/lib/docker:ro 84 | #- /cgroup:/cgroup:ro #doesn't work on MacOS only for Linux 85 | restart: unless-stopped 86 | expose: 87 | - 8080 88 | ports: 89 | - "8080:8080" 90 | networks: 91 | - monitor-net 92 | labels: 93 | org.label-schema.group: "monitoring" 94 | 95 | grafana: 96 | image: grafana/grafana:7.3.7 97 | container_name: grafana 98 | volumes: 99 | - grafana_data:/var/lib/grafana 100 | - ./grafana/provisioning/dashboards:/etc/grafana/provisioning/dashboards 101 | - ./grafana/provisioning/datasources:/etc/grafana/provisioning/datasources 102 | environment: 103 | - GF_SECURITY_ADMIN_USER=${ADMIN_USER:-admin} 104 | - GF_SECURITY_ADMIN_PASSWORD=${ADMIN_PASSWORD:-admin} 105 | - GF_USERS_ALLOW_SIGN_UP=false 106 | restart: unless-stopped 107 | expose: 108 | - 3000 109 | ports: 110 | - "3000:3000" 111 | networks: 112 | - monitor-net 113 | labels: 114 | org.label-schema.group: "monitoring" 115 | 116 | pushgateway: 117 | image: prom/pushgateway:v1.4.0 118 | container_name: pushgateway 119 | restart: unless-stopped 120 | expose: 121 | - 9091 122 | ports: 123 | - "9091:9091" 124 | networks: 125 | - monitor-net 126 | labels: 127 | org.label-schema.group: "monitoring" 128 | 129 | caddy: 130 | image: caddy:2.3.0-alpine 131 | container_name: caddy 132 | ports: 133 | - "3000:3000" 134 | - "9090:9090" 135 | - "9093:9093" 136 | - "9091:9091" 137 | volumes: 138 | - ./caddy:/etc/caddy 139 | environment: 140 | - ADMIN_USER=${ADMIN_USER:-admin} 141 | - ADMIN_PASSWORD=${ADMIN_PASSWORD:-admin} 142 | restart: unless-stopped 143 | networks: 144 | - monitor-net 145 | labels: 146 | org.label-schema.group: "monitoring" 147 | -------------------------------------------------------------------------------- /server/docker/dockprom/grafana/provisioning/dashboards/dashboard.yml: -------------------------------------------------------------------------------- 1 | apiVersion: 1 2 | 3 | providers: 4 | - name: 'Prometheus' 5 | orgId: 1 6 | folder: '' 7 | type: file 8 | disableDeletion: false 9 | editable: true 10 | allowUiUpdates: true 11 | options: 12 | path: /etc/grafana/provisioning/dashboards -------------------------------------------------------------------------------- /server/docker/dockprom/grafana/provisioning/datasources/datasource.yml: -------------------------------------------------------------------------------- 1 | apiVersion: 1 2 | 3 | datasources: 4 | - name: Prometheus 5 | type: prometheus 6 | access: proxy 7 | orgId: 1 8 | url: http://prometheus:9090 9 | basicAuth: false 10 | isDefault: true 11 | editable: true -------------------------------------------------------------------------------- /server/docker/dockprom/helpers/aws/README.md: -------------------------------------------------------------------------------- 1 | # Prometheus on EC2 & ECS: 2 | 3 | Some helpers for anyone configuring Prometheus on ECS and AWS EC2. 4 | 5 | To get started on AWS ECS and EC2: 6 | 7 | *For EC2/ECS nodes*: 8 | - Import the ecs task definition and add cadvisor and node-exporter service/task definition and run them on each host you want to be monitored 9 | - Any hosts which have "Monitoring: On" tag will be automatically added in the targets 10 | - Expose ports 9100 and 9191 to your Prometheus host 11 | 12 | *For Prometheus host*: 13 | 14 | - Copy prometheus.yml configuration present here to base prometheus configuration to enable EC2 service discovery 15 | - `docker compose up -d` 16 | 17 | > [!NOTE] 18 | > Set query.staleness-delta to 1m make metrics more realtime 19 | 20 | 21 | ### TODO 22 | - [ ] Add alerting rules based on ECS 23 | -------------------------------------------------------------------------------- /server/docker/dockprom/helpers/aws/cadvisor_ecs_task_definition.json: -------------------------------------------------------------------------------- 1 | { 2 | "family": "cadvisor", 3 | "containerDefinitions": [ 4 | { 5 | "name": "cadvisor", 6 | "image": "google/cadvisor", 7 | "cpu": 10, 8 | "memory": 300, 9 | "portMappings": [ 10 | { 11 | "containerPort": 9191, 12 | "hostPort": 9191 13 | } 14 | ], 15 | "essential": true, 16 | "privileged": true, 17 | "mountPoints": [ 18 | { 19 | "sourceVolume": "root", 20 | "containerPath": "/rootfs", 21 | "readOnly": true 22 | }, 23 | { 24 | "sourceVolume": "var_run", 25 | "containerPath": "/var/run", 26 | "readOnly": false 27 | }, 28 | { 29 | "sourceVolume": "sys", 30 | "containerPath": "/sys", 31 | "readOnly": true 32 | }, 33 | { 34 | "sourceVolume": "var_lib_docker", 35 | "containerPath": "/var/lib/docker", 36 | "readOnly": true 37 | }, 38 | { 39 | "sourceVolume": "cgroup", 40 | "containerPath": "/cgroup", 41 | "readOnly": true 42 | } 43 | ] 44 | } 45 | ], 46 | "volumes": [ 47 | { 48 | "name": "root", 49 | "host": { 50 | "sourcePath": "/" 51 | } 52 | }, 53 | { 54 | "name": "var_run", 55 | "host": { 56 | "sourcePath": "/var/run" 57 | } 58 | }, 59 | { 60 | "name": "sys", 61 | "host": { 62 | "sourcePath": "/sys" 63 | } 64 | }, 65 | { 66 | "name": "var_lib_docker", 67 | "host": { 68 | "sourcePath": "/var/lib/docker/" 69 | } 70 | }, 71 | { 72 | "name": "cgroup", 73 | "host": { 74 | "sourcePath": "/cgroup" 75 | } 76 | } 77 | ] 78 | } -------------------------------------------------------------------------------- /server/docker/dockprom/helpers/aws/node_exporter_task_definition.json: -------------------------------------------------------------------------------- 1 | { 2 | "family": "prometheus", 3 | "containerDefinitions": [ 4 | { 5 | "portMappings": [ 6 | { 7 | "hostPort": 9100, 8 | "containerPort": 9100, 9 | "protocol": "tcp" 10 | } 11 | ], 12 | "essential": true, 13 | "name": "node_exporter", 14 | "image": "prom/node-exporter", 15 | "cpu": 0, 16 | "privileged": null, 17 | "memoryReservation": 150 18 | } 19 | ], 20 | "volumes": [], 21 | "networkMode": "host" 22 | } 23 | -------------------------------------------------------------------------------- /server/docker/dockprom/helpers/aws/prometheus.yml: -------------------------------------------------------------------------------- 1 | global: 2 | scrape_interval: 15s 3 | evaluation_interval: 15s 4 | 5 | # Attach these labels to any time series or alerts when communicating with 6 | # external systems (federation, remote storage, Alertmanager). 7 | external_labels: 8 | monitor: 'docker-host-alpha' 9 | 10 | # Load and evaluate rules in this file every 'evaluation_interval' seconds. 11 | rule_files: 12 | - "targets.rules" 13 | - "hosts.rules" 14 | - "containers.rules" 15 | 16 | # A scrape configuration containing exactly one endpoint to scrape. 17 | scrape_configs: 18 | - job_name: 'nodeexporter' 19 | scrape_interval: 5s 20 | static_configs: 21 | - targets: ['nodeexporter:9100'] 22 | 23 | - job_name: 'cadvisor' 24 | scrape_interval: 5s 25 | static_configs: 26 | - targets: ['cadvisor:8080'] 27 | 28 | - job_name: 'prometheus' 29 | scrape_interval: 10s 30 | static_configs: 31 | - targets: ['localhost:9090'] 32 | 33 | 34 | # sample scrape configuration for AWS EC2 35 | - job_name: 'nodeexporter' 36 | ec2_sd_configs: 37 | - region: us-east-1 38 | port: 9100 39 | relabel_configs: 40 | # Only monitor instances which have a tag called Monitoring "Monitoring" 41 | - source_labels: [__meta_ec2_tag_Monitoring] 42 | regex: On 43 | action: keep 44 | 45 | - job_name: 'cadvisor' 46 | ec2_sd_configs: 47 | - region: us-east-1 48 | port: 9010 49 | relabel_configs: 50 | # Only monitor instances which have a tag called Monitoring "Monitoring" 51 | - source_labels: [__meta_ec2_tag_Monitoring] 52 | regex: On 53 | action: keep 54 | -------------------------------------------------------------------------------- /server/docker/dockprom/prometheus/alert.rules: -------------------------------------------------------------------------------- 1 | groups: 2 | - name: targets 3 | rules: 4 | - alert: monitor_service_down 5 | expr: up == 0 6 | for: 30s 7 | labels: 8 | severity: critical 9 | annotations: 10 | summary: "Monitor service non-operational" 11 | description: "Service {{ $labels.instance }} is down." 12 | 13 | - name: host 14 | rules: 15 | - alert: high_cpu_load 16 | expr: node_load1 > 1.5 17 | for: 30s 18 | labels: 19 | severity: warning 20 | annotations: 21 | summary: "Server under high load" 22 | description: "Docker host is under high load, the avg load 1m is at {{ $value}}. Reported by instance {{ $labels.instance }} of job {{ $labels.job }}." 23 | 24 | - alert: high_memory_load 25 | expr: (sum(node_memory_MemTotal_bytes) - sum(node_memory_MemFree_bytes + node_memory_Buffers_bytes + node_memory_Cached_bytes) ) / sum(node_memory_MemTotal_bytes) * 100 > 85 26 | for: 30s 27 | labels: 28 | severity: warning 29 | annotations: 30 | summary: "Server memory is almost full" 31 | description: "Docker host memory usage is {{ humanize $value}}%. Reported by instance {{ $labels.instance }} of job {{ $labels.job }}." 32 | 33 | - alert: high_storage_load 34 | expr: (node_filesystem_size_bytes{fstype="aufs"} - node_filesystem_free_bytes{fstype="aufs"}) / node_filesystem_size_bytes{fstype="aufs"} * 100 > 85 35 | for: 30s 36 | labels: 37 | severity: warning 38 | annotations: 39 | summary: "Server storage is almost full" 40 | description: "Docker host storage usage is {{ humanize $value}}%. Reported by instance {{ $labels.instance }} of job {{ $labels.job }}." 41 | 42 | - name: containers 43 | rules: 44 | - alert: jenkins_down 45 | expr: absent(container_memory_usage_bytes{name="jenkins"}) 46 | for: 30s 47 | labels: 48 | severity: critical 49 | annotations: 50 | summary: "Jenkins down" 51 | description: "Jenkins container is down for more than 30 seconds." 52 | 53 | - alert: jenkins_high_cpu 54 | expr: sum(rate(container_cpu_usage_seconds_total{name="jenkins"}[1m])) / count(node_cpu_seconds_total{mode="system"}) * 100 > 10 55 | for: 30s 56 | labels: 57 | severity: warning 58 | annotations: 59 | summary: "Jenkins high CPU usage" 60 | description: "Jenkins CPU usage is {{ humanize $value}}%." 61 | 62 | - alert: jenkins_high_memory 63 | expr: sum(container_memory_usage_bytes{name="jenkins"}) > 1200000000 64 | for: 30s 65 | labels: 66 | severity: warning 67 | annotations: 68 | summary: "Jenkins high memory usage" 69 | description: "Jenkins memory consumption is at {{ humanize $value}}." 70 | 71 | -------------------------------------------------------------------------------- /server/docker/dockprom/prometheus/prometheus.yml: -------------------------------------------------------------------------------- 1 | global: 2 | scrape_interval: 15s 3 | evaluation_interval: 15s 4 | 5 | # Attach these labels to any time series or alerts when communicating with 6 | # external systems (federation, remote storage, Alertmanager). 7 | external_labels: 8 | monitor: 'docker-host-alpha' 9 | 10 | # Load and evaluate rules in this file every 'evaluation_interval' seconds. 11 | rule_files: 12 | - "alert.rules" 13 | 14 | # A scrape configuration containing exactly one endpoint to scrape. 15 | scrape_configs: 16 | - job_name: 'nodeexporter' 17 | scrape_interval: 5s 18 | static_configs: 19 | - targets: ['nodeexporter:9100'] 20 | 21 | - job_name: 'cadvisor' 22 | scrape_interval: 5s 23 | static_configs: 24 | - targets: ['cadvisor:8080'] 25 | 26 | - job_name: 'prometheus' 27 | scrape_interval: 10s 28 | static_configs: 29 | - targets: ['localhost:9090'] 30 | 31 | - job_name: 'pushgateway' 32 | scrape_interval: 10s 33 | honor_labels: true 34 | static_configs: 35 | - targets: ['pushgateway:9091'] 36 | 37 | 38 | alerting: 39 | alertmanagers: 40 | - scheme: http 41 | static_configs: 42 | - targets: 43 | - 'alertmanager:9093' 44 | 45 | # - job_name: 'nginx' 46 | # scrape_interval: 10s 47 | # static_configs: 48 | # - targets: ['nginxexporter:9113'] 49 | 50 | # - job_name: 'aspnetcore' 51 | # scrape_interval: 10s 52 | # static_configs: 53 | # - targets: ['eventlog-proxy:5000', 'eventlog:5000'] 54 | -------------------------------------------------------------------------------- /server/docker/dockprom/screens/Grafana_Docker_Containers.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Akilan1999/p2p-rendering-computation/36930be8e480877414fec654169b9b2969168db0/server/docker/dockprom/screens/Grafana_Docker_Containers.png -------------------------------------------------------------------------------- /server/docker/dockprom/screens/Grafana_Docker_Host.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Akilan1999/p2p-rendering-computation/36930be8e480877414fec654169b9b2969168db0/server/docker/dockprom/screens/Grafana_Docker_Host.png -------------------------------------------------------------------------------- /server/docker/dockprom/screens/Grafana_Prometheus.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Akilan1999/p2p-rendering-computation/36930be8e480877414fec654169b9b2969168db0/server/docker/dockprom/screens/Grafana_Prometheus.png -------------------------------------------------------------------------------- /server/docker/dockprom/screens/Slack_Notifications.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Akilan1999/p2p-rendering-computation/36930be8e480877414fec654169b9b2969168db0/server/docker/dockprom/screens/Slack_Notifications.png -------------------------------------------------------------------------------- /server/docker/kill-containers.sh: -------------------------------------------------------------------------------- 1 | docker kill $(docker ps -q)\ 2 | docker rm $(docker ps -a -q) 3 | docker rmi $(docker images -q) --force 4 | docker system prune --all 5 | -------------------------------------------------------------------------------- /server/gopsutil.go: -------------------------------------------------------------------------------- 1 | package server 2 | 3 | import ( 4 | "github.com/shirou/gopsutil/v3/cpu" 5 | "github.com/shirou/gopsutil/v3/disk" 6 | "github.com/shirou/gopsutil/v3/host" 7 | "github.com/shirou/gopsutil/v3/mem" 8 | ) 9 | 10 | // SysInfo saves the basic system information 11 | type SysInfo struct { 12 | Hostname string `bson:hostname` 13 | Platform string `bson:platform` 14 | CPU string `bson:cpu` 15 | RAM uint64 `bson:ram` 16 | Disk uint64 `bson:disk` 17 | GPU *Query `xml: GpuInfo` 18 | } 19 | 20 | func ServerInfo() *SysInfo { 21 | hostStat, _ := host.Info() 22 | cpuStat, _ := cpu.Info() 23 | vmStat, _ := mem.VirtualMemory() 24 | 25 | info := new(SysInfo) 26 | 27 | filesystem := "/" 28 | 29 | // If the server is running windows 30 | if info.Hostname == "windows" { 31 | filesystem = "\\" 32 | } 33 | 34 | diskStat, _ := disk.Usage(filesystem) // If you're in Unix change this "\\" for "/" 35 | 36 | info.Hostname = hostStat.Hostname 37 | info.Platform = hostStat.Platform 38 | info.CPU = cpuStat[0].ModelName 39 | info.RAM = vmStat.Total / 1024 / 1024 40 | info.Disk = diskStat.Total / 1024 / 1024 41 | 42 | gpu, err := GPUInfo() 43 | 44 | if err == nil { 45 | info.GPU = gpu 46 | } 47 | 48 | return info 49 | 50 | } 51 | -------------------------------------------------------------------------------- /server/gpu.go: -------------------------------------------------------------------------------- 1 | package server 2 | 3 | import ( 4 | "encoding/xml" 5 | "os/exec" 6 | ) 7 | 8 | type Query struct { 9 | DriveVersion string `xml:"driver_version"` 10 | Gpu Gpu `xml:"gpu"` 11 | } 12 | 13 | type Gpu struct{ 14 | GpuName string `xml:"product_name"` 15 | BiosVersion string `xml:"vbios_version"` 16 | FanSpeed string `xml:"fan_speed"` 17 | Utilization GpuUtilization `xml:"utilization"` 18 | Temperature GpuTemperature `xml:"temperature"` 19 | Clock GpuClock `xml:"clocks"` 20 | } 21 | 22 | type GpuUtilization struct { 23 | GpuUsage string `xml:"gpu_util"` 24 | MemoryUsage string `xml:"memory_util"` 25 | } 26 | 27 | type GpuTemperature struct { 28 | GpuTemp string `xml:"gpu_temp"` 29 | } 30 | 31 | type GpuClock struct { 32 | GpuClock string `xml:"graphics_clock"` 33 | GpuMemClock string `xml:"mem_clock"` 34 | } 35 | 36 | // Gets GPU information by calling nvidia-smi 37 | // in XML output 38 | func GPUInfo()(*Query,error) { 39 | out, err := exec.Command("nvidia-smi", "-q", "-x").Output() 40 | 41 | if err != nil { 42 | return nil,err 43 | } 44 | 45 | var gpu Query 46 | err = xml.Unmarshal(out, &gpu) 47 | 48 | if err != nil { 49 | return nil,err 50 | } 51 | 52 | return &gpu,nil 53 | } -------------------------------------------------------------------------------- /server/gpu_test.go: -------------------------------------------------------------------------------- 1 | package server 2 | 3 | import ( 4 | "fmt" 5 | "testing" 6 | ) 7 | 8 | func TestGpuOutput(t *testing.T) { 9 | gpu, err := GPUInfo() 10 | 11 | if err != nil { 12 | t.Error(err) 13 | } 14 | 15 | fmt.Print(gpu.Gpu.GpuName) 16 | } 17 | -------------------------------------------------------------------------------- /server/upload_file.go: -------------------------------------------------------------------------------- 1 | package server 2 | 3 | import ( 4 | "github.com/gin-gonic/gin" 5 | "github.com/google/uuid" // To generate random file names 6 | "net/http" 7 | "path/filepath" 8 | ) 9 | 10 | func saveFileHandler(c *gin.Context) { 11 | file, err := c.FormFile("file") 12 | 13 | // The file cannot be received. 14 | if err != nil { 15 | c.AbortWithStatusJSON(http.StatusBadRequest, gin.H{ 16 | "message": "No file is received", 17 | }) 18 | return 19 | } 20 | 21 | // Retrieve file information 22 | extension := filepath.Ext(file.Filename) 23 | // Generate random file name for the new uploaded file so it doesn't override the old file with same name 24 | newFileName := uuid.New().String() + extension 25 | 26 | // The file is received, so let's save it 27 | if err := c.SaveUploadedFile(file, "/tmp/" + newFileName); err != nil { 28 | c.AbortWithStatusJSON(http.StatusInternalServerError, gin.H{ 29 | "message": "Unable to save the file", 30 | }) 31 | return 32 | } 33 | 34 | // File saved successfully. Return proper result 35 | c.JSON(http.StatusOK, gin.H{ 36 | "message": "Your file has been successfully uploaded.", 37 | }) 38 | } -------------------------------------------------------------------------------- /shell.nix: -------------------------------------------------------------------------------- 1 | { pkgs ? ( 2 | let 3 | inherit (builtins) fetchTree fromJSON readFile; 4 | inherit ((fromJSON (readFile ./flake.lock)).nodes) nixpkgs gomod2nix; 5 | in 6 | import (fetchTree nixpkgs.locked) { 7 | overlays = [ 8 | (import "${fetchTree gomod2nix.locked}/overlay.nix") 9 | ]; 10 | } 11 | ) 12 | , mkGoEnv ? pkgs.mkGoEnv 13 | , gomod2nix ? pkgs.gomod2nix 14 | }: 15 | 16 | let 17 | goEnv = mkGoEnv { pwd = ./.; }; 18 | in 19 | pkgs.mkShell { 20 | packages = [ 21 | goEnv 22 | gomod2nix 23 | ]; 24 | } 25 | -------------------------------------------------------------------------------- /wasm/p2prc.wasm: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Akilan1999/p2p-rendering-computation/36930be8e480877414fec654169b9b2969168db0/wasm/p2prc.wasm --------------------------------------------------------------------------------