Skip to content

Commit

Permalink
merge with issue #60 branch
Browse files Browse the repository at this point in the history
  • Loading branch information
parvit committed Sep 10, 2024
1 parent ae96390 commit 461aa44
Show file tree
Hide file tree
Showing 104 changed files with 4,224 additions and 1,703 deletions.
47 changes: 45 additions & 2 deletions .github/workflows/integration.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,49 @@ on:
run-name: Code Integration [${{ github.event_name }}][${{ github.head_ref || github.ref_name }}] rev.${{ github.sha }}

jobs:
docs:
if: true
runs-on: ubuntu-latest
defaults:
run:
shell: bash

env:
GO_VERSION: 1.20.14
PANDOC_VERSION: 3.3

steps:
- uses: actions/checkout@v4
with:
clean: true
submodules: false

- name: Install Pandoc
uses: pandoc/actions/[email protected]
with:
version: ${{ env.PANDOC_VERSION }}

- name: Install TeXlive
run: sudo apt-get update && sudo apt-get install texlive-full

- name: Set up Go
uses: actions/setup-go@v4
with:
go-version: ${{ env.GO_VERSION }}

- name: Generate PDF
run: |
cd docs/
CURDATE=$(date '+%x %T')
SHORT_SHA=$(echo "${{ github.sha }}" | cut -b -8)
sed -i -E -e "s|subtitle:.+|subtitle: \"User Manual - rev. $SHORT_SHA\"|" -e "s|date:.+|date: \"$CURDATE\"|" user-manual.md
go generate
- uses: actions/upload-artifact@v4
with:
name: qpep_user_manual
path: "docs/*.pdf"

build-linux:
if: true
runs-on: ubuntu-latest
Expand Down Expand Up @@ -201,8 +244,8 @@ jobs:
- name: Build QPep Installer
run: |
sed -E 's/Version="[^"]+"/Version="1.0.0.0-dev${{github.run_id}}"/' installer/installer.wxs > installer/installer.wxs
sed -E 's/FileVersion:\s*"[^"]+"/FileVersion:\s*"0.0.0-dev${{github.run_id}}"/' version/versioninfo.json > version/versioninfo.json
sed -E 's/ProductVersion:\s*"[^"]+"/ProductVersion:\s*"0.0.0-dev${{github.run_id}}"/' version/versioninfo.json > version/versioninfo.json
sed -E 's/FileVersion:\s*"[^"]+"/FileVersion:\s*"0.0.0-dev${{github.run_id}}"/' shared/version/versioninfo.json > shared/version/versioninfo.json
sed -E 's/ProductVersion:\s*"[^"]+"/ProductVersion:\s*"0.0.0-dev${{github.run_id}}"/' shared/version/versioninfo.json > shared/version/versioninfo.json
set PATH=${{ github.workspace }}\wix\tools;%PATH%
msbuild installer\installer.sln
Expand Down
45 changes: 44 additions & 1 deletion .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -255,8 +255,51 @@ jobs:
check_name: "Unit Tests - Windows Platform"
junit_files: "unit/*.xml"

docs:
if: true
runs-on: ubuntu-latest
defaults:
run:
shell: bash

env:
GO_VERSION: 1.20.14
PANDOC_VERSION: 3.3

steps:
- uses: actions/checkout@v4
with:
clean: true
submodules: false

- name: Install Pandoc
uses: pandoc/actions/[email protected]
with:
version: ${{ env.PANDOC_VERSION }}

- name: Install TeXlive
run: sudo apt-get update && sudo apt-get install texlive-full

- name: Set up Go
uses: actions/setup-go@v4
with:
go-version: ${{ env.GO_VERSION }}

- name: Generate PDF
run: |
cd docs/
CURDATE=$(date '+%x %T')
sed -i -E -e 's|subtitle:.+|subtitle: "User Manual - version ${{ github.event.inputs.version_tag }}"|' -e "s|date:.+|date: \"$CURDATE\"|" user-manual.md
sed -i -E -e 's|page-background:\s*resources/draft.png||' user-manual.md
go generate
- uses: actions/upload-artifact@v4
with:
name: qpep_user_manual
path: "docs/*.pdf"

create-release-tag:
needs: [build-windows, build-linux]
needs: [build-windows, build-linux, docs]
runs-on: ubuntu-latest
defaults:
run:
Expand Down
123 changes: 37 additions & 86 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,33 +11,33 @@ Basic testing:
* Ziply Fiber Gigabit in Seattle pulling 1GB test file from DigitalOcean AMS3: ~1.6MB/s
* Ziply Fiber Gigabit in Seattle pulling 1GB test file via qpep running in DigitalOcean AMS3, grabbing 1GB file from AMS3: 10-25MB/s. Slows down over the course of the download.

