190 lines
6.1 KiB
Markdown
190 lines
6.1 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 {name, wg_ip, port, displays}
|
|
4. Artemis heartbeats: PUT /api/host/heartbeat {wg_ip} 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/displayinfo.h` + `_linux.cpp` / `_win.cpp` | Display enumeration for relay registration |
|
|
| `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 |
|
|
| `scripts/build-boringtun-win.ps1` | Build boringtun for Windows |
|
|
|
|
---
|
|
|
|
## 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"
|
|
#include "wg/displayinfo.h"
|
|
|
|
// Boot sequence (run before Sunshine starts accepting streams):
|
|
wg::RelayReg relay;
|
|
relay.setBaseURL(config::relay_url);
|
|
|
|
std::string err;
|
|
if (!relay.login(config::relay_user, config::relay_pass, err))
|
|
BOOST_LOG(error) << "Relay login failed: " << 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
|
|
|
|
const std::string localIP = wgClient.localIP(); // e.g. "10.99.0.3"
|
|
const auto displays = wg::enumerateDisplays();
|
|
relay.registerHost(config::relay_name, localIP, config::relay_port, displays, err);
|
|
|
|
// Heartbeat thread (every 60 s):
|
|
std::thread([&]() {
|
|
while (running) {
|
|
std::this_thread::sleep_for(std::chrono::seconds(60));
|
|
std::string err;
|
|
relay.heartbeat(localIP, err); // wg_ip required
|
|
}
|
|
}).detach();
|
|
|
|
// Shutdown:
|
|
{ std::string err; relay.unregisterHost(localIP, err); } // wg_ip required
|
|
wgClient.stop();
|
|
{ std::string err; 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
|
|
```
|