artemis/README.md

181 lines
5.6 KiB
Markdown

# Artemis
**Artemis** is a fork of [Sunshine](https://github.com/LizardByte/Sunshine) — the open-source GameStream host — with an embedded WireGuard client that automatically connects to a [DragonRelay](https://forge.wilddragon.net/zgaetano/dragonrelay) server.
This lets remote **[DragonMoonlight](https://forge.wilddragon.net/zgaetano/dragonmoonlight)** clients discover and stream from Artemis hosts over a private WireGuard network, without requiring port-forwarding, mDNS, or direct LAN access.
---
## Architecture
```
DragonMoonlight (client) Artemis (host)
WG tunnel: 10.99.0.2/24 WG tunnel: 10.99.0.3/24
│ │
└────────── 10.99.0.0/24 ──────────────┘
DragonRelay server
├── WireGuard server (wg0: 10.99.0.1)
├── REST API (JWT auth)
└── Host registry (5-min TTL)
Flow:
1. Artemis boots → logs into DragonRelay → provisions WG peer
2. Artemis starts WireGuard tunnel → gets IP 10.99.0.3
3. Artemis registers: POST /api/host/register {wg_ip: "10.99.0.3", port: 47984}
4. Artemis heartbeats: PUT /api/host/heartbeat every 60 s
5. DragonMoonlight: GET /api/hosts sees 10.99.0.3 in the list
6. DragonMoonlight connects to 10.99.0.3:47984 over the shared WG tunnel
```
---
## New files (WireGuard integration layer)
| File | Purpose |
|------|---------|
| `src/wg/wgconfig.h/.cpp` | Parses standard wg-quick `.conf` files (C++17, no Qt) |
| `src/wg/wgclient.h` | Platform-agnostic WireGuard tunnel interface |
| `src/wg/wgclient_win.cpp` | Windows: Wintun kernel TUN + boringtun FFI |
| `src/wg/wgclient_linux.cpp` | Linux: `/dev/net/tun` + boringtun FFI |
| `src/wg/relayreg.h/.cpp` | DragonRelay HTTP client (libcurl) |
| `src/wg/boringtun_ffi.h` | C ABI bindings for boringtun |
| `cmake/wg.cmake` | CMake integration snippet |
| `scripts/build-boringtun.sh` | Build boringtun for Linux/macOS |
---
## Quick start
### 1. Clone Sunshine and apply the Artemis patch
```bash
git clone https://github.com/LizardByte/Sunshine artemis
cd artemis
git remote add artemis-upstream https://forge.wilddragon.net/zgaetano/artemis.git
git fetch artemis-upstream
git merge artemis-upstream/main --allow-unrelated-histories
```
### 2. Build boringtun
**Linux / macOS:**
```bash
bash scripts/build-boringtun.sh
```
**Windows (PowerShell):**
```powershell
pwsh scripts/build-boringtun-win.ps1
```
This produces `deps/boringtun/libboringtun.a` (or `.lib` on Windows).
### 3. Configure CMake
Add to your `CMakeLists.txt` (after the main target is defined):
```cmake
include(cmake/wg.cmake)
artemis_wg_configure(sunshine) # replace 'sunshine' with your target name
```
### 4. Configure Artemis
Create `/etc/artemis/relay.conf` (Linux) or `%APPDATA%\Artemis\relay.conf` (Windows):
```ini
[relay]
url = https://relay.example.com # DragonRelay base URL
username = host-user # DragonRelay account credentials
password = secret
device = my-gaming-pc # Appended to username: host-user@my-gaming-pc
name = Gaming PC # Friendly display name in DragonMoonlight
port = 47984 # Sunshine streaming port (default)
```
Artemis reads this on startup, authenticates, provisions a WireGuard peer, and
starts the tunnel automatically. The WireGuard `.conf` returned by DragonRelay
is parsed in-memory — no file is written to disk.
### 5. Linux: capabilities / root
The Linux WireGuard client opens `/dev/net/tun` and runs `ip addr/route`
commands. Either run Artemis as root, or grant `CAP_NET_ADMIN`:
```bash
sudo setcap cap_net_admin+ep /usr/bin/artemis
```
### 6. Windows: Administrator
Wintun requires Administrator to create the kernel TUN adapter. Artemis ships
with a UAC manifest (`requireAdministrator`). Users will see a one-time
elevation prompt on first launch.
---
## Integration points in Sunshine source
After merging, wire up the relay client in Sunshine's startup/shutdown paths.
The key hooks are:
```cpp
// In main.cpp or wherever Sunshine initialises subsystems:
#ifdef ARTEMIS_RELAY_ENABLED
#include "wg/wgclient.h"
#include "wg/wgconfig.h"
#include "wg/relayreg.h"
// Boot sequence (run before Sunshine starts accepting streams):
wg::RelayReg relay;
relay.setBaseURL(config::relay_url);
relay.login(config::relay_user, config::relay_pass, err);
wg::VPNConf vpnConf;
relay.provisionVPN(config::relay_device, vpnConf, err);
wg::Config wgCfg;
wg::Config::fromString(vpnConf.conf, wgCfg, err);
wg::Client wgClient;
wgClient.start(wgCfg); // tunnel up
relay.registerHost(config::relay_name, wgClient.localIP(), config::relay_port, err);
// Heartbeat thread (every 60 s):
std::thread([&]() {
while (running) {
std::this_thread::sleep_for(std::chrono::seconds(60));
relay.heartbeat(err);
}
}).detach();
// Shutdown:
relay.unregisterHost(err);
wgClient.stop();
relay.deleteVPNPeer(vpnConf.id, err);
#endif
```
---
## Privilege model
| Platform | Requirement | Why |
|----------|-------------|-----|
| Linux | `CAP_NET_ADMIN` or root | `/dev/net/tun` open + `ip` commands |
| Windows | Administrator | Wintun kernel driver |
---
## Upstream merge hygiene
Artemis adds only new files under `src/wg/` and `cmake/`. No Sunshine source
files are modified — this minimises merge conflicts when pulling upstream
Sunshine updates:
```bash
git fetch upstream
git merge upstream/master # only conflict-free for untouched files
```