# Windows Build
# Build
Following here are instructions for manual building the additional parts on windows platform.

### Main module
For building the qpep package you'll need:
- Go 1.16.x
- A C/C++ complier compatible with CGO eg. [MinGW64](https://www.mingw-w64.org/). Specifically, download [this](https://sourceforge.net/projects/mingw-w64/files/Toolchains%20targetting%20Win64/Personal%20Builds/mingw-builds/8.1.0/threads-posix/seh/x86_64-8.1.0-release-posix-seh-rt_v6-rev0.7z), extract the files, and add the "bin" directory to the PATH.
- Go 1.20.x
- CMake 3.22+ [Installer](https://github.com/Kitware/CMake/releases/tag/v3.22.3)
- (Windows) A C/C++ complier compatible with CGO eg. [MinGW64](https://www.mingw-w64.org/). Specifically, download [this](https://sourceforge.net/projects/mingw-w64/files/Toolchains%20targetting%20Win64/Personal%20Builds/mingw-builds/8.1.0/threads-posix/seh/x86_64-8.1.0-release-posix-seh-rt_v6-rev0.7z), extract the files, and add the "bin" directory to the PATH.
- (Linux) A C/C++ complier compatible with CGO eg. GCC

After setting the go and c compiler in the PATH, be sure to also check that `go env` reports that:
- `CGO_ENABLED=1`
- `CC=<path to c compiler exe>`
- `CXX=<path to c++ compiler exe>`

After that the simple `go build` will build the executable.
After that change to the "backend" directory, add the `GOPATH/bin` path your PATH and execute `go generate`, this
will generate the native backends for qpep (at the moment the `quicly-go` wrapper library).

Once done that `go build -o build\qpep.exe` in the root directory will build the executable.
To run it, first copy the following files to the executable folder (if you are on 64 bit platform):
- x64\WinDivert.dll
- x64\WinDivert64.sys

If instead your system is 32bits than copy:
- x86\WinDivert.dll
- x86\WinDivert32.sys
- x86\WinDivert64.sys (alternatively to support running the 32bits executable on x64 architecture)

#### Note about the windows drivers
The .sys file are windows user mode drivers taken from the [WinDivert](https://reqrypt.org/windivert.html) project site, they install automatically when the qpep client runs and are automatically removed when the program exits.

_There is no need to install those manually_ and please don't do so as it might mess up the loading of the driver when running qpep.
_There is no need to install those manually_ it might mess up the loading of the driver when running qpep.

### Qpep-tray module
This module compiles without additional dependencies so just cd into qpep-tray directory and run:
Expand All @@ -52,100 +52,51 @@ It should be placed in the same folder as the qpep main executable and will need

The configuration file is created automatically on first launch under `%APPDATA%\qpeptray\` and is a yaml file with the following defaults:
```
acks: 10
ackDelay: 25
congestion: 4
decimate: 4
minBeforeDecimation: 100
gateway: 198.18.0.254
port: 443
apiport: 444
listenaddress: 192.168.1.10
listenport: 9443
multistream: true
verbose: false
varAckDelay: 0
threads: 1
client:
local_address: 192.168.1.24
local_port: 9443
gateway_address: 0.0.0.0
gateway_port: 1443
protocol:
backend: quicly-go
buffersize: 512
idletimeout: 30s
ccalgorithm: cubic
ccslowstart: search
security:
certificate: server_cert.pem
general:
api_port: 444
max_retries: 50
diverter_threads: 4
use_multistream: true
prefer_proxy: true
verbose: false
```

Information about their meaning and usage can be found running the client with `--help`.
Information about their meaning and usage can be found running in the [user manual](https://github.com/Project-Faster/qpep/releases/latest).

The file can also be opened directly from the tray icon selecting "*Edit Configuration*", upon change detected to it, the user will be asked if it wants to reload the configuration relaunching the client / server.

The module can also be built on linux and will work the same except for the menu icons which fail to load currently on that platform (by current limitation of the underlying go package).

### Generating the Windows MSI Installer
Additional dependencies are required to build the msi package:
- Windows Visual Studio 2019 (Community is ok)
- Windows Visual Studio 2019+ (Community is ok)
- [WiX Toolkit 3.11.2](https://wixtoolset.org/releases/)

The `installer.bat` script is the recommended way to build it as it takes care of preparing the files necessary and building all the packages required.

Supported flags for it's invocation are:
- `--build64` Will prepare the 64bits version of the executables
- `--build32` Will prepare the 32bits version of the executables
- `--rebuild` Will only rebuild the installer without building the binaries again

At least one between `--build64` and `--build32` must be specified, `--rebuild` can only be given as a second parameter.

The resulting package will be created under the `build/` subdirectory.

After installation there is an additional requirement to launch the qpep-tray binary via the shortcut which is powershell, this way the tray program can ask for UAC elevation immediately and run with the elevated privileges the client requires to work.

# Using Standalone QPEP

>:warning: **Disclaimer**: While it is possible to configure and run QPEP outside of the testbed environment, this is discouraged for anything other than experimental testing. The current release of QPEP is a proof-of-concept research tool and, while every effort has been made to make it secure and reliable, it has not been vetted sufficiently for its use in critical satellite communications. Commercial use of this code in its current state would be **exceptionally foolhardy**. When QPEP reaches a more mature state, this disclaimer will be updated.

## Setting Up The Network

The testbed comes with a pre-built and pre-configured QPEP deployment. However, if you wish to use QPEP outside of the test bed this is possible.

You will need at least two machines and ideally three, a QPEP client and a QPEP server are required and a client workstation is optional but recommended. The QPEP client must be able to talk to the QPEP server (e.g. must be able to ping it / initiate UDP connections to open ports on the QPEP server). The client workstation must be configured to route all TCP traffic through the QPEP client.

If you wish to route traffic bi-directionally (e.g. correctly optimize incoming ssh connections to the QPEP client workstation from the internet) you will need to run a QPEP client and a QPEP server on both sides of the connection.

### Client Setup
The client must be configured to route all incoming TCP traffic to the QPEP server. In *nix systems you can do this using nftables. QPEP by default is configured to accept incoming client connections on port 8080.
```bash
$ sysctl -w net.ipv4.ip_forward=1
$ sysctl -w net.core.rmem_max=2500000
$ nftables -f nftables.conf
$ ip rule add fwmark 0x233 lookup 100
$ ip route add local 0.0.0.0/0 dev lo table 100
```

A systemd service script is included with helpful start/stop/reload options. IPs/prefixes may be excluded from proxying by editing the list in nftables.conf.

### Server Setup
No special routing setup is required for the QPEP server. It listens by default on UDP port 4242. If you would like, you can enable ip forwarding which, depending on the underlying network implementation, may allow for fully transparent proxy implementation.
```bash
$ sysctl -w net.ipv4.ip_forward=1
```
## Running QPEP
### Launching the QPEP Client
To run QPEP in client mode once you've set the appropriate IP tables rules:
```bash
$ sysctl -w net.core.rmem_max=2500000
$ ./qpep -client -gateway [IP of QPEP server]
```
### Launching the QPEP Server
To run QPEP in server mode
```bash
$ sysctl -w net.core.rmem_max=2500000
$ ./qpep
```
### Changing Further QUIC Parameters
QPEP comes with a forked and modified version of the quic-go library which allows for altering some basic constants in the default QUIC implementation. These are provided as command-line flags and can be implemented on both the QPEP server and QPEP client. You can use ```qpep -h``` to see basic help output. The available options are:
* ```-acks [int]``` Sets the number of ack-eliciting packets per ack. The default ratio is 10:1.
* ```-congestion [int]``` Sets the size of the initial QUIC congestion window in number of QUIC packets. Defaults to 4.
* ```-multistream [bool]``` Enables multiplexing QUIC streams inside a meta-session. Default is true.
* ```-ackDelay [int]``` Maximum number of miliseconds to hold back an ack for decimation. Default is 25.
* ```-varAckDelay [float]``` Variable number of miliseconds to try and hold back an ack for decimation, as multiple of RTT. Default is 0.25.
* ```-minBeforeDecimation [int]``` Minimum number of packets sent before initiating any ack decimation. Default is 100.
* ```-client [bool]``` runs QPEP in client mode. Default is false.
* ```-gateway [ip]``` sets the gateway address for a QPEP client to connect to. Default is 192.18.0.254 but you will probably need to set it yourself based on your network config.


## References in Publications
QPEP and the corresponding testbed were both designed to encourage academic research into secure and performant satellite communications. We would be thrilled to learn about projects you're working on academically or in industry which build on QPEP's contribution!

Expand Down
8 changes: 4 additions & 4 deletions api/analytics.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,9 @@ import (
"encoding/json"
"fmt"
mqtt "github.com/eclipse/paho.mqtt.golang"
"github.com/parvit/qpep/logger"
"github.com/parvit/qpep/shared"
"github.com/parvit/qpep/version"
"github.com/parvit/qpep/shared/configuration"
"github.com/parvit/qpep/shared/logger"
"github.com/parvit/qpep/shared/version"
"github.com/rs/zerolog"
"golang.org/x/net/context"
"os"
Expand Down Expand Up @@ -183,7 +183,7 @@ func (c *analyticsClient) publishEventsBuffer(client mqtt.Client, events []Analy
}

// launchAnalyticsBrokerClient starts the analytics client
func (s *statistics) launchAnalyticsBrokerClient(brokerConfig *shared.AnalyticsDefinition) {
func (s *statistics) launchAnalyticsBrokerClient(brokerConfig *configuration.AnalyticsDefinition) {
if !brokerConfig.Enabled {
logger.Error("Broker client startup was disabled, check the configuration")
return
Expand Down
14 changes: 7 additions & 7 deletions api/analytics_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,9 @@ import (
"encoding/json"
"fmt"
mqtt "github.com/eclipse/paho.mqtt.golang"
"github.com/parvit/qpep/logger"
"github.com/parvit/qpep/shared"
"github.com/parvit/qpep/version"
"github.com/parvit/qpep/shared/configuration"
"github.com/parvit/qpep/shared/logger"
"github.com/parvit/qpep/shared/version"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/suite"
"math/rand"
Expand Down Expand Up @@ -75,7 +75,7 @@ func (s *AnalyticsSuite) TestBrokerNotEnabled() {
results = s.getMessagesDispatchedByBroker(5 * time.Second)
}()

Statistics.Start(&shared.AnalyticsDefinition{
Statistics.Start(&configuration.AnalyticsDefinition{
Enabled: false,
BrokerAddress: s.brokerAddress,
BrokerPort: s.brokerPort,
Expand Down Expand Up @@ -108,7 +108,7 @@ func (s *AnalyticsSuite) TestBrokerCannotConnect() {
results = s.getMessagesDispatchedByBroker(5 * time.Second)
}()

Statistics.Start(&shared.AnalyticsDefinition{
Statistics.Start(&configuration.AnalyticsDefinition{
Enabled: true,
BrokerAddress: "9.9.9.9",
BrokerPort: s.brokerPort,
Expand Down Expand Up @@ -141,7 +141,7 @@ func (s *AnalyticsSuite) TestBrokerSendEvents() {
results = s.getMessagesDispatchedByBroker(5 * time.Second)
}()

Statistics.Start(&shared.AnalyticsDefinition{
Statistics.Start(&configuration.AnalyticsDefinition{
Enabled: true,
BrokerAddress: s.brokerAddress,
BrokerPort: s.brokerPort,
Expand Down Expand Up @@ -184,7 +184,7 @@ func (s *AnalyticsSuite) TestBrokerSendEventsFromDataRoutines() {
results = s.getMessagesDispatchedByBroker(5 * time.Second)
}()

Statistics.Start(&shared.AnalyticsDefinition{
Statistics.Start(&configuration.AnalyticsDefinition{
Enabled: true,
BrokerAddress: s.brokerAddress,
BrokerPort: s.brokerPort,
Expand Down
10 changes: 5 additions & 5 deletions api/api.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ package api
import (
"encoding/json"
"fmt"
"github.com/parvit/qpep/shared/configuration"
"github.com/parvit/qpep/shared/version"
"net/http"
"net/http/httputil"
"runtime"
Expand All @@ -12,9 +14,6 @@ import (
"time"

"github.com/julienschmidt/httprouter"

"github.com/parvit/qpep/shared"
"github.com/parvit/qpep/version"
)

func closeBody(req *http.Request) {
Expand All @@ -26,7 +25,8 @@ func closeBody(req *http.Request) {
// formatRequest method formats to a string the request in input, if verbose configuration
// is set then also the body of the request is extracted
func formatRequest(r *http.Request) string {
data, err := httputil.DumpRequest(r, shared.QPepConfig.Verbose)
config := configuration.QPepConfig.General
data, err := httputil.DumpRequest(r, config.Verbose)
if err != nil {
return fmt.Sprintf("REQUEST: %v", err)
}
Expand Down Expand Up @@ -173,7 +173,7 @@ func apiStatisticsInfo(w http.ResponseWriter, r *http.Request, ps httprouter.Par
reqAddress := ps.ByName("addr")

lastUpdate := ""
address := shared.QPepConfig.ListenHost
address := configuration.QPepConfig.Client.LocalListeningAddress
platform := runtime.GOOS
if len(reqAddress) > 0 {
address = reqAddress
Expand Down
Loading

0 comments on commit 461aa44

Please sign in to comment.