From 6b2b137c1d4ed85cc1f3d858d9003c00e85f5c8e Mon Sep 17 00:00:00 2001 From: rmanach Date: Thu, 1 Oct 2026 13:32:45 +0200 Subject: [PATCH] feat: relay several servers, registered through the control API --- Cargo.lock | 80 +++++++- Cargo.toml | 3 +- ENGINE.md | 49 ++++- README.md | 86 +++++--- diagrams/ban.png | Bin 40847 -> 43802 bytes diagrams/ban.puml | 3 +- diagrams/pairing.png | Bin 0 -> 61150 bytes diagrams/pairing.puml | 29 +++ diagrams/tasks.png | Bin 57085 -> 85045 bytes diagrams/tasks.puml | 16 +- etrelay.service | 8 +- src/control.rs | 196 ++++++++++++++---- src/et.rs | 119 +++++++++++ src/filter.rs | 2 +- src/main.rs | 389 +++++++++--------------------------- src/proof.rs | 121 +++++++++++ src/registry.rs | 454 ++++++++++++++++++++++++++++++++++++++++++ src/server.rs | 317 +++++++++++++++++++++++++++++ 18 files changed, 1496 insertions(+), 376 deletions(-) create mode 100644 diagrams/pairing.png create mode 100644 diagrams/pairing.puml create mode 100644 src/et.rs create mode 100644 src/proof.rs create mode 100644 src/registry.rs create mode 100644 src/server.rs diff --git a/Cargo.lock b/Cargo.lock index e7a2911..873d0d7 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -114,12 +114,27 @@ dependencies = [ "tower-service", ] +[[package]] +name = "block-buffer" +version = "0.10.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71" +dependencies = [ + "generic-array", +] + [[package]] name = "bytes" version = "1.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fc652a48c352aef3ea3aed32080501cf3ef6ed5da78602a020c991775b0aff04" +[[package]] +name = "cfg-if" +version = "1.0.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4e7648175b45a9a48536d676f68d918270699102aa8dab5496df06904c914600" + [[package]] name = "clap" version = "4.6.7" @@ -166,15 +181,45 @@ version = "1.0.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1d07550c9036bf2ae0c684c4297d503f838287c83c53686d05370d0e139ae570" +[[package]] +name = "cpufeatures" +version = "0.2.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "59ed5838eebb26a2bb2e58f6d5b5316989ae9d08bab10e0e6d103e656d1b0280" +dependencies = [ + "libc", +] + +[[package]] +name = "crypto-common" +version = "0.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "78c8292055d1c1df0cce5d180393dc8cce0abec0a7102adb6c7b1eef6016d60a" +dependencies = [ + "generic-array", + "typenum", +] + +[[package]] +name = "digest" +version = "0.10.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292" +dependencies = [ + "block-buffer", + "crypto-common", +] + [[package]] name = "etrelay" -version = "0.2.0" +version = "0.3.0" dependencies = [ "anyhow", "axum", "clap", "serde", "serde_json", + "sha2", "tokio", ] @@ -220,6 +265,16 @@ dependencies = [ "slab", ] +[[package]] +name = "generic-array" +version = "0.14.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a" +dependencies = [ + "typenum", + "version_check", +] + [[package]] name = "heck" version = "0.5.0" @@ -461,6 +516,17 @@ dependencies = [ "serde", ] +[[package]] +name = "sha2" +version = "0.10.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a7507d819769d01a365ab707794a4084392c824f54a7a6a7862f8c3d0892b283" +dependencies = [ + "cfg-if", + "cpufeatures", + "digest", +] + [[package]] name = "slab" version = "0.4.12" @@ -558,6 +624,12 @@ version = "0.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8df9b6e13f2d32c91b9bd719c00d1958837bc7dec474d94952798cc8e69eeec3" +[[package]] +name = "typenum" +version = "1.20.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6f5e870be6c3b371b77fe0ee0bafb859fa4964b4404c27de1d380043c4dda20" + [[package]] name = "unicode-ident" version = "1.0.26" @@ -570,6 +642,12 @@ version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821" +[[package]] +name = "version_check" +version = "0.9.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a" + [[package]] name = "wasi" version = "0.11.1+wasi-snapshot-preview1" diff --git a/Cargo.toml b/Cargo.toml index 6a4869d..04053d4 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "etrelay" -version = "0.2.0" +version = "0.3.0" edition = "2024" [dependencies] @@ -9,6 +9,7 @@ axum = { version = "0.8", default-features = false, features = ["http1", "json", clap = { version = "4.5.51", features = ["derive"] } serde = { version = "1.0.229", features = ["derive"] } serde_json = "1.0.151" +sha2 = "0.10" tokio = { version = "1", features = ["macros", "net", "rt", "sync", "time"] } [profile.release] diff --git a/ENGINE.md b/ENGINE.md index dd94a90..044491f 100644 --- a/ENGINE.md +++ b/ENGINE.md @@ -16,7 +16,7 @@ Our ET server sits at home, reachable from the Internet only through the front s ## The fix -`etrelay` runs on the front and owns the public UDP port 27960. It does two things on **the same socket**: +`etrelay` runs on the front and owns the public UDP ports, one per ET server (27960 for the first). For each server it does two things on **the same socket**: - **Proxy**: forwards every client (players, server browsers, masters) to the ET server, one upstream socket per client address. Packets a client has no business sending (`rcon`...) are dropped on the way. - **Heartbeat**: sends the heartbeats itself, so the master challenges the **front** address. That challenge is just another client packet: it goes through the proxy, the ET server answers it, the answer leaves from the front address, and the master lists the front. @@ -29,7 +29,7 @@ Masters are independent: a server is only listed on the masters it heartbeats, a ![After: everything goes through the front](diagrams/architecture.png) -## Registration sequence +## Master registration sequence ![Master registration (every 5 min)](diagrams/registration.png) @@ -55,16 +55,42 @@ The last two lines are a server tracker that got the address from the master. The ET server sees every client as `:`: one source IP (the front's tunnel address), one port per session, the port of the session's upstream socket. Its own IP bans can't tell players apart: bans are etrelay's (below). A player coming back after the session expired gets a new port. +## Several servers: registering + +The relay holds several ET servers. The ET protocol has no host name to tell them apart: each one gets its own public port (`--ports`), with its own socket, sessions, heartbeats and bans. Masters list servers by address and port, so several on the front's address are fine. + +A server is relayed once its admin tool registered it, with `PUT /server` on the control API (`--control `, on the front's tunnel address, unreachable from the internet): + +![Registering a server](diagrams/pairing.png) + +- **The relay's token** only lets a tool register: it keeps strangers of the tunnel off the public ports. +- **The key** is picked by the tool, and is what every later call carries: it names the server, so a tool only reaches its own. etrelay keeps its SHA-256 (`servers.json`), never the key. +- **The proof**: before taking a key, etrelay checks the tool runs the ET server it registers. The tool makes the server show the key's fingerprint (the first 128 bits of its SHA-256) in the serverinfo cvar `etrelay_proof`, etrelay reads it there with a `getstatus`. Only who holds that server's console can do it, wherever the request comes from (a NAT between the two changes nothing), and the fingerprint, public for a moment, doesn't give the key away. An empty cvar is left out of serverinfo: the tool sets it to `""` afterwards (`unset` isn't in 2.60b). + +What can't happen: + +- **two servers on one port**: the second one gets a 409, the first one is untouched; +- **another tool on a registered server**: it has neither the key, nor the server's console to prove another one. + +One limit: a server that is gone for good without `DELETE /server` keeps its port (the masters drop it, nothing answers there), until its entry is removed from `servers.json` and etrelay restarted. + +An ET server registered again is taken over by who proves to run it (a tool reinstalled, with a new key): the former key is refused from then on. On the same port the relay goes on (sessions, bans); on another port the former one is freed. A relay that lost its state answers 401 to every key: tools register again by themselves. + +The registered servers are relayed again after a restart. `DELETE /server` leaves the relay: the masters get a flatline, the port is freed, the bans dropped. + +`etrelay ` still relays one server without any of this, on `--listen`: it has no key, so no control API over it. + ## Control API and bans -With `--control `, an HTTP API listens on the front's tunnel address (unreachable from the internet), bearer token on top. It serves an admin tool on the tunnel side: +Once registered, the admin tool asks about its server, with its key: +- `GET /server`: the registration, and whether the ET server answered the last probe. - `GET /sessions`: the open sessions, real client address and port the ET server sees, so the tool can put a real address on each player. - `GET /bans`, `PUT /bans/{ip}`, `DELETE /bans/{ip}`: bans by source IP, with a reason and an optional duration. ![Control API: real address and ban of a player](diagrams/ban.png) -A ban cuts the address's sessions at once, and the relay loop drops its packets before any session lookup: the ET server gets nothing more from the player and times them out, and they can't come back. Bans are saved to `/bans.json` on each change (written next to it, then renamed), expired ones forgotten. +A ban cuts the address's sessions at once, and the relay loop drops its packets before any session lookup: the ET server gets nothing more from the player and times them out, and they can't come back. Each server has its own bans, saved to `/bans-.json` on each change (written next to it, then renamed), expired ones forgotten. ## Filter @@ -78,14 +104,16 @@ Only what clients and masters send a server gets through, checked on the first w ## Internals -Single-threaded tokio runtime, four kinds of tasks. The sessions and the bans are shared by the relay loop and the control API behind a mutex, never held across an `await`: +Single-threaded tokio runtime, four kinds of tasks. Each server has its relay loop, its heartbeat task and its state (sessions, bans), shared with the control API behind a mutex. The registry (the servers by public port, the hash of their key) is behind another one, which the packets never take. Neither is held across an `await`: ![Tasks and data flow](diagrams/tasks.png) -- **relay loop**: reads the public socket, runs the filter and the ban check, finds the client's session and pushes the packet into its queue. No session, or an expired one: opens a new one (and purges expired entries), unless `MAX_SESSIONS` are open. A full queue drops the packet, like any congested UDP hop. +- **relay loop** (one per server): reads the server's public socket, runs the filter and the ban check, finds the client's session and pushes the packet into its queue. No session, or an expired one: opens a new one (and purges expired entries), unless `MAX_SESSIONS` are open, all servers together. A full queue drops the packet, like any congested UDP hop. - **session task**: owns one ephemeral socket connected to the ET server. Forwards the queue to the ET server and the ET server answers back to the client **through the public socket** (so they come from `:27960`). Ends after `SESSION_TIMEOUT` without a packet either way, or at once when a ban drops its queue's sender. -- **heartbeat task**: probes the ET server with `getinfo` on its own socket (up to 3 attempts, 3 s each), then heartbeats the masters through the public socket. Masters are resolved on every heartbeat (DNS may change). -- **control API task** (with `--control`): axum on the tunnel address. Binding is retried every 10 s: the tunnel may come up after etrelay. +- **heartbeat task** (one per server): probes the ET server with `getinfo` on its own socket (up to 3 attempts, 3 s each), then heartbeats the masters through the public socket. Masters are resolved on every heartbeat (DNS may change). +- **control API task** (with `--control`): axum on the tunnel address. Binding is retried every 10 s: the tunnel may come up after etrelay. Registering starts a server's two tasks, leaving aborts them and drops its sessions. + +The code follows that split: `server` (one relayed server), `registry` (which servers, `servers.json`), `proof` (keys and their proof), `control` (the API), `et` (the probes: `getinfo`, `getstatus`), `filter`, `bans`. ### Heartbeat states @@ -102,10 +130,11 @@ The master drops a server that stops heartbeating after a while anyway; the flat | `SESSION_TIMEOUT` | 2 min | Idle clients (server browsers) freed quickly; players send packets constantly | | `SESSION_QUEUE` | 64 packets | Burst absorption per client before dropping | | `MAX_PACKET` | 65 535 B | Any UDP datagram: `statusResponse` easily exceeds nginx's old 512 B buffer | -| `MAX_SESSIONS` | 2048 | One socket each: spoofed sources must not use up the file descriptors (`LimitNOFILE=4096` in the unit) | +| `MAX_SESSIONS` | 2048 | One socket each, all servers together: spoofed sources must not use up the file descriptors (`LimitNOFILE=4096` in the unit) | | `QUERY_BURST`, `QUERY_RATE` | 5, then 1/s | `getstatus`/`getinfo` per source IP: a browser refresh or a master's check passes, a reflection attack doesn't | | `MAX_QUERY_SOURCES`, `QUERY_FORGET` | 65 536 IPs, 60 s | The limiter's memory stays bounded under a flood of spoofed sources | -| `MIN_TOKEN` | 32 characters | Shortest control API token accepted | +| `MIN_TOKEN`, `MIN_KEY` | 32 characters | Shortest relay token and server key accepted | +| `PROOF_BYTES` | 16 | Bytes of the key's SHA-256 shown as its fingerprint: serverinfo holds 1024 characters for every cvar | ### Protocol cheat sheet diff --git a/README.md b/README.md index 20ec017..0fd0845 100644 --- a/README.md +++ b/README.md @@ -1,26 +1,34 @@ # etrelay -UDP relay + master heartbeat for a Wolfenstein: Enemy Territory server reachable only through a tunnel: runs on the front server (public IP) and makes the server show up in the in-game browser. +UDP relay + master heartbeat for Wolfenstein: Enemy Territory servers reachable only through a tunnel: runs on the front server (public IP) and makes the servers show up in the in-game browser. Each server gets its own public port. ``` -players / masters ──> front :27960 (etrelay) ══wg══> ET :27960 - front :8090 (control API) <══wg══ admin tool +players / masters ──> front :27960 (etrelay) ══wg══> ET :27960 + front :27961 (etrelay) ══wg══> ET :27960 + front :8090 (control API) <══wg══ admin tools ``` +A server is relayed because its admin tool (etadm) **registered** it through the control API, or because it was given on the command line (one server, no control API over it). + - **Proxy**: one upstream socket per client address, packets forwarded as-is both ways, session dropped after 2 min of silence. - **Filter**: connectionless packets pass only for what clients and masters send a server (`getstatus`, `getinfo`, `getchallenge`, `connect`, PunkBuster's `PB_`). `rcon` never reaches the server from the internet: it travels in clear, and a stream of it blocks the local admin tool (2.60b runs one rcon per 500 ms, whoever sends it). `getstatus`/`getinfo` are limited per source IP (burst of 5, then 1/s): their answers are much bigger than the query, a spoofed source would make the server a DDoS reflector. At most 2048 sessions (one socket each). -- **Heartbeat**: every 5 min, `getinfo` to the ET server; if it answers, `heartbeat EnemyTerritory-1` to the masters **from the public socket**. When it stops answering, one `heartbeat ETFlatline-1`. +- **Heartbeat**: every 5 min, `getinfo` to the ET server; if it answers, `heartbeat EnemyTerritory-1` to the masters **from the server's public socket**. When it stops answering, or when the server leaves the relay, one `heartbeat ETFlatline-1`. -Masters check (`getChallenge`, `getInfo`) the address the heartbeat came from: the public `:27960`. Those packets go through the relay like any client, the ET server answers them, and the master lists the front public address. +Masters list servers by address and port, several on one address are fine. They check (`getChallenge`, `getInfo`) the address the heartbeat came from: the server's public port. Those packets go through the relay like any client, the ET server answers them, and the master lists the front public address. How it works in detail, with diagrams: [ENGINE.md](ENGINE.md). ## Usage ```bash -etrelay [--listen 0.0.0.0:27960] [--master host:port]... [--control ] [--state-dir /var/lib/etrelay] [--debug] +etrelay [UPSTREAM] [--listen 0.0.0.0:27960] [--ports 27960-27969] [--master host:port]... [--control ] [--state-dir /var/lib/etrelay] [--debug] ``` +- `--control `: servers register through the control API, on a port of `--ports` bound on `--listen`'s address. They are kept in `/servers.json` and relayed again after a restart. +- `UPSTREAM` (an ET server's `ip:port`): relayed on `--listen` from the start, without registering. Nothing reaches it through the control API: no real addresses, no bans. It can't be registered, nor its port taken. + +One of the two at least. The ports of `--ports` must be open (UDP) on the front's firewall. + Default masters: `etmaster.idsoftware.com:27950` (id Software, the one ET 2.60b clients query) and `etmaster.net:27950` (ET: Legacy community). Passing `--master` replaces both. `--debug` logs sessions (open/close, packet counts), connectionless packets by command name only (`getinfo`, `getstatus`, `connect`...: no arguments, `connect` carries the userinfo), probes and heartbeats. In-game packets are only counted. @@ -29,7 +37,7 @@ Default masters: `etmaster.idsoftware.com:27950` (id Software, the one ET 2.60b probe :27960: up ET server :27960 is up heartbeat EnemyTerritory-1 -> etmaster.net:27950 (198.51.100.10:27950) -session + 198.51.100.10:27950 as port 51234 (2 active) +session + 198.51.100.10:27950 as port 51234 (2 active on port 27960) 198.51.100.10:27950 -> ET getChallenge (27 B) 198.51.100.10:27950 <- ET challengeResponse (32 B) 198.51.100.10:27950 -> ET getInfo (22 B) @@ -43,18 +51,44 @@ Without `--debug`, each player joining is logged with its real address and the p ## Control API -`--control ` serves a small HTTP API for the admin tool (etadm), on the tunnel address only (e.g. `10.66.0.1:8090`: unreachable from the internet), with `Authorization: Bearer $ETRELAY_CONTROL_TOKEN` (32 characters at least). Binding is retried every 10 s: the tunnel may come up after etrelay. +`--control ` serves a small HTTP API for admin tools (etadm), on the tunnel address only (e.g. `10.66.0.1:8090`: unreachable from the internet). Binding is retried every 10 s: the tunnel may come up after etrelay. -The ET server sees every player as `:`, the port of the player's session socket; the API maps it back to the real address. +### Registering a server -| Method | URL | | -|---|---|---| -| GET | `/sessions` | `[{"client": "203.0.113.7:27960", "port": 51234, "since": }]`: open sessions | -| GET | `/bans` | `[{"ip", "reason", "at", "until"}]` (`until` null: until lifted) | -| PUT | `/bans/{ip}` | `{"reason": "...", "minutes": N}` (`minutes` left out: until lifted); cuts the address's sessions at once | -| DELETE | `/bans/{ip}` | 204, 404 when not banned | +An admin tool registers the ET server it runs, with two things: -A banned address's packets are dropped before reaching the server: the player times out, and can't come back. Bans are kept in `/bans.json` (written atomically), expired ones forgotten. +- **the relay's token** (`$ETRELAY_CONTROL_TOKEN`, 32 characters at least): it only lets a server register; +- **a key it picks** (32 characters at least), and the proof it runs that server: it makes the server show the key's fingerprint in the serverinfo cvar `etrelay_proof` (`sets etrelay_proof ` on its console), where etrelay reads it with a `getstatus` before taking the key. The fingerprint is the first 32 hex digits of the key's SHA-256: public while registering, it doesn't give the key away. The tool removes the cvar afterwards (`set etrelay_proof ""`). + +Then every other call carries the key (`Authorization: Bearer `), which names the server: a tool only sees and changes its own server. etrelay keeps the key's SHA-256, never the key. + +| Method | URL | Bearer | | +|---|---|---|---| +| PUT | `/server` | token | `{"name": "...", "port": 27960, "upstream_ip": "10.66.0.20", "upstream_port": 27960, "key": "..."}`: register the ET server `upstream_ip:upstream_port` (as seen from the relay; `upstream_ip` left out: the caller's address) on the public `port`. Answers the registration (below) | +| GET | `/server` | key | `{"port", "upstream", "name", "since", "alive"}`: `alive`, the ET server answered the last probe, the masters are told | +| DELETE | `/server` | key | leave the relay: the port is freed, the masters get a flatline, the server's bans are dropped (204) | +| GET | `/sessions` | key | `[{"client": "203.0.113.7:27960", "port": 51234, "since": }]`: open sessions | +| GET | `/bans` | key | `[{"ip", "reason", "at", "until"}]` (`until` null: until lifted) | +| PUT | `/bans/{ip}` | key | `{"reason": "...", "minutes": N}` (`minutes` left out: until lifted); cuts the address's sessions at once | +| DELETE | `/bans/{ip}` | key | 204, 404 when not banned | + +`PUT /server` answers: + +| Status | | +|---|---| +| 200 | registered | +| 400 | port outside `--ports`, key too short | +| 401 | wrong token | +| 403 | the ET server doesn't answer, or doesn't show the key's fingerprint | +| 409 | another server holds the port, or the ET server is the command line's | + +One server per public port, one port per server. Registering a server again (same ET server, another key: an admin tool reinstalled) takes it over: who proves to run it holds it, the former key is refused from then on. On the same port its sessions and bans go on; on another port the former one is freed. Unknown keys get 401: a tool whose relay lost its state registers again. + +### Sessions and bans + +The ET server sees every player as `:`, the port of the player's session socket; `/sessions` maps it back to the real address. + +A banned address's packets are dropped before reaching the server: the player times out, and can't come back. Each server has its own bans, kept in `/bans-.json` (written atomically), expired ones forgotten (`bans.json`: the command line's server). ## Build @@ -67,20 +101,26 @@ make release # both Artifacts land in `dist/`, named `-v-` with a `.sha256` checksum: ``` -dist/etrelay-v0.1.0-x86_64-unknown-linux-gnu # dynamic -dist/etrelay-v0.1.0-x86_64-unknown-linux-musl # static +dist/etrelay-v0.3.0-x86_64-unknown-linux-gnu # dynamic +dist/etrelay-v0.3.0-x86_64-unknown-linux-musl # static ``` ## Run as a service -1. Binary and unit on the front server ([etrelay.service](etrelay.service) is a template: replace `@UPSTREAM@` with the ET server `ip:port` as seen from the front, `@ARGS@` with extra flags or nothing): +1. The token servers register with, on the front server (root only, systemd hands it to the service): + ```bash + install -d -m 700 /etc/etrelay + echo "ETRELAY_CONTROL_TOKEN=$(head -c 32 /dev/urandom | od -An -tx1 | tr -d ' \n')" > /etc/etrelay/env + ``` +2. Binary and unit ([etrelay.service](etrelay.service) is a template: `@UPSTREAM@` is nothing when servers register, or one ET server's `ip:port` as seen from the front; `@ARGS@` the flags): ```bash install -m 755 dist/etrelay-v-x86_64-unknown-linux-musl /usr/local/bin/etrelay - sed -e 's#@UPSTREAM@##' -e 's#@ARGS@##' etrelay.service > /etc/systemd/system/etrelay.service + sed -e 's#@UPSTREAM@##' -e 's#@ARGS@#--control :8090 --ports 27960-27969#' etrelay.service > /etc/systemd/system/etrelay.service systemctl daemon-reload && systemctl enable --now etrelay ``` -2. Nothing else on the front may capture UDP 27960 (DNAT rule, nginx `stream`...), or players bypass the relay: `iptables -t nat -S | grep 27960` must print nothing. -3. ET server `server.cfg`: stop its own heartbeats, they leave through the home connection with the wrong IP: +3. The UDP ports of `--ports` open on the front. Nothing else may capture them (DNAT rule, nginx `stream`...), or players bypass the relay: `iptables -t nat -S | grep 27960` must print nothing. +4. Each admin tool gets the relay's address, the token and the public port it asks for (etadm: `--relay-url`, `--relay-token-file`, `--relay-port`, or its Relay page). +5. ET server `server.cfg`: stop its own heartbeats, they leave through the home connection with the wrong IP: ``` set sv_master1 "" set sv_master2 "" @@ -92,7 +132,7 @@ dist/etrelay-v0.1.0-x86_64-unknown-linux-musl # static ## Check ```bash -journalctl -u etrelay -n 50 # "ET server ... is up" +journalctl -u etrelay -n 50 # "registered ... on port 27960", "ET server ... is up" tcpdump -ni any udp port 27950 # heartbeat out, getChallenge/getInfo in, answers out ``` diff --git a/diagrams/ban.png b/diagrams/ban.png index 362adda255133c2701eabe3e093d599b5bf1a9cb..93e1cf6e4bc753e89d57cc20dfd88be8d165ff4f 100644 GIT binary patch literal 43802 zcmb@uWmuJ6w>C^8t#pT!f`oLZl%#a0ba!_t9nvL;ASFmQ0@4lA-O}B$zKQzWdp~=> z@A3S2KmW+F*1WDYV~lg0qvm@BISDjmLS!f?C^RX_SBg+ju&Pi{Fqw~Fz$ed-N!~y~ z`9Vp&5>|H8-OWIBQx==-N>Ydy;-P*V7oz|(3cnQ>bRD3GV;+EQPWOx)7yH$SnxJ_Y z+LJS}H@V1E~D4pQ|u+ zxu0%o_+|_XeijOfshx)B_a8#Sh?tKb{`$V-2M71?#~}|nH1xwCjp&j>5C21z!v4Pw zIewyro>L>VdMsVd`*9v&+wfv^m%~mliAj%?(?;9L$tm`!*c=BZN+&ebP9Qt%hvn_@ zA~N4w`&QKI-|*kOx6eM>Q1zwu<^@G{0ND8 zU3R}V?2pl!!?ti<OIL_%ZZ=X?J@US?=$X!bfB zkEz*VJxo2xR-G9gN}a5j;3HH@N{Z`(J8jbsiC3>0FBUwdq@*ev(s`UMz+zZU`oAdU zM@>;+)VeU)+f{B1q*Wx!rg7lx*pN|ib6?%x9OSo)M-mcn9C9&cMa)C*aVX$5B$?Fs z-#pi@WtM$TPcL2EE&l=^5vmwt0#(89V$nBCck$DwPfCi4Kk8>G%rCc#O5>iLo}8SV zoqcYD+$}<41J=-{RAVzU1?-l-`}z3|4-e;OdW6}k6|06%_->7UmLT)4lu2O`3&S?> zL6q;pK%1^Gjb@M-Wj7xULT+%`!z6qZn9gM%fWGBqf<_#4HmZkx)I*z9X*JEl%v`4a z&G6f|Z}I|HYgZ?m?t7h)L=8?`n53j~jvu*8H7Y{XjCq*}+%I4e(Vh0^rWY5pGE)uO zLq=GsQO#=n9Vf;1vV8BaEXE5*lr);XuFy$%iuGD_S2$n!m|Gc|)FthG|Gc$qgigQ` z8}a)!*n(nbBm>^u5@h*T`1L7OCSQp-+41uqJ82YB}+uUWjfu?th zQvTvdyEm107h7YY?v-=)T_kvn+QTku*bJJdlX|{5A?u+YHV58Xt~1G$PoGv+&DT2{ z!6OnK9yxmI+}&K@?KpI@oe(``V~vQ=*ynaI_XtWvCEV;!VVyxp*Orxv=GzprMPGT$ z{m42E14flFd|E(jE~#t*f;1tlRAVyk&rP+GNHyLC&N!x*C^0RLx1x zZza=Xj7*yl(c*pM!h?!|u~|c>+vJfDDgHcmPpI&1+8RDouYqYcj6VESsq`>?mAXA| zmE~lf37Pk4?8H?oB3Vp@&3yfCOp}Z4LSqU^TuzRtudnYyCi_yT=4KqVbS2oCd~0%{ z`GVF!41sQR08+A{l`R&tWx{aHx5v`i{&}IIWx8!*vE@{oKs~DDW+ZwvKEK8(i5GtA zS4gK?+|6H?8Zpez$QXqV5OI*`g-*Tl158d2>f-S$)){q0#nZ@M18gYOY3Q6uzS=Xy zC8(HlTpK+tL%7x*FH)PVtQWS)&+Ve-X8M?wK+2J~#zIXy9xeZLA+IhBsO6Z!$;QBR z_PlZrN6$;B5AALPQ2Nh_z3|Fjy~q3+ac?)tGmY?Fki)oi9{j#ZsD_3{fBP&7SRO!v zsz1y7eoo}$Ilbr$(fOi4vB&E*4d8b8T*fm&+6O!243n{UXy{;~$0i@Z!OtZy%=_+a z(!6D|`mGA;MjiXgUUvgHv2^sI4BoEUvC~S}8S9w6UFQ;wiaY>4a~gFH#^*+&CO-Vf z(tXuQo>AJVq!U7m;c=|IL%&b5hL;{F*|hO7La~+WEs&#_(6tx5R&%xAWIr+O<^7fX z@?c~?F-b|uGHyGjkIVP3Lf3MWoL#zg8>-OYqMQ9w#_Gn*ukJ1uHDLKQGg|pleV)1y z;Tukcb2w~p1`+Zd{lLoML=*_Hdq#d>qlPeT9b?S`-7uMuagu%8n?Mf?($VpHUwj2H zF%B($x1;5eG}!M1E>&?nE{-5w3a9rjP}IScJQF>D$y8*L1CFt0%YVF)@#|234}S z9Yb<*lb(mPJFLy``QTgB2v_&O?dm2a0#TY~OYQucMbT1e_36Di|GzfcTO_sX`BsnT zpeZji*lGXYJH6X|2}~)uJTP3Ir@ssu?j}$q6vYI|q39l_Znxf>;BmG+?O^kZg4^wI zskOhqe=J`faz1No+jxYq=sDH2-P+oEy6sCB8ZB`BZhnxdPEF^q3?rlEYJ+G`NAFs9 zdN4C8J~0vZ@#Ce{RmaOigOV)t9x0Vu4#ysH)CM%vm%AO+Cl2eq1DX81&z}QRCA~S6 zwfN1bE6ui9N*-IQz-&*cM#~NwPonlVcxC>G8b@mK#Ohzzn7W|)eS-b&A@cxc(fS$VIrWVtI){3D z3ss76@0!$V?Uup$Tl#j)*c86ywTpy$1|5h0McBcC<;K}eRGrA9!*(PmSlzT@gmF-B zC1rD>mM8iUmLS9$e=sAe-DkJV`{vxRV_)C1s zr97FD9I>s~SIfySjeHKvSbC5d2Dd0u{?}Tz zl9G>ZUQLyub-f?6PtF0L?ynx3AuCsygRrZ>@yuxIFFs==UPWdBOXh;YE zZ(m>)UJO=lodeUjf`yIErvKgV=TBt=;-0c;bSFW(C82z|jN7}rf`N7n!D5K}+Xgf$ ztQhUdJlQml^IeT^hGHJ1MJh$-E8$GK^-fYNlSUV#r&w5gE=;l*mNAKmz*K!)TGHR1 zt#dRb3?1L_e(iA_cY@kbG1^X;tV3h_y%#+S0`w=Im6-&pv5d7?}fteea7nEgbJ=DJV)xZb=OO z&YCxUu59o6LeRo_1VupfrhekgHdKMhp1cq0?<7L+4)lDDYPBl&R%tH31r_iyKy~Q;VTtA77KFRr$IrLW$6S-5B&bUp%`P3-G_)9fh>HMU*MD zi$B}&MRt%g0P84H|6#RI2Zoy!tR(k3-xn@*gdRTd3lJLgMZ6mFx`B|qUGuti{p~vW z!L(27LDYXu1~lP)fxP0{^o7&&g+mdW1WvuHnDf7yI0X}qCL zY9D=erpG}={xC}DYd2q3z2mKxbO2WJ#%eWH?Kn7B&D#?_^nVTLslT@Et=HppslUJR z1#h7Dg{Wct`O+_b*T;ZEO2`A7{>48Z{oM{XlD`|Ti}-i&B=nz+RIroOXo(EU(9yyZ zjG!Xt-!3{8Hww!?BL4fp(+0)T>d~~|e|_YJ_j}1u_!UHdx6F;`|MvbR=l?i` z|G$UeL3HaI>AoU@t;j7`x3>Q4$~wqSR9OnTc!r&lvC_p$SiLm>Uv%TK4C%;dw4j-2 z^zmiU37C>!xS3{BxI(Ew4X(I6E;&EN{t^ZDri2 zYh)OT<@2+5y28-Iw&810_!OAsGmxQ7gK<@$IyO-cHY|pztR(h4qPTdES$g`t^U1gH z24velM=A{R!TamYr;x-CNDX?oLSLSOM-pcqso=srOs#dcT09uFp%&$+nor``?^Lua zDcJQR+vR#TUPnD~w|v#l5X~@WT;R$7&#`XYDVs_yU#G(z^u3EDz8dS|6giR$jw=#b zm>=1q3qMTAZFb^Ii~*i2#X{nyB<uz4hih#Y&jpYh0*ir+Yiqq4Tb0oja~8t!JFJ z(M6D{`v3H$rTvO0X`F4OIvmjSV|d$HLL8Re6~-U4$HYCW8C-XkOd%~KMkK$FrqS9` zxw|a9;qk-LqwySAY+J5g+y+#B24G6AXLmATRxy1lhckeN7oam2T+2PQr|Gka5!W?a zduXb-068Io2s*H(s&Bse{kHU3!iHEp@8>e1WB>8eAN{w#cw#K@U_Xw0#KEGab z972rUDXXJp;szQ6!bv0K{^ZFMV-y@Zs;zF#@-{tRhP{O*6-h~b zef^%VI#_a<+8149(!EJcvdHhV?p8X;+S>x;vUE$c#xq=1ncn26S6Pf?`CPMHwA}1p zPEEbb5epw)E!G&a7tC;)E+>#p{h8;O@EmKj#x_(b|7-MCcd%sVnsJHs;=Ox?iF1WR z(2{M-d|2V|{o!(HUm_ZN@k$6dlJ1kauLK(>ds{~7f*~Xt(yHBkA~E=JT}9oJ+|pqK zDhIQ5E^J8v(uJDIrwKW2Zp&Qu=uVRptG5nXlB%p{-yW|?s3&~X{KZU>z1$jDM0_BL zHt{thA@lyE&QXx>`WI{4(IDT10 zQWr@)ZMo2>_T{jXXqD8rvBu@CHLIi$CuNUg!-k~5iD(T2TpfkGkTA@HJ_(nzSKG{+ z^(D$*Q4}NsPoccrXLI)3Dhe$R3*}3R?J(q>$)Tw5@MaflqLUgc_s#RYER@JJwt^=8 zR>&5j`Ap?t9JLa7mh;?3TXj&X#`-2gEraVD4I5jGnmOVV##aJ))sz+VYSnZ061(et zEecotDQGzKiPX`q8)hC%QK_!l#kU-}DAdCA83qg-WPYfhJF8E%cXRuj7g zBA{7#U9CIO?Jl;g>^JOK4z=}9*3>T38n(7V=hk0RB=ofRvfZ~p?hCE^^C?;$UnS2( z^-EF;-0YJ3Ockl!e3s5XI*%~y2jV%Q`Q@W=$?<163spR za~@lxCi{@x3J8a-&s|0}5>`lm79`atC?-Y-k(#{ft#MQ53h7nwnuSccT!v44m(#$MzGH-F){O_zaKFAhGZ+)raD!Zxasq)c-G{6vQ^5hs|3rCUm7)1D=F?AFM~ zn36G8kprpY-kTYwXFlam#gO%yJa)X<4L0MQ))?;Yyg?u$Hi6UX((lHcG9nBaa?}-V z_Som3al))myY|qz33z}!w+x)+)Y5OsW*nk#MI6{oUiZ#?{~m|OXtkDkvdI~@xz^(x zvR9X)qG5o?#Qbo6QpXyZf^kvqdXF3`M2_9Yad(eO5?LgiaLCi^svC>1V2o7VD4ICLMbwu?BWtoG*WmYQ!gSs^PON|cm+Zy2n<0JhPi z##t-jLs3T?TAjLkndv75rmIcRBCD%6u2C%brXC|HZmLGwx8{KGTLPqlpn}6k$VE$xOaZZ3ajA?{$L>URTHGd$X&ns}d3T6v{Y~>2(~X zy@ITc^13k2-wQVIRL zLqlDUtXDSOO>Wz#) zEZl7-k82-;{qODIV*>ln`xM%8@@o@_VM!-3W(fM;k4TV_@VPN_AJlDTVhCLNx!xYO zV<4gtz6u5rj@X$oBM*;jLCEb`we@V0o=-~EHyuc9Uyx`h`jIXv9OkgppVj|l$;Kn` z^+%&wg0H^g3Ao&F}T&obaW3!VEeuB+#q5>`uidCv#a%F=xN-3r4|v`t<3S zG7tl?i+AnGp)=Sn)~FTmUSRbR0=WP@ss?DDO8-2T zU3<+nej}ZLKxVFigTpaU9#$5XTFA+eAczQZdut?d*k#bF3pX z&08tFt=MW_qpq2&c730c@sr;j=_mC;-`k$J9f;)Q3s?g=BJevso|&wDo|&88a1#9h z2@8|y4fc_0UnL&V`T9bB{v?9ruH788Z2Bk$y?OIS@a|Lz_}G`O0$*-H+`7EnZ%uo@ zE2Us+prt^m3!6zd;?5%JheLzmNkdb13fjtpb{V>+OjQ9i5WK&PT{x&rp{|g4L2bMj zLoqM8I%)~eFK}zed3-n%jG|Yn+oT9Q?k)SH6)lMDH!)4x+enQW(rTwE7lW8EEXo_@lh99mVo#5T2FkDYRPNBS5*G&+tVIF6X$K^3}Du8 z#u?wQyB^oQ^{Nn_i%$~L*=59P*jQa{hh#NL_rFNtH!RVdXLm9K>4oN}DiYCD&^_&i zKnhmN%08Ahdz{SGk^PG86@>65sqi1Y%KGsmgx8g^*2$cezuI#0EkKjqb4=9m$>25q zp_Fxg?h}CkN|WHV*dKGTbaNM)=1HIO?qqcHm z)>O6v5`6V?nUt7jZ{Bns>U&$I**)gXhJ&c+$jFaKk6Og(3s$`0f9qx}6IN3OU!BeM z>9<=9S_;ptqq~c&=y%Vw0Depe#eEAY66GZ)QnCz1_tvSldM3C#w%O^sN{*&k@5Bs& zj|4d@MxOdcAEdEL^W$B?YHqXp`)1Q2pCOE)^l63iTr&ELUnAl-1Z_VHj6BY*x_a59 z_J-UQQsh-ee+$RcAxG~8A3z+=PgX1O8ZTEK-80R&F@k{b=>ELc`t7CW11)`4aDQne zb#?q1(Bl(>2O~<=e8^N%rD0voL#6WbZcJY9t4;&*9xq!BhM<@5Y>BxA<^Ck`%yU2q{KSaI5g2{S*}z{=DDZ zARySdnTgv-!1VLW6QFr7EMn4ctq&F;TjNDdJ~SdZOuAlogLK<}X(c2}IgYMkJm-}z z3hsGdCZ4*?6TU4A!RgT zq&Y+55inD2&EkGc*+@;V0ILa4MKYLivka^QK3^?8w>jRw@oGUldP&vL+^~8jMswFM zw$1KZTw;mr52}Af=$b2gcWtkf7m+8}^X%24uVB7T15H1Z@BU?l%nv&rE{-`nWw#%?480qlvkns($ecrzUSoUHn6A->%8K~rLUmEuH){SS- zKE;td{Kj&IiEgg9JmBWl{npi2gB%|iQ+CjG@ry6%nMPCRqg2^5@prqj--UnQ7B5w(s z&#$kD?ro}X>sE)31K=SbSZZWl3h>*tv0WL!<}JxBjpY7(^a$-C-<;USUD$CvsM6uiF#kB(||jQ{?cm7yZANJMi?Gb zXD8YZrHcX^Pk2vH7 z`Ta6!G&2FySsD4XXy5X%i7X`w7Co=1_!U!BxTkb%RUf%QcXnWwDdi_x%{zdoGcZhd zfp}}7*8$CuKMM42y@I6+Q6&aNbYVOt6Qw3(kuK*P10h$Yb92dm$Cf=Q?48&;& zJTlU=ub9RFJ3YU+_$)CKxD^YB+fpH+-ljZ}6;2=}bgdLar4Ll+TGPbepE@|&2{=?y zzPUH^t_KqZO6)aFe^-zC{7p`>stSH}M6|6CUC=QFt0VoL`}eyn@AJitfzlQu318R; z=jSb4&vuORG&!{GOcaS;-t>1p_9qH?LJ(-*sN~Q z|Gm}(OlE3hhNgFVwPmrMgISA`q%QHbw}JY5TqeKQJQ0Td-0N(+q((HAqojQ?uD>_M z?|clpg04NbA|~lOsYzeZ>|h3pc=SHVLYV=xwbAe1x{ug8Q>bnH;^Gm#i0%9LXrZWE zodR9v^Yu>>wqhrd$>5YUxbRBufM!bGu<2myq}~VWmw+%sPJ&-3#^SX=*kMPM`B-PF z_qR`$lR;{_?l1mpJF;K=_QnP(8Mc@nH{)_VIA2mv#KnRkm#Y$N@0JJh8b7~vmMpZY z#|S`Mw5)v4p09fM9*((a6?Zpkhl2gY?)%Air(<2?gl{;4^$%QDq(Nn!#6=M9(0c>>4#al6Amh z?)S4;jM)%Q$}QL4;4pLCNlWIhS2wlQmmrZ~eU)|TMd#w$uT3*~seZ{ut1Fcf z&9fBKOm5%%#=J#_e(}fZ4KCKJosrh!EmwxB>r2E|JR+i^9pZ8na@|k*k4xn;3QyTk z1`nD&lOTf~yVF=xOs|!{YQMRBga6Noh2zR*>l6Y<8 zPw?)^c!}0i$eZdHh?%@LOiibc7(_jO@{k;SWtV_i02CCIHf8WQZ%=(Q%Kd_XPTXB2 zX%rkBT%uhUmy5%%=niTIiVH#d`XTQPvXe}D&FLRLuvtx&{rK?;__YMWAHfTDCQEC! zoHBEJTe%;hlJZ?vP3mGb{XQG2t4;n5NnIG*yzfl$z%@($khoy${lG)^`%l*U7MEIx z*Bs(eo;<`}Ts!Ah6KDNE;+lqvDv0d-*N9PP1i`J{Or<%$=lNQw=3oZz=FSeiha)SD zXz2+^podHoSMJW%Fac+hpI@ig4w)B=;#8S)JnH=WY5<*4At-CyK2uJ*gRAN(xzO+Q8m}LY|+&{lMo4qzuJ^4Tyq=-5mCJossYM8thgnWD^ruY0qG@c>~7=Z z5s7#+qVp5_CwO@L&fEAs*1@VAz-wB`fcN5wN#+`CWA<$1nKA(a{%OQFgYeiXFk zrgER6VFN5RkvdHx`@>IIyW0e>9Tg^T(k+2xyzOlD9#FM938p1rWd|_`KyezV=&~5g zi(D3TcYF)SV8X+srAeIyn-78$54rJQ1F-)rr&oF@SU*L5;=u~ltk>ay;H}}l+xL8# zl+he9lw}(3F2PQImtFM&#m}#7ZN&8@fgFSxa3FSqm#!9u zhtqZ{C5Ga6L_l8`rWC&KM|nucjtI!Cl*I7q;y6mcG=sW?hW+{-P~&AN=5j7Cc!!OP zTMdfLQ1BRsKb_O+Xx7-sl7LF0gw)h}AmJd}EC8%QBW03h+>^=yD$=NCAkS|%Z#iT^ z*+5m6eFL1mNYw8$j#{HWG%1sLVfheinLVBZF1yN0SE?m{e}B$qd3&r9V(nTxgDQ*h zFkA*gJiHpWBg1_?fMB!L)`0;5A|fJ^!aiUTpv0z8mA<84yt}z6g&9$nevGbbGbSd6 z*>zvr=NH{WFhb%O(~b3i9;+6`5!<2>|KhO@l%E$YJ-RyDT5g)~ zcj{+^#2^vk=UukqH!dVsPXMPKkkjf9Qo>V+|6$M@6&N~?9crks035_(1c%W9@+C}c zw5Y;A*;*(rwEvN|{BJqK!q-A#woPzCZ~pC9A6|G3Zv}-7{~vz&KTI#h3;D8Tiy%i@ z`1m>3RU`@(xehlfLSU;tb28TX1yNRbn+SX3#SZ!DtxnT5_MdOmzeZ5~2zVNa?1!xU zL{bR<_otaJ;~q<>p#>wKK8o>U{{0!Bk&K8Cya&jH{c8v##YdQVki7l#o}pw_kuOCs zN6wG`d|#%WOiqEV;(yX~C1G$XPlvkkZrX~YY0PpUaHKn0X|pTYraF@7M)fPPHWVWq zLPhZwbx;`HW6Z}0eN_gI_(4JB`2yNB>$|8!CosJv?7u33& zMviivgK5Qsno-S{-Zro?Sb)6Q`}f6uek{S_m%*8IORJ(?WPwsoy%Rdf0< zFqpXYh4!#$#aSRVi{~;j5g^oye|2+Kl#+h?rF!ycm6Bc+^>Ii*>zWA-#ZN_lumj27 zW440V9O$WyrHvD*8-v^phwqsyZt+?5_I{0Y<;hvAhs+C4L=vP{aJ9!)<} z@u={0$re7@cp{zXL@On+DtK!*k4|EkA}Ao>&>HYH6rJDUd>0FgmP20h-RLKzjZzuV)Z37=4F(P)l7Nahq zjTQ&vxm+oRoE(_IKldWbj_-Zm{uEMzUI} z-n@IK7>qpK*5)OjN!-yTB}Jf;7eVGuytUI!+@BMh$Z`Iyi|_;ere1ZiAkNf{;>(x9 zysqemXdC@o-N-+wIXI@QylfbKpPCF>X%#3cn0+}oTs|8cvu(8QM1-tHhc-AD;bJO2 zWiE3|VpNe**B*F6kmWP;9;4hBa(H+cmoG19<03A_jMmj+!SrbES*D)X$a zYvrcfp6EeYh4)xN`#{ijAE{p4r`GdAzdq*Y&zEu8`ek#eIR{@0V5rFZOK7YxoTlm= z6TELiM&tzT4Nvl9DU(6a4+{(H)BTkxK2ouO_rBZhQHV>ZLt|ntf^|xz+DP7bg(=$a z%^NFFN)Qbt&1TvAQQ9~f7kzTv#~=}9wWP1tin^(f8+o*vR&9Zk@qsPig@C|u-DaxJ zfP2?^NzII+e>$k4{N$b5OZ7xDC?&F#eNx~FTT>vSM9dq5wxEr+=N991O&-pr;dos! zZA33~?!WsxcZ0w(hN218rFt4PtVP9CYQ`H(nf9Ynp2tC1J{~b`lD+H{6k(Nk=7ib) z9IxBpP_wWn`kCY6f<6c)3<=Cudf(vlFlnT5Bm~);4LWW(eMA~o8RkmkI2)Td?o|FL zs4w|#-d+kL9i53@w$493o|GC}3T%`U|zcXS25gm1s zXJAlrb$8bF6ZP}=-Q9i>5wry|(IX@N#l5l30R)4sCYX`06KtBKD~-CoCnuBBz0eqK zl8D|`CSO;suUstF*emdY+}TSfxo{HcSzg-_WX|l41~q$mv_J&j$wptDMGmFA^F7VM zrsp(!Jou_T%NM;sAsaj6qVS4y`Z34NU5=+`K3QW4htx z@$?#B$!3LYlY!B`#QDiwDR{uwn-YwC=L{+mnIIhCsFxG@@%sfSl>9lHa}HF&}TJV%e;X9)uSQ_3AG+8(i;)M54*+ zN{i2OTi2}jUR8)zup+M(YmR@iU)|w#`Xs(yW8?iy&HId|zx4&7i7i)^6~WcCX$BDo zYCa1;qvlTr0Rctc0OsZi?VDG-GtN8KbaxGYYZU$oaV%j!7kc79)n?_X6{&8$G$Ire zgLgGKcF#nbVIxKeiv5t{LQ2_^?H z05auMt@ZWoQ@IBgk8BxfsUwFaM9FlomGZr=;@W8YG%0a@9r&*53Z;=ZrXJ1?Vq)fGdRIR`X*qt~hm7<3+r?0x zye-L-H`^_c$fSth_yH`M;RQ^!xssHp8Zmv$61l7>;rc;KsLPJ3tS93rfz##v4P=?L zg7tNPIY;w6`J=@2+h04Sv~hInqAo!SN2S8mz5`!3D!0?s#UXz~*PyzRsDpVio zPO$ypg6hW2ERm4u204)`?v8sC>?=uBi*UC$)lLU_`xrDF?(&|s0<#@DI@=bk1Dx&E z9j#oO`SK#Q3q!dI*6pqo_M)a}`D~RU54-49?>e9myO?HOpZOcCrg!uNKEpt6k0$jH zv7fIv0+W~p4}!BV>1=0RRx=sekE%9iXbm^|s{yu9P*8`Um*n5syr6%f=c5O-K`i__ zrtsrP+bpM2YmRg7Q3nExovR$nb;MQ$k2E)$I7GKfryi6=#0WoGFhl& z8I>02`!BZ=8TS@G3UdXs(a^kOqt0Tm{M0clRVM#=nhSe03pjQi>x+)^>+%9G@9J=q^=E4^s3^W%wClr<|J$(ict5qT5uO+G zF0ONLQX!0}{r%!mR(5OMpKi|4 ziSVz%Ga{`=tM!yGsqP?YKpjXB&5 zsBrejuyx}$_btoGV`sbMAKEzXYLW5uV=WKQLivpe!OU>hNC_oHXC*?s0o@ND zVW6SDBauVz5mD(c3)~1!@(# z`xLw~LqdyFrj7p>cQv5lK$|-mk+@JUCEeImt9?bzk*;1VJH*YH zOaYgvvK_~F?~y!qO0*o8#P2hB5x*U$bCYQJXU0xV>AT>bKkM%`IY#vu-YB~Ig!n567WJ~RxC)?F4UP46SIB*1SQTru{iD?(fd+aBGPId0Mcpr90H z{zGinR(C?LkNa+3C!GUgmzMj9654h72Wp`H#2cdJMydpTk%Z|-e~F@n_(Yy8wf9p3 z-SEfs6|E%c?I%N=mg98SORZ0&q$pQbDbKiNU}AGAaJ~o^D0U2HdI$7UsfS{e4h^=+ z=kFPxgWbXQMnaGaG@bkF5^qxL|2sES@OSy~hX9stG!EdBkkr~P+Wp=estG@hK!oL8 z{sch?v0}DJ0Sev^&Uizk!1V*IbnX+kSFfI{a?HY~th+qh<2ws2)^|z4p-1RX9=ZPR zucZSwb}&XIqmdG@w4)W2Fwlv2-F#(|cDycqf9oi?&-Ne_jOo8+!h$lrD|a+i!I(qj z^J`%zMb(8m#~6WF)Kal`3DZmHgTgm7WYmQMp-C^c7CuQh)5QqT)CpRudeSZW`p%7h zo-a+MZJB2MC9HHxjn9RaY5y1IGL!r&-KW?9=`*}P-!s}6Xt+OG$J>a(ZEQ1rtgtz#A|mQduZFJsZN+DgAo$5zsL3iyq*N>4nX*yISn;QMzgZcRr^Kni zuV^PvcCMT!eK_BVAi9bt&p1a%JIh(9-^(URhD^3ut_RK%XTlE2?-ADmpAhc35go|p zdrX(#fSkRM@o`L6Mld@TPcH_)VOTR9YbtV zFSipV7(GNNypOFTfy|P!=Dkr?CSMG!66gJTU(%4A{1HQNHyQA=+L%39Clv-Hi;oi6W3J2Q^v=A&%U=$PtczN=0Kr?{wNzXm(Q5Mkz>FTTBCVRH{> zlO%1eOpo~e}G zGK2BJnuNW31_C3CABCMyTM}R$vxQ+ii2h5El%S|V^y@?<5bl)YAA{fzf>ZkNt^baM zpeF(qf&Nk6FKK2wLcUcS1n8uXW_IMz2F&Wh%wl>0{$oo7u75ZbW&8uz%8PklYWPv; z(=W8kzuY44Z+H<~8B|yU((`|6cUSnoMkW{UVZUemCmQzu6IZKz%t4fi{xHSbz<>ho zC^A6-!yoT{{rUxRYGSWm&3PU)frd-|qVg?frQh+8JCii ziwX-P1l{Kk6@HnSKA>B#BOH&@aw1}!(1JIr(dGJdt33n_tLfnxs6q-QK2>pto%Qej zuvzXK1S6hUb=~okF29ETe^TLq>Mf;GU4A{iMbM-_l*So7t_xBMpObXMqN32z(Mg&0 zg)}t@Plz};oQ^9Vdh>pMc>|*8^jg&~aDK&bCiA-5L=v)t7GhBJ-3a`Z9y6%g$30=N z-zmvy=TU#t$8PNCgjg?VUOqmrgN3G?3mS)5+Jb@pe$+>gKvTE2%iwcd2F(w#u}7O( zzUSNH;q1wvy&eD%Ix&~s`R;VH_YLS-OT9uPBI3E4e&{a;wSZ(j6ciL7Foe`742n?W z;^HLr7lSl1oHRtoSiayUS-Am3D z`a;l%Kp*FiUL1N=uaf~z3^IXY>&JL_7a)W5?HF`i=j7z5PnUhmj?dz!p)mpNW5o~4 z^nrcK&gFBPc`hJ z+~EF+&ntBp*;6g=FSbC&US9Ls|>|eRVP6IpIBHta4l6CoDdvLWgZU>uU$F9xD^80EgOpDl9P)YO(nEPEzo$z_7>@e~ zKQ>7rAt4hJ8s6Qxx)YEO0u_^z4#A%t(quq&^dh$3imoYI~;jljM2hgwJ&AUy+~ zocq#Rh_$q+786<%<4rQdX^W?03m!{U)?jBC>;&w;20vT?VkZh=V8rp&xy7l!Z;BDk z^3AvQ`|sJ9hbFWI^sScQW>*y38>D|jzE6d4%BK_3P{o~Ri}0xCcY7Ik!8Lbq|1%{6 z19gmk&kGEz8^Z%If`9+3A#KU|3mr60(-|g|SZf%p>OV7-P(k|g3$F}X0sG&!;$cJ2 z|83yIQuN9G!yxdsU$I(D)*LGB@Is_V-C?jo|0UIv=7h7da1em0c%a}qSMo_~Y4F9U zE20pEmzNi)Jim(cK?#sbw+leJG&@w-{j2vn8K76C+Bf*VyO) zRD^+nX=`r>wbf4GMv4v4NenPg+YTKhB-uzA|33bkwJC^UJ`QTe9H^*75XDUH|c9`zT&Unt=&9Ep2xU3gvnx3_b(#wU#=vm>5gQD zJC!Y@l<+=(=)4S@Y?>q5w}af@*k+3aS7w5uVgbnQ3CPj|>*9H{SCbNdu^#+T>V7&Z z4f?-9?>Q_2s-(2^D%!?ihSn!>G(o`@aR0)?MHk%M#VIb&Sk3e>9zD`ur;$x9)~pIk zC>So*sL7(A%G7?V~#g%Gg0#>qB~aKYz$4^U@^BQ#3R*YJwlV zxiD#*wu8O7S3ww@1au{^s=u2CYP7r|#MK z;)r+eKE80c)!=Zlh-G7rP^{k9xCA8!z-R-ML=DZER@^|5Yfl6kf=pW2Jjd(3^Vuhq zvZ@B05jabW3~+x(RCM%WjqM_^4WSrhgXxV-OfsPTL#0R+5!gV_bF0N>Z*ULA0Fl$y zDE0H_?_VwFO2yZ13}@*aJh?pXV*)qowDwl+WbrtMCCF#;5ny9G73rWm)kE$tT0#zT zruT|EtW-^Wdfd6G;v}gp|FvdnWAUW#y}9sLRWU4{;8GC~kq{LT0hfok?$2>=42@Tr zZpsvcnx7tSh2>y8U45VHB0u!#wTHa6K^xpcv*YF&jruvBJR$?EBn zTX$9KB1oZS``djHYzR8rnH-aYfSWHIqvu^K7{OIS_A9UMZbYZiPsa^8C;Nsk_#HP;pSLV6Edf*j*O>GHB{TA=7vF0LG%zrjJGcaAtxe;5Uhx0% z_SI2UZ(F#V77#3?K~x$k=@2kb3F%FjBHbZff{KcO3P?zYG$`F63P?(KNQZRyn;VZF zJ@?!(?ig>p=RfzJ&4ypBwPt+to8J`sQd!@Z{&gp%Y=ec~K>oGW^w;zI>Bnn1eNp>5 z8JX4vXHKox>S#d^IQgpo%Yq6HJQ30adf1XJ2UtYwaji<=YtYfrEn`!1;W7?bGd{GF zg`?!LJwcMu{>r8AHqO@WuCI3Oj?MA-AoGP5UQzaV=y8EAhxqAEUB|NHPQ$RuZ^vm^ z_$-GahA-ZJ4Dt~ta>-L zk>4A%y0?JzFDI*>Ig2AE@(YvI+q1EBiy$oMC1lvr0hasL))r{^G%R98aO&Nh>&lQ| zOGrwBo|Z&t@wtZa?d6SUOLvpMxxSN$BnKgz!=AN4hhd&Q1F%zCaDby;y|M;L50GF| za^WLAH=Lf8@As+tX#M&(5D+O$ z%IT3qO`7@)`LVLbI9exS{wHUw2ErnJ{^eQA*W1i|STqaYZ@BM)#)o0F8!xb~goPt8 zF>P1MORaz*#W(EA#m3g$(vo%68yi}f;LrNx`r=?=8JiMJ>9xNK4-b!Ay-p1(QTOEt zWv{Fg9WGhJVuFs#+WI=(6>g9N;xcSD^0|kVQ{Km$o-V%NFkad#VA%{b%8DeT>r&U$qk)Hz-d-AfVM}y-JTN(# zaa;5$hPIc;6+BWfXn3GeB%0F1p+S!F0JK1y?Uc!&ADWPwEXXsV`eOru7KWJ6ES$X51!KLFw zc)>|NgajVPa_O_noI}l<<&@4`?P$HtR zenzYi!PQyHw^a`jX`b%G9>zzjMBWA;L5=p?7mP@94hetMJMhwf)H@Ic|Di|V^H<#c zkH`{&?C0)i6#ocA|24Y2iZ(vHcDxm91^bUW4b~0xw)4l|Gi&?@l0|G+V+BV{B=q;lCFBre=i-(xpJa3!cIjk_VK0&Ha&32acR)@u2L- zYoVzpc;9{d)3_TJ*YT%ee}%W{mU^KlL;CVg^LmgZ3XTboN=6rvBq3UfjvDffsJqev^Wg|iF!Uf5*%yx5k=&#S;o3?w8_UtW? zrJN6oY-P8$&rbM2F~R>CuH+r6i)8fz?J_aeV|Xme11cY1qA_{Ikl6zUF<<@Q^F%yboVWorK2TYxgVI8@OD37+@DFayH=i9&C!}g9J8qEB0^=1o=edTE+8K&z7fz^Q zXsk}gsSA3zuQjk2j9WIp+Mg2rU^_MB(&?H^v7_Wuo~YZ0`;u7LeXqvnW3B%cVj@}- z#r;o(5Fzs9JPX^Vo0_=kT;_48?p&dzXqVwk{GXf5GYk`Wm?v2vaE}2pigKnB)6-pt z@1%A69qz;B-})9ldV2jJhX?WA%U zQbROou-8-+&Ld^n^Yzx{AlrA*o`Vi6kDeJfS?FZIm7vj2+hBF_LGe^ny>rFIUze#H zrt2$ek99!H8^k|*S((9$j?Rx!rCG;nHkd%-4HQx=`Z{Dq(Ya1vIXK|6aMQE&Hf}8- z(HOWf{5tF#CS_5ytk8#njR^x@&ZC`iIZZLCadUWB?n@C53X?^|cuG~~o3ngyLF>;= z`Lww0G8sm{r(OBzQLG z&6_|W{4NP!prLaH}reftQ_+Hq5lTl@^z5&)^ z?0+Y6{w8GwY5LHz{;e@}BTEk2D2%$OfBeo+`xr3kf-HEod@@fhTfCk=52 zp4Qs7^@|HQpc81SHgMmY72^X}2GA zp?~E@z3@~Nk3tTCdN8Xa>TSpF;YF%Bk)NfuNERmT*+y5cXf}2Xw^uvE{RdD(KlZ&@lc8_slehh{(Z) zawhc8<2ed5lo9+*kFFhKX}*ekn^M5$5#j#cUg6Y4hz@-~K!9x6Wqnj?4YGKXhE&5) zN*7uvtnThEP|i>vc3mY{qyy%|Z-1H=CG z^pv|ofPb$f#}N4P;(4b|o%;TgXDG+;L@-Fsnh7it4Ruvvez_09#|5KLQJkm^hxIa< z?cKQQ_SW)PR_O{J6)1VWbW+aJ9)wi#>sPtg4(W8=PJRA6*KuEeff!Z%>(eWGOIJA% zVr0jWBx$2QU%q^?Q;oZUYfnl>CgB74y_2LQUdf%8e8hryKBrONtlU9eYeNHmyVe>E z(4JN$@cn(AK;%Z&N9xTblpf*B^Vf6z^7Qv(FxB+es9>o*g6BQupjQ(8yulr)?>SzH|2?Y<2 z7%Hf3J|x0jK7Le08aj2efsOTIl6uZ8Kyt4ittpaqSb|tCe+<3?>2`1gO00!LOEDDqe!_`b0`I0jw0ZrrCH(?E*V99_5R7KicbxC z^{C%I5O(9nT=ydMn+$lkRBOl#iTn0&3jsbk2!h7F^w*0{y2t%$V55Or)Yq7+d+OQQ z*#KyeL{vi!<&IBd1?(I+kipEz=Y5-t!-s&)x=Q=2>7eEClkQLnurJod)ZD|@y-UkN zhzRifc?%aUmQrbo)?cRuj*p|{9V#3ahrD!rN4U+Z!$1-N)G@N>c^ZWFZm_E7s^**Z zrYI&UC@4H3r0V;icdKjUPh8fBmX`LCcIno1YdlJ0mD^b1-n|Rw0`wK z0eZ`7{Ha)+A3lEdXAx%^JBwTWfz9ZrXK*mfq61lQdt$HSoEGdAXo9Z3c_6it@4dQ3 z4HYRo)Aw+bfN1$VdW4CM4N{T82^6b}yG6EBUCHv*kosGX)d1vu?|{d&t0PUN1uPX* zU!aLhui32W*+E5_(8GpQ$wNf*1-!!d5}xPl?|Ftv=}E9LJr&evl2q(f-DhP8F*7sk z>(Ep%4aemn&-+rJ8(v5BIU}r9PO+W4$wu~+t;$C+F)OsgfCxeDMVCb<_NA5bO)HP# zmhB}0sF4*^+Yaq6t*}W3X`#fcJE6Rl3E$m{_4;j`G2*)2 zk%xtp1SuOmN_D+(QSC!bw@kAiwk^b26Q#)6YC z8@JJRB>~3L+uI9L&y0+Wq&y}aUt_PU39ZXYNPKB(Vr65C5_Y=WQvC7bN2paQsjC-T z4wnNs^5N#h!=N{8T74NBe9B3L!WF_U8|f7lhwJXa(_&c_2ZA15a$gqmB~kas#?QtF z$m;p)Pm(nNv#)%XYdNkk*82r&jMSM4CMuVs&@(j(G685xml=e*XZ7sf0~cm!;rsUO zTe{3X*z3=;fS>`+nLbqNw7Ryo7Jn-sTl}UIjRnB_xdnhW`m;JaI?BDPn^js~TPq#P zTd^8{_trwtaVaJ{@|0y-93M^i{OH)_iHV7V0hTa0JxJv-JQey~+5 z3ee}9JQpXY;NV~;mp5iHYgz)vFomd83CBNb09*CHAZn9#HO>VzrO{5|3#IyK_(NI$cRW^9;dL z?UIo~>6beIqFF~w;$y)#fmo09oVKWu!utNKy zczNmr>J>#}CDiY2gFO0bmS&L+z}Dq_WkfGil9NHWSlq~nQA3G(+C;w@7(6+a<=amR zG&^$&u&QMzfG!RL0|O6Frv+XQREDU8?1SL7;(=_JednZ@v9U3@;rv71NG?PF$r5Lr z0>Is=nVVC{+2f{g5dn8)&Y6as80Egh&HZC|*3gJTS#iOxB5pVSIX0_WB) zwxzq*x2^_tW@cv4q3;IEQX#1nChAe13ODFW%&L&c6C`)@=1pvDY=2TtuS1V8g@~RW zRd#mv`u?`|_W5_70G~r_0Ky3~u=nllH;@?^DMV+_YGstZ0ibfIqRp4RyiT+q&`^Dc z0c)K3_s~-cG=qkg7L|qP$hCar#@z>W)+MjTUW3#J)V71zy>4J~5mwTj43v3-M)K0m zDwhj{Y*(xl)wygZr5~8GTJ=3dq<;DW-(map#uGfB+z=OEE#gGnHMtJKc~H+wChifGqJH5 z3__{rWq3F_De3go6dwrdmX->4m4iQmA_}0=pK5D8R=zN#e@IU^gS`E7jWx`av*p;3Mi0fcQZz zX!mqS_APG)7$4B=Y54NxuJ2%p!_=Uoxb0!7w~2gbro()AcU`Mvn>x7$Qb_foBi#DA z-*261%-X>L1tTN3N-rZa@T!(&ID8YGUjpE_sL*+{?@^s7(lgcc_Skb5l zfId_m(`7*Wah518Bq#{h;C(UmtjEf@gmTh>^IH~0L2I1OxKyphKAx;syVLOjMoP#M zbl;OL{D`URzjo%jJ)8T?1kiJa!2ttt1>TGay9^-ZCuPHu)$){jfaFDJ++en94VpM7db z>ACuAi}py|8Aobrrtk2RBFTv;DBiw(n`U-5EZ5_&vsszhym-K?mpYWG?eMAmN1mZm1;U}B)px54aY{z#9rY{%FKjB zBeXRK1_nZ)B_+@fPq@22SKG(5u9kgY0{UWQWMoWCn1@q64i8{D2O}$M;u<5A3VHlt zE@nfvy!DpSWdWg6nKDMOc2CIh|xG(~mc=#o3wW(eE3 zOG~!V7Tg(^y`4Q4Tngp`y+W;Zd4Cxru!$q&QCJGw10|*gV%aMaR~z{`D1O=9XNqD( zL_`ch;&)!lxGz6=5^=&x&ga)=x*dU@`W6v`-JIE9UT7WAA}si!(K6PdJMr%3_uYP1 zVfRaVxp+5oEO~vu=ZpjZUoi#FwVKv!aVTp9sim z2QDj?O+~ptOS|F&76iXntCJD$k2~`sGu*RZumU6?462n7dUdj-NKl7p>Wk=Eh#avA$P+9wXrD?X6CA}3wbR1f6cWRp1T;)lFXH>R zAy@*^o0peY6lkvjH6(ijboLV7y@SYMXM3A~l!JzyJz!JkKfF$Nx>`G=8|ThN!>NJF z-Xk6pW)>D8C$vIz2dWr{u*);G%fhqTgvk2t|Lw$L#fLn=e?XYKu&`i(XT}fxwOokW%a!KHZz~LSB4aYEbS@F6EmD3U!wqy6CV90q6SbU64P+|@) zDBz2%1RLter(6Vjk1ScGr%#=_S`zm`-w!4etwC_Bx)0*?_s5ADeBAMG4WE`N)0fHi7apgo z-|oD+c%SiE>}S1TFdYoip_SmKeq^ApkU`UoLA0&PcAA1aP@Iilkbh>G=5*fc%vVYR zy82E@Ny)7^U0tW>w2v2ooEKsvDL4u_BCwMNvUDmUA}I5F%3K_V{E$$#?u);5V%7tA zM5iv^e1Fp)`_XC1)UWbJD&Q271ofW>dFXVW)9y@pmzW4tpVg&r)evn`2sm{CtKqTCfsEnkF6pD2&%oi?mO3KzFs|}*mLDIJ@kDZygaO?X z;Jg*+6VoWWxFW7Czfem|Ku9;CR5YL8ubi&h3PTZ674coXlr0^RIEkf!TKHq%zE!F0 zLu?b&z`Uc)@ash18vAw=@28EpwfViwWixvRw*FSm9i`YytfHcaz~F_2Z73 zibo+us<}n1I!GBG0&z}KN{Y!Aww&Tdt1VEUb8~Y+>~w{=ERc-Pg3{xzCV-;=UOIV{ zv*HpGPLhpx)~gJ*9?UR4XEVv~PINktEi0B+C->1|*llxJyzC(|(skY6$VC9?8u7FN z{)yY_m1)6;=;fdl30pYj062p{eXUrop)d;`YDOjrLNX(WG=aPq1mn_H&R8*S6IbvZ zL!{pM@e~F1eBXW~UJB1EqnR}zg)=it4+&AZaRYM#C%@>i2`3j<4x9i;?WqLq>YAZM z&nW}O;5^iU46iZEKRz^6d~i8vX?u6qbn>pVS(eo5wc}Bqld(*kCVjaxK%wo48>&o| zDR;h=TNVMf#*a$q&1oS?Lzp^cTQ+A2G^7#$Z-CCbVKPy>Cg%oA|Krxd?8%Uv{xfp& zICOXA<`$c8bu2_fybLnHo4{1b)Qs)8H8{(kRkqQGf~zbt=B8gSV_75eYI#nCAP{*~ zNTv~Z=|PKnSO^Z$Zeh)?hy?aB%$GrzxSEknx{wC+)Q&xDuR9(10Q)GBvu>)^Z<0X8 zEfW8mYkuIJb|9}!@ylc1cjJF)SBOSCkxa&L`znNVy8!(GFYf*O_YBdlE0D1o%)@D8 zFI~DO26T4kXCD2ZfT9U=NO}vc^=45SfvLN5^iV#tMFnS@#dx9X^(TU>8x%s<)&-d9 zt7v|NGIL|EemqCKK?DuXEQGhp%F5c>Lt$Ko;BruIzw4k`XmJ37dmk40$8Pwn64KHj zC%O#zQFFAYsME@LLPEma?vCG3e)wARoldxrBx83ln zzP>)-O7C>kU_=aZ%g{*C2Lj++i^1?rmhnJ(U~*V(JZ4TuhAEJK3o(Q-YZ!w z*Yl;OriP}0dk<0_ot?E8)r+p%K;jP~%5uHUPYaN(LVQj3%hq8lD=QinMdI7~g_^&d zSE}|hMHAs~Ddg&j_^$8iy>(f1005wx17s@7r>BjE9x6B~vokR*g9_z?rZP0o4sPl` z1meZ&#>V8ZXaiCROY;v{jOEfLn8|nHCt5i54uuv50-FpfQfV42=D>4=RE&`k2zbhS zI-T}Ha@T4UWS^YYyoy>g*7{*`q>+5*)x6{)KE%uLjq7i>C3f1R5E8fsloOcwE$9l8 z@(KzcXOmGa4=2>8#5V|B*JDP=7@J9T`lE|?PO!CtIDD$8U~0>%d4w9 z{|1I7{Rdi)M5onmV0@gFu-xF zHbCWp9IMGfQ{LYmtJ_C;Eib$Su*w!67l4 z9RqJoaqpcr!8kIht&TKrypF<`KN7nHPax47P=*rxL`D45nPQHN8qq&KrGd-_p+o^G z)_eBqd6{nFbzC%rSQ9Gd%|Rh+BUX_0RDOqC3Be!n^N$3X8d55Vy`Sg{&Hc+}n&Lgx zK=dOYN|$D`ENgfOB^N|M9)+o*;HS=x4?Pkh#&CU zQJAeMG^Xid$H8#p@n2vpB+C*y&bTy8C0q;l-0z}t?}$dlEGtZjbK0@Wy?zo_mwqOo z#}M?d3hqu#R-NJUc8=64&?;-bdUW4#uZU!S-|fdZ2Cl`-2UU>CvaZd#-rL50aH1BK zDIPs!j7d+syKgvcrU{pkd^|P&+~9+Iy(+UZgpY|%A}YV3vc>az#ue#HyUL%hgnk=( zcA1M|+(YFRyqOO4pSPLPS^*2tc(eQ_vOJB?Qc!WS6z4NLULa*`;JR+l1UreD_75%;EkDvpTo#>6U&fA%% zLF9k0q2(w3iM0MJrixlHKwu_*{q7&``zILjKRWe4;fYES)W&V7NqGC#)MDTbmDNQ+ z;Ja@qK%9WONz{c@dFi!+(berM{QyqZJRc8mMyyhZxH`h{6eT586~OVe-ALs_m|125Q7i>Cw`prrnN9;1Z`%Js;6r>Ic*0qDXQn2k)1rralh{6=;*z!%o`@XkZ?>>s%9*T+9$-BXwFQSVi? z4gyt_lK+`t=gozt_IQY?3=9o*3aw&eVsxSP4s3+}d`B!)pTOzHl|uMu3?_O3nn`42 z2sOSBl?lxO%Gw3b1J*Sfn)85v2I7l%=OuH~eyet6I!r?m5`-DO3Eh6=f=iKKTVQ?x zU~TMx-1E#*Me0zU0hv8OeNic^CUm_dXkro5{)O$(J_aC1aX$0~kn&{*=X-N*1=Di= ztW{CTLWj1&e@r1PXaGrH7l9RO7*G}!g?wyDz~v6(;y%J zXU|Zh6#VA0=EtKC_Y9#Jo^LT&PqFTwSzHXjGc?+ryW*_WYb2M4Gk^yh!|!W|*O7xk znXx;0dTssvCF$ueI;EtfoL=WbN)Azhrzc_~S`h`SX4c285i^n8r??E>zuw|_Ui&Gv zNM<|w^h^h%*~(qpj)&PjFdsp!H`&3ifTG3z_d*u5^#t1lYjsjvvB0kT1r>GrOOzR+ zfi&VDfaE) zO48nDYG?c`S|vL_{`rUrf0=H0I-4Kf3s~ddwuuvO04oBvHsIkBckX1E;PLq-!RCFhhI&hiy|e=QT8E-6RQzt-yeShcGT6}In+K)0*RPq? zp%3P^tZbGEo+>028lRyzZ)XSmHzy1^?)9@ybG^ku#Rp^i6a)_rjo_3N+Zn^0J^+1! zGMmD79CIL>VeD zf7qWMzb|0Y1s2(gtN>qCZCwMzN%7h{iwvIBHF-9BoPm1SFwd$_L9w&z+le>(N!9UT z55E|8o2z7{t$ojFi2{@#&=^RN_8N2!;{deW`n0BB*~MJk&WrK z$hG=#bc4F>pP7=Jw00xAFvnOsGUJ>&by)UJCIiW~eNs(}@EL#ieDy&JljA4Qp=?8l za^oks2peyb1v*jKTTlyIf6!?=T%de?)}B4Pvd55 zRp4U!P)--@8tQJ~Ujxd+q6&2X6(4JjL+x^Mby$oLpGC2W}aVQ%nr32U!O8UDHg=NDtoGb4Ni2*d+CI!-WAKtaI6 z!*kx5Nn+P7t?N7SA2mFk3X#wqcGdSWz&(K^4Hp*|SQV!W{;dKyZx;jeW!etFq5y!D z(U{1+%3OA!6b4q@(Xp_kM2PiGaIhcs6+v!pZqU_b&aEpk)_$k$!Xra5%e(gu4G|*~ zOG^)P#~tZXrJ))6Un_Bo(LX9}YOOyiZ5J$LrKCUxZR%UK4~+BW1F99LUd{Ur$X~O^ zsDXU&%pP-BmWwFw-GBr0)WQE8c%BdE?!dI?1c__=X&gLny z)ooOwifs0RFINgvo6Kj{lO)B(A8Yfu3s?w-q;zXnw-X=dhe~Z>}a8QuhU~!&Kg?suw1Q_3H6A9~^cu;#JwHe3@V_8_zl9J@2?!t@j zoZyn3{N{B3dQH1DS1Ggm_wVcKjyyeeaZAGp;2kmwin)o2v!_mho{`^O(CIA7&0Pb1Z`_m{XAfjGP)n6nW6Xm4*YU~S zmJl5HS&f;UFoE~*=!ghlLMIm?_G>M%Ia5$MXZOjYz%wOS4B|LX^+eQX7|AqpD8q5- zXV{6dMu_eEg@ZGF5LY95|8N6^y!5Q0=*9MxcVv#J0=Xk=7*^*|rlY$i!8BmuG;!(u zF*w)>fB98EQ@yslTMoGR+S%5>S? zjv^uWQPA2OoimwKR)N2)pXO&TCYp{bV7?GBgvFscp{on8@flV-SSZopbF`z+Wdw>` zt7jiET*e4&$?VV6o}#&p7E36GvXT#~KJR_BymjDa9eAU@MPzeE*=2hencykM@W(SV z>aC2g5FD26e>fiSsD3=l)IhgIz3DJh{W8`kZ_gj)IHRf=oRMp&LKabAcl3tsVvziH zS(z_|gTu80htAhre?8JKM}Jo!8sB&4(X8M%k-P zAT#*$Gu4qWVf-6MYY%l!q7Wi#M}uZ`{X1v`RaZ_^QxcGrZ|X*Nxuv z@mrXG&&l^S9|_|)y691fl=Ou}zt9IV$zU6D???iBTSs}S0$!PT-i?`;7x+1wD!DX> zpZ*L7;dDGmJVCz*l`5mLsV?RLC>@J$!;o& zZ?Sx9>s@)dcBCLrf6*##m$v3!w_(%_DS00UZNhoLux$Gah8L*FX3i0fbKUziPe)g= z0i)?;F>q?Iv7L9fd2UM-O?0G)=4`aJP1X9%QJ!jjWG_Xr68XNKZ&-LJT`hj5-9-VW zVv^9yE_B5`))DjE919p$mg9J`J{~kxIaey)c}ESXKQ6=0rtbq}%epe&W@>EKZVp%Q z(bHGamjCNqLN6w74URQs?!U)v4(CalP@n{%FTIDpQD>OG+F9_^osSwu*m3FjwhtO*Dkf zjfTI+VR`gn`trHM+mezd)=MKxIfl0mmjeo5tRq!@bE>UeUJvhzcw6HB z185pRbB`WKp>}^RS+r;_o}r3tOKB02Vq$jofBo6#oQ3&#VYpsefk$V4xL(7FSb;hg z6_MLBOmwd4EiccT>$qf;j6BUPaNk!4754Ugh8Pk=es^-OMJcH(VM+dv6D-A!mGJ0A zCq91d)>en!dfn~AbMB6>I~^8WFEH2Z*lG+-?Jh=ld=HF1G=q1k9N8Q-LaMfM$}+_JvYSoz zV_2x;DmLFHg~mftRyKF`?3LPCrC9MMbDmwZ-WA7t_k2AOmIabgQ49IIN(+y&{YZ4A z<#-kHKjrHS3%d_`zx^P5z0;3jmu^blBcvkF zoR#>zL1!8chk*S~t44>AAWIOJzW$Yyzk0`oqn6GC90iqL#?~( zrZ8Rh5Z2}vldh`j#fkj%X)2Z9U+aD5XxFv?VyNv=55+m$Xlg}iDG53dM)Q9#y;>FO zjpNhqzC~^3!Gn#jP)W}DWeH6c695Ijs?c-=yxY&3+hq^gXvg~~uBF`DJ)zmPJzwBb zU^YWSI(>(U%A?u1HyejB8tNQRpB8S63Y53tlSFyUB$j-vrcgZKHhr^0RTV^1^BD`q z?#|mxxEL5$_w>-{=wuD=vvG5A1+Q<{ioV|4r(kSR<9a6lASdG~$-4i+_7p~6e%Y7W zB<-bgO<8U@T0(4QCAUF?`cb+^*59H?#+&gjqs`b;g<+y(d6Y!w2zX(4z>hOM*2&r@CRW+0)Flc zF}NqFA>uR9JjcaHC5oPXfU|yngvF%mN9uZ>1IF3^Sdj!5R=nr9zJdx`SG$P5(pKZ> zp8A8G^WQVYU*PwzwD?yj0Aa(|5&VZ}mFNFp1pPnFU?XM|JVV?CphRikO-ydle{(8C z3QK&p6)pMx6XVg!d#}l+D!snUon(7qO9GLrcP&!Sq8E+t<29y{uzESMSR4C6`}Jvr z(noGir>gM>$4qOA;7eY53w>yO7phH|Mh?gn$E);GI32b< zONx*TcV3G>$ZS$rPEygN4$-vVoSIU+!ordUtV#lMZqN`32Ynv^I=2Z?#1?95pd2;x*_}=B?7Y@y0Va5!&7bgZx6OAya+>6gd7%7S)7P#p-Hd;h#@#S@*|<@OhQ7U zA}?Rn2Wj;INKVMp2?#hr%3CTr5d;L7bQz(&gWbh#=I*va-jYjaJ)A!aSmUn1?l6bl zL6i2mh|H^2L2n@f&2SOxJjjOx`1`xhB!-}fL(IwoHsf`m4d?Cctp-S`Y}e2a4rMB( zi0c-NB{lGa^4)s+_z^!V^SkT=Np7{l3C%F{HnARFJW1rPP{K4-2kLq@9o(F%Yv{=0 z(MR~G>oU|94J!06>pdCa><{fWv2ONU6>cHc=>!UrBmtDB-9a=0z~!L>&^tnPpg@2l zy#;8TYJ5S#CW_*tC2nzqojXyX+wJ>p2POKZ35Eo?K%^C>d|L zh$M@EMu)P>DawZJR9j}RExkmo5)CL~e}x*sJhOhv{D^Jc!Mgp?BKJnphl{fheSc$O zsVbG&H+8W`ZuQ~gO?KA7Y`5JCm$hjST=X8*y1ODMw>~;x(Yia>%i1~gRhRSn(y^L> zx(SLIy{OR$G?D~;S0upwfD~veD6GsE4A<1wvhc-jfM_7-yag9PU4x#312n5d_drSn zs?a4sN`kRY`I0|g-?7nvdVi{D;MJDLtt{_AP&d7Lup1Z`XR)!8ddnjnh~=ijCsQt) zb~S+f+SV3#;e3ARowp(pq8@nbv7apl1;@uP0q2^I#dK23A#Z)v)UN%`LvNhnw;=_} z56CU}?)lkHzVP)YOga-2eYn%@sP9pRbk#r}EzYO*`!j81LG|25a?u8#(z5(Z?Tjh# zd68e+T7YmvCoKGFa8T?0`MEF5yPND1cjnc$tFZh)=}Fjy*JW|2(V)qT>H6p`Q4e>$ z_IC%Ohv`u~xvStkhx$w0&CD7CM5Ai@v2w24(vugRtP*k3Qd^@|RoV}r-oHRgd)xLb zI~XZie^_;{D9hvL=C@i0UasE{4wuHfdi0Vt*(d!rx0h?vgMvPdjCkJkb2T<$*Et~8 zp(C|D=*Pud8I!G6j1}C+YmV4%8<|WEOtI?nESX8tcRhOrdk{z;sIzp0d#hO39PDia z+dWdmExbT8!!_wxq8l{D9zS+$x-+dCN(*0r?qE|s8}XdxAbD@Q#hbA#zFxz!Z0UPW zz|sbLd1z<0eomh0R9kvOvpe5~3qd#+kc^%2+Y)KouFHoIBR~W*?+Qkzc-f+~t@uGl zIL~1mVQs+S=Brx^WZcu6`G#?LYoC4F8S9MFK7J%v3!Jsv%r23%%;#rdyQ=MFoPD<% z2kcl}^ykky?HCq|Lk@Q$cXAC%i?nvPJcaxz)%0Dj&n``b9LC)m0^%2l*ZM$BIUlpyJfKiJV-)hG*XC}E{+d6>hErNtZGGyls!3E8SyPmMlZ9SvbU2fzs+}k zBf-ltc*yM41-7cknC-LzMZjD?w<=z*e(zp*PVs!CWA|zL5=eE;%9f-S=ci5 zown_}hRSvq?Z0m+b%q^`>J%<5<_n!_AuJ1HEI+v{5=@bO!BO|yzVW=nus$u_AgAjV zhL;u+oM{m1MT{+fZ+u3>W^jzUDzwD-!@OR}d3JCZ3Cp?WBmn}4^I!FDXKCZsXMhaa zxf;F#Rs&M24SoVgwz9&zePTkdR^$r_4#Cd;Yr1x|D;!@J2a48R&q}SU zMl!p~n6ULJXKHT0agfVA&5e!89qSFboucm`GTbHe<$1QMJk0h4V?_^H*?{^0{E=vq zkytXz+`1L&F^b8_OiF$ZCVu|PjMIx>Kj_URN*T)0F&GN$UwJ2t$08y^zoJ@oGdr>&?+Hc0uzCPkqU} zZgEUHb6S?3Xrdt>x?8Ovy0_GMhT)*L|Fd4RhfrdoMlyrcg&BssPE^^=m2xSuwC9->HQhqwYGjSuq|jdIK8}>NeUmB>? zz{BH}Yv|4CJ-cymDt#beD9-$Ien56d+LY7w%6bx`po2wiv_NvQFxrHu*SfOtLJ_(( z?#A?;Gt5LO} z&67Wa7&makvNiu+|1C9e zEC-{$YJ2C9z9dPlSE2Ta8Dxpms*zYUh4+cBC!X(4a=P}ujBd*42oQFiAv4kxPHC#URvX`((aU+j55dFHBS<4IvJ z&Te0)F}G>itIj85Dzc0$n#0#^YW*|RN?vhJO}x=i|4P#?JEV}<6b!aU+ehFsmRa`# z@eWTKISjTF*t0DKTPUU$6QWWU8akPJ;<3ENkDVBQ$(Oi{jLaz~DG5ghHI}k5se;{H zl<1}`P^f7n|-)_gZJzVXMC>NYk>^moX4&1XfebWb13<>O)KH8%t?$+r7NxieGv zS!Q1PYpcd2;*FmEB+Y;44Xevs>#g0se2olLLV!CqV3G3W2FLZKI{wK{wwu_(LP8}_ zytot2Z9G)Eozo(s0o_KLCBPT}{{PPU4151pW25xY0g(PgK}!$fM<{@y8c!S8D>UWg zVtN(?%dRB5f+iSL#Vpj%?Isn}j|dFBY*m4hnu0?r(2vOOrfjvd+#Eff-e}f7zO{Uq zZ+s?x+xmnu3o7}@=P%GO;Xeh-+UDnU=lLtN#b5kPh#r~ZokyQBY%$k=2l+(VXF}_;Eh{YECA0v@b&AhClR_Qn4!N6M*L;Gy%WWts=q|3 z1Ws_LhQcygBTd}x+D%pFgSF?c3Ncx@I=QV&Hojnq)SuWXut9~pik~6eU45qeWaO1; zqp51D;0UPG!X!c0Cjz>`;ku0^!O(w9a_-!@2d2o4%AQH52;H;s4up~r zF6274FtyJ<5U7mmDTWNwL&>j!~>sflsV+AGl+{ zvfqL3#_fkV)N&ccCT1rjy@X}oOS%$D0>NDQT>?*n%QbXVj-}99h?!RPk1RpE6U}2f z)(3h8>PgB}`Cn53*P>WnWt^%z(t2Qb`OEAfrHH1RR;Lf*yJ+NXbTg8xvu6 z)qEdnh-}m1HcvJVU77G=s#Wk7Wno802Q)IKX_$&_KEgcuyOP$p#7e8izzZOzrXHo= z`-B-}LIg==s#8Rc!YY5(HuVc4xLACR=JR{5m7uKA1Tumt+O&py!-Wj8QDy^$AByvs zU34*>qK@8qBk;$8)Z?@~D!%@l{Jrh9@T2s}QPYd3(>45t_+Y8^m~j7w3CYyJMS?e6 zhUKoaDG!6jcp;i~KbVolNO_zE^PN0C)!ypLS`-%rA=R;Yef?qS2>wf#R}A`6VFnTC zO)3`2mSremflD!=o=Wc!<~J?JxdAQoK5K(%%!R6`` z`0ScJ*F<;MicG-}^$$uS!GI=DS~p8JdFM>Ja45hj^C!1uf>Wjgy|j@IL)&nSlT|d! z{u;TNsh*em{{2gLX3;iCPQ!Q`8yZ-cnRj;PvLL11Ym;JMCU7dI@A1xl8}m3v3l3JM zvODh`7%;fvF+dnAa{i*~-hA`{JxnChm|mH$p;J{uo_p64)fB}!mbI5=H$c=g3gq3> zu;`Gn3j&pjO;B*4AuVdY!1TU;Q|Vl0zPr1hMKP1r(ufQAlvMk=jg(8G`)lI2Z=clJ z8$0K*e~q{PDvU+n@<}dRZFbzi5{1S*#)=UinYS`gZpK+vZSP}Sifre$@3|ioLnffM zUxnlHf!#xoj&;7s=iEZ|tljH+S-W^aQDl{Js!dS{Vh>2%-wjE4w{iUVT0DZ9gXWc&$&XA%N~&OKFiN!ImBL=MM>%m%z20*1(D#$+ zaZRXU%KiBnuCC-?i`!Ktne7Cr7l@)VE5Q>OL$IUX{;nGT{>3x3TbA&JZj2* zMl)wp=ka3-u%N-iANq?Q5b?B`uYf@oS*g3?jlDl)?~_l*mN~IG%$`smd%Yor!CYz` zTJE22)CgXJgz7Nda;G;=oOJlE{YHu1iXE=qc{}>O@=WIXGcji<1XivV$N7>Jpn_15 zJ+yrTcuUne6qHP*@6#-h1*=( zQPbSx+4pkZEH|C)(5bloq89r>jGCN6_I8L)IXTa4EVQM`jk#?;cq`<9K0Lp>DC@lP zg{WWe!*gBxW6G_QL{jyZ9}ZhQ3{nW?@A{8?7-8+n1MiPyz$#UeyHRn1h?$!R1{X7dhy}7o;D~n$a`6MUS zW_Ye%bdWsScj`ufd=ruf9FA+XTC`wJPjEr9^%qX*Mn8P(bP-J*&i3z4Z*ZRWxG zaa^&!aZ>U4N>tZ+qcaQiYP&2dVx8q%>GSIw(x|f(W5FhCLm??FV!(KFL7armEH*mm z`V!JBL+SHzhh@R*lvAmNiNk}awB~dCt%|45jGJBhEVSj`Kg`a3UY`|`C@Q}-ccIwf za1fw@RKe9N#|(UQgEjt7V^d=yP~LF#l9p(gCN8bd*t0<=Dqpjz0c&Ie119i{yz8KbMDDK z=X~!uRMMmu)HOAgfqVpZykNzFaRZb({tW=UnvS8y=Y530ne9u7qn2c1i4K&i@!K>| zc8q#Izw_(sGi#zfnSrYnPE=GI%a)AxFe(tOd`5AAMy>XVC*J>2LH1wMM~)B|h$fw9 z_1I-SL!8dCs}Zqei~&j*Ozp|+W@#sOkSc^)tMV@3Y20l{aA4@JRx1LVT}I{OaSV;o&F&Y)uV! z-?p5#OOl~+nae?aC#PtR86Deb39Z@Lclx8J|GqXu(QFR*=3mBh;S3^&pK{U&0#f^T zzBm*!kc&n}?UQ^sKyF&2H(!+|sdEoVM<>?_(9(f`ylald7^8(HOxi}wMM8erf-h}*-q(4MP@axQjb5BXj43=s{z`Ob z0dvS^NCUtq!(Pi&UVb??+LdmoY+f%%k)9BKLtTK1YBCF0}@}j8D>t!x5p1j8_C7X zSX+}B?4QtDX!T0ZgcunLgC`jeOxA^N-TheRJsfT;@pKPO+$?M3wrr1nBQRSSWb6r= zvW5^c#u~f`T}u0aKtn*53g&7mj@*CAd&7(gzRVG0m^>xjo}7OQxt{@S5q+8BvNBsx zJQAryli^nu>dnE15p~u2Q;_`)p-Z;nu`*YwO2B=S-`q9tIu)$y_C@;Kzr|2f2!tpJDxyWo`2I)74JYp#uj_ zO=T>On{KSo)tC_xZHkI5Px!!=t!8Uf|u z3wNf>p#*(kE$dabaPyhYOXcUQ%3PlMGdysLJEp}GEf{>{S9oi_E$^j z7V=o4@OOq~T#lU}PguRFq=aP$+umcggBnxBPF1C&L^h9NFLr)sAKwwT_Z}D*;~%fD zkzqcDh9+CgiMFF4MSuF1e8H^)?v96?jNijlwkcQbEhAyPbNvAV{IAw5W}mKXQKCWy zW!xOd4MKWl6;s`V3Qo}JHP=h-JKcf;Yb1FiFWV{^vb%2cZ{9rn)_oIETd zl}fqBTB$D4V6|QLq=pQM$a)k3q!bQnP=4i}9%nOV)hh-xHan3kS3Z-AGaC92{$f3_ z(!JE3SgbSuQ^ki8LL*ZeYOd+js2p-e6{XOF%fv zr2}zEKiMp}2^J$}Nl>`WFf^iG3wR^Pcx}$bZ$(rSAPIsMsf~36f5h3ahN^grWoK?! z(t(4AX=uC^tSlzmhL9nqK(trfJ%HZ{KkSkbYuIy|Fc6Ns>p={keqWRrvNWk zRBEFr$Gzz5Dgb{BD2RB~(vd<2b|7mXXA^l-#6MzrKP2kegtpYq!+p2ip`4&U7b40; zQewkmIJ?ykGk@$sbgN&2%Bwi5MK;@MCvM4w&j#Fq4^SMY-04efpgr2Qw#`s`v?r@+ zrIGu(w3ramZbBMuja|y0QEXiK93UF_xHi5c3|%Prh$_VLW(b7)4CWR}7ilpqO!h!; zgLBOptHLO^I9ikHZV$WXg8ZDGMf3*D4$wCH;Lf=Hs5|($Ki(Y8K{Wx;v(x{8;r`!Y z{k6{7)aJlKeMdeJELX|QePr+O`vRp@c#VG&y1=#yobFDUdu+M)`)ql2Yf`HWTy}je z!W9@H|4o}{Bns)Y6Z3EMeVi#KiL%mu2HL+Y%ZP&+0bC6@(NeY13O`#{N%}3U`dcW_ zR(2VL;HnAEtsF2*97jQR=Wi0+xvMu4?4ShgYdPu4c>VJ)cj@5~iJIuZ5p@r;JbM-I zX(|SKcL#am``+!~vOy`%i%^TGDu z?u2G>UB1uh+tvNNyKDTb-nh3&fP3g$9vuW26qjkwc9Bq9$LmXcX?~pNLA$kg9eAzq ztI*x&laN(v?^YaTZS~7na`%i0WS5b~w0F)e=X52oLkf)g;6*2|BK$U-4 aXxMyFypxF7rKfbxeC{GOZ{@0*2mBi<*HFX& literal 40847 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 SjQ}1BAt@#&nkS;~^?w0D^e7kr diff --git a/diagrams/ban.puml b/diagrams/ban.puml index 39e7d0d..9680309 100644 --- a/diagrams/ban.puml +++ b/diagrams/ban.puml @@ -9,13 +9,14 @@ participant "ET server" as et actor "Player\n203.0.113.7" as player note over admin, et : the ET server shows the player as :51234 +note over admin, control : every call carries the key the server registered with admin -> control : GET /sessions control --> admin : [{client: 203.0.113.7:27960, port: 51234}] note right of admin : port 51234 = 203.0.113.7 == Ban == admin -> control : PUT /bans/203.0.113.7\n{reason, minutes} -control -> control : bans.json (atomic write)\ncut 203.0.113.7's sessions +control -> control : bans-.json (atomic write)\ncut 203.0.113.7's sessions player -> relay : game packets relay -> relay : banned: dropped note over et : no packet: times the player out diff --git a/diagrams/pairing.png b/diagrams/pairing.png new file mode 100644 index 0000000000000000000000000000000000000000..9513e099d32ed513c6df8d3487ec894c02efab88 GIT binary patch literal 61150 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�#A9j$LeLt-2p zvyg0m@*`%{11ted_47Iq{9$8bYen%pgHP*9jyOY34jjyUX6=8qS!l{EVI@jPNI-mh zuOu%Il#W94g+(@?Tqc($_4&cUdNYp5E2jCekeiHz!6Ctnp0pP({7kVSCOn37!RHq4 zclBczX^Dur*%@CAXStEz)_HdFq#^i&lp()BYjbzq`R;=s zY7Fn>u3zgMI2c-SUj~W}b$ztXlOtIpN-8jTp6?Z_9&Y0#z%CBAT^;Siu8Z=%5jKZ6ajsnDi5H| z3G!>)>iU6`Cs^SwECNmI9IBpFTD|IRpFxWV3nJfK19pW>t^mstW`u{x4rDYp|a@7pyA`3bS@xuTJ`51V_N9rnSO#1zO|0 z)QfvHD-6g;_0XkV(z89LjleX%J8$Lg4|EoazQ>38L=9+bc$B33d;sI!;HL}+O!O&v# z9{48t7B-Ab7ChbpJ;TZ`VL+pyWV3QcR>Yo3Kp>n--)+lC58I>rUlX&)eP}0gV*qwJ zWYQw(Ws7Qw;U@J2VryuWg3>Ahi@s->)3GM}g}}E`RM*kb0enx;KbxtCitJ2BjX`$^ ztTxE`R>1YGq4npni-va@K>c$HghPjHd6s%!Vs* zFJ5~!ZH-79#XU0wsIgL1u3~E_r2BP@7(aA>0zHiUMPKGy7 zLctEO`dDMi@3A~itZzim;Wir~g*l1mB4&%(vdvf`4$CI6(2ul->hy;j)7#j(v-yM+ zj{ckBq2f@HU2R8c@Uuz2qA(4Um9<6z2hqa?zp~`o9iznoxrOdh#UgxM8eIf7& zf5X2xH!aN8&qK@eb7Sr;pY=PZ^QN*Kc}+&y4tPVayM>Q^!Y|5klO@2CIojS|)}l*Y zo-_mo;foY=rasck=e?(h^~5_bm;LXLz_3a7mwzE!a`A^(=CJP3+eKnCo zoVO^3h6p`6uSnZsjUW5H){hm3v_{ABHc?Diu;!*GJV+RoJQafv$9K4F9#1L&7RLNo zVPW{P;ivSN%OUX_)*>F9x;6~Y?q%Xc5P3Lymh-lPX*nRl22|1@*mg95MewPzUcC5W zH~ntzjm-&tChDO(dt8x%%=NM5QcLtLavX8;3+3x#1-DDzU~7k%iw!wVw|&F>FV0== zVj~d#!k(RG9Tq-M;KfL=>^T+YIzGf~AWG*ua6=Pkh!8#|9!6eb^bK+RtOweM5k4jC zKa}%8)U(C&=%2Dq4Ss7lWw>P&@C{yboFieRvxF`LE-X0j5~ka&fPXTpIA+|Yr~^6q zaW0B=hk&Y$tKhWFyD7x#_HM9=r>TQzb+yY z%xnFS=KgrPj(a@)bJHL3+RhsaDql3S_@+$4>dOdQ?mSHi7q*ZIjq)z+ol{wojj<|w zmzMRMapx`?hHv@^7DSrc=&?ZTm4uMCSXa5$H-&YD*CQ# z8mKTlx+axgfstNp4 znZON*T)8s0I!!1O)s`%unQw0O$cR19oSI|x>LTybQrymZz;KgbsWFTlD$@aXXf0kN z6}BfaTBGKcd(WTwNJq!S(Q$adLEwgyO)0`~M)rgt|Ch+vA>@zM;zf)3UR(WgH@1@} zJ>%k#xj8d?yDQ#my^xGs&PQ35(?L~ar@lKK%aa$B&F`J2Jn`>WeOG%Km?eRG-*AnF zpX5mw=XKW9hh}Euv)LQQx<1V6WT}=3^isjao(S@$Z)yVV!n%ps<15!zIu3FK5{A#M)(w&^Af9WxV|N$ zt-Um~vN=Xqm=G;=4Pc0cD61S|qUu4X$KR~SEY*VKT(4aVDc`Zov!*Vqst!otx1@bG z(}9zNOt_PO=6W8Rdf7_z{P;+%&u9LP!TxcyJGGelH>n7bBHeKArROICnCupG9@mGi zXT)U8v?Xa7LPh3^CJ|{fq5j3ZAG9go@hTZ3pQl+SI}~$MioKQ94B$COOMug>-FEJ@ z64hc66Tw?aNQu`32y__+S+NiJm6s0z?`i-t4dfSMTYpqU;^2i13%hSVAmLEGW(l%a zOb+O>Af)@QwVaO5iyUgS^KgZ9S!%bW?NA^C12v6y08%^uV_n92xBifRx(46GAQ3Z= z{mlOqdX03LJ5#TJIzw03u=)LKZ~W}}*E!+$5oM~j?@!U3c_Qr;A#n}WZkM(x0pJ9| zE%9J%+#$kJLKl{CK|Zt7`A#d*85wzOMouV5&^|*Cnll({?kF@#Uj4w0Yv_V(a(pzw z@_x0raG!Q1w`D;=)*mjShNOkgdY|KgkK^R87DZaYPsfU`H<5lm?lje&lI_+Sg^_~o z|1tnsY#ZQgRZ$UiXY|}q@y|ZhXA-FT5c>f+>f7na>F6xks{JV1FF99mgj5%!E21hK zBmzU)UR=KCss$yLml^FwD)n66i2A2>zu|d%QsgP4c99HMT(%zdASdj9q$Yw+^m-Vl zvG~_}dWw_z)?=xJ6!&YYe3zy8`J`H%Q6WLOh&7Lh2=*t+f+|Uy9+4J4)*V*|g9jfF zHLWUiCylmH4p>XM!Z{O?|LgH#ZJodj-89yc8-hR6IolUrEhUNTzSj8^73gBUJ_k_j zch!c<$|dcBeaS6(xtZ!}UB_!z&77R}YPA-I#NzeKPaAC%4Av)Bh3n0neaLQXlcv6RIY#r=&%l^<1mN z>xM@qf>D3HEfcnZ>MDOS#faAHoEcZAt=!x9_Z9pQv^jiG?Eq(XO}X;jwRThTL6xaW zY95^k!N&@BWMmAVKE2rxc7;Q8T{DPtwR5&IDpTv)2R+ma53Gahc3C19)8?R_6&ZTk zZQ*C<<9oPEVTPM`f-KL{xlXLisSTrxc=QJg?uMKb7pIKk^9Qvv^7PYzYPL7y0wx7z zO!>+2ehACOy&IhFL+#ucaUSC%JLdJCaZ^FttA$cLxQXx4ofLY}Ja-n=Qv(R|HX17v z7pphelA1)&3ob6V82#mTUjq@iiuG<^VhVki&(7ccly}oZ!5Ks(^09v4ly=q{5k6nL zZ&RdWZ5nPxz9BIzFJFmz{L= zW~?QC+x5XC#{)B(#AUA~_W4UP{bii&K^DlG2)&Rb2YN3Nau=4xOYoOt7tRp#Y`(S` zxP2C%=aB>1_#T%8xgktuSRU+d4PlvT+Ex3Fn}b74IO2F-Xq-WuG76h89U{l3c*z1# zJ`fcY{9rdr10>${GnnXeW0}tTdci(42qviJ{ZhJJMhyAEZkXB0`XFdpMp~zX@uqb*DX6z zsct>zH(Co4?J5Hh>D%+{-44TF&32(0$&Xu#!8?7hkdJk<%{N0LHWd2G4`xQ21iB}i zUT?^=jXb@iXj$Vv@s?lINXB^#5ht7tf%E=C$&V+>Xf?UWj)gGoQ)y?@%)4l^eSc~`QEx{j+Jzv;b6D7d5MmPX9O?PrHkXcUlT+>UesYw6U6+s%ni#pl1p>mgk?B1Li zS;uQ@KO`nDLP$W-b&hPI*bTE7^~3i~783QG2R-1=&)4!F9tp;IBVV)+Ez5c-V|WZI zRg-75!t;rpL((aVZ+cEi-9Hi@wZz8WQ@R|sk+hv%R=j<#KV09el-#5=mD_~-D&g~l zjpAfI)MSK2(qLMvGn?|1!n*a^%&{w1)O+GTeM5MgFGO4pRY7!1Sh1}2r4vW`lN-|f z;pqca)zmHv_=c;wdGR#I3;@{ZXr^^f&~3J>e03o@k^U8llAd1qwa4^*jE-Cmy>HO;3aBlup5!J;8{OitE6iZ?CV`e;BOu52ZQJS&|UXl|4n zEZd7|Phknx%FxPXPd{ycxa2OgT1P@m!I@$6a(%SY z_a$885)*IZ;p68$Ih$)^cGe;7?u>3))zl7nS+$EJP4I5V#%?`sl1W)%e5PMkY87&c4|C$p zsZiEqj2dinp9Y63ZUY@M*d^0_5{iw#wr8ATy=evSLa5e{1oV;L=md)pmkFw|caoWUS9{r~!U zgZ2Afg%5Y7PZ$2z{paWdaPeZB2XcF?+?$cuvK}{aZ;1C*i*%4Y&K!u?Fos13seHuwX|UJ z_f~}?egN$dn&a}$@^J`N-XE)e4{Cw@!ou1ahu7RsH!R*QT*Xrp)BfmMHz5~Fl9iSdRBSWvDHKRLY z+;JE~@_6RdDU2+EauFaJ&`kvuGCR=h4t15^&q4M8gd!&(>pRX|#}Nc#E1m7bkd+q# zRvsi|QlK4pTI~5Q8q-@3#JNSihtK=4%i2q#be4dN*%kag?YnZkyBX-+p3d z!dsPmAKP-Uvqxd%|L14 z%lcITQ0dCFN#Vhws$^_B7L1R>zDU@H7vs0{`52x)!v}sBOdm^AB%jt_D|)i)oPaS9 z=sQ8HcgA}t=7D18vuED{r2wQ@G|rwr{j8~=SZ9BKKO?3dk{B6sP~6T8xC{{pESwc_ ze44g>+<=m#jTX!4Xh$QT_+`BKI&Gh}JA|RTf|lyfIS8&>xq7*8nKSq-8w;nCqkyiB z*@#rA5+=A*g9R<+n^GS_3B0X(KE(k(q-N5d+(fPK@|AsHj@U!}^1l#)mIqIZi<+)G zuX8%(fUc3uveP;Rivnb>>M{B{B!KR?Y3v$TWVebh)z9S1GL$uAsrh;FUp>w{!ocW4F$|Uq_JwyVob4dU?htJW{{sh5g$o)asZGx%F+}IfU z^Z+~Cx||0qtO8yPs}%r8Jq0|O#ZOC>bmETxg?F@^hhvBL8pwcvvF0Hc)=hklWT8(K zxKS&bckBnQk1qk1^kVk(KXxKh8rmin21*XkT8@q3e3;R(`LOK*J^h1q*A{N;UlWR0 zv?mTBk>T^28IP;JIH?O~S_xj}xsdriT^ne{y0h1|L;E#q24BJN zTEE4Vt;p}Q7-}cY(fxQuZ_gi=>*gsU{$JUzYVRq}zv?b!D(?cs z=pcNL#2H2L*UX0Aam;q(V_`KOH$7qK@veD7oGwdH;eekea>&lGiOLB3_fDmUp;o*F z1KD!Ey+|Z=3|Y`Y$@7%xXu`uly%~mMdcvgviAKK$4jSXs#p5YQSQ}XxM!pQp==0%? zS03ZPVb}i&03DhoMw-K!L*F9Je}hP#qOK`<81Z+^a5<0t4d$u#Ws_lHMc}r9*!O=7 z_%DkN{s)Vb5c2`=n|4K|*2L@08uikq4mo-AbT7n*x2T-;giI9$jx7EeoR1ETAr4B)$i!tp@)unAsndVe7c30P0e~KC~ z36^8_8yTa22&9ui5a;SGU{Es$9pdzsx;mf`Z@`ozycfIzjM`97p1TeBGvK<@z;`C* zv^)+R$$p@+TLS}afwuQeCXU4_=)GX@kE?|G@vk$YJwzO-SMIIpcmDO{?Pir|IZ<8* zvIv4^9(eRHcJ1gc6oh5CfG2^92n_{!d0_eA;W$`s;DOTUjEqDmO#qcjr0ILGt}E(h z{$HFoEHwsyJ2kCd?@XQY<#XJWmG>Vg52%=YyWCS;oRCh!qWW?&28-hJuPx-E`1+xj zzf7Pe$|D&w9m!)`gn{?>Ko16P4d9-%Tz!cs9c!RtU&GkHw2=xR^O|}!0%(0TBKuNF z1a&lrFYikBGuv4gWnFTrwG$!TIY$;q(Qpl% zCTLGzci-Oy*3kZPcX!bSjJS5dq`QANB(bAKhkBub7zBKCw%aTv&uF~-tl2Is*CZoQ zkafczl{rP1OdnbDSn}_QITs(pGWG;Swt`Vm4^+Y(VDW@kR) z#}MUjLwx2%o56pEY7^f#iqKq{t$weK^^gka0-7@ZE9S1=!t0_XKCXSbhjCmZa%~n; zmWK-rGpWZmzOFgcx`OJurRkGwMYp{9nM*j76q7(w!1A~#{yPRtwl!RnYGBXTpBcKd zbv(r*&+}h#qz=Xfyq^2$=BawKufiLa;ohm=xVr%pAozFR{BtV)iG6>A_q`s!7Y%C= z3v4*%#}ONzjQJTRguRRcT4a~ciDC&yIH0U22nl@ZYCz~bY^~6lW000z)u;m#5`}qz% zOyl>4GTVl*^LOu#aEHsHKE7tRZahU38sd_#D;`;LUdQ#GBI9B9qC&28PPo4yNVlvs zySQwwZB;$VOi5w6(;nA!!EYP$g%|%wX%yw9MoaZ3nOa9kNU+BWtpvlLTy|RY^+e~@?d?}yyr=+F!F@kB3Sm2wX-*I6 z!;Q7saEUP=KaJ-4j~gp3WXtRRR0H?R-PVSOJ-RZjpoxVw9fBx>T;m^rzyWZh?~W=! z+(HOnqRswV*YQ&kwVm@mR;ROtS~t530;Z}L$0j`Tu3b0^D3T;w9PFo0xo&QM8ou{{!GIbu~6#b{Gnn^q;xXneL-^?QwESN{#D^yuJ9>9#CTwwEP)RjX`o^ z<}dW0^$u8WGNo4=t5&8FI02oxmD%NiG<+YcTI1xMc8+j)mJPt=p-#+bjn7;I3ZG^H z>@2Y-Wf1)2`LBT^a+`zhOKWGJpHK7qeQt{KrnVqR1<)m2|Aed@$)gD$pUZmCcc`SN zI8R1V3wwIZO83ab zUO$)sq!yMh*-66wA))c_r6i3Gs@1b<82p7FBzOd zIBamF$|PDG+yH6T7%Xbf>=s52^se|vs(d+(=uD@!9=`dd*k4c7A{spoYs2wFbDHin z<-c*7AZ8L)&bQt=D8x-UIZC683`({&J|{^Ok|*6}4j%`QgOc(0-{<)93$OHDBYzIZ8tzP@7xmV2`3!MoLKAuI(z z8Ba=bXA&8SFFAOHCwu7KHM05N*tcj@E%iST_qZ@X+#dmO4c`8VmEqi&p_^HEM`Ja_rD_x9bhKA0S)ISuXfAMLEo`^f9uuRRzcwB8#j3% z)}WGMcebNwc{n*ne%!wye8ZwG@s5&G6=0zPmb8ig8XwR6mbE^t62>BXyqnrmuuD?! zD6*xK7dD}sj&?z9FH^X%d`dxw{$Yb! z$KPPcpZ@K4sl^|j^5{$cUYS49p8pGv*SHZ)?JjJ$`pso%X2m&1O%tI{tr$bqaso?F z+>e*j>h9ag3HHa$=lT8hc5pvl`_{%;N;No0QmW$XvsD(d&e&~7ahtv8Jx>fBR_XD! zR(hLBTCXXjPBV#Y?k6M1aP|xJ4Gs&g_FX^7Z0XWbxsQ?SGFS#o(zntZ>TC((HSY@v zaW+*NkIaiphlZmQQEcqnm7lkbR4q-jaj-6V@#Yo37kSQzNJ56dlb=ux()-}JJT9vB z<~Zi@l94o%o2BLa3q8|`@lU+OQN9KE=Z_6(aW4=5e?6kYAfH>cWL zg>6jZG+UI&M&*Q@PAqXEL{HEM35SJ<3^I5JMi%JCJj-JjDryd8`_>XOU?viZ`EruV zCE{o5C-PH+>(P*QN_5>ZmaH;ej6KllHXf;DIYnWPi=&q4 zUOI@FMeiCaKNu{PqT!PvBKinLW^F97rQ3bx?P;W3Aak_aZ`HkQT>1&I_Wp}S6gcus zW#)&q!7(*~uB>x@vk({f^C)C#3xwHw>;uD)WUrnTC7R>+zB!W;*PR&7xKPkr?rx`{ zabHc%vGe2C&<^wN8#S7!z4hE@44FDbrJF=a|0zG-4D1=pMQp)>KDlT zV9*{T%3)P_{?(JSL)&Sp44T>W>$BOTqP}=my*X|M21%izn*u{Fuexb|3iF~>7ieF6 zjVR3s9kkFi0XPnQM@q^pYt+W(UZk(MW4kHKN_&Eov(W@sL7sN$Cd2Nl)P&GZa|LAm zy;0^f7rd^v@#3pBz>EEYc3J!?{_K9*;!j%&D4TDb9ddQhbJ-;|TwzPE8|Y4>_||fg zvQ}SZzy0HLhB6k;jJ_s;f?@xH!M-;FW4?H#r-t0!Z}4p{)sTAQZ=B(sqFRetT$kg} z7;l|U*7Nn%p5j58s<2ukFB630YaYj)rSvMO@-w z)i6`=#3|`+h~c*LWMc}inEh;*ef8@fE){usG-M2VibjzPp_hgO1dI)h?QP0SU>^y6 zXG8?>yw6E`N;fbqO?qR~;KrUUz@rDk#*K8}o^NompNPXHPF{XM&F%8A=M(3IpY$`? zEUnz_NWPY6k)nwPp71wZ25Z$DCr~?~OP*(f(&lQD9QrByzBwT9F*|g>hT%ZU6R=qz^pqk`P`RR z85b1k+v<@*uvI;EE^(;xJb3ej)vB6!Ys-I2seE_Y&CrllfBY2pof3O_(*)>ykJ|G# zDJ7~S9RJQpied|=n&F=b)Bzrrxc<1}8_Wr7Uo5PaCCx%Y)uNE5H*c8pXs?UumV8lO zzhCB(yffg+3f2zqhq=p0D3|Z-l$+Egn_$D~)I~U9Dym~Z-u`$EIxBWZ{Vz(4!J$w} zOvArY<}fvo@|x_sqnwe{CGUQ2D@F6Vp~RG-h-lFYgH)!+&y%#y_y`Ek%Z72X3`bug_h~FQ|gH*cklWDx{NuF6`2usRvLas_4mojgWGA|m z8u<*}TB3NC;l)x!eV`m(fv$bT?If9FcC*zgSxAXHsuEsrWB%+b&TYr|Z^O!outHGSy`og(gjXP5N zP0L2J6IRp_%J&nmsS|~_Mc*E7qg4vVKR+Tm>b_@~Fkr5#%w_$}@Sow%3kf<{qq z3B2OEcNv-S_~y;3#KgYJ4OX_2DXx#iGyF0W6HPMGsp@fFV*0WNIIWEm2ehf>Qg^M8 zleLocx`bGAw|PiWoJR(V*VNE3?*w6*3JL)v$e?XO;mEs9^ew70=PPv4er9F`LRw-lu6{tO3C-9dx#AF$Kpu|u_k7CkR9;kOb_*bKwM4U+UaFgF}i z6FUf*-f$rRtGtzP=k9__%Io>VE!A6D^7?;$lpUeVt%+n8M~HQe@?t_(iI0oiC14RY zn{D14`aSV;_jO^;_Zlh^5IAmIZX-b7{MkO1q~uOvUguNnX-7ydjG9$Q;UA1hO#`I*IHUAmzXvCe}0C)wDNX zaFA54Hd!8@7#i{`I7ceGyj<)cj#~ACdZWX%P5X*bq*?|+D7EMcq3-5 zvcZ^ux}JVer4C+Yt;3+bc6YaaY+Od1@UfjsdfUI?0aBkCSW6a=&qs?4(1YrGI}R^j z5Rj5)_7zy2+rhmIJZG^V%8nhQ3<;Sf7?KpT8cYZ{cM%s?9oV^F<^<~S)*{Y0gYH!;I$z4!TMkl^K_cOG8rXnkM?rlO?O%Qt)4|3yBO0jG;L zIAE(yHmIul&d%1B?{s^!$<6E0}g1F3yYHU*oH1_ z#Ew3@v-+w%WC;WU%w(1MGRO}UEH_5|Yl5tjbsiacPhBO@^w#rwPa9^e+_xB}12Nd` zvTNt#sN`o|tQ*2KBYE#8m-9BXM}w^57hYtpy2PYvF4>I;#SNBieG8B}@gqYw%s{Lg z^VQ1gZTZjK#}_jZnCSpXEVEFt_&2QEh3{rqim%PkK6Yq-V3vL1nzHJ z1*i=3xECRpUu4^e9mCBxd2`*o%dwc6ipp|pD#3T4q`>a+-$84A876EGTCb+L*3-{u zY0tyH|3l(B)pe%p+}E!+F?1NCI*?F!t9Q3dLsyZBIlff1Jz)1a!+sNW8ZEVE2y(i- zcVp05S@d|C{k%z^dzrLRWMoGZTzf-B5lCuHf*?wcERpT4{hbxI8`C^UWcjt;58_Pf zZ2`kI3<4zdKfTMRK2USXrKK(DyA{1A!atFb6xI=5AM3u47f^k!)m?wr__jNn!lnnk z5665DT+rH2>K1;QZ;f-v$;Dqp=Lx*v_I}DYb+Hy>w>V2Tnqwqc+VSGC*({``$A!JU z*jK1eNuNENSzzHD!qX=9`0m|&tzH8nK_?sHCguz|jkk)dl2wY49Ih-yavI4riJzoZ zvCwwgt1NksTz<&!d5z=TNczqTY4TnlLWdujskfdR^OWxj4xI4Ci@C^{1~mDRL!T@} zh6CwjwVZl$4yOC^19G~-zzm?9C9@uW^-7!X7f5)N$ec7rd2WiX3XVO6n{tS0ca})8 z=)wNZ<5J_fp09bDYKq9!@QkMr+ξ>r}zuw)5ULq1uN%V8T!~JlXTn!{b%`FR8Rf zXEwN4B+mWd*iYk2M~HN~efD;^c;UI#Q-_X+YLH(w zO+tcc=q^QGn}bF+y#_ekmy0Va33KsRwJ#cS?tO#0M1-1}psd6oCliyJ<25gbM6cy( zhBYRhc5YmJ{AEc2-*KF>DnU~1FBytdX3OIb>Zyfrief#yAc)qR5q^040Q9SuYu{}A zq+Q(IYSG&IS=5qx(Kc%}y#5I?YM`^P06j0oKqqq$*fy_)(rBIQCHt{=Z-p;qf3Ku5 zY9lqr&mP)GcV@c+;LfW8nqsrrEyK3B1GT2_v&-%)Y&dSqZa811a6vu|N?EA<^6I_l z;l4c2?jz;sNH9RW$%IVvD*#CNpq;ixaI!lys-f&76$%O_ zRUga?J#`hxay6c%?~FWmZy)el4$kJ2wtIl%Eg6ZsI{54w`CE!jsxe+ehXpoOKaSWZ zC&%567oYwVNhch3W2Ld@81_|G{NCA{N#}ws;}u2ul2bR?>fSJ0aacHrhgODMB2A!i z@~29h$(Lz*zttT`7sYX~Gg057Ps`x$?OAdWgiZbBqq-hVT(^7Zv%&l5Vb+b~Qq%M$+m*@ocB|5ZeYd%jZ(hIdQcEs($y~f4jP$iYvg??4yinR!c*VW{ z^^!nB`qcJQyYldmZ>J)BZg4+nxrVRTGOM-?Wpm#5)epRpTAq5XLpvnvGJ7XiQlZL}wV^Ef)z z4mfNi8;+#^RJ!tbC{qp<=veEb_Upbr|*Hk z_+kCyhiRE9_bLKnYOCV3H_Mc4NwxSa7dthAZiQg?j^;itc#8sp@77|w1lwOX9;E}F zMF72M-^%0ZTCZIQNpjQ~+)GmtYnS^D;C|Jrk3wfyA4W@%v%?@MC=V~6A?nar4wWxz zU1w@Url(VCws&@NH8&nNol~5698o&!^$ufXM$gLuSuWIX^l+XIf%cSlWnWCz)%d0o4v1K9bxWFRdynbufRp62U zg%bJM+r=j#j*NS@(9NT}m1&5;{#f(whAVGU=HeE;KuNoD>*vtTD&BfMxLxXYC#-(R z`_Zizl|}zxqMmj;r2xoRpYdbN*aU@*WEH~$%eD*ey4p_jIxSyz3j!}XrzRsKLT6xR zCK4^TRx8>3`@s2g_~1{&^|CXQ2E($tw!uosb9+b*w zNNcr`zZHj#{)7Pqgi7qa!gi=#h~SUsLh#;qM_OT6`zW&4zJm@vFA5|h_JC|@7nBVq z-pyIobtJBimZ{k}*X&-FlaQlA&{wEEZW:27960" as et +participant "etrelay control API\n:8090" as control +participant "Masters" as master + +note over admin : picks a key once\n(kept on its side) +admin -> et : rcon: sets etrelay_proof +admin -> control : PUT /server {port: 27960, upstream_port: 27960, key}\nBearer: the relay's token +control -> control : port offered and free?\n(409: held by another server) +control -> et : getstatus +et --> control : statusResponse\n...\\etrelay_proof\\... +control -> control : fingerprint == sha256(key)?\n(403: not shown) +control -> control : bind :27960, keep sha256(key)\nin servers.json +control --> admin : 200 {port, upstream, since, alive} +admin -> et : rcon: set etrelay_proof "" +control -> master : heartbeat EnemyTerritory-1\nfrom :27960 + +== Later == +admin -> control : GET /sessions, /bans...\nBearer: the key (names the server) +control --> admin : this server's only +note over admin, control : 401 (the relay lost its state):\nthe admin tool registers again +admin -> control : DELETE /server +control -> master : heartbeat ETFlatline-1 +note over control : port freed, bans dropped +@enduml diff --git a/diagrams/tasks.png b/diagrams/tasks.png index a70374a692ce4e00d39e666d2ea68410bca314c9..ac8ea2ce9b4366b1e87bbf91a3d0a02c6f810d4e 100644 GIT binary patch literal 85045 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

-c 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 S*lKuI=(Mr95zgTJjei0TT%8mE literal 57085 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

WBo9TqxYi7z;77nyDX zPy4jWIaDp*IhxC8VHs%nY(;^F5!fq4Gq~R!d;F{aVl@4E^Q#e^$;ruIDWsr|D^kT_ zjEe2wz9qIw*CZC`_&p>I?Pk`_WA0`y++{~vCUlJ)Y|Z--P^ecrT9Mv?Kg(w+ff}Jm zL`7@e)~hvS3So9XS7qA9HyQk6RSBevqveI!3&Bfh+-ti!d0AO^wMAeH@7=|WO5fNK z`W-1B8O8UwX{`N~1cr~f!^URS^+}ur*>soo{?XxbZh8kudl68FrFT|5f7{aj(77rE zaZe$a&3j45wb7ebu3Wi#HQ%HouC=vwx;aEKUZh$+hBvFkYNVvs?z0aLGc&WW>-Kw_ zw3Ue7EUhpfkiLe|W@#Pmu67^<8LO`g-@g5-4_fUs`;H%@LUD0%Hm!m?;3+;nr?!vx zN!G`!1v5YJ#c&$p8mWRqA?&Zh-x5+)*i4A1i!Vxn!*>oFd$~8A8w9R{w$rW)kwAEby^z*P8|;i=gHii zv-;{sCVM%fS0#rYB$bX;IuTI|m06EfsOo?Lknx^S0fA^W+sXuM*>D!M#7Dkhozf2p z{x;xdZUScxxsGw1flH7F5Gmy2*Na1ylfcR@Ko;Sq_k`WZFpdZ77UCK~s>!+!5dRhg z_`A>BE4nX%KRNFWJRR_8m;Ub_?f=_Jf)qOVtVajWrOE)e-BD1%hMSAA=_|nR-ay1@ zx!nsr4bwM0#vCu4+lXtyU5nAh@%)>`Y&ymXWtt3f&TXCFICwlUF4PA&?xuz9)?pQv zXQf^tQwBp-E)|LY@$}6_xIfM!3B=px5%A_oJ>1>Q#FsFEZsHBlm;}-!S%rZVQ@hn% z1bPP2L3^0ZlP*U{ZPtbIS6}-56NXe3*Woff%C*MS1k0pa{%V2W$3ZN@P5N0{xnGKk(@)YK?SO@N+BT-cjBK4 zM@S(*^7zY1?K22_%==zi_Pe|YPRQ%06zYyEQDa$JVuv3?^MU0L#tA1$gizluUg@5# zDKr`AMAs8J9j{e#cB@Z#3W9@zXZosStZ0z}l>>J76y4(GwmT$AwI+_Qo=Hl2MTvp- zQ@{S%@bu9-8S_YlM{h&^bGFyWXfT&yUArsqAyE}p27H2!A&dKZ^Sw^j#jLtGDG3La@tC6 z`GkLL8Dn?)@iDf!8rm5+^y3rRC$~L4Jym5}lv`qBt1Sft-H3{lU$p4K?Yg)!Wn=CyG8)6r?TC@8gSk9?FWtz%)$65+UyKJfQZZQ_ER$pWcrbZ=#m%7e*j8(gd zT#DeJfydQ^vDu74Ri+_u-){0nvOx5w2vOTi6pj(apJMtis=j!UU2K7rsihhz+g$GK zoD{GZsjxF@nQe)gnr3ubw2Rkfbehn0I^I9))?n@~m=z}Z_I0q>>&&Mqn2v|gTV^0< zuPY}kj2PGjH8FR-0%8f6HqtWn|1@DQdNyA2aW8t0gI+vMM9y~Odji~Rnlk;&D?II7y_1xJ zV7vdNEiDtM?6w*~^x1#-wb+jzEBa)WppAY!R@#(Q zW4kmhbcfclT#>o$y12%gT6CE|~h}^APuRs{^UdLqIuaGA8JN*ty0}OZ<~kGkX1AVrSUBczn!_D&bkQBe1$R8)+AatQ zS280G5o4aNt}wYiJwLtp*!bwSfr_v{2BGLlrxjox*b_Q<__W%SY}#?d!J6(5ovpzF zq{oXyPuCs_;?;yY-1g12$Nodsj%1bOTYT$CB9q4&Yc6)(25z2M`c^D|d?zGDMeZq)(N>5JvNf#e0O~{quc6$rJlfvJ1Z} zB+?Qpj*qscI)drJX5+TQBM!`we}2Ik?A)D`lI)I5i*+h@qxsu4?fic%BrsW}^}r}b z-B+~AX1^K8a{#6LLrk`Ch0v;^px0-|LM0OMg%dg7mtlWweu*};@#%<{rN^?D<>H|- z(26^P@SHx#Z6+|q+BwCJemUe{!nKn#$&Fp%Zl~MdgM3DXYPA2{H=`bAhOL1XLA{Lv~qw>Ek~bvO|TYzz^1RmHS) ztIz4$?}oY?0ShR%-JcJB(s2iNBkr)rtVTiNk8P{$PM;WBt#z;FN;S`|w^3;8Kz+9e z{Bt6GsM;ODgWy6^uXIApG`i$GZpUM?s^{bP>I9%kkD zVQw?kHlH%Lq4!dev@pA;Bj)0E5@t! za`-a0@1UTcYoH&ZW&H;HzJlgc>A+(Vbs-c#p$;sHfssBBi zbx(VE94X0`IlLvJ^OyZV%Ytl=|8jp;byQynb1$I;nES1xc^W6g`SO}v*Db`<4TNV< ziBs1hhq0Hn1^L)odQf5He#KPTqEe`WOH?9)-25_x`n8}6&ljW$XxnjAZ9FnHHGT17 zrZ-(BWhf;f;Th)m^YyBc z+wcHuZj~~o6Wo{4V)nB#q0%^4)4x2YoqB>|?}-j}Z8_ZG|Qi;o>BY1wp2 zF5}~ykCtuv;9SyFvYO#vksls-g^dTAi~?re$&bQ&j^?EwE8{%lEMpX>bBFG%Rj%)@ zjU5?;g4V0d7HWTUy3%3Uajx~|NB?-|DgU$MdC|M=@tVCMUjJ< zJ`H^~c(KN^lEUh(@LX~2PHPTKf>U8X-(Gu+ZUHS!J@-vz#GruLr`tJ+mG3|VCm>(}zY%u`xV2+M>Q4XSvU`oI0u9{T2 zXl2m*_Bh&=epuYIyio*s;9rkmCjZ`(USQNBQw#mp-X390Cc|LKl_C>vU~7FCs=m`; zhLK(FQW1+f@&$R2)ZLzm`3B7vRVgfO!hjxPD>VZ}qY+swb#qfxz zS0-w`G&MEr-x3UDY1R9f(=|W0DdLc+9d})3b5UB|w#&T$xqA+50lcU1UXd5H5A-iV z17gJLY-WC*QD3b+lH9g9o-;~n)m3+FtEYlg(QN@`50|am^udY4VwqK5Cn^NZj43AYwG1g@ zlf4+0fDaE=8md7^F;dRgwsqZOGC3DqGte9}Nm#_d# z3S7(+35lj?Zj*%zvm8Uu-DU-DavRIdw@W}wD@m!iUBgE<(W84p@~#0+vwDyf$<*_fCT z4)){R)|fSNp2qN685kOBxgYOuf}B}dA#5~j<(|UP;k@XXR`vxpCNKHv3WHpYxpG;- z!|IaMO?{P;lTAYk{~w+KAR0W+dv0ceR@(iS`yVb*A@b8zkljO|N=>=^;7~rZtNP`b zopEc_6HwyqET0{pr1mNUqbq(bWH%!PFr~!{0DBSgIz2YfhofU>W@oEUc1J)@63*hW z)2DHlsnl*3^|QHBY&irvW^H%Vc zBq5E695*f5Haj$Tz;_`#b7_0*sQ2q=X1Y5S6W1dMgs7fdiU*1`vAL6?f};$+sXxEamc&h#SQgtmIqtK*VrzQ=mRLg`Yp)3jO9B>-@r07ktR(| zs;dqQ#T+0#+H`S+HjPO&VSNBKl6q)8u1M1s1WJdQ2Jv0@Dsd`ET`;E7_vo?r z2g1LJ5k0F&8To4`JFco^oe48M17>YbiXHS97U4bZo~67Xt$fYl6%iTnc>wf?S};#@ zgQp)rX9Gr;7mwnP_)Gf5<|7$4Frt%#b#D%CueeAdpE}WRZVacsF5U6GKiw)`LkNMy z`U26ZxX%z6de+RpwTU#&sUryof(_T#DdiEW1c_WUg4BN%E3doM|S;At9Lm< z^oLyj!YuAJm_0Q))r9B)H066!FojN#&R*Ayk(z6R$ToUT%>wM5NlI!e8k^(+3@EX% zF?n$abgj&uo$%lOI(G)oUK=Qhpt1@-fI^UEB5_z%grIbZx-YB)+F=A)@zP-oRt_>> zwsBa=2{ec7UVbTU0V9rKATyLR?gkXIFa6t=z;<}b#zQbUGg%-emqCBt_KAI3L;e77 zp!v3UB&PB8ipB(dE2>Yi-xuES(58uxGOEfOOPzg9ek|57<4L zd`*PD&d!uRK-)b9L^NT@KK4*DS=8Y&ShP+E3UIrqfxeE`5X~~I8?B&*#LVPcgbt_alt+#8y zuM{fyIEs!{I3x{=2a;}HSFoMtKcC0j2PA|4k_@@AyHfe$+lREYG)#UH&3}a68I0p- zzid9jo+i;4aDAlMf{ccy!-_T=1I(ynI=djl1V9}UiB!o09bS^B6|nSPOOT(FnDu8x zlZ3vc%F(Z_5%VJieWgnvC0Wb99GKw+lN&iqs+j~_R@zb#f`Gr_(dz{beHfQyIMvjk$X z)(e0@7RlryvMate*j|{_{ZXPe-vlOUyrbgmwrd6QS0d5l_wn%^KD}Ox-6?)N%U4u# z*CT4qZi>9j%Vv@fwV~bF`0hue92bf}2wU{u4G6ix>EmNR*P1w6<8dU@rsw<}Cm@J| zPa!~RhDzD>@euZ`BftQJoz^JXIy2zhW&;JDnyUb=U>^GP6Btr>@#0QjoREuhKwcYY z(|heKsi8QAmb|gBb95_9OuK0N3wsB@XGTCnIrwbGW82w`9<5|+6A5j2_xi`Wi}?@h zr4effgZPX>9RdV<(Q*O=^emYrMt~on4ZXa)WD=7J6=V4y7Q;wzZY_vk(0J{Vg3pd@mYK6vGoP&Z0?= zAT=!p*^Om5F$u}z;^^pTwoGURIqKPiH+*GnTVoiPf)YX=(W^bhah3#e$oQD=k8=QfPsP7#wD& zC)FCCW&b%a_%Vu=z0#dwYYPT$qW5HSS z`PuR^2K3y5)oTxzShdGXZD`n>mit$Csn>3;zc&(qyX5t4Z^L3N4+nCLPF@y+0?9I5 zrNmMzCJ7e6#dwebGah8o>38l!8(RwS?S&{xr}RqdwLDQbTk++RB28rN`y?Kyq31FS z5bmsiM&{7sv4a-%w|X2S0fB?n?k zyRCo9Q->)qZvvVxS|tiwxH6yvuqrcUMH!h-E(osMi-=yz1NG6|twD~JUeBRs;2>b9 z1vZ@t4^;)hiDIS|y}YUxtdU)kMH<@aKb66=ODioaYq-Ar=|9mo8FNwKK`6!p2q(Et z)z8~7ZcJZZgyR+-GOI>U0s!m(h{1)f=5$!emx^w$gKiS2qb*nuEz00o5vM$+*vEM*_I{sWHW&$%8KCjI(5%j9V$eU zd?(a1RGU`IWXlx41DIyX831aQz8YK&@N0nFy+QYmj*f!A559=szh%Q~*mN0{2C8V+ zjmd|k&rj|?EqnjVE&YcPED<07i{QDa{f^+Ro>+M{i$qg^*j{qxIet4s_t~>&z)1o( z+O(stq*UjLlu*yrV`~%`RbNTE;uBD0F#r-mhk_FA;;i^``*~jAQOwN-y7lQ;j9$C| zC_PHFDNOKku$qjk=>YJ%!v)%pxd3VpIt$+@OjnFRJ@FckC`YH1y{|t<_Xu$16ciMU z)kfLVbWr@Ps%d#zI?u9K@I8Qs+vdNNJK5suh#$I>C z3FeW>SPG*E^;{Ct$D=Kn10!Q#%B#QD71bW6|I)5|Y5^teb@)=^;TjbU0sd6}3jg_+ ze7}FMOnNRi(uvTS4m4gP`6f1NEgsw>rSXHTy~Z>Nf6Z80aif$j$9h6o(er(n9U>R| zwsRvG3Ga`QMzVvl#LkW|9l9QF1N`e}S!7j+QlP6IOltZo(l>J}dmS4Y_Htib^+Qr0 z_~v5U%;|!o{1_xz|LA3tvhpO-=93}FdXAgm$E}t%yCp@2(wN2(Nfzn|WFpeP2g~W_ zLy@`br$M)jSw-2#*aSz-&qqfnPg^$+T|<;=u*+6ydh5iR<8E-(~W-WGq_}3 zL6ryPIer36^Z1vaq-Q;uDR0x&8|^e+*uid2nT%MYBOO^2t$mS{bz2jD1ITmncX{%C zk`F8lGWJeS^{2PGxlDJyy6JPUQ5AD#N$M@h*Dz}aNr6YM{H|=x$7?&=9v$zrfE=Jt z+|Ds{LuK`|(L=;8A;q^+?7*v*l;;-we&0gb@`A0-VK+RRrTtM<=NfD$633yc;^@M} zg{;S4Z7(EXn)!ci^UDgx-O-=z2K`6bXou?7rDj@uJG)#Oeoyz&QXSW-s;Xmb*rJw} z+Wb}b%i-Y{c?q$$#XwFQN^Qc}#3420s-zu`R3SlXoAtTcF;%8y}Zb7q^b;c@a#GS zif`QKt1#B(C_J>qbF`FDE5RAJs$@lx9;Ri_iCXPQ4t;Z$qKbMIJP9W?-)XkwtHZPgTCzMxUr~)T_~%*; zan-{M1Ux@-EeIL`jOngtcD9S+lZ5K5&!`)B3S72ef%+B})D+%281r`yDO7VfWMc-qnmn>@gV;Q(-IoZl zT0UW!_-gUDrrs+=>wp6I2S)$b9={;B)6Uc<(GMIl$l<05VJ4Spy_(R0zh}CI;3@@} zTHY;;RiJH4stina{d6xrQOvc1M&<4r|E;TJl{pOP4hl{go<}0>gw-OxDJm4}UWctK z{58Wde@{Fbsqmx}bxR|qt0}wD<47Ee^9)lb)6Gn0-C}eyi+0SUqY2LL@&iDIjdA}D zS0;@UD8vdEM$a#j{LLO{jy?_1ysOoPh|^Q9uo}&C+Q*meKD!#Ib6Jn$zVXg9;mV*4 z3xXwmssZbd$8K8Kc-$`G;)t%OP(J;`;V!sj31ZV0EGv6b84Q#?;tZGPItKk|~46 zXtheMCm{EvEH3j+RIyH=o|mFe)`sury6)tqt4w?tE;a39x_8g}oy*MENHlu4aMuof zS`OgIziAKCLB)KVbfjY%yzToA#xO(>5!SUAF)5?4!=ao61-a$(o=rT&fp zLjAE#hTFEOCK+N~`auc~za$ej3?i4h2zZS+E|ahNmBS12PqUMK0Vx6i_|p|rGQRk; z9r5~^L8TT0vCv3$=1Nc=;pnI@N31%bXZS$7YGbP-Gue4>ZEt;K4^bpjY0;Tb;vQxY z*u^;~t^VtzO3;|Nrb0{-g`4zPsD; z>vV5ztrs&(Lq|u*$F71R{{k8#PH2 zAy2@w$dL#}T_W?OZ8WPl>ls%sK`K`ion`Cb!EJMHP#MO(m<9ErIyjO)_nJGUjN`TK zCw|*|P(Ds*-_2@0bKt3|wu3m$m2&mu4`NUQS&vW_lO5Td4w1zpSjrK)j0#SBD1$Oydb!kFI$UJ-Wr|fj2-%*FXC|pk zj_l7anuzz*)~j?Z&aH9v%eEffcQ7^Gh!p_6oPt^Oto-I?SS74HL`__xU%S%L+|!fu zX88ZG7nOi^SOa&X|Ld-D|E~1*g&k!>bvo$e=z zF8S&C0&83SYzzx>`4A4Ow;!Int2w$WUEyF+T%a^W-3q8T_|NCt(-o$BJQj{t0HG&OEjVPpYvJ*9nDfm4`)3KMv}x7M+=W6U z7|G)s=r|sEGQ96vPWj;{=WnRsKB4?CgM}$LkbAw03oF#fP(Bqd-`*4=N0_=_3#qzr z5dGj^KXF;y>wg?6Wavd(>9<^kp{1(J7*We;$4$=tW@nf)e`D(oE69~ffAGCRxP?^^ z@|$kZS>#dPr_EoJXjwxgR%?=Bzr;?^z z(^%zhO`Gjaw;6M@!9Mg%Fzdnf_qU&Kqv*?fPNls%n4cn4?&S1e3Z7R*UjD>?R{{x5 z8juavIw^bI&dG2F;SMH(*zao@5Q&aHISf)~`J3?tcMIL6*Y7|3Z1#iB#RV8-6gEO? z>B_ze2yN+17z9OCp8j77wa@rz7AlB;4JFLWJGu$aTj2OEXTbJCmwHWkz39VdzOu+| zub1TXik1h%#o41QMjGAfYwZ6+NlM#fN&gPlaiehT0Lz%11~Ru%*icZo*U7M=qPNJ( z*5WpeAE~f-Hpz1!m;=x3E~xx}6E@0VkEgNgdPQVc{)3{W!uuW!_bn5?2p^WrGRv(f z{?D~G4J$@%kP9b0dCCD}K=7X(j$~qD(MwuH_deuaamO`Tx!94kC&JnZxs^^G8ociV zB%mpqH;so606VYgw_p-fjAwsS_|NC_+F0W0C1%$um*3Hx=^tjS=la=by^1 zs+IneUx8={a#@|vmN4}L;_NSfTkhmzsFB7Q>$2ukH-lrJEm>YYX`xu# z-D_UmvVZ;Zq`xg;Qas+OWN_EZ{i}?DTg?N>ui^Bbdp!dwSgS;}_wVnyLcMl{TYl}! zzjM+^x?H3wh;nE)&p=y$`^nPoJk-E2Dl?JIz|62-VXCDX zlO{?}dvkz5y1n&;JKpuT(YSVx@Usa>=>J`eNIPpcvz@Ce57knDjINmg$Ie_Ar#*nQ z%IxbX28bx};ab z@tOa8Jfd-l2ENyS3gQJ!HE{fM>nP zJ0&yq+$G%P8KqALW>a_hvDc>#w_lsJlIXz|LW`12)ZgwXoyy0bsEg36fqJ=Acpp{l zAz7|n`sMHW^tNw`-b&1D(wBODFF5*3WjFH&9;cme(t!u2p*~eQfP`bGwkla7ik_el zjh)FH!=Aq4j=AA-^%*(0??8&m%>LkkyHqORYW2>f0HW0j<-Wvl7q@%y&`;f+yMmR< zsp4!14UdmTxD`jmThE!y$K9yCl{)o+pGw4ka6YO@?)xPS z?QYVaO;=yLXU2w1V|`}%skiL~5%72K3z)S!bu-VE?mtGQmFymyU}$*=mEY&s*M_QT zZr@e|))oM8zYQG~T`#fgKQ|XbTgPLJPa}tnT9MTNJh#soP>&9dk%obruYRAw1Q4o> zj);~&5)5^p%x)8#96&w(n8Fz4{=~udoOQyeL?> z9y0ar^wiI@{Le>DTl4ySqkFx(lBY5Dvu{Znei-b}y?q5ky$8nWHxX69a{PVfjmKS| z-_(9?5l;MpZ#5))XdW1+@1Ii&FfKnry*;BSS>ALi$r=F$0VwLgAV4_|p6dbqk3B+) z@+!|-&{zP929+_eN*Ia+K%GT%eId2^#ZS);F4vsHK#%`?@_2fKTF2KYypo1yk4+!% z77uXBv;dmLPgY?!n10z)Fi5Z`Tzs^?PBt^Q$p$&^3j^x_;3rszcsGA*N4q@b_FRND zopp){IvDc!&2Jy0ZB03t`1uV+4JD{mltdShW>2vqFyq7Hif_zxan zq)Lcw!t|V;&b*|Ii!NpX*sjIVJJf544=5sUo%8Ftal;o(Y(BkVF#0YkqnbT?q^%L_ z%`42T=HNpg@FDs1#!?QAVaA?FttGKO)~)lH6?H~6JphK+FbUr%D|a04 zJu%F(b)yJBg#q4*&pxNbZfF{!lPv2YBR0g!rNZyrM zR!9{9z#vx_qMH&lfxyZ3lm+ombjR)9=R!8Lb5d1)Txxhmfaw}Rc5doy%Nr(u=3C%) zNc}S2yXO7{K+U{ebFNOX{G&pC3|<}nworq3iWfOH0T}FsDP^kVkqGcJ1G_ZSV5;{5 zi@o4FV#zsptUod1lGk6CzIF28n!i^l|GL0mb)(b}I65w`>Q)ViGlhLO^9di3x8O6% zsmoEoFal$5_|>`>8+f!Z+5iCmIz$h|>c1era?gTqz9@pKZnPFf|HS$JYe+&xIx#O z@W>Z`+W`=P&@2Zf0AXD1&!)&$h~^U4YWX?YB{KHp2yjhiWP#4@po?;C!EVf;6 z;l~C(X_l6(`8hiE1cZwhx>a8^AewPGE*h^{`8ojoXIOAK`G~HIau57>PSz9YGb!A0N|X!<=s1X?(pzzhe}cl*v|#2(ubDn7rc-LH}C;s zo8p{b`CeVXv9kK%Yh18$aJ%?ZZqeP7jdZ2_Ret4vfHLNCcnsn&J0r>ftiSE*kY5OD-ap6AF=e$l=|CyB`j+2gYh|P~1RVv~UW|9{ zjDov^N9(o7SZ}o_#$r7JMxwtVzH51lA$Fp=H7Db1!BCxlT8-D-+fp>YuuyhK17;6oYN3)hqizkCu_ z)@ELRe5yTYcXoP`t5+=}&894cQwT87@egw0RYWYc-#$suI@nJwJ&?dYo~#C3XEntD{YA%vh9T0$qb1;^ zgvmE6BJuBMUZD3;)j=vym7qLZOMn?15H;QS2?Sq-KFWFZrd!J#Aj{u0NWSkngWez* z3J`yzNgsjtK)im<9Bio88}y+>v=jzcpc3`0%41>+%N?(92t?<3dqd3XgMu#Wbh))B z|D~W1BKCapr^k`I>8Dkz>!01lXf(11ysU3}`vg?LV++oz@s793^8~7I>-G^Tasi!0PnjGB-2S|VmctEz;4u8u7%Hufn%Rke%FpRg!t!mo64iL>jUPOEs# zj>HK%wTJI101xuylRBVSfCG@Pt^G_5evp3w(FC@k3fxX7vtvcF+M?Z8oomn=F)My9hXTTczOT5SVWJ?H z1?4Ge{0*|Mvwrz{ukdq#Qm43j2v!4lgTVUSeQ5`ti+XkMdqfL;(q-kWxCAb|x_>bj zi1$2Xwzx&qt@n}F>TqX3UvMwdgG$gb`RmNLFnc>YrnC2a{C@(-{YvyOA8>LK&%47c zjofiS@LL<4W$To#0agQ`ESREG zhY)J{d;Tg-_G_c%fYsgOvwPGqdv&)k4B*BBSwEITVEIl&%lkya2GCZ0mqxhAi&1no zBPH3{3pP{A%F3?W3%4hDSy;@!eV~Vb1Fs;-(JGYiR7D$e8@B?H0cZ<|uP?5a1G14T|U=)y7djxL55oddXoBO>hfb_Q#a++-To`b9s>i+F&#}Vl_#1w@Kfv`W^sKz5o1$^( zUkDsSBY=jk{*$PTauO;kXji2iwYZbi8N63`b>SYN?a$D@cEb-`Gb;9SIW`z21Zk7Z zAD>#2`@v$~YBNCe0eAA8&W_48cYP4EL;@hd2Q zF4>*#d)43@m{-1I}33FHYiz-ebZX)9kanwQ5`(xP2*rI7^ zv>H2N$~;kXjoL2;D(q$bo#qV4tNcseSbNZSfM8irZ#{t3M=i3aOvyU(+6# z+Vg4xZwin?J~)5Fj~~1Jn{+ufRlgW2Eg81dU7-tZzbLQ9%Rj^`4H2sp1~|CJHKHwB z?+c_z`;BTaQ7g2Ge(827%kw?AgT+Aa|p?idia++n}=F2|Q18I=+(qgvc z<#1!4AakJhll)6YszndVd#|091fHxZ3Pv>W`A#`Mqny)|)w$WtHjg5xIhXMG_TPI| zMw=>=d;Rvr2YZE_lIBmH2KM+Bk1{JZ-uc}^VwVbkIhZrK`|!?b>*eOVG{VIM)r#E zxcp?*k?`ANhM9YxMSpzpIck@tztsH$n3z%#`7>EhP&7AZ5%pHJ@tEUFw(#Y|H{){h3@0~?j#9!ZXq7!8|3ecjrv?hV2!?If(ACOH-r(BQ8}AYg5g1B zCZxKc#`>Dcym5-i_7WEi7dHMD1a&}tZhD);A z9NacV2+rpjnL${|l+Lr0))H?i+py<$mIIC{D@3S0U{O_X{8W;9vA1*`d!)2OL2<%m z%Xli3uEn_hI6*#!A?sD#d|4cCZuM>mcrTB_O-bg>Um9?=7GnYTDp;8Kzv6@{9H{1> zB5vpuD$eCbf-~Q&#fkWM?|U&8b_L6{a@Q8+Ko929a)>BtG7=Sqy5>>gY{O##+F55;O3B4c9&}ilhCRZtV+8vOP@X91(qtz!(DF*hBha}1qtEx7e zRMxAuF6-ndC4#qpScF>vfGoa%-7I{V$5ctjjkvfBCIoJ==$G47kswzxJdQ|}V_xHt z$*6t%cJcZ1&z4%*I!^+3Xr|P`aa|}USjFvO4vz8FriK3A36R@-1U`W#;d_1Qr zfB}(8lKn?rAL^%;N#V8hWacK$!yn z@F?=rBcSv&MeY9a$879Wic(UI056uY)lU7ZmqGN*Ta|u7=6}i%VQ;sKqDXR<1$*Ue z>^M4(l=yqEz?E~c#gP3O@l}DfJkwHeX*qE_o11leY-=z-_cD1e;zP{l^jV7!e9&x$ zosjQIploxJ9P*La+5S~HI%@W+-=Ai}7o}h}dKdL7c#5s@&}quX;u`3b;?v-4@Uy0> zfE-k&))NtKTRdM@|7mP)wKU#ktL-_8KfDJy4FF4n7I6P7ig(q@h$2|NcdC065Z#2J zu0FlSvnWBpG2BTA8tijoRL(yY8#M>%%ayGoxpEd- zl#{_S1ysM;S@6fyr|lTq>HOyv-$c#Mx~z0QRNL(Q2Gnb6ZLS=P6~FAH?RvL|r%J|F z-*Crpt@B8IAJDowXmbs<1TKoq4i zUXZm!wjopHL8?!x30=OC8M1kSS@LGo2aU|PZV%XbLFp>lDi8Q(j6VJDXlDHX_!bC* zMLDCvAy4fSXtU&lv4wZ1Ru&8Q$;Qe5KJ1hC3~~o0#0NYRW&x+@5X6d;4(pd4*Z;27 zH|(@cDlH3A8bA<2dSd?$G;%1>i|zf?15z2>XOIQ;j{?{&O7|Wvk=;A-AxFbefNxDE zaQnxjqqqh&Ov(cdoEa7xCdAhhDq2U#)o(!XdN5^iJoWR%+0F@aGAEz%FwGsVx4Qx2 zciHqbwBT_BiBBm@3;?X|_UZcc0?^M8VkU34cF{L*}FP>0o|u%ZWozgW})y(q&`RX*Gs^ZVjS*+J-~w z_}{}wk%-8H62!^X+I(ybDnEBdA0yR{jr93@2qN zjHd~v|M~?rZ3|dXoA`K@aa?zehlhZ};mT;N6xP(6#Y;`iTNT+CKJ11 zE+`6XZ6uuA6lYouVA3dCZ&Wz~#Z$ zaiNC@rj|>s*ZBO7;?mpyZ&WI|eNC-~WqdPo;Lu4kgIba554R^2hEcD7U@=k@tDOlN zZU1QVjTzSHe`L0>CKa)3YFvx;9zVnjTn(0frZg0RoSlIDyE&R0RRMr5w+2daeFoC! z^V5~`J7f9exW9+@K3Pi`S!XtMWOV&_U%pkc1tDgME&fBy`aYT^9&^*5q{-iVilyIY zuRWb`T&171RlF;2WIn-xeOw5nI(oVzK14pTVh_jo>+32X64T5@%ggR>g(Ou?evr+O zF=q&$upe-=F?MxN-LxSE*4s87fWEk)N&YJeLfa_KE_lw-O&BqR$d6TP@#wNuvOMb;zn}}F;s^W0MzSlqTfE%vN!uSO44zO#>vwrEqqy8Xv^ zu*CvE0Oxjz0o0`s1gz2M>33`u->F9`Yc`S`hp{QQv~KQi1betL&o!3%eHz48pmqh# zLn3g55d)QH{YA2Wy#xtN6gBp*M)qOb_=>#Q07}G}L96fdq`6N}k!5_ExShbkI^4JP z4H5xLDQ#0tc$~nM$^s$iU<%(B-5D}MBX9Q0or!8u#gF;kKKCC4iHSRq-VRoR=wtiz z4x9w>A`i&Q0VObOjesBIcz@+#weh3D-omRPxNR8?$wK_^;g-fOnV(0h079|Z_$ zA2~7<)w1B!vl_p-Ikgn#b-ZV?(p?-%S@S7X(1RENF|~+bz#z>gOD-}uH#fjlomdSc zm`s1Rw@YMrgJX=$W`#|mYJ%l)%YV6UtaR!8$47EOybyD1C#A(gqSceFNV9-Nyv@NyTNLc@KF#bP2)2<_n)1bySR%?a*Gr;xEMiV6J z1qGZ~6M{IY<^`QUT=WK0_CHQQ=n6%|%Kz;Tr@c)e#m-d3f&%JGhB@E(`Aik5`wQ7V z9BxjITH@8We8?R_vxAD95k(Ob9kXOK%lC%o-WpuGNZxLIxVH+#2%)ZO>@QEXfI3gp zJ_kH6x!;+~Xm$j{lBAo7_usPFywv*jW2uU604~fw9kUI94 z#|xnw9R*#EyPHR`3{3LTsj7nMmrKZyl5WO)PTyNy9rJ?pcw>$r;{EkUa5HuH3%&QGhuj)I-rt=enhcoZCSP265{Nc-S87O}H5+D3FN8%z&KTEUW*1{(_UFdWYHk60q! zO^ha!CH-|a@>}t;6cymgSF=DsvF)HJzg90_Vr)?yipnh z(mtn!&O*P7?rtzXn!QW4(9D3-9E5Q7M5iPgB_Y{d9EMQ`CC+lR?qhzQ+n2~L=ZMWx zPgZH9n7I=hUA5AQ8-oaP-VWu0x6*B1MwzJuZj^Nm{FRE8EY;iXzXC&&3(oH?fM=^ zhJ@2nSu7 zb1Wtat6+Q`ZUP#E)!IN*p#44fh>{rrZEuX*e3j`4@I8gJw4dDzhWX=OZJKm?z0U{R zs)6toI@P7hL#I8(igS*ib4WojeOh~^h5g|$EV0a3UmPyrT_Vw#jBO{myVIYhHC-;- z?;5Ddr)P6R2(^Dvmj6l7<6g5UrjO-#p;uD zp021SMaf~>oG`2jOhYB6i6NGsnkEM_$vGp9msF!<=$5di}@`L*I7MAj8 zU7EyNHz{tO95E5FQb#ixCUR~lwt>i&L8~Af5|B4Y0(x&pl&_@2HmGgutqln=>?XDL zOa>X#u*VmgBj3ofyRUQ}eMo}JDm7r!b96XpTza@!kkOlMU-rHHXmK9W=I~di$9ruK;_o3Vl=bPfY8Qf;0 zpa6duUfEJ8EXF^t7q}^yBK-_@@nzGy8HU=U^|d4_+l%~Zb3Q~98JU!NxxWz%BM5-g zO;3L+C%_vzUweyGfH^T$A5#x^(Le9hlzep<$Ep9-*4A!64p$vPP^yJ{q@{(z%)GcQ z!&`AwTet9}3~pHh-wF9|2Z|0>g{V;DSWC=WR@=@8p5eO zS>#2gp)VN=%^wIKE+=U&;6+2oY4S z{$$z6=sc|6{vAYtc>Qm}&!O&LeK3suawIOm>RsY)wmO<6sohrm295glY@&u;1X3*(SgR?K+%sQ`o znS1oW>b6R>H~yYZZSx6{=cq-F8~9?jTTC%N{pP8Yrp_Rr%fyq^J)f5=%>t3~aPS7| zQdq5*_h99_P%1*2DM%DKb-Rf1ajYg zrIos(;g*GMo*F5Zba5v9QANO*8e!pQ`BLY}U5q^I&HaQ&-th;gpG1|K@U3 zOsXCdbZzJ+Xo$HtP9VE;F?V^+JRLClUFtV}5BYbPQza=qjfSPMlRNPP7wyP%zjOSb zve6GAIX|nYNZCAW%b%66$QW<7;MCZy7N~cYrYyqC4;vm7+NZ@XIHnxcW0)x~ycPF9Z}|1~kI#n7wUxu*QFTS`y{4s9p4WpyuCiXiy~B>lyV2b`A$c~TPGoPl*-L7@6rBKc}e#8x3Ml`?$(iJq_JkSZYSmWWQghk3pJHKXcbDE~(FGTD z@I=o+FlYrIxCLIlYW75I@A5x)h~aZuh3zmZsg_t-bz<;2|8- zHh^?@dul8%KL>57&6%EW(S=BL;L$npdEorv?fr?)VVula0==6uX>v^%EgPmUB;15% zCOB?ltOJL+r?s2*pySEw>=-GQhSr4H4mcmf2LG2t%Q_AjEmhOiTveX-j+W}Z8nh6t z=aGauipAd*mtnRv0umdp)60Ezd!6c233Fw>ws^aXJ5JX(+ETGiD{RLM$%Lea=A2N3 zGB>;l~;ss&lGv|q$21uV58v$d4 zc7*G9-nBg6e=H`79^tg=c90uRo=I!0-9no0K}NY@03 zNrQZpBBO^8zZ1&<-^4>=jr#Vhw{hoLR+EwEsOOsrsDXX?r=-q_xXEHS$Z_(ar;E3t z1Ghqbv^CkvA*~K)&fM(FG^T??tf2%-`J4hm}{L>AZj#Qwa^gTjt&A5;0$kvLmy~hu+c| zY|83dC;)};SFU7|M^#M%kl^dmEDm$g*w z$*qa(tLAcKY0jR=gw5{^joh!UKN%WIaqW#@geST{chY7R!ilE<_jlK1Rg6|&1QGJP z3r+>}5MiX=TB-UE5P|2^%F-J|^pkJ-jd)w1(6W59v#TFMydz+y>29-p{qK`^dve7O zXj=wqvEc-f=)JON&Psj;=@aPj3L2_{Xz9>&oP=p|*E?noNy_Hsei+mvsTdOY7aJv-Jv87spq~p_igUK~+1=hc?6XTMs|NP-nw#0QF zGYj|etp!=n$Tp)v@VE>hht6n7+5BDITw68vATB~rOnB%6LV1|+!*Da{<>K8(2yvav=E>NH-BC-zGFhH<5xn0XNk>P1Y-r-2RaaxESlfjeW(navVMD9fjvaia|~)hZ0Y6?f9M7< zvmIb>f;D*5QNDsyq6A9al7fL~xbQAEyzkw#$6KPSqudSOKWC*$5!f*TH^`>4(dx)_ z>*8+p4?I5Sn9sd)F^l$uM*e+nXo6gHRPq)B;n5%__-lGGz1i{4|Af{>LyA3MD2ILV zBm5ip8C1-hiEhJ_=*gj<&><#8N0gn$jPw1$-H_5#L1}$Xl9l_^D!Ik#c%Nv5D`UQ^ z4$GzIcJ6H_e?{9N3%AL>*GVd{M(9UtB*=a#&!8b8v=n23A{*H=shzKNiP^mIW{+>% zqk9zqSC)4~=wb3X`4tksJFw06 zI^B!X-iz$XP!!*F4z*dz&Ck7=_Eu0z+Wy#2r(NH{_0OL_g}XP=pN6XYH zRg-a}E|)gb2(RyGkJbLd;rf)*Ps9RBx}Zo=;Oye#f|Rc6Po7#5FKJ1aSP`vnibQ)vg+cuWodb0> zH87FnD^TSIG@OLSni_kc_6;P~fVhd*E2{8gAahO6%nT$7JWBMIrq7bnVB?ZF-+giU zA@57p+vCNhvdv&%YiNtJ$8S%xd(pt*!fGn`77CK9Qhc>5l$BLmAGa{EZP%Q}r}X=Q z9|vB8os|_04NVY~&VYz^{PIamVWFuQW2kDaC9%GClQSz7iSp;qpHEgoxWkVDFHS_# z<@g6po?evkgcGnnjslX-gN~b=j3>=4ff3Co<(gy*@fejtN-BN8s(^nyd5qd@oyHy? z4?f}UuvRFV!L2D|OC^FkoIfK^`}EgGdqHbKga#J{MMqDsV~v`c+MknyBVjVtSyz`J zW&>TcN$$&@509BdT7KLee>2^*haZ&Mc56+C2WnFhnX4t=8(Dq_+3pwVsXb+u(;k~x zkZtqpKT=x+NB-HO*0a=vm+UR1RZ=||5jqq$x4*2#4h&J#2p!6I%GB28%S+>+iVSlcGw3w70I7HoZ$daa6HJ~4s z{7iW7>RZ)=keaXz)v>a)r1SObZ)%{8=6BS)qmVZF;d1`^qIyM%oaCnr z?0;$^wi^@@oYT77CDb`Q==kcocP?(XgvcPf=u+1u}s$A8Ci)EvgFQ@wgRcZrmM;R!P zXgu7M-|?zs0$HJ3VU}c@afFHcl}!eNs`ZPci8}1cA~OFC?Z9u8f#N{vN`Y}$ZQh_jZGhPOO2i`PqKaM;j`$0K#mQwk*4hHfoAkS>RtX)hnq}s z=0go;jeK<UVQqCLvX$x$i)DmhW42`0|~ZJz?rFzwm)60y(ncXM~>pPGuJ4{z1*S%6E{-{ycl z(}5CEUl_K1>}|3?e<^oc(x{l zEj*2pb#SkFibt>Ia;8W~nEnL%`FCGmE1{>#5(wa&L>1!ig-=Q#EqZfcYhtn+NiH80 z9IRet0ujmt1VuTmNmxePQd1AKKgry<)752V)1{w%OHM2-EC8u9E$I3sB<^kErj8$0 z#$7BrlbJG#d{0HrMNMPcJt<8(;gBxMb@q=*PhaT@BV1WoDK9GnDt1TU&bEauV`pha zMFrScAXJ&Pn-M_Azm}XFt9^gIyCicebL=!A%G|E?o#g8VMO}S;JWz11t2+*UcJGt# ze1nw?_@Y3a?iMth4Gj%Jvb_@2s+qkG1t$J{z{h_g&<#ckbgh|--b~dW^z{v9S5pMo z-27o)I6XU~rlRWW@7JpNwzNA{F6vOql~WOD+6%awHD{JL3DeIe1p$Sb8;mws$mxV6 zH#~gra@C!E2Rf9W;hzP{Iq2-VnLFQ6nohh0JGebnt`8J7W84lGpVVfgeN{TYxNy7K zt2WH1Apd19An7Gn+t>yYG`YS0u`n|~P9uu1z5zh5ZwIgfMMU8Amx71}v=tsVuG(y_ z%Mjc1+e9uaPfA;jGcPYM(6{tU>^0y!>_fY)?l2nOOGtQUWo1QEoP|WOr#thMa{0i@ z2$iQVk;TH(e8~JU0^|P}rS?DtA~Famg-?kD>(~U8cQS#~9%m9Ubb@qRQs}3cLQ^|@ z78^{64+6HOEhDTk(4AUsk>L7g3t(gK=jww7q-&(vKYCg7KU!K2oY)SKC0#`Kmt9Na zTir8uzN938vrF`W6;Y8zO>^S{#lO4<&G;Ue&x1lJQ~^T%4u85(u!sW{h}~6|4fc<7$KK#Y_E?JrO0$IX=5*NRJ;N34Z}i1 z4<-DKM*DOgF5Dh4kW=`E!`>73Ddd^TScOX^*zK?|F&CYicav(qW``#R%iG=E4FqRq zYAgu#a|_0w0P2JW7d3To^Ag2E({EUTLJ*?c5s?|Gy3;c5oEJ{QA985B(p0MP%YnEn zn4AHIsDarWI;6RRAL=Kocy7Kl0?9`O8-D0VhrU74dN2|{{r!`6Z-+u+)2Q(cMSTlW z%R6vx-)yFb068B4G#-}M4_tdXthp>+O*XkgV6~0G(5b4bD!MoiDmb98%YEOyGt#a_ z{k+@|u;j(W6&vW}S>lgF5>>o@M&Nw=Q#rQ@vf&X#@=zN8MmWj7enkmMNf^lz*E`34 z15?vRK(hpq;_}jd(&iRH`RbgJ3kbDhb2(oE%N<)_C$@FZS%6WEtVo96&#bk1%a7hs zhp;@;(UDnG^VX3a%qjWz>!`Gw5(+S0`YAFa|8vx6YqoNQ{5lFW%!ktKfYB_B;nQRO zj{lY~&&#XrbW6HvAg?Ui!^(K8|Ae1wWR-Z)8GKxRTAD6+J{T7Bk)D2gp}9Fe9$Oy+ z-1>@$7y%k+c}A0n0_85sArMR)tA&5IT=e8jy-&Ngb`>O@wR zr@)*7KL2AlVh*bWgE7|}G=l(xK}mhoP!{G`8uRWl-RYd6I*r(6`kLuTg8DI4pPun>E$d!+*ao#+1a z0h~~;;=t%0If*}W#f;$Tz7MY$a3!aQ?!i;}SYarvj2NZi71NJd-MA>={mvxybfScY zKQQ`=u9?YBsl7iIkd?et+g9Ypd=kITtb1Siz%qzyN?bI_HZ3nom4zV{3W~%l; z0E$hLYE~3kv$|(QN8X9=X{87baC6LAr?bE`k_Dd*PnHL&-=oqbd3)^+L9MBDh3As$ zwp)z{dPgt@amRzSy8to(m=XJ9zt0?U)^PjcBapPsk>utnw)^Ch(Qm~QldAvo zP_6onWY%^pjI?9c2dw{IZvS4HKnnGI(%}X#&6(gIbCwn1cH{EnzpCsTuX#n4X!dxv zv8vBMzYND6RuT|~7=4P*l?wbbsaulm?7J_rkVihHdF{rezGl_?pVj{0g7=Ss=?25g zUM08%!?a&#m6eDQZpHp=YuC#Wj4B+%y?SvmfN*$Wca_WH$4uVr#W zp}K8`cFp~5@s7a9jcYe%;fDkB>3~hR$ATH3i(uj&?b8FXX(1X}cBq<60~tdFIZ7rt|(TZ4Luf>pZJ_XsWfoEP%y)uVBl*F zHocOBlwt|^DvyF-!K`9Jl3;yY#z)eHoiQX(0%yG!aS3-IZoMfC0X9Miv5{W^mtDb) z8@fg@E<1>OJji?D*b#5pE=V_&2x;9e30G*Fm7D67$F_DFq3=nSBNMC#J*w}O@x%3>vC;mk8x|3!{)_knHl~&(; zJLpnH%J06^c-{IGgf{^FB)Pi$R35na?0Qv?o-957bmF0Y>LJm)GHLV#b!6X3D*%8V zt1AF!WgF3dek*R(aD-fH39JeMtKLM}9Amunbo=OWhD2s<+ASv@F5veB=7!NNWOjoesP;Bkr zSi`S+g4jz(k9zJDz0Psvnc81lKl7*Dmw)TCXP@ zIPt!ik`Uv(qYekIp6mk~Yya`>Z)PqENW564z>JuGq}^2HUT-Z;-5z^EVv#c0v9S zSZOWG%O}qgK%JGEY%XF^k9Se7R2{t^q*56V>cGd++N7Ht>MJ>14LQv{c>Y@`1-P!T zK=~#sGaak_J=G=3d*?US;;KqgG5ONREArkU$Dpa;vgyQVdlI%7qMW$Jup%(hlD!aX z>u`MxkRHSN7UGbyD{mVSGYJCg?g3l;U7lu?lY?7Vx$4%6@mY3D^k)R7g4R#|f@M&* zJG%gwhIC5s;27M$i(MeqU)|XrG$~^A=k@2&%sDLV$ccVM)U1#q|I^KVH?1H;6sJtE z{9xI9^k*EL>e4niNZak5j#85t&9ifBKhe?0tbDlik28|9-6&_;O{;C}lQD(St|Ddg0 zP7XR2!~Q2R?_6^ne_H+yIEA0sdM)wP_c`LTGZ;Go(np|CmK8?hCM12q@9J$K@|0}o zDc%?-o#RRiWO;F~Yr*Cr@6XjsK|N78Yo8USEWUL*E7WTiE|?X}#9lCgnONKEO^pRT z32^-UXrx1?NWx{h0R5AB(5K>#chJA?cgAt~O)s64%Ks%q?gbVZ15vnBvOGwix+>jXti2(l`$mkz2HjCs zB!t1)wOWnRJTX`9>xJJSO0+U8DU$|TWertbrF4v5wha7(6?*=#jUejSJVu?Ogr@+o zzB9qlO1xkIVF#L!;bTw7Xo(pamDIpX?R#GUlqqkRe>s6k1xL^Ptr@ndUg#|U&i5R0uvFsS% zn6Dc{wgUB!Ss9MyO9=XxAJ?d(b-?o~y4_1Fn=M5DB+#Rd;J{4mS1he`GgFi|k^;bo zMSo|;gQwCwJ~cSuDb9kQl`;4FypH*_2i`T@Exg6>Boo8O09(AMsBY3b9s>{tc{v|) z^!UCO*Pq;oP6rrZKu(t~QK=`aVMk`~JAXf{NdY*sGX(br-_f_Ya|`wTp0wKy_q4~Y z*MXt=#n!@mbH-MyAxCa)?dd`^4vZpB#x3#bJnb*~<@ZnN9)CPfAI=)UG}aP2^V z{S}&@-AjRHgA^I(!c8vWp(tCtr)*?Dixf`P@;0Z`jtKVh-L#Y|E@g)zsTXQ6G zV8d>p%xN{>v7!>VRH3Ln+2Fv?L;h?CS+$2eg^n1Q8~^H0PJkybuD-d!M;Z!+-Qb^_ z4$;}LfwEkZ{r2oO2950^``D9US~F&m;;fkBDc9NV;JHVAr-dgDgZc^F;9RgVGX%)Suc&X%pd z68CfL!AJz;ht<$OUU1SLEljG`SBmEm=az)Fwze{XafJqhcmxEV<=+rI*TxIgGv2PU z*8A)XH)J@12->iVUZB)qG*m}z9c4T5K7__MdGFza=@|U#YjucE%fRXcqC6&T)0m6m zTx+k7zX)so+4(6GdirauFX`cdXK$P)H#(!055O9)#!O93{k@HmFTpije~atWt#+v( zqrrv@5@%D!FZF2yVK(Xp!gHWiv3NR6x1W%fgda2M2||+x8@xJI=zEKa#+~oj3-@1T zn6rC{S4%~~5NmK{*~H9jK0_20Kyk4*v>G+PYHJ+ky1Na*^iptXj){p0huKWS*_k7^ z9!RQ^4VLKeGcc5c`_-%KT(uq{`S#!rIDoex`mKImzkcx`C@F}gmleQ0F66} z4_)(&cz~EGVr=sRK>Q6e-4%-We>auKrXiXZWKSTupXhY_vBaTI6BF7=0&X;VHEt{~ z%c-c?gPE6&P8at(+7HVbvqAIV-rvqdvDdSueN@lmjD0{OA|xaX3!W%kD zfadLh$k^z~dAJ^L-nyLZcK;#}%uQ8Rz@?v5DKZ0Clge{j$By)w)%XR|dIpQD z6%5kk)AYh)VVcrM*wK1*3^uYSC;7bo=TvrLtwjAPO6_+Jrlo!y&6;n#+d34KR*k3tuY&v#C_HtJ zqLj5nPY}7r3}+2?D7@didDHGdt6A61cwE61f^{Q-`GVr6n-*_e)D@EtpjW@tWn_4$ zG`#RE0I&is^S(5Ceb0wOb!)?$C7Ujkfu2j&XO(lHsG*?&>_|dF0&fHi1P3?hJ==+F zz!eG8+gjmpM&OG>X6 zXMW_DFb#f)_c2@w$s3yZsw!DI=( zzVEAMT|-0i>aHhyR<>NGSd2Et+#~?0EiL^(wZ67y;mx|0g^VJ^cpj%+^V{_pK7W^p z*aZ$R>P_D2n=duhh5($T$Xl2gu(NOwwaoji1#Wx4qe{tKEG{o+C^jOtmX>Wy$J5qQ zdB?J}1A#mI|H5cPT8Ky#SpD>HGE$dm!uT>*GlIPO6!o0ebUiMm9Z&Bq6c$b0ch;baSNEJvOC1#h)^wJ4x&lvzqKr4Flrfr zm}}UfejC1-d-bNyh$Yz%wQ{A`NsaNXHI=BslL9r&E&arvJhvh`MNF^irFSM;&?Q zXb~f7VD8G2Q|9?Lz`+Mo;^I`r#9or+ft%&NK0dDxK!{1*2f@aHF|X*4$2ECP%x`8c zB(zLDz%+=);A9QUW&Rs5Qhe+SaXISV?Sr-t;7LI`!=!GIwg0mC%L7cw6&Dd9BPTyP zK9)O7y4@H!;_C%k`FL(1aGsu?+RZ!oLcWPcs{yXO$=h4-+c!Eg|B`eZU-ehm^Echp ztMl{oFN4hml}GgVUr8z`ydf{hN^WgcAWctC2i)}mAhjLw)EV&|3)Gl!FqR;d(RH7l z#RXp>xJyn;djKwP&z9R)?x0l+7OFFoAtibUPD*rnd2{G>n;wJV2%^UCEYw31w?EPV z`h#9EBPcJTZK!>!dfxp#$8&zTT*Kb3*x%(-gKQ_OhSTAd7I2@g&ks0-1ae z1hz(VN5Jj-46hgMmF{_7iNB54ANfY`ge7 zQ=Cc&?h&-UI|=vKfr`HgMVQ^F17!24h@&g@Z>>H5$A`FFh*y>o0IuexUo@C)e%npF zivK;uu(uVR!zwUDLg$>2;oabeO+fZHHtggkV!!cB%Zn%%dnBuUr8JFV{cGBERIG}s zcU%6(4;CDH_hxy3wiQ7NY#UDaR_kKKTwhY!P*SsJJ7!@Tq^I`-fSAtD5mXp>5R6I6N zd)ONMklUKI6cCNRpB0oLPkzh?p0q{Dzk|6Lrjfep2S>(@R*XTi1lW82R=3;qZO70> z#dSFN3`dP;f@d7cch1lMNI~GqwV=PN`ASpDBEtdJsp(j2@q6)_{hl-p{=l#98tW0j zpGd0^1{5TpH`Vapf-KWs8~A?x?%ITJHuGYdLjUg~xLa<&n5}G%FrBYG+A}|9`%D`X zs?P$~Y^(q>7admev&g2#4E_g^+ndwe{uSd3b2Nk8!CLMiC04?J@|h=*@&f?&fxGXp z2K0{UlH!JvSX%~v4ZftMZx5#tG4ZHH&SfO0TqZW7yuxv8005} z{c}oy<~-W!Z(>bHH-A7yv3s!24LKN?pa#3?(*|tlDv-SB2_5IemA+lrHKEa66WCr< zSAkS2<&GVm7c%p;Yj8a(S~6$dd~pQ-^ImCRe1xuoH5Nh0*lKr}?tBe??Kz*I1*AW{ zsyYPv^?F8dos0W zmscq34q%}XY-ID2u{VA!_(=LNB^L#7o1dtd18dN`%|r*VpbNR3QCe8i5cK!#1gjD( za#jOrrs^a40>T{#jTP$IUBs)Ha3Ce-|0d05TU6%Acec+QQTfEnz^|;~>F8mUYJRPt z6d5T_26tZ!Zn9(9ANChF92EHjhJu9)uyHp@7$M9!Z&+MED5_}vwPmQa$Y(g$-hcr$ z*w}knV@kTHtvFps2mJ6!}Z@(LQx*GOWAfM*9Ste}6iF|2c&^w082RG);ajA{7KXLbML&IP0aTgLK` zdHYarX>yPRW5Ve>y4hE>%xu689AVeuU2j0QYssob17J_0VwZc?{g7O0;CPeiYCo9< zFEWG?E9KY`_nkZ-afLL~9Y$W&$iM&X8S43Bek*gSHT;mL>Z6s=YnYb87DOH8z zU^72ZclRtF*eAY>tcGR7)?!|6#TDHF7sLL0cDv6<#av!oHU}IySxf4@uF4MvZ(B(m z?7~4!W^urV@}odGO#D0ah6AOW3eDNVc8)tpgIj84D<-eYp6bS4KCEt!e z=d4^acG;Gf^db-PjZfq7!%`CPYH$@B5CXQJiR3>w$2C5*Jrt&d2Y_%Uic+_~7~Gx7 zoj=L=nD24is@VtL-5)tANYS1N%K^1A-%v+AD9g^9LZ!JUz@7NCS8_WT@9ZNNq!&MtDZUR!~+!=^+N%+Y0PIFsYxIEvu@6#%Q z(_V0{U2B?t2dnzJ{>l%8#PkP0iUTg(fJ6sRxBP@4A0EsFo#YWN%>Q_(jkM@jDL~Jf zchRr2OGGYpwBsFyt`kTkU|i*Ny`4nL#Z9P}X1i|v^;xoj6QkgW{Xo1PA$E7y#1U_t z@r<)%px}B>K=>vvzna>&{?&D??L%8PGq*c^w%et*EuGhTXREZX$q<01AtZIhkT05n zFVru&FPq0f0teVth1qtLA_xu|4jKK11qO#P%Y`s6^S=fNRSYZ+IXjPI?Y%Og>=4gK zYdj~Lf6d-wiY9sg`l8Hzy_3)AKfik59`KYJCZMNwtP4O~bKLJ0szZ9j!LMHZiElnX zneom=j41B3OiFQ*I6;@lb{Wg4r@S@wLp;+qHFp#QT zM#?Y*@cBU602sLzfD=itf5*R&Z*xqPG8)<$}NO`uDMJ=_{-(LDRZoA{I5&%ww!1x?>Vn$tUs<07E5u@Y{U*iTB&2G0w+xVtTtmaeF#leBIif#k0+1`%Agwnm_9APYPrUJq0oCz(S^H!~-XSw7 zZK*(hp*vKc(MwD&`%o=?=@-+g2kDs#+-LZB2-X0?;488}-O{$_2#GflzGGji5kGtC z7uD4FGBT5do#ef80Du$?iR}cs>FcIQUa*j;S!|+ze@cio^Qu$^Q~m8T2vS6r{Y3~6 z;RfYea0{&u*jg$J=Q_w299&DQ@>{zW20|#}N(P|Qg7R}U9TyRrG$T|=Y5Gl<1+e8u z#%UYBeEhZ;zrWx7IwpT-oy*1Xqv3H{re5b*{zgo+PhK&>*Np)qb~~ENGJ5mbOPI@> zPTXF<_dPYWrXFh4>P@3ng-1b{pXupuN0|ftD~W7g7Bl{QWukYMa(#1PW8O5?s9H`! z=ksuFOl;B7UIRpoh9_%?gQ`U%Oom5XMA7cv`pSg>GkiAmE>fO83vY{eIhDa|rRh@e z=y&NlKlE>B%u>qffyrJ@F5BjwCMT-d;=JZ-+D?yIH&a2FnKMIPB1qw?CaML z)_MmES9kM{L<^d8*yo*GqDuO{GyXVOyXKdXuAdyO%)ZlbYk889F~V10xHp53?-n6Q zHd3fgdZyUED{u-V4Q^INg>_+V^i1b`BVWL?OK2eBTmq@0@ZLbi-m%wMAGRn&6I+dg zNubrQ269Qt;69sAmQ;W5C@Y8Nor<8SeCzuPcm(Ljc^UwGcq*NKRZnQg!Z z%Z0HU5SE^YkBGN9o33BIvn{e1zq-FsB_S!~dT{P(a>6wc0ZcZ4cJdO~BYci(N2X0Nw_BNg1H5Cp{UV>4;VukSCJ z=h{9SJJ!+m(acmo3^qUHC)~}}E-YzZH99HleYxaxwx1t4VaASk%LNWiiW**C{&}PS zEAnP{Vau)h&{gBIdizgBRrmo;6FAtR9O@OIXyNun*IT#mk6Ar z`7tnjM%2`>Ot+->S2MG*O^=RN zl*oY0Y3vUL%6o!WkR2usHU&iY^?WiEl{s{C z-WjK!chGka8Nl7n_nW$s9|g-_P|&AspBi>3_<~4U_5Z%NR|8o~Yud{G9Hk#6)$X@u zS59r`(hmj&+HQBzuZWiXhQGX{kIle=*D=vSrS2s+$}7r`yKz9?@ru>#%{lOKq+J3d zW>-2xvI_^&bmWbYt3H{Vy8-y3C+Bq?2?2XfsIrz!MZG467O**B>e&XM|Iq1h^t_RG=No}j1o*pRI zfwWV;O}7B3Y5A{=h#7h_>!BD|%;1LWHBKpUO{ z4qP&5m-31VlaZ`HU?jGfSdw#9R6(R#K`BSKO#A@m)#c^oDc~eS>UYO8HZVU;KeCQ` z&;y9LVPj*ftEvK#d#`P#WVdrYv;@E*f>4zQ8-dmu?{jq4dT;LzK+X{njKU_E)e_~z zuzl_q80b}q7ife$Cn7-e|8+nMNJ+-h;WM6fSBt%W|6cgVJ4{?$q*enkFA-=Spy_J^ zlov?D>F7#{i^nsYEKhNK zd^|z309tqLiU(6&eJ0WfuiSD?OgB3qEa>`}h;Y_9;J=B`5#{u9)p}s^q=p-qb!}>5 zl4B+>qlGLg!(5A%a|56XOIsOx7#Qi|x|~_$rE{^p+LC-3C?!cuMZO7vFTSIpzU7D{ zrX-Ne;lENO-c<#_XZ`@7V+IlupI*QuOaTasMiZcTj=sPjL;#CLLrIxmz_kGot`>7) zIL4J$g1$`+oOLJqvw(lL3l$TydySBQplb?cDNj_$#UUKUj7#ueGIeA-v)CN^Ce#*E z!H;bwn6=7^iq#3?nc)gU`KAQ9TKv|%sA(%5FUj+XD-ZfG#mq;iU4~+wh$)sya zM~Q}lf}n$CcW)0+*+>{x>O89ukhhzkN6nz%v1Ucu<#UtDBou&D>qt;es^?u zw5A79q#6^H@f&rG+!v%HbG+@aBxsCMt{x+OZx#qiAPu-m05z7*b{CnZ_>NOv+PI>+ zTC4dUJ~c5Jcyn&4pfWOR2Qv_mAq0ab&6l8}@Hq09_VzfxErKffEgi@Jj3Z+_>zM=b zm_9uEfnHER!18feSQy2?U`A$USRF7Fn3|xTKNwG2N88%k`uc*@A(sDSIN8q+E^0<3 z!kth0gFb{QM)%E_&D0AiKp2(NC%Rd!h;d=hg* z{>`LB92{aKB-A>7*I5QmFEE@{{LaaV$jT~&e@O$cN%S|NmLbosGMUmfHinO2+YAW} zMLrI?1JF6ZRb4OkHMiGO!B9z4aJI;Jt5Cq0TE_nT`MOYsoD47l+3=K-=%=Tq0Ky15 zF9EaMU;dj=Xb?JzMma$HORt?N`AsaH&QrLav^0WHc@P~of`GFCq0|g+8QC?a*Ex5! z)?0Fx2cv!{gaEPsJ#}%g@UUNh5dNQKdj1xiY_-JNoZC#V!(in2lSs;c@F}({8;%m? z=E4;van{QvdZZu;F;;Ffj*U4on&_|hmEtL`C#Rh@UuL+y|5_Ca3JM;av)!qYuC5%w=QJ}jOK7a9um*CK z>+9<&Xtw*aqCH?_dcIDZ4}fLcEsvH3qb~f}+1RR##sUg{sL`sv*>P8K=&1p6uaBJd z&x0>lx2g^g4*_wS#|si4zb!&FBT@9ivy)d{W&G-nAaw#p58^bK#(I5yZ7GyH^Yncz zaB}P4!^5w~(=4%HjNU&ZzUaWvuE>8*zZ!tEi4RW8$w?J6*)<=yYGtE=-2V3V_C;e3 z1h`y$=?GQfRHGmGzhmFVkjo2UVON_>9cTWNJ+nG#B!C%aOoz0`;!1ELHOVJwr6QbK zVh zvb}cc#j8TqX!&<`H!h|k_9LUI>{owSMDWYxt6aRa#5r|puelZP8S~?=w5KM$9JG2} zrWESokq>p-mq%;Lu9n=I|2bXOwS9fQ}|4>E5&FI_WNc7IhcFn()r( zJTfVeX1sb?mHCLMBuV$n3%sWkOr^c&-CQr!UCnwt?@y5QRqaloP9<+J{kqx>KlYCa zG2@}QN?_8SxBv1mper!70raSZ8esvZyA#LZN>g)4FaoDZye2od>f!R|Q?XafGzdxe zL@dV{xmj;U8{4f-wN^_q9L$`3X5NQOxj~{{YBRevTEhc3G4t3zj)jV|feHh`sE4C8 zV&y^HEUFF6V6|PldT5lTeyv*uk{j&Qd z8eb5CJcf$qYIN_azBC_xEBN~UF_!+OR*9?oO70!qkxDr6YJN*gSa<3viI`x?^+Ydv z<8R*cOz-wv6~@)Ph~KVrH8z!?-jyz_{Vghrh=!9MEK^r4rE;#+UJ9aEx%}GZY(^3a z*F}1JM2v7{R{`&)lVMldd4of6X5vo&^<`FAUxkaQV(q0ApSE|}be&kxvbzzOo`%`^ z&?azF=i>9j6+ge&o9yOg-I>a%wsPUF6r__<*os&eW26IOw3*I(&rs5TWm03NkAs4? zDl}c@kr$cis_-_xR(jB^&GvSJ6*|#`!Cw-&?lW)9B{Y2#tl4|g1VZDVuQqy_;e_3P zpyjspohXnr(s}vLFJCh-@`_7Pu=4%H8_l1H29)ma>fHLSK|}YIgDx?}nKSIyNjDW6 zb#)vQTsS)3aU<^8r3VFV{Lc1n5m>u>Y;be$H? zkS~{MyTy-1rrU(7LG<6h zs3;L^xE*c^(l2zK9btGc=<$ua8CE_2c= zu`9lciuwc+ewtbnf}$JQH#s*zVddK`vgD=dpG_yX-$Pf`2pz3UuB|K-m2%rJw46~9 z`u`kJk-5T_f}off)8#d|qK%{)_hijaAMNH<@X^HIqGH`u=HbC=^2)~L2J8OY$o092 zLO>|Eo5fef5sH(S!dez;2MgFO*gY6~bqT}ZxNE1R zcjE$yT$6vQg88IQBmv3o+ZDRApPm-lEfkXyqt(@ZM7+5|vD5IOE9;Kw9pAo&jOb`8 zUFpy7L!xUdnqQA_m7~dC&Cw`yB;TN)Q&1oADK{UPft$Qna21mKm6G(oDVY)aem$5B zPk(o$d?4{B5JN@vUxbapDd~kUIHbB=KPamzaW`jsS8GTquf-j%_nLcCrMUg;=HV5o znN+4rMi^^GKil*w@sO;86~LrCk2PKor97ad81~52_!`b8#mNXZJSq)^$Yk!odv;Gl zjfP9f>+|e}$-j-Qj$=va9(toucxpqgTVOsa`hjE%*HUMVuhWRzAr-!DE-`RP4!(OT zY}sviWgm@vdw=lV1Mje~Z5+WE1_r`lyf5c_DUz`w7)`Se-0qsA0Kgh(qndi zCF_FtidrHGYoIb6NiP3vZmhd9P7{_2!6EON7a>PR$?DUxM?;ld572SuHEtv)$IsA| zXWBet=Uxi@K{cPst&L(YZZ7sJ|BI{UNgLOP)MO>f zToqvOJ=$Y)cyr+HfHTnzTcs^I`j_TEVpszT2ui>1AnUnI?2#V*pNK26-{0Z+nD zkg#y}`AC}oww9NlzfX`oX7^(bi$`d2UC7W=7bVf3+RNq)uIZWfy`yvMPwyd~8B9(w z0ja8k=54V{omt*nD(X~hds}TP6lK)K4 zWyZd~UVx8Xa^zt21zyKGz%gz%T-t}%PS^5i#I3aXMox}v0u^QgJ8cFC5B?dXXzyiA zoK0{mP`%ujWN-B`LHShwbJ~7LlzL`(6820;bo6|{6mxlMDPkjL#+avWF$)jIkc~p{ z0$1?muTTPJQxofHvQ@oLQ<7U{4^fd+BM6tG1~C9{ zF>}>bv~#zrGSs@?llBGb&xp!-ub19X0%gXj0hzdk%0>436XWtgY6iM-M~h|(bd~H+ zS7W3liU#`wKJ2FAAp3emFh};4roJR(ZoAP55M=Fil@3wVc9Y+2t+@wF_f2{_ldOI2 zSVQ{4+4+LA&E|%VE`XK4vI&d?p+z*#|M;c-fkngj)|n;Sw*`-%FKHq~gN)p|g0(55vgw ze7vHtpXD$7vUR(3i89=$tZW~&l_Bc|DkRq0B}zhzSt$yHQG=Z?nETGp^GcsVNrmgn z>DLL3m?G}e2BV6g9AF>W^2Ird(#Z$FO(}0!#-5BcVFCC;tOU$(l%BlaGLkfgcV?+Qj6fm91J6 zFed*^yxj;64*myNTWhSW9BqkC9l!;Mh6#NeJ$E z*aCEsUnoltXh2w4SaEl5XKU!0nKk#_$x_obF?j=Hi;6;KRqvp)WXHulX|n46a3AF% zR26OL8*yHh*U=fNti0Oh3^xTui8x*Pjq*tZCMPEYRV?80Nw=Y)A$fUuEiEm9#7JB# z@{?=l93{yK(vf3%a^OIRnK1HD^P~ED*|?U%j{`vorc^>AqK46mgLTdY6=fh20$po6 z@eQ+j)9=cd~Blh|up(4#>#K{}mq* zhoa1i@V#r%E}ZI2siCE>U=U7gQ%c&}qCg&2lq-F9`G4SKbW`-d(r~}aemGs90$>XV z9{K&E+*|-4u7u}gakO%x7Zy7k8cqSu0!8+kv!ObatNL0u}8FZB@@@!ER~G|Pj`uwc?hLr1`?t7fL;p1s-da* z#V#GS(aGLE;`M6_U)mZ%Lc$nkr89*jd4_s=P%xqfi9>n~eg3RFQtqNzp7&9hnFOx+ zX+cQn1G^Wlzll3UqR=*q_AIRk21Z7^*&eg8TEA+h9$jNj)!QRJqBb)sjb1m7h^eqi ztHslIv{x|XTJg5$wkyI-jg4iKWRk_FP^1H>(E!6QVHT?STjIbH3YTw0S^P|&ZF7a3 zXyBVU^gWG;(kOTS0QT$$W}mMT^kusXC3`DLU*TRYxK%{D1(&;}rUvcd2v~xtH(y`P z$N^c{TKazP?66Q6$UUJkL=dBtvZ}hYPu4K$nXmsV#14$60{h-4q#7HVn7qUVWg1VTOhn8 zCr?1ax;Is|pSQP+sVN(C#ZQ!p32VhG>dNZc8md`WvBem?Q{^bL-qF#)AonWb&70>f z&-G!WqhE&fn=<%Ui+LF4w&n;jnnguw+BPLT3H)ngKwVkiFB^yZt*AtuBi;(qQ~YtDm`@rRaP)R=2D7rT9BhpR^y;`pm$E)3u;xe&{8{0F zOc5V7eRR2bV12plp&~o@EN9M~Nq%{C3$5VEMz2>F5mM)Vdh(36o(O{RndRZan~cx* zwYe`y|30t+Q-!y+S0WtuwDZV*ofP4C*w{0}WhFaAH>xwsBkfXdcd>kU% zHbl4aQQIkJcAXkn8d_WVxVXH1eaA@PRvG7&@dg9mwkb{IaWR(Y0Ks`6ynn=E1(i<@ zCF%IP9h{@xIMrW5{&3(X&k1&og0y9iSix|}h+$0IqOq5<2BX9sZH6t27Bj)13r4Ow z`t94}rEi@j-*}aT+3M4Qy%?;(OZRj1HYCWNh|P>aPu{_Pw3=*qeF+WkQIO89w1h1* z71`wfYH}S5fU5y!9Gukg@%1HT*LbL}-}6>Ws6MdsfzJ%7E94^os`=7JVI;u8ftV-? zAuvN)J12)c=T*af2x+z%1E(0OtL*v64m0y*kg)*>JRjCgx-0G; zB>6LQEAGW5cUsI9cflR)JlS*S&cRtHO|p&c?KaB7&Mu#pU>vG^`}S=mB_&PK3m2|t zB}C>cCkdYY78~6UF*G3YHe5&`LQ0k5HL|PtsNbtxIJcGB*!!2A=SC_HhwMfee4XPT z97D3VmdEOFYVa#^WsM4*w=IQ)ge+G>8ht+fTNp(uBLInkE2F)n654>04FAqnmm29V}SnSD`XcJRYQzN4fR+ES@V%AK~ z@jo?AKBcC)=CxKxJ+TBsq) z8i^Qp)z4R`F2c%nJ>VaaBMDK)q&qs*t5BcO7ACP3(L!ovv@@qV5KQg^p8^x-UW7P) z(#F)dQv+t@QHD2s1=T^jU=OU=??>5d@Yb`g6F`bFn*ZmebV_cHA#2|Jijo08TiP2g zM{;@eGI{^DHutlo-$t;+OmM~`!`)V_$oE+X<>4=Bo&Rii!5`C`!8}%Aes=L9hX=eL z+8ZK@u_JO)_(zqRj{e}Hr10+_L{^}`N10>kM`^bpZ4!Yy$)d={j}#V+89!+l4i3vj zyquO@^~H+tmxeUR@gkpGrzET23?`WWGdx2qJ#~jEgIUO3ss^*(25>VZ>*+jZf@*?m ze*k=Z2LJbu%O*flTyI+H*W@5e^=*&Df**95PDtp@ORGQcpy^YgWv(ffu9YO@_*I62 zO^m*^yBlKRkKDWPRzlHZOJg{s4sMRF7KMatlLe5E?Cx&2i=q zb&CkkFo&xzaZ6Pb?*BU z=(q88{tRU4O5_Z!k$kUCyjCpaWyBgF@jqxch<{L~#>J0~H zy0_p49qzud^`eamHu3y1e@@hyOt!zjzXP{SYIQ$RfMwvEfF(Uy09;1dhxM~NCmfl; zw&Q~aM46eHY25bSK{!0*qC6WLTZ%%g>-S2u(KDw{qt+~~G;tOgw%>ZP?l#+rNTL|y2HR1v*IL_~{2B^cyt z^n|EByvmm~4lUgR&c})($^Fl0DAww3=lIW~66I1$XtOF1Fv z+hAQ@ZGb4%{d5bfCs5i62215mRVXlH$BWi`wkQEkqBgVKsoCA}{6LHtNbUXqvNV6b8O2?W$Fe4%EPdkw7nsvNowHumfM zVc_?@9PrNl3OQ~qa-Yp_V@{zjLBQ|z-K=*`5D1jdu&}gDz{VGUEZzWDDcx^3w0idZ zgJd8x_VACik?yma$`2(2pGpGd;gOPyvgT0cog7PFmhT(|K|Hsdi)SiJFR~I3*t!b2 z1Ks6PB_d@G^?RBW5*QE(B>dVnYBAS6Bde2;NR?rK8(~x~5T?rMp=e3+NNN9V%D2)kAK0!{>>1`hciGt4 zCrDH)3j@Q#B!#LcLVtEW21V$$lFJh&A&H+_L>x~KRbmbOdvz7#pCqGEeO|OhcWgds zxL{K3?iiLaONNDouVzdK&7cep_wyCGlfVexS8m@tBZ+hW`!!;8xFYrBs}a}TY$z_% zb*e(#ZwTre-32C#w%fkVg?x84H8rM~vagIrR!qJ-TJoP&lWt#cV1Ae4K7?OcxU{wW zpkFB@s>3G2C^r8>bG z?n9q&0kfX=Tt)Ig$-r9|{zo2XX4wuZCSB||v`rRWHU!vWHV^BU#XIn9a+fGYzPt6O zrld6H*y>EqL;g;TWQHPO&HY@^`pj}4mJ4LCcy(+^sXrt7IICrgeWOw4a z9iSxI8R~=DkeD=4bdmYzveM%tLib_3==Q9FQ|BF-PoeOQ`$;!~5&{ndym8oT;7+0k zAMVl6(3peq0sePHgxalJmf(Q+Q34A~P;~h^m2!tDOR3$Pq(Gn#;h3kts<6BJl|;Iq zJmQ7mP0{sc$7%lML95oFzO^-Li-$|!K0mDP?d9X-Y;A6qcjWabDgr&(F+EUV6cQYK z;pGjpk@Dzs0#IYlVw^n2pFd$YIR%qZmd0xiOd{<3kDLq@X9O%0($kG#(2(Bb>+35+ z#?Yq}5gfxY| zym%4r`*emvT2St)rVp;CgbbyI#zvpZazMr?8g^tA5ZLx+oQX&f%v@?XsgHMtoO>Lg zp-~kZk*&`oa?~p=?QSl2R1bP7pFsV=eh|oM<|L62oM1}0^`jGrA<4>(<^h_ot|uUG zot2dIett5T2R2Q5z_Rm;RJw&3`*h|?Z&6WENFO|pcm3+=bvG0nO<7k;jc8#9OW0=g zvccgcl<{Le-% zuf;+H5E@Z97>r%|w#cyP;!_cR`dna+aW(V36QgHQipKpsdA1q3H*Cma-zD@PqM`2v z{qsK{JHq z9P-c4??gI<$(VC`KX%Ss>z8-L-TFBtC##uJ9znlGTI?M?tzWCz{~#1uR@8MQ5kYml z@lzbUlu-s@$`6dJQ1jc zRMCZIV!Y*briSX;qP&=n(#PA0K_5lb(!|?xCbJJRQPIn97S!oaV@}cioF`huiN|uo z_7wgdv)dRL%{QH`lvHa(bloox#q}(x>P-aDU^+_u+g$R>BlW%U?RJiQ)<-6ll>@rR7jm~u*%l;8F3K#tUzL;WFv4uA9l1@Hc z@xX(B!eH(kk0q`P(-hvn-}QP{fYXrw zYMzUd<$BtXA37H0)p;|~lQh%m6+Z>&2|wB=c84+DW^mvhs1WTBeD>0LzYtr-|G55i z#g8hxH~foNEFA;izKnV%(w;UC(9$y3M9$G}V-g(4{G>l)uNKu{skqsnk{nvV` zJ?B>q_uxm1qy8msCitmIlG@nY_t;5B&pvVd-6dTy1o>XLxA(g;7tifggR{g8^>~?K zSEFwI=X+CX`O#^nUfvEn62%V;bGru)+ixTVWVKV*&Y%=KW!{$ zs0j09qp-0x1n!CBDJzeG{S(+(DEiTQbEbQw|9xSwe;_LmHJhueBZSjD>oACk>ynf; zIJJkE$KP36(Pd|Sk(2fJ!3Z&vlUtqbO|*^$FsX=2uz>gS<+BQ*q{oM@M3#EPR8|46 z*ox8hV2>Pb&?UQ)RZ%SDx~I6D3)jzu$OTyhQwrJ`+kN{)p_}1$xBz!|IL_WS)zux0 zzjk+UDB9g3IJ3W~2+}=OB_swLLR^(oUUuzFb!ZW$-nd9)H#S--^Mp>v*Eb-r?TT?| zNb2OdA<|w8pCz?%a+&zy5?s^%BzGu5GN1KMWqMPvrRB{0ASsvZMb8)=OH{?p86r;C{OvT2`M6Ug^sYOp$ms(_NlIl>6P1FU^p4~+St&i3m zeM@UmJWzdaf^p`b4=9&d`0VJ7dR^JYcC$&N(V4?6L7nly9y)^r=o%PTfmE*o0}T&sGIp@C0;J{Hv(_V2RfRX=riTT{>n)K>qQkd8!J06or$H-#-t@4-(>Rhwam-U2~Ew+u9#~x zQD1xJ1xx*k{f+wFqDbLw$>n_F8{4~_q@s>-(s*}uM)W#Zm3v8n5W%~@Ye#C=&>W)H znf3a$hol@xLQoK8b@~hkY@Loejl745kc(2|nfwV$*Qx#y!_aDGkK{|YE{|W0I;n{F z>)hn^QnpctV`@g?=Q)&%Zjr%(V}UI$^6TvC>AD|vRpj0AzMmOY(ISbpkWK8<ea6`CAg{gWV2Yf;{p_ zXe=_)m_GM^RMpoHboS}{XvKKY#AyIz&WK0~xDSht$&kTDTuSO*Ym6;=@TOC8Dn`L0 zGo@RWDz1h7EF5DhHSnpdQ{C(A5<4O)DyQ<@g>jGz zPW<<@Mx&pex+&aP3aVvpu5yd(|FG(`jb@Sw9Zc?hgkD6myLBFA{m3wI zu1+`V9DHxS8R~D^msj7?k|INt2ngu*4hPXStT04cP+VMCrKfSQm58utS{naFF)7ho zL+XOa8L0NA8y~yh9KGAqpC*1)XJ*D~+m10$l&(`qrM^s% z3UbgAJHoi|!ZRoSAmU{(KQZYfIO}&-3X8YuKUjTEloAMPQx3^5h+$I6(Z(epm>nOx ziiZA{jHmWP28*Pt$Cod(PP@1(%Eri{6a^!sPs42*e}}@%!$TCTUp=H-wWI7dqb3t& zX+sqnReJ4Qg(bt_=lBQmEgg;tiYY0z<>gI|Yq<=RyIw$jDnM=D*6VjzG9u-_9}+l9RTX>EaODeNrs< zexNX)@co$rf`BhyP6L%ANGBIL`! zDzS3qC`;P~;O_U1h8D!kvr+N7>`Z~KuF=Y4uVv0iQkPv_%AU$8pWzV8I%;@r-9ue8 zK7a;x7xGlDk&aqfUM3Se$Z1^~tT+sx8TLU~elf}MYiRIhVv+Uo>8IVlm--x|_pU}{ zh??z~)R*;HrSS_K9H&eyUrCX?sFs!8vH3za*_pb(I4n=Eqosv`ynSrkvmxiwqro2#cao)KI5YN%X8-hWyP4Dy2tPhll6Wq z^!VVg`uVvN8pa`8GwZn04Km}NFJCGXlHUw`tFJ%9Dyd+nL~|-e+dD?b0Y+7)Y_VAWF3+1vP-{Q^6lr#<#Pyr7-XM4GqHi*wGz0f=H?t@hu8jND z&RiYyeqm9voTM(72=)xoZJVyQpW?18L}su!QpCj|l@yMJtjOmpW3qWUor!Uxx~iV# zB}-p-5923MW{&hRergv{&)7ue8k^(UF2*clw_R_Ccg$<&#P^ZfnPfE75f?Yofrr4& zp@=$A)$GB&_o;=HuALY+e?PuI^h4YCMuN12%R|))d2n^!ZhN9`L) z!_2NRrLi3(b8fg5oXw;lbN}^FbC4`T*o0gJ+n7bziaBj4V(JuuTK6Yfq==kHq))EA z^`gsRi<6d+_cmv{sq^Ex>KW6c0Z{}v9-Nlrzx=~(N=Z>(qTeI#ed6K}^XCloD_~GR z#_^LD;Tu(^i#BLajEk%q6KmF7|5kD9zUrwrN8PSXi~--`d#ggKv;-A6U+!NK87w)) z0Wjv@&C7D=4D=eE6v1X`Q&C0kGKWd?N{-vSxmZZKF%+IjXJYC%Ik*5XAidYF+|6pO zEaQ7bNYQDt?@CP1=rp%(;_K1qFH@_|n@!(RQo9*& zHCr}vdU=9kTBgPy~-#C+{I_05FZcNtIRk>~f-F(uXUK)XluQAyJAud3yv?B=xC-D)w8H9$qN zza0BrdP*tnO!)gboM~>Q*}I*&e}CT{bcaN9m{=mbWPM*8DD`OsaWEUJkJsLcPk@ATt&(M>A(L`G`Qzw(fg z=X{lDMB`>aB@c61OhrzoJI?H>DJ=58YocPqd+Exfj>$D9;j)YspL$Y#s@VNgBJpSb zE^5X{Y8T;ty(=Qv3Y^;`G4B>=j94;Vc0Zgw_DZ8d!z4QVJ?~umshI0j%QB zJ!%s(@=EtU^(;Vh-$fC6yV4k9d>e=#dX85?2izl?L^ehajb${l?!AnjZtt(Mi`wDY zyP;UZRiqG;${2$bsOnW{?38D1;(L)4PL)@$Lj3CM>s|MEfYq=*)n3)xdnY10BLmDs znQ#s*h(zeOM5$};P0dS;zsUn$LJUw?%=)bXG&3>^5H(6KE!}&LCz=aI?Td;ae~rD) zf@QJI8`K#ekwPaCHf;Vk#rqa$D3_@V(F&>9o!#w#PqYvBm&(bt#)t^H>{#peG&Pw3 z-v&O{*xKs0zuqghzox7k<*a;BJ~9-r+>Y9l z$&Af3#JsW4Bw*NC>(;IN`uZ152L=XW1+1jLLi*hpH)2TCK@_x1RGYoyRW9WGdcyqD zijOJXbsxK16ikB}7aAHW6LJw?NgKFyo{jBh1cN|>cml){D*3}gsAo>t zB29fnEstX?Bsd@z8Dmd@+!DjCnkU5FVHF~RtSsq5YP9^Mh$txf!EV$o0^$ZVI+~UC zkzdc;JT@kV!!%aZB{H8s%;^$yn%{2WDd}nNRCf@d(V048lq66gBw`M(8^aifJ=_+f z)sU7J`s!6Me>Wtw>TW<-$JWM%0V^GX7XktfP;k4_-o|2Pz`Vl7&aPqyUmz%zUs5|6 zl%jccY6p?Rk;JtIu%akJyRR-+jRDTnhlzH=WGS%|Y?1I{ByzoJvT*E;S~RF$N2Ehj$3g9hAUp zV@d<$2w&@|Ec|}5=}?q znXeOC1QKS0RvT0)jK+9>x4v8HR`YFb@vODt^?3nDNU6VO{wFm}!hee_p}cRdYkA@VsamI_#rQ&tUo=PZ5C zWRul3XiYQv?}DV_x^G6l-H<+&`y90n@ZXS(I#lmJ15%*!a@OtfD^_s~l?GM!G<&G^ zpx~OaYV0C$)t@y@#XU!{E9SPK5GTET%XZ9mPfq9D)G8;*0Tu3_rHT=JJl>5Ke#rTZ zdg2D+hGuSaaTlj+`mSBH$=^vKwbj ze8*AcP|pkxc50+>Nn?rLnr7MGqbC(NNny`x z8KrD}{!PpSaX>&Hy{}mgRm0g2O>{d;} z_vRO4MEMO?>o+M|Mj|WpOr(^7tQ_pkXb>?t9@n_Ph!_Mk7V&z&kt*tN&cucG7 zifES~UXq*VqM{HPb=fi87%Ynn-};f@LUjm9od+%`%zsBSBd}Ywp@n|v^=8YVeR~cL z?+`X(!|54=xxKm^-L-hO4|lBj<_FHuE@&@nIcm@x8zFUbS)<}^xGg0v_O$Tl z5mUps!n+`SA}QBi@5{%+I7e$gecO0IG@_|u$q*jXL-Tiq(`J6OUlt=WsJM8|mU54- z%QjeN?6c>fSQ6g-DzIuQ4-bsN*tjD0dNuvn2j6cs=*)3%c`AOMm*UxaQ@%H5@IZ6& z#k#!!BfWo2r^2!JvlHU#Ti4LeBj$|+U#5?&5vLf`z%Dc8S*Uy=t}iyaNB*~6WsHuB z&GYKU=5pa+ZYEF8$SfyERr8U;0qL@lN(BhWT0zY3t>9Z&YXwIp8TGb$X>p0S@>Z|* z+VyDPHN0WIG-VYb9b?`gsJmo6nt8o!8Uu#PQLJwtnhwV3!x7srONPS#YLj%MM$y~{$A zwd-?WR_2_0vG9J4aLTJTmyO%JPmW-ZEMDsGt~Ww@3=wf_2?>dO+=cE7`9&EgP?7fJ z{p@90#IzQe*GxwSY!3zAXy`C8fU#Hq-yW+p`<6agkyytDOzAw*tbNyGKf{3Nwm48M ziTOS)T*Z9 z1%zDu0N7A_se>|O>hSsVneJoB?m=)J^gI-UjgOCid|$B*>VK5Hjvx!cakO_@Al#jOX4(?HEw4cE48X!0dl)CI^d#%=iN;5EQlu&_j-7Qu9XAyFT|&LcIx=SSJ6 z%lYEr?7L?^5-&qUw_;QE!aT_!h?4SBoM(Ev1rlV;C!x_2{#GAkHs7xv^oAfHT#R6w zbx8#Y#Ni{|0$963!c;-KM+$ErPa=e;*P;arg&yDYyVPCbwmH!xR%XNcKKIf>TRi*1 z0zxB4%2rDg{a{%-BA1eMQofRWTSL>?-91JrF-llu5>xr1FpKdunTGa(BD_`rn}ili z>9wC$r>w1^SmLctwie}e({iW8Jk`hYk>Z| zQVG3QgF?>2Fyy^mi+NTo*AbR)rK3C0kX{r!60oA|p1Rt^sRIb{3(Y#Bpo*AA zBpUf!a*P=e6O%NAbu!NH3NDkrhoZeHg*KU+!*52%#)3kK&Wqg{WM`Elv}<67sPP3! zG75@d^*r{QdV2G*!rL`H+3csO3F{hcRaJe~o^`z~X1{H-sju4}ER1FmZW=X3??d1A(QV!>U@!ZNv{^??W#)S1(XOGLH@ZG44EMX3RG8LNC8_6jPkfIfkim+jb zuLi(7`%a>*yu4rXwv+~)6n`*TXtYaQ!su5(yE>c#sZ*Tpuw`#v3{W2JJWttO!%S$= zU-0hq87+3I-sS5VB@7J5MFo2d3}uH$kCKX=_O=j4q4BPLe5Pt{+r%8&r@8pdIZP?Z zdCTnaDKtw6(`g6o4+g!dXv6?@PM!P62hCItmyo;9aQwU_^I`s1a5uOm4h)N zVhswUZ)2lM6J4BUqlGF+>uiJxW{B-Gz=Bc4M0&TN2Rtl{ch=f-%C1~wWK2k7IuEi2 zXlw^lXL6HOM^S>O$9~Qw$rWkCshQGJL+(QT<~#oWA|4h%H(Ofb4GRlcK_#}srPeez zGAg&39i`;E|5hiUzv7UTH2i6$N`)&FR}f|85Vf3(Fb|-9&+Dz+Jv1;}rajIa$aq1N zii<5+3vl=GtjfybpTK+aTeqD8H%KS!&Av-JH)DUH>pvR{d+aP0s(C5bTN@J`tJNRR zF*Yw?U8B&e#*@u0EbJ?Fh_@$cAOi8!cyFq2HUza=NNe!emNs<|{-#hT_A!CO;Q7sK z!P5Eq`XnUmLxbqjQldK*mdwmTyPJ!TOb6YQqEs`>(`2A>*YJ&Ot=+;h7Yw?@+7&!m zT00Ksr4v|I0G^KbR#-E4eU2a79C4$cyS;fm?asIKEId3nL~As<=?RTQ?#zB8Y7&1lQ;YWSiik*@jfrn?aN-J%&%bim z_1;YG;!QFR8iQPS%@xz+b+A22601-cJOgOvab5QYPJm10b~$%Ean0!H_|B5l2IV}wyNAO*uH?8;K=<5k zp<1VGX8<5uf@{zH(~J2Rf$SZeQ&S_|5{*O6+t|=)<-gz*$L-_K>W&2Nh5dV+ubr8( z_ZMvG(9j5I_;UIJv%DzBam@iI8MvhM{$3?8=>0v{P~i04h<$>>X%SA3x4eiEA}u4+ z$BdZxAq52q#4H-SZ4@n6a4lvU!yf;P0B(xwou#@10Zy^?x;KSCD2)~Ctdd%SLuly4 z-lZ`;E$v^iKn82h9=RfL@asl#^YXr`W$susAKshYw79RXR#0lgdV7#z;NkVJ7Xz;D z*XVHFoQlYM|EL?T8N1~kAAg>laiCJg=I57kf8zPnG7Gm&%Hz>(gr%trjM%g50((Cg zDJ%c4Q!PZwwh&C4z}r}#h%RvJ>nmvtqo|BWKGnrhQJBWJ;S_rMG18wkup}E!6477H zJ=8~sTj}fTYL1CLQUU!&=0TG#^sR>M<^ED-cBf8K@9NRm}9}Mr4b}gSvPF}wy>rc-2C~eJ6_Mfv1Hp%EHT~ALoH}}aJ0=L77 z%2d3yDc#xGlAGs{BZ7F2l$75DO{ln*vP{$k$pt^uI8g0uY#JXwobi7-NQ*Ek!{9bF zG3kVLTfQLpHrJ@rj$Vn^=>GV(Hl9lxkbl=Qi%3T^-ow}*W5U!IsSjmynn4g%*}kTD?5^u9F@l3)N~Pk zY#q)($3KeG71q)X;!RQ6{%do_JbU&`t?k-4rL-I8ES^awh4>M!f0_E*G2i##=fDfd1cqfZ=isz)!U(OV6?lfQfWu-rc9J zWkxxGfgVBQs)~yEIG^b9-cL{99--_gC@97dbAbQENx>%lKmXqY8W#68wl7=EyvQHP NNFuJky?XE2{{vtpNrV6Z diff --git a/diagrams/tasks.puml b/diagrams/tasks.puml index 4dcef5a..51af6da 100644 --- a/diagrams/tasks.puml +++ b/diagrams/tasks.puml @@ -2,14 +2,18 @@ skinparam shadowing false title Tasks and data flow -rectangle "relay loop (main task)" as loop { +rectangle "relay loop (one per server)" as loop { card "public socket\nrecv_from" as recv card "filter\n(commands, query rate)" as filter } -rectangle "shared state (Mutex)" as shared { +rectangle "server state (Mutex, one per server)" as shared { card "sessions:\nHashMap" as map - card "bans\n(bans.json)" as bans + card "bans\n(bans-.json)" as bans +} + +rectangle "registry (Mutex)" as registry { + card "servers by public port,\ntheir key's hash\n(servers.json)" as servers } rectangle "session task (one per client)" as st { @@ -17,12 +21,13 @@ rectangle "session task (one per client)" as st { card "upstream socket\n(connected to ET)" as up } -rectangle "heartbeat task" as hb { +rectangle "heartbeat task (one per server)" as hb { card "interval 5 min" as tick card "probe socket" as probe } rectangle "control API task (axum)" as ctl { + card "PUT/GET/DELETE /server" as pairing card "GET /sessions\nGET/PUT/DELETE /bans" as routes } @@ -36,4 +41,7 @@ tick --> probe : getinfo tick --> recv : heartbeat via public socket routes --> map : list ports,\ndrop a banned IP's sessions routes --> bans : set / lift +routes --> servers : key -> server +pairing --> servers : register / leave +servers --> loop : start / stop\n(with its heartbeat) @enduml diff --git a/etrelay.service b/etrelay.service index c04f193..e449d2b 100644 --- a/etrelay.service +++ b/etrelay.service @@ -9,12 +9,14 @@ Restart=always RestartSec=2 # One socket per client session, at most 2048 (MAX_SESSIONS): room above it. LimitNOFILE=4096 -# ETRELAY_CONTROL_TOKEN=... for --control; read by systemd, root only (0600). +# ETRELAY_CONTROL_TOKEN=... for --control (what servers register with); read by systemd, +# root only (0600). EnvironmentFile=-/etc/etrelay/env -# /var/lib/etrelay: the bans file, kept across restarts and upgrades. +# /var/lib/etrelay: the registered servers and their bans, kept across restarts and +# upgrades. StateDirectory=etrelay -# Port 27960 > 1024: no privilege needed. +# Ports 27960 and up > 1024: no privilege needed. DynamicUser=yes NoNewPrivileges=yes ProtectSystem=strict diff --git a/src/control.rs b/src/control.rs index 3d75745..c1444b2 100644 --- a/src/control.rs +++ b/src/control.rs @@ -1,14 +1,20 @@ -//! Control API for etadm: which real address is behind a session port (the ET server -//! sees players as :), and bans. Listens on -//! the tunnel address only, bearer token on top. -use crate::Shared; +//! Control API for admin tools (etadm), on the tunnel address only. +//! +//! An admin tool registers the ET server it runs (PUT /server, with the relay's token and +//! the proof it runs that server, see proof). Everything else carries the key it +//! registered with, which names its server: which real address is behind a session port +//! (the ET server sees players as :), the +//! bans, leaving the relay. use crate::bans::{self, Ban}; -use axum::extract::{Path, Request, State}; +use crate::proof::{self, KeyHash, MIN_KEY}; +use crate::registry::{Refused, Registration, Shared}; +use crate::server::Server; +use axum::extract::{ConnectInfo, Path, Request, State}; use axum::http::{StatusCode, header}; use axum::middleware::{self, Next}; use axum::response::{IntoResponse, Response}; -use axum::routing::get; -use axum::{Json, Router}; +use axum::routing::{get, put}; +use axum::{Extension, Json, Router}; use serde::{Deserialize, Serialize}; use std::net::{IpAddr, SocketAddr}; use std::sync::Arc; @@ -18,19 +24,28 @@ use tokio::net::TcpListener; /// The tunnel may come up after etrelay: binding is retried rather than given up. const BIND_RETRY: Duration = Duration::from_secs(10); -pub async fn serve(addr: SocketAddr, token: String, shared: Shared) { - let app = Router::new() +pub async fn serve(addr: SocketAddr, token: String, registry: Shared) { + let registered = Router::new() + .route("/server", get(server).delete(unregister)) .route("/sessions", get(sessions)) .route("/bans", get(list_bans)) - .route("/bans/{ip}", axum::routing::put(set_ban).delete(lift_ban)) - .route_layer(middleware::from_fn_with_state(Arc::new(token), auth)) - .with_state(shared); + .route("/bans/{ip}", put(set_ban).delete(lift_ban)) + .route_layer(middleware::from_fn_with_state(registry.clone(), by_key)); + + let app = Router::new() + .route("/server", put(register)) + .route_layer(middleware::from_fn_with_state(Arc::new(token), by_token)) + .merge(registered) + .with_state(registry); loop { match TcpListener::bind(addr).await { Ok(listener) => { println!("control API on {addr}"); - if let Err(e) = axum::serve(listener, app.clone()).await { + let service = app + .clone() + .into_make_service_with_connect_info::(); + if let Err(e) = axum::serve(listener, service).await { eprintln!("control API {addr}: {e}"); } } @@ -41,26 +56,134 @@ pub async fn serve(addr: SocketAddr, token: String, shared: Shared) { } } -async fn auth(State(token): State>, req: Request, next: Next) -> Response { - let given = req - .headers() +fn bearer(req: &Request) -> &str { + req.headers() .get(header::AUTHORIZATION) .and_then(|v| v.to_str().ok()) .and_then(|v| v.strip_prefix("Bearer ")) - .unwrap_or(""); + .unwrap_or("") +} - if !same(given.as_bytes(), token.as_bytes()) { - return error(StatusCode::UNAUTHORIZED, "authentication required"); +/// Registering: the relay's token. +async fn by_token(State(token): State>, req: Request, next: Next) -> Response { + if !same(bearer(&req).as_bytes(), token.as_bytes()) { + return error(StatusCode::UNAUTHORIZED, "the relay's token is required"); } next.run(req).await } +/// Everything else: the key of a registered server, handed to the handler. +async fn by_key(State(registry): State, mut req: Request, next: Next) -> Response { + let key = KeyHash::of(bearer(&req)); + let server = registry.lock().expect("registry").find(&key); + + let Some(server) = server else { + return error( + StatusCode::UNAUTHORIZED, + "no server registered with this key", + ); + }; + + req.extensions_mut().insert(server); + next.run(req).await +} + /// Constant time: the time taken doesn't tell how much of the token was right. fn same(a: &[u8], b: &[u8]) -> bool { a.len() == b.len() && a.iter().zip(b).fold(0u8, |acc, (x, y)| acc | (x ^ y)) == 0 } +#[derive(Deserialize)] +struct RegisterRequest { + /// Shown in the journal, to tell servers apart. + #[serde(default)] + name: String, + /// Public port asked for. + port: u16, + /// The ET server as seen from here; its address defaults to the caller's (the admin + /// tool runs next to its server). + upstream_ip: Option, + upstream_port: u16, + /// The key every later call carries, picked by the caller. + key: String, +} + +/// Registers the caller's ET server on a public port, once the server shows the key's +/// fingerprint: 409 when another server holds the port, 403 without the proof. +async fn register( + State(registry): State, + ConnectInfo(peer): ConnectInfo, + Json(req): Json, +) -> Response { + if req.key.len() < MIN_KEY { + return error( + StatusCode::BAD_REQUEST, + &format!("the key must hold at least {MIN_KEY} characters"), + ); + } + + let upstream = SocketAddr::new(req.upstream_ip.unwrap_or(peer.ip()), req.upstream_port); + let key = KeyHash::of(&req.key); + + let allowed = registry.lock().expect("registry").check(req.port, upstream); + if let Err(e) = allowed { + return refused(e); + } + + if let Err(e) = proof::shown(upstream, &key).await { + return error(StatusCode::FORBIDDEN, &e.to_string()); + } + + let registration = Registration { + port: req.port, + upstream, + name: req.name, + key, + }; + + let registered = registry.lock().expect("registry").register(registration); + match registered { + Ok(view) => Json(view).into_response(), + Err(e) => refused(e), + } +} + +fn refused(e: Refused) -> Response { + let code = match e { + Refused::Port(..) => StatusCode::BAD_REQUEST, + Refused::Taken(_) | Refused::Static(_) => StatusCode::CONFLICT, + Refused::Failed(_) => StatusCode::INTERNAL_SERVER_ERROR, + }; + + error(code, &e.to_string()) +} + +async fn server( + State(registry): State, + Extension(server): Extension>, +) -> Response { + let view = registry.lock().expect("registry").view(server.port); + + match view { + Some(view) => Json(view).into_response(), + None => error(StatusCode::NOT_FOUND, "not registered anymore"), + } +} + +/// Leaves the relay: the port is free, the masters are told, the bans forgotten. +async fn unregister( + State(registry): State, + Extension(server): Extension>, +) -> Response { + let left = registry.lock().expect("registry").unregister(server.port); + + match left { + Ok(()) => StatusCode::NO_CONTENT.into_response(), + Err(e) => error(StatusCode::INTERNAL_SERVER_ERROR, &format!("{e:#}")), + } +} + #[derive(Serialize)] struct SessionView { /// The player's real address. @@ -71,13 +194,13 @@ struct SessionView { since: u64, } -async fn sessions(State(shared): State) -> Json> { - let relay = shared.lock().expect("relay state"); +async fn sessions(Extension(server): Extension>) -> Json> { + let state = server.state(); - let mut list: Vec<_> = relay + let mut list: Vec<_> = state .sessions .iter() - .filter(|(_, s)| !s.tx.is_closed()) + .filter(|(_, s)| s.open()) .map(|(client, s)| SessionView { client: *client, port: s.port, @@ -96,10 +219,10 @@ struct BanView { ban: Ban, } -async fn list_bans(State(shared): State) -> Response { - let mut relay = shared.lock().expect("relay state"); +async fn list_bans(Extension(server): Extension>) -> Response { + let mut state = server.state(); - match relay.bans.list(bans::now()) { + match state.bans.list(bans::now()) { Ok(list) => Json( list.into_iter() .map(|(ip, ban)| BanView { ip, ban }) @@ -121,7 +244,7 @@ struct BanRequest { /// Bans ip and cuts its sessions at once: its packets stop here, the server times the /// player out. async fn set_ban( - State(shared): State, + Extension(server): Extension>, Path(ip): Path, Json(req): Json, ) -> Response { @@ -134,23 +257,26 @@ async fn set_ban( .map(|m| now.saturating_add(m.saturating_mul(60))), }; - let mut relay = shared.lock().expect("relay state"); - if let Err(e) = relay.bans.set(ip, ban.clone()) { + let mut state = server.state(); + if let Err(e) = state.bans.set(ip, ban.clone()) { return error(StatusCode::INTERNAL_SERVER_ERROR, &format!("{e:#}")); } - relay.sessions.retain(|client, _| client.ip() != ip); - println!("ban {ip} until {:?}: {}", ban.until, ban.reason); + state.sessions.retain(|client, _| client.ip() != ip); + println!( + "port {}: ban {ip} until {:?}: {}", + server.port, ban.until, ban.reason + ); Json(BanView { ip, ban }).into_response() } -async fn lift_ban(State(shared): State, Path(ip): Path) -> Response { - let mut relay = shared.lock().expect("relay state"); +async fn lift_ban(Extension(server): Extension>, Path(ip): Path) -> Response { + let mut state = server.state(); - match relay.bans.remove(ip) { + match state.bans.remove(ip) { Ok(true) => { - println!("ban {ip} lifted"); + println!("port {}: ban {ip} lifted", server.port); StatusCode::NO_CONTENT.into_response() } Ok(false) => error(StatusCode::NOT_FOUND, "not banned"), diff --git a/src/et.rs b/src/et.rs new file mode 100644 index 0000000..f79c9f9 --- /dev/null +++ b/src/et.rs @@ -0,0 +1,119 @@ +//! What etrelay itself says to an ET server: is it up (`getinfo`), what does it show +//! (`getstatus`). Everything else is forwarded as is. +use anyhow::Result; +use std::collections::HashMap; +use std::net::SocketAddr; +use std::time::Duration; +use tokio::net::UdpSocket; +use tokio::time::timeout; + +/// Connectionless packet prefix (Quake 3 / ET protocol). +pub const OOB: &[u8] = b"\xff\xff\xff\xff"; +pub const MAX_PACKET: usize = 65_535; +const PROBE_TIMEOUT: Duration = Duration::from_secs(3); +const PROBE_ATTEMPTS: usize = 3; +/// Longest connectionless command name shown in debug logs. +const MAX_COMMAND: usize = 32; + +/// Ephemeral socket connected to `upstream`. +pub async fn connect(upstream: SocketAddr) -> Result { + let any: SocketAddr = if upstream.is_ipv4() { + "0.0.0.0:0".parse()? + } else { + "[::]:0".parse()? + }; + + let sock = UdpSocket::bind(any).await?; + sock.connect(upstream).await?; + Ok(sock) +} + +/// True if the ET server answers `getinfo`. +pub async fn probe(upstream: SocketAddr) -> bool { + ask(upstream, b"getinfo etrelay", b"infoResponse") + .await + .is_some() +} + +/// The cvars the ET server shows everyone (`getstatus`'s serverinfo), names lowercased; +/// None when it doesn't answer. +pub async fn serverinfo(upstream: SocketAddr) -> Option> { + let answer = ask(upstream, b"getstatus", b"statusResponse").await?; + + Some(parse_serverinfo(&answer)) +} + +/// Sends `query`, returns the answer when it is a `response` packet. A lost UDP packet +/// must not count as a server down: PROBE_ATTEMPTS tries. +async fn ask(upstream: SocketAddr, query: &[u8], response: &[u8]) -> Option> { + for _ in 0..PROBE_ATTEMPTS { + let attempt = async { + let sock = connect(upstream).await?; + sock.send(&[OOB, query].concat()).await?; + + let mut buf = vec![0u8; MAX_PACKET]; + let n = sock.recv(&mut buf).await?; + buf.truncate(n); + Ok::<_, anyhow::Error>(buf) + }; + + if let Ok(Ok(answer)) = timeout(PROBE_TIMEOUT, attempt).await + && answer.starts_with(&[OOB, response].concat()) + { + return Some(answer); + } + } + + None +} + +/// `statusResponse\n\key\value\key\value...\n`. +fn parse_serverinfo(answer: &[u8]) -> HashMap { + let text = String::from_utf8_lossy(answer); + let line = text.lines().nth(1).unwrap_or(""); + let mut parts = line.split('\\').skip(1); + let mut cvars = HashMap::new(); + + while let (Some(key), Some(value)) = (parts.next(), parts.next()) { + cvars.insert(key.to_ascii_lowercase(), value.to_string()); + } + + cvars +} + +/// Command name of a connectionless packet (`getinfo`, `infoResponse`, `connect`...), +/// None for in-game packets. Arguments are left out: `connect` carries the userinfo. +pub fn command(packet: &[u8]) -> Option { + let body = packet.strip_prefix(OOB)?; + let end = body + .iter() + .position(|b| b.is_ascii_whitespace() || *b == b'\\') + .unwrap_or(body.len()) + .min(MAX_COMMAND); + + Some(String::from_utf8_lossy(&body[..end]).into_owned()) +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn reads_the_serverinfo_line() { + let answer = b"\xff\xff\xff\xffstatusResponse\n\\sv_hostname\\^1Big\\mapname\\oasis\\ETRelay_Proof\\abc\n12 48 \"joe\"\n"; + let cvars = parse_serverinfo(answer); + + assert_eq!(cvars["mapname"], "oasis"); + assert_eq!(cvars["etrelay_proof"], "abc"); + assert_eq!(cvars.len(), 3); + } + + #[test] + fn names_connectionless_commands_only() { + assert_eq!( + command(b"\xff\xff\xff\xffconnect \"\\name\\joe\"").as_deref(), + Some("connect") + ); + assert_eq!(command(b"\x01\x02ingame"), None); + } +} diff --git a/src/filter.rs b/src/filter.rs index a2eaabc..7efa5b6 100644 --- a/src/filter.rs +++ b/src/filter.rs @@ -1,6 +1,6 @@ //! Which client packets reach the ET server: in-game packets always, connectionless ones //! only when a client or a master would send them, queries rate limited per source IP. -use crate::OOB; +use crate::et::OOB; use std::collections::HashMap; use std::net::IpAddr; use std::time::Duration; diff --git a/src/main.rs b/src/main.rs index a7d9c17..329cd32 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,72 +1,59 @@ -//! UDP relay for a Wolfenstein: Enemy Territory server reachable only through a tunnel. -//! -//! - Proxies every client (players, server browsers, masters) to the ET server, one -//! upstream socket per client address, like nginx `stream`. The ET server sees each -//! client as :: the control API maps that -//! port back to the real address. -//! - Sends master heartbeats from the public socket, so masters challenge (`getinfo`) the -//! public address: the challenge goes through the relay like any client packet, the ET -//! server answers it, and the master lists the public address. -//! - Drops what a client has no business sending (see filter) and banned addresses. -mod bans; -mod control; -mod filter; - +//! UDP relay for Wolfenstein: Enemy Territory servers reachable only through a tunnel: +//! each server gets a public port here (see server), registered by its admin tool through +//! the control API (see control, registry) or given on the command line. use anyhow::{Context, Result, bail}; -use bans::Bans; use clap::Parser; -use filter::Filter; -use std::collections::HashMap; use std::net::SocketAddr; +use std::ops::RangeInclusive; use std::path::PathBuf; use std::sync::atomic::{AtomicBool, Ordering}; use std::sync::{Arc, Mutex}; -use std::time::Duration; -use tokio::net::{UdpSocket, lookup_host}; -use tokio::sync::mpsc::{self, error::TrySendError}; -use tokio::time::{Instant, interval, sleep_until, timeout}; - -/// Connectionless packet prefix (Quake 3 / ET protocol). -const OOB: &[u8] = b"\xff\xff\xff\xff"; -/// Same heartbeat period as the ET server itself. -const HEARTBEAT_INTERVAL: Duration = Duration::from_secs(300); -const HEARTBEAT_ALIVE: &str = "EnemyTerritory-1"; -const HEARTBEAT_DEAD: &str = "ETFlatline-1"; -const PROBE_TIMEOUT: Duration = Duration::from_secs(3); -const PROBE_ATTEMPTS: usize = 3; -const SESSION_TIMEOUT: Duration = Duration::from_secs(120); -const SESSION_QUEUE: usize = 64; -const MAX_PACKET: usize = 65_535; -/// Longest connectionless command name shown in debug logs. -const MAX_COMMAND: usize = 32; -/// One upstream socket per session: spoofed sources must not use up the file -/// descriptors (etrelay.service raises LimitNOFILE above it). -const MAX_SESSIONS: usize = 2_048; -/// Shortest control token accepted. -const MIN_TOKEN: usize = 32; +use tokio::sync::Semaphore; static DEBUG: AtomicBool = AtomicBool::new(false); -/// println! only with --debug. +/// println! only with --debug. Before the modules: they use it. macro_rules! debug { ($($arg:tt)*) => { - if DEBUG.load(Ordering::Relaxed) { + if $crate::DEBUG.load(std::sync::atomic::Ordering::Relaxed) { println!($($arg)*); } }; } -/// UDP relay + master heartbeat for a Wolfenstein: Enemy Territory server. +mod bans; +mod control; +mod et; +mod filter; +mod proof; +mod registry; +mod server; + +use registry::Registry; +use server::Common; + +/// One upstream socket per session, all servers together: spoofed sources must not use +/// up the file descriptors (etrelay.service raises LimitNOFILE above it). +const MAX_SESSIONS: usize = 2_048; +/// Shortest control token accepted. +const MIN_TOKEN: usize = 32; + +/// UDP relay + master heartbeat for Wolfenstein: Enemy Territory servers. #[derive(Parser)] #[command(version, name = "etrelay")] struct Cli { - /// ET server address, e.g. 10.0.0.2:27960 - upstream: SocketAddr, + /// An ET server relayed on --listen from the start, e.g. 10.0.0.2:27960: no control + /// API reaches it. Without it, servers register through --control + upstream: Option, - /// Public address to listen on + /// Public address: UPSTREAM is relayed on it, registered servers on its IP #[arg(long, default_value = "0.0.0.0:27960")] listen: SocketAddr, + /// Public ports a server can register on, e.g. 27960-27969 (or one port) + #[arg(long, default_value = "27960-27969", value_parser = parse_ports)] + ports: RangeInclusive, + /// Master server host:port (repeatable) #[arg( long = "master", @@ -74,12 +61,12 @@ struct Cli { )] masters: Vec, - /// Control API address (session ports, bans), on the tunnel only, e.g. 10.66.0.1:8090; - /// bearer token in $ETRELAY_CONTROL_TOKEN + /// Control API address (registering, session ports, bans), on the tunnel only, e.g. + /// 10.66.0.1:8090; the token to register with in $ETRELAY_CONTROL_TOKEN #[arg(long)] control: Option, - /// Folder of the bans file (bans.json) + /// Folder of the registered servers (servers.json) and of the bans #[arg(long, default_value = "/var/lib/etrelay")] state_dir: PathBuf, @@ -88,268 +75,76 @@ struct Cli { debug: bool, } -/// What the relay loop and the control API share. -pub struct Relay { - pub sessions: HashMap, - pub bans: Bans, -} +fn parse_ports(text: &str) -> Result, String> { + let (first, last) = text.split_once('-').unwrap_or((text, text)); + let port = |p: &str| p.trim().parse::().map_err(|e| format!("{p}: {e}")); + let (first, last) = (port(first)?, port(last)?); -pub struct Session { - /// Closed once the session ended; dropping it ends the session. - pub tx: mpsc::Sender>, - /// Source port of the upstream socket: the port the ET server sees. - pub port: u16, - /// Unix seconds. - pub since: u64, -} + if first == 0 || first > last { + return Err(format!("{text}: want -")); + } -pub type Shared = Arc>; + Ok(first..=last) +} #[tokio::main(flavor = "current_thread")] async fn main() -> Result<()> { let cli = Cli::parse(); DEBUG.store(cli.debug, Ordering::Relaxed); - let bans = Bans::load(cli.state_dir.join("bans.json"))?; - let shared: Shared = Arc::new(Mutex::new(Relay { - sessions: HashMap::new(), - bans, - })); - - if let Some(addr) = cli.control { - let token = std::env::var("ETRELAY_CONTROL_TOKEN").unwrap_or_default(); - if token.len() < MIN_TOKEN { - bail!("--control: $ETRELAY_CONTROL_TOKEN must hold at least {MIN_TOKEN} characters"); - } - - tokio::spawn(control::serve(addr, token, shared.clone())); + if cli.upstream.is_none() && cli.control.is_none() { + bail!( + "nothing to relay: give an ET server (UPSTREAM) or --control for servers to register" + ); } - let public = UdpSocket::bind(cli.listen) - .await - .with_context(|| format!("bind {}", cli.listen))?; - let public = Arc::new(public); + let common = Common { + masters: Arc::new(cli.masters), + sessions: Arc::new(Semaphore::new(MAX_SESSIONS)), + }; + println!("etrelay: masters: {}", common.masters.join(", ")); - println!( - "etrelay: {} -> {}, masters: {}", - cli.listen, - cli.upstream, - cli.masters.join(", ") - ); + let mut registry = Registry::new(cli.state_dir, cli.listen.ip(), cli.ports.clone(), common); - tokio::spawn(heartbeat(public.clone(), cli.upstream, cli.masters)); - relay(public, cli.upstream, shared).await -} - -/// Dispatches client packets to their session, opening one on first packet. -async fn relay(public: Arc, upstream: SocketAddr, shared: Shared) -> Result<()> { - let mut filter = Filter::new(Instant::now()); - let mut buf = vec![0u8; MAX_PACKET]; - - loop { - let (n, client) = public.recv_from(&mut buf).await.context("recv")?; - - if let Some(reason) = filter.refuse(&buf[..n], client.ip(), Instant::now()) { - debug!("{client} dropped: {reason}"); - continue; - } - - let mut packet = buf[..n].to_vec(); - - // Never held across an await: the control API takes it too. - { - let mut relay = shared.lock().expect("relay state"); - - if relay.bans.banned(client.ip(), bans::now()) { - debug!("{client} dropped: banned"); - continue; - } - - if let Some(session) = relay.sessions.get(&client) { - match session.tx.try_send(packet) { - // Full: drop it, like any congested UDP hop. - Ok(()) | Err(TrySendError::Full(_)) => continue, - // Session expired: open a new one below. - Err(TrySendError::Closed(p)) => packet = p, - } - } - - relay.sessions.retain(|_, s| !s.tx.is_closed()); - - if relay.sessions.len() >= MAX_SESSIONS { - debug!("{client} dropped: {MAX_SESSIONS} sessions open"); - continue; - } - } - - match open_session(public.clone(), upstream, client).await { - Ok((tx, port)) => { - let _ = tx.try_send(packet); - - let mut relay = shared.lock().expect("relay state"); - relay.sessions.insert( - client, - Session { - tx, - port, - since: bans::now(), - }, - ); - debug!( - "session + {client} as port {port} ({} active)", - relay.sessions.len() - ); - } - Err(e) => eprintln!("session {client}: {e:#}"), - } + if let Some(upstream) = cli.upstream { + registry.add_static(cli.listen, upstream)?; } -} -/// Forwards packets between one client and the ET server until SESSION_TIMEOUT of -/// silence, or until its sender is dropped (ban). Returns the sender and the port the ET -/// server sees. -async fn open_session( - public: Arc, - upstream: SocketAddr, - client: SocketAddr, -) -> Result<(mpsc::Sender>, u16)> { - let sock = connect(upstream).await?; - let port = sock.local_addr()?.port(); - let (tx, mut rx) = mpsc::channel::>(SESSION_QUEUE); - - tokio::spawn(async move { - let mut buf = vec![0u8; MAX_PACKET]; - let mut deadline = Instant::now() + SESSION_TIMEOUT; - let (mut sent, mut received) = (0u64, 0u64); - let mut connected = false; - - loop { - tokio::select! { - packet = rx.recv() => { - let Some(packet) = packet else { break }; - - if let Some(command) = command(&packet) { - debug!("{client} -> ET {command} ({} B)", packet.len()); - - // A player joining, not a browser query: kept in the journal, - // the ET logs only know the port. - if !connected && command.eq_ignore_ascii_case("connect") { - println!("connect {client} as port {port}"); - connected = true; - } - } - if let Err(e) = sock.send(&packet).await { - debug!("{client} -> ET send failed: {e}"); - } - sent += 1; - deadline = Instant::now() + SESSION_TIMEOUT; - } - res = sock.recv(&mut buf) => match res { - Ok(n) => { - if let Some(command) = command(&buf[..n]) { - debug!("{client} <- ET {command} ({n} B)"); - } - let _ = public.send_to(&buf[..n], client).await; - received += 1; - deadline = Instant::now() + SESSION_TIMEOUT; - } - // ICMP unreachable while the ET server is down: keep waiting. - Err(e) => debug!("{client} <- ET recv failed: {e}"), - }, - _ = sleep_until(deadline) => break, - } - } - - debug!("session - {client}: {sent} packets to ET, {received} from ET"); - }); - - Ok((tx, port)) -} - -/// Heartbeats masters while the ET server answers, sends one flatline when it stops. -async fn heartbeat(public: Arc, upstream: SocketAddr, masters: Vec) { - let mut ticker = interval(HEARTBEAT_INTERVAL); - let mut alive = false; - - loop { - ticker.tick().await; - - let up = probe(upstream).await; - debug!("probe {upstream}: {}", if up { "up" } else { "no answer" }); - if up != alive { - println!("ET server {upstream} is {}", if up { "up" } else { "down" }); - } - - let message = match (up, alive) { - (true, _) => HEARTBEAT_ALIVE, - (false, true) => HEARTBEAT_DEAD, - (false, false) => continue, - }; - alive = up; - - let packet = [OOB, format!("heartbeat {message}\n").as_bytes()].concat(); - for master in &masters { - match send_to_host(&public, &packet, master).await { - Ok(addr) => debug!("heartbeat {message} -> {master} ({addr})"), - Err(e) => eprintln!("heartbeat {master}: {e:#}"), - } - } - } -} - -/// True if the ET server answers `getinfo`. -async fn probe(upstream: SocketAddr) -> bool { - for _ in 0..PROBE_ATTEMPTS { - let attempt = async { - let sock = connect(upstream).await?; - sock.send(&[OOB, b"getinfo etrelay"].concat()).await?; - - let mut buf = vec![0u8; MAX_PACKET]; - let n = sock.recv(&mut buf).await?; - Ok::<_, anyhow::Error>(buf[..n].starts_with(&[OOB, b"infoResponse"].concat())) - }; - - if let Ok(Ok(true)) = timeout(PROBE_TIMEOUT, attempt).await { - return true; - } - } - false -} - -/// Resolves `host` (DNS may change between heartbeats) and sends from `sock`. -async fn send_to_host(sock: &UdpSocket, packet: &[u8], host: &str) -> Result { - let ipv4 = sock.local_addr()?.is_ipv4(); - let addr = lookup_host(host) - .await? - .find(|a| a.is_ipv4() == ipv4) - .context("no address in the listen socket family")?; - - sock.send_to(packet, addr).await?; - Ok(addr) -} - -/// Command name of a connectionless packet (`getinfo`, `infoResponse`, `connect`...), -/// None for in-game packets. Arguments are left out: `connect` carries the userinfo. -fn command(packet: &[u8]) -> Option { - let body = packet.strip_prefix(OOB)?; - let end = body - .iter() - .position(|b| b.is_ascii_whitespace() || *b == b'\\') - .unwrap_or(body.len()) - .min(MAX_COMMAND); - - Some(String::from_utf8_lossy(&body[..end]).into_owned()) -} - -/// Ephemeral socket connected to `upstream`. -async fn connect(upstream: SocketAddr) -> Result { - let any: SocketAddr = if upstream.is_ipv4() { - "0.0.0.0:0".parse()? - } else { - "[::]:0".parse()? + let Some(control) = cli.control else { + // Only the command line's server: its tasks do everything. + return std::future::pending().await; }; - let sock = UdpSocket::bind(any).await?; - sock.connect(upstream).await?; - Ok(sock) + let token = std::env::var("ETRELAY_CONTROL_TOKEN").unwrap_or_default(); + if token.len() < MIN_TOKEN { + bail!("--control: $ETRELAY_CONTROL_TOKEN must hold at least {MIN_TOKEN} characters"); + } + + registry + .restore() + .context("servers registered before the restart")?; + println!( + "servers register on {} ports {}-{}", + cli.listen.ip(), + cli.ports.start(), + cli.ports.end() + ); + + control::serve(control, token, Arc::new(Mutex::new(registry))).await; + + Ok(()) +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn ports_are_a_range_or_one_port() { + assert_eq!(parse_ports("27960-27969"), Ok(27960..=27969)); + assert_eq!(parse_ports("27960"), Ok(27960..=27960)); + assert!(parse_ports("27969-27960").is_err()); + assert!(parse_ports("0-10").is_err()); + assert!(parse_ports("a-b").is_err()); + } } diff --git a/src/proof.rs b/src/proof.rs new file mode 100644 index 0000000..d295660 --- /dev/null +++ b/src/proof.rs @@ -0,0 +1,121 @@ +//! Pairing keys, and the proof an admin tool gives to register an ET server: it picks a +//! key, makes the server show the key's fingerprint in a cvar anyone can read +//! (`getstatus`), then registers with the key. Only who runs that server's console can do +//! it, and the fingerprint tells nothing about the key. +use crate::et; +use serde::{Deserialize, Serialize}; +use sha2::{Digest, Sha256}; +use std::fmt; +use std::net::SocketAddr; + +/// The serverinfo cvar holding the fingerprint (`sets etrelay_proof `). +pub const PROOF_CVAR: &str = "etrelay_proof"; +/// Shortest key accepted. +pub const MIN_KEY: usize = 32; +/// Bytes of the hash shown as the fingerprint: the serverinfo string is short (1024 +/// characters for every cvar), 128 bits are plenty. +const PROOF_BYTES: usize = 16; + +/// SHA-256 of a pairing key: what the relay keeps and compares, never the key itself. +#[derive(Clone, PartialEq, Eq, Serialize, Deserialize)] +#[serde(into = "String", try_from = "String")] +pub struct KeyHash([u8; 32]); + +impl KeyHash { + pub fn of(key: &str) -> Self { + Self(Sha256::digest(key.as_bytes()).into()) + } + + /// What the ET server must show in PROOF_CVAR. + pub fn proof(&self) -> String { + hex(&self.0[..PROOF_BYTES]) + } +} + +impl From for String { + fn from(hash: KeyHash) -> Self { + hex(&hash.0) + } +} + +impl TryFrom for KeyHash { + type Error = String; + + fn try_from(text: String) -> Result { + let bad = || format!("not a key hash: {text}"); + + if text.len() != 64 || !text.is_ascii() { + return Err(bad()); + } + + let mut hash = [0u8; 32]; + for (i, byte) in hash.iter_mut().enumerate() { + *byte = u8::from_str_radix(&text[2 * i..2 * i + 2], 16).map_err(|_| bad())?; + } + + Ok(Self(hash)) + } +} + +fn hex(bytes: &[u8]) -> String { + bytes.iter().map(|b| format!("{b:02x}")).collect() +} + +#[derive(Debug, PartialEq)] +pub enum Missing { + /// The ET server didn't answer `getstatus`. + NoAnswer(SocketAddr), + /// It answered without the fingerprint of the key. + NotShown(SocketAddr), +} + +impl fmt::Display for Missing { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + match self { + Self::NoAnswer(upstream) => write!(f, "the ET server {upstream} doesn't answer"), + Self::NotShown(upstream) => write!( + f, + "the ET server {upstream} doesn't show the key's fingerprint in {PROOF_CVAR}" + ), + } + } +} + +/// Checks the ET server at `upstream` shows `key`'s fingerprint. +pub async fn shown(upstream: SocketAddr, key: &KeyHash) -> Result<(), Missing> { + let cvars = et::serverinfo(upstream) + .await + .ok_or(Missing::NoAnswer(upstream))?; + + match cvars.get(PROOF_CVAR) { + Some(value) if value.eq_ignore_ascii_case(&key.proof()) => Ok(()), + _ => Err(Missing::NotShown(upstream)), + } +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn fingerprint_is_the_start_of_the_hash() { + // sha256("abc") + let hash = KeyHash::of("abc"); + + assert_eq!(hash.proof(), "ba7816bf8f01cfea414140de5dae2223"); + assert_eq!( + String::from(hash.clone()), + "ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad" + ); + } + + #[test] + fn hash_survives_its_text_form() { + let hash = KeyHash::of("some key"); + let text = String::from(hash.clone()); + + assert!(KeyHash::try_from(text) == Ok(hash)); + assert!(KeyHash::try_from("zz".repeat(32)).is_err()); + assert!(KeyHash::try_from("abcd".to_string()).is_err()); + } +} diff --git a/src/registry.rs b/src/registry.rs new file mode 100644 index 0000000..470fa26 --- /dev/null +++ b/src/registry.rs @@ -0,0 +1,454 @@ +//! The ET servers the relay holds, one per public port: registered through the control +//! API (kept in servers.json, back after a restart) or given on the command line. +use crate::bans::{self, Bans}; +use crate::proof::KeyHash; +use crate::server::{Common, Server}; +use anyhow::{Context, Result}; +use serde::{Deserialize, Serialize}; +use std::collections::HashMap; +use std::fmt; +use std::net::{IpAddr, SocketAddr}; +use std::ops::RangeInclusive; +use std::path::PathBuf; +use std::sync::{Arc, Mutex}; +use tokio::net::UdpSocket; + +pub type Shared = Arc>; + +pub struct Registry { + /// Folder of servers.json and of each server's bans. + dir: PathBuf, + /// Public address the servers' ports are bound on. + listen: IpAddr, + /// Public ports a server can register on. + ports: RangeInclusive, + common: Common, + entries: HashMap, +} + +struct Entry { + server: Arc, + /// None for the command line's server: it has no key, nothing reaches it through the + /// control API. + pairing: Option, +} + +/// Who registered a server. +#[derive(Clone)] +struct Pairing { + name: String, + key: KeyHash, + /// Unix seconds. + since: u64, +} + +/// A registered server as servers.json keeps it. +#[derive(Serialize, Deserialize)] +struct Record { + port: u16, + upstream: SocketAddr, + name: String, + key: KeyHash, + since: u64, +} + +/// What an admin tool asks for; the key's proof is checked before (see proof). +pub struct Registration { + pub port: u16, + pub upstream: SocketAddr, + pub name: String, + pub key: KeyHash, +} + +/// A registered server as the control API shows it. +#[derive(Serialize)] +pub struct View { + pub port: u16, + pub upstream: SocketAddr, + pub name: String, + /// Unix seconds. + pub since: u64, + /// The ET server answered the last probe: the masters are told about it. + pub alive: bool, +} + +#[derive(Debug)] +pub enum Refused { + /// Not a port servers can register on. + Port(u16, RangeInclusive), + /// Another ET server holds the port. + Taken(u16), + /// The ET server is the command line's: it isn't registered. + Static(SocketAddr), + Failed(anyhow::Error), +} + +impl fmt::Display for Refused { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + match self { + Self::Port(port, ports) => write!( + f, + "port {port} is not offered: {}-{}", + ports.start(), + ports.end() + ), + Self::Taken(port) => write!(f, "port {port} is taken by another server"), + Self::Static(upstream) => write!( + f, + "{upstream} is the relay's own server (command line), it can't be registered" + ), + Self::Failed(e) => write!(f, "{e:#}"), + } + } +} + +impl Registry { + pub fn new(dir: PathBuf, listen: IpAddr, ports: RangeInclusive, common: Common) -> Self { + Self { + dir, + listen, + ports, + common, + entries: HashMap::new(), + } + } + + /// Starts the servers registered before the restart. + pub fn restore(&mut self) -> Result<()> { + let path = self.file(); + let records: Vec = match std::fs::read(&path) { + Ok(data) => serde_json::from_slice(&data) + .with_context(|| format!("{}: not a servers file", path.display()))?, + Err(e) if e.kind() == std::io::ErrorKind::NotFound => Vec::new(), + Err(e) => return Err(e).with_context(|| format!("read {}", path.display())), + }; + + for r in records { + let pairing = Pairing { + name: r.name, + key: r.key, + since: r.since, + }; + self.open( + SocketAddr::new(self.listen, r.port), + r.upstream, + Some(pairing), + )?; + } + + Ok(()) + } + + /// The command line's server, relayed on `listen`: never kept, never reachable through + /// the control API. Its bans (bans.json) are the ones set before servers registered. + pub fn add_static(&mut self, listen: SocketAddr, upstream: SocketAddr) -> Result<()> { + self.open(listen, upstream, None) + } + + /// Whether `upstream` could register on `port`: checked before asking the ET server + /// for the proof, and again by register. + pub fn check(&self, port: u16, upstream: SocketAddr) -> Result<(), Refused> { + if !self.ports.contains(&port) { + return Err(Refused::Port(port, self.ports.clone())); + } + + if self + .entries + .values() + .any(|e| e.pairing.is_none() && e.server.upstream == upstream) + { + return Err(Refused::Static(upstream)); + } + + match self.entries.get(&port) { + Some(e) if e.pairing.is_none() || e.server.upstream != upstream => { + Err(Refused::Taken(port)) + } + _ => Ok(()), + } + } + + /// Registers an ET server on a public port. An ET server registered already is taken + /// over: who proved to run it holds it now, the former key is gone. On the same port + /// its sessions and bans go on, on another one its former port is freed. + pub fn register(&mut self, reg: Registration) -> Result { + self.check(reg.port, reg.upstream)?; + + let pairing = Pairing { + name: reg.name, + key: reg.key, + since: bans::now(), + }; + + let moved: Vec = self + .entries + .iter() + .filter(|(port, e)| e.server.upstream == reg.upstream && **port != reg.port) + .map(|(port, _)| *port) + .collect(); + for port in moved { + self.close(port).map_err(Refused::Failed)?; + } + + match self.entries.get_mut(®.port) { + Some(entry) => entry.pairing = Some(pairing), + None => self + .open( + SocketAddr::new(self.listen, reg.port), + reg.upstream, + Some(pairing), + ) + .map_err(Refused::Failed)?, + } + + self.save().map_err(Refused::Failed)?; + self.entries[®.port].server.answered(); + println!("registered {} on port {}", reg.upstream, reg.port); + + Ok(self.view(reg.port).expect("just registered")) + } + + /// Stops relaying the server of `port` and forgets it, its bans too. + pub fn unregister(&mut self, port: u16) -> Result<()> { + self.close(port)?; + self.save()?; + println!("unregistered port {port}"); + + Ok(()) + } + + /// The server registered with `key`. + pub fn find(&self, key: &KeyHash) -> Option> { + self.entries + .values() + .find(|e| e.pairing.as_ref().is_some_and(|p| p.key == *key)) + .map(|e| e.server.clone()) + } + + /// None for a free port and for the command line's server. + pub fn view(&self, port: u16) -> Option { + let entry = self.entries.get(&port)?; + let pairing = entry.pairing.as_ref()?; + + Some(View { + port, + upstream: entry.server.upstream, + name: pairing.name.clone(), + since: pairing.since, + alive: entry.server.alive(), + }) + } + + /// Binds the public port and starts relaying it. + fn open( + &mut self, + listen: SocketAddr, + upstream: SocketAddr, + pairing: Option, + ) -> Result<()> { + let bans = Bans::load(self.bans_file(listen.port(), pairing.is_some()))?; + + // std's bind: no await, the caller holds the registry's lock. + let socket = std::net::UdpSocket::bind(listen).with_context(|| format!("bind {listen}"))?; + socket.set_nonblocking(true)?; + let socket = UdpSocket::from_std(socket)?; + + let server = Server::start(socket, upstream, bans, self.common.clone())?; + println!("relaying {listen} -> {upstream}"); + self.entries.insert(server.port, Entry { server, pairing }); + + Ok(()) + } + + fn close(&mut self, port: u16) -> Result<()> { + let Some(entry) = self.entries.remove(&port) else { + return Ok(()); + }; + + entry.server.stop(); + + let bans = self.bans_file(port, entry.pairing.is_some()); + match std::fs::remove_file(&bans) { + Err(e) if e.kind() != std::io::ErrorKind::NotFound => { + Err(e).with_context(|| format!("remove {}", bans.display())) + } + _ => Ok(()), + } + } + + fn file(&self) -> PathBuf { + self.dir.join("servers.json") + } + + /// Each registered server has its own bans; bans.json is the command line's server's. + fn bans_file(&self, port: u16, registered: bool) -> PathBuf { + if !registered { + return self.dir.join("bans.json"); + } + + self.dir.join(format!("bans-{port}.json")) + } + + /// Written next to the file then renamed: a crash never leaves half a list. + fn save(&self) -> Result<()> { + let mut records: Vec = self + .entries + .iter() + .filter_map(|(port, e)| { + let p = e.pairing.as_ref()?; + + Some(Record { + port: *port, + upstream: e.server.upstream, + name: p.name.clone(), + key: p.key.clone(), + since: p.since, + }) + }) + .collect(); + records.sort_by_key(|r| r.port); + + let path = self.file(); + let tmp = path.with_extension("tmp"); + let data = serde_json::to_vec_pretty(&records)?; + + std::fs::write(&tmp, data).with_context(|| format!("write {}", tmp.display()))?; + std::fs::rename(&tmp, &path).with_context(|| format!("rename to {}", path.display())) + } +} + +#[cfg(test)] +mod tests { + use super::*; + use std::net::Ipv4Addr; + use tokio::sync::Semaphore; + + const LOCAL: IpAddr = IpAddr::V4(Ipv4Addr::LOCALHOST); + + /// A registry on its own folder and ports (tests run side by side). + fn registry(name: &str, base: u16) -> Registry { + let dir = std::env::temp_dir().join(format!("etrelay-test-{}-{name}", std::process::id())); + let _ = std::fs::remove_dir_all(&dir); + std::fs::create_dir_all(&dir).unwrap(); + + again(dir, base) + } + + fn again(dir: PathBuf, base: u16) -> Registry { + let common = Common { + masters: Arc::new(Vec::new()), + sessions: Arc::new(Semaphore::new(8)), + }; + + Registry::new(dir, LOCAL, base..=base + 1, common) + } + + fn upstream(port: u16) -> SocketAddr { + SocketAddr::new(LOCAL, port) + } + + fn reg(port: u16, upstream: SocketAddr, key: &str) -> Registration { + Registration { + port, + upstream, + name: "test".into(), + key: KeyHash::of(key), + } + } + + #[tokio::test] + async fn one_server_per_port() { + let mut r = registry("ports", 47100); + let (a, b) = (upstream(47110), upstream(47111)); + + assert!(matches!( + r.register(reg(47105, a, "key a")), + Err(Refused::Port(47105, _)) + )); + + let view = r.register(reg(47100, a, "key a")).unwrap(); + assert_eq!((view.port, view.upstream), (47100, a)); + + // Another server on a taken port: refused, the first one stays. + assert!(matches!( + r.register(reg(47100, b, "key b")), + Err(Refused::Taken(47100)) + )); + assert!(r.find(&KeyHash::of("key a")).is_some()); + assert!(r.find(&KeyHash::of("key b")).is_none()); + + r.register(reg(47101, b, "key b")).unwrap(); + assert_eq!(r.find(&KeyHash::of("key b")).unwrap().port, 47101); + } + + #[tokio::test] + async fn a_server_registered_again_is_taken_over() { + let mut r = registry("takeover", 47120); + let a = upstream(47130); + + r.register(reg(47120, a, "old key")).unwrap(); + let server = r.find(&KeyHash::of("old key")).unwrap(); + + // Same port: the same relay goes on, under the new key only. + r.register(reg(47120, a, "new key")).unwrap(); + assert!(r.find(&KeyHash::of("old key")).is_none()); + assert!(Arc::ptr_eq( + &server, + &r.find(&KeyHash::of("new key")).unwrap() + )); + + // Another port: the former one is freed. + r.register(reg(47121, a, "new key")).unwrap(); + assert!(r.view(47120).is_none()); + assert_eq!(r.find(&KeyHash::of("new key")).unwrap().port, 47121); + } + + #[tokio::test] + async fn registered_servers_come_back_and_leave() { + let mut r = registry("restore", 47140); + let dir = r.dir.clone(); + + r.register(reg(47140, upstream(47150), "key")).unwrap(); + r.unregister(47140).unwrap(); + r.register(reg(47141, upstream(47151), "key")).unwrap(); + + // A restart: the port is free once the tasks holding its socket ended. + for entry in r.entries.values() { + entry.server.stop(); + } + drop(r); + tokio::task::yield_now().await; + + let mut back = again(dir.clone(), 47140); + back.restore().unwrap_or_else(|e| panic!("{e:#}")); + + let view = back.view(47141).unwrap(); + assert_eq!( + (view.upstream, view.name.as_str()), + (upstream(47151), "test") + ); + assert!(back.view(47140).is_none()); + assert!(back.find(&KeyHash::of("key")).is_some()); + + back.unregister(47141).unwrap(); + assert!(again(dir, 47140).restore().is_ok()); + } + + #[tokio::test] + async fn the_command_line_server_is_out_of_reach() { + let mut r = registry("static", 47160); + let own = upstream(47170); + + r.add_static(SocketAddr::new(LOCAL, 47160), own).unwrap(); + + assert!(r.view(47160).is_none()); + assert!(matches!( + r.register(reg(47161, own, "key")), + Err(Refused::Static(_)) + )); + assert!(matches!( + r.register(reg(47160, upstream(47171), "key")), + Err(Refused::Taken(47160)) + )); + } +} diff --git a/src/server.rs b/src/server.rs new file mode 100644 index 0000000..7c43518 --- /dev/null +++ b/src/server.rs @@ -0,0 +1,317 @@ +//! One relayed ET server: its public socket, its clients' sessions, its bans and its +//! master heartbeats. +//! +//! - Proxies every client (players, server browsers, masters) to the ET server, one +//! upstream socket per client address, like nginx `stream`. The ET server sees each +//! client as :: the control API maps that +//! port back to the real address. +//! - Sends master heartbeats from the public socket, so masters challenge (`getinfo`) the +//! public address: the challenge goes through the relay like any client packet, the ET +//! server answers it, and the master lists the public address. +//! - Drops what a client has no business sending (see filter) and banned addresses. +use crate::bans::{self, Bans}; +use crate::et::{self, MAX_PACKET, OOB}; +use crate::filter::Filter; +use anyhow::{Context, Result}; +use std::collections::HashMap; +use std::net::SocketAddr; +use std::sync::atomic::{AtomicBool, Ordering}; +use std::sync::{Arc, Mutex, MutexGuard}; +use std::time::Duration; +use tokio::net::{UdpSocket, lookup_host}; +use tokio::sync::mpsc::{self, error::TrySendError}; +use tokio::sync::{OwnedSemaphorePermit, Semaphore}; +use tokio::task::AbortHandle; +use tokio::time::{Instant, interval, sleep, sleep_until}; + +/// Same heartbeat period as the ET server itself. +const HEARTBEAT_INTERVAL: Duration = Duration::from_secs(300); +const HEARTBEAT_ALIVE: &str = "EnemyTerritory-1"; +const HEARTBEAT_DEAD: &str = "ETFlatline-1"; +const SESSION_TIMEOUT: Duration = Duration::from_secs(120); +const SESSION_QUEUE: usize = 64; +/// A public socket that fails is read again after this, not in a tight loop. +const RECV_RETRY: Duration = Duration::from_millis(100); + +/// What every server of the relay shares. +#[derive(Clone)] +pub struct Common { + pub masters: Arc>, + /// One permit per open session, whatever its server: each holds a socket, spoofed + /// sources must not use up the file descriptors (see MAX_SESSIONS). + pub sessions: Arc, +} + +pub struct Server { + /// Public port: where clients and masters reach this server. + pub port: u16, + /// The ET server, as seen from here. + pub upstream: SocketAddr, + socket: Arc, + common: Common, + state: Mutex, + /// The ET server answered the last probe. + alive: AtomicBool, + tasks: Mutex>, +} + +/// What the relay loop and the control API share. Never held across an await. +pub struct State { + pub sessions: HashMap, + pub bans: Bans, +} + +pub struct Session { + /// Closed once the session ended; dropping it ends the session. + tx: mpsc::Sender>, + /// Source port of the upstream socket: the port the ET server sees. + pub port: u16, + /// Unix seconds. + pub since: u64, +} + +impl Session { + pub fn open(&self) -> bool { + !self.tx.is_closed() + } +} + +impl Server { + /// Relays `socket` (bound to the public port) to `upstream` and heartbeats the + /// masters, until stop. + pub fn start( + socket: UdpSocket, + upstream: SocketAddr, + bans: Bans, + common: Common, + ) -> Result> { + let server = Arc::new(Self { + port: socket.local_addr().context("public socket")?.port(), + upstream, + socket: Arc::new(socket), + common, + state: Mutex::new(State { + sessions: HashMap::new(), + bans, + }), + alive: AtomicBool::new(false), + tasks: Mutex::new(Vec::new()), + }); + + let relay = tokio::spawn(server.clone().relay()); + let heartbeat = tokio::spawn(server.clone().heartbeat()); + *server.tasks.lock().expect("server tasks") = + vec![relay.abort_handle(), heartbeat.abort_handle()]; + + Ok(server) + } + + /// Stops relaying: sessions are cut, the masters told when they listed the server. + /// The public port is free once the flatline left. + pub fn stop(&self) { + for task in self.tasks.lock().expect("server tasks").drain(..) { + task.abort(); + } + + self.state().sessions.clear(); + + if self.alive.swap(false, Ordering::Relaxed) { + let (socket, masters) = (self.socket.clone(), self.common.masters.clone()); + tokio::spawn(async move { announce(&socket, &masters, HEARTBEAT_DEAD).await }); + } + } + + pub fn state(&self) -> MutexGuard<'_, State> { + self.state.lock().expect("server state") + } + + pub fn alive(&self) -> bool { + self.alive.load(Ordering::Relaxed) + } + + /// The ET server just answered (the proof of a registration): no need to wait for + /// the next probe to say so. + pub fn answered(&self) { + self.alive.store(true, Ordering::Relaxed); + } + + /// Dispatches client packets to their session, opening one on first packet. + async fn relay(self: Arc) { + let mut filter = Filter::new(Instant::now()); + let mut buf = vec![0u8; MAX_PACKET]; + + loop { + let (n, client) = match self.socket.recv_from(&mut buf).await { + Ok(received) => received, + Err(e) => { + eprintln!("port {}: recv: {e}", self.port); + sleep(RECV_RETRY).await; + continue; + } + }; + + if let Some(reason) = filter.refuse(&buf[..n], client.ip(), Instant::now()) { + debug!("{client} dropped: {reason}"); + continue; + } + + let mut packet = buf[..n].to_vec(); + + { + let mut state = self.state(); + + if state.bans.banned(client.ip(), bans::now()) { + debug!("{client} dropped: banned"); + continue; + } + + if let Some(session) = state.sessions.get(&client) { + match session.tx.try_send(packet) { + // Full: drop it, like any congested UDP hop. + Ok(()) | Err(TrySendError::Full(_)) => continue, + // Session expired: open a new one below. + Err(TrySendError::Closed(p)) => packet = p, + } + } + + state.sessions.retain(|_, s| s.open()); + } + + let Ok(permit) = self.common.sessions.clone().try_acquire_owned() else { + debug!("{client} dropped: too many sessions open"); + continue; + }; + + match self.open_session(client, permit).await { + Ok(session) => { + let _ = session.tx.try_send(packet); + let port = session.port; + + let mut state = self.state(); + state.sessions.insert(client, session); + debug!( + "session + {client} as port {port} ({} active on port {})", + state.sessions.len(), + self.port + ); + } + Err(e) => eprintln!("session {client}: {e:#}"), + } + } + } + + /// Forwards packets between one client and the ET server until SESSION_TIMEOUT of + /// silence, or until its sender is dropped (ban, stop). `permit` is given back then. + async fn open_session( + &self, + client: SocketAddr, + permit: OwnedSemaphorePermit, + ) -> Result { + let sock = et::connect(self.upstream).await?; + let port = sock.local_addr()?.port(); + let (tx, mut rx) = mpsc::channel::>(SESSION_QUEUE); + let public = self.socket.clone(); + + tokio::spawn(async move { + let _permit = permit; + let mut buf = vec![0u8; MAX_PACKET]; + let mut deadline = Instant::now() + SESSION_TIMEOUT; + let (mut sent, mut received) = (0u64, 0u64); + let mut connected = false; + + loop { + tokio::select! { + packet = rx.recv() => { + let Some(packet) = packet else { break }; + + if let Some(command) = et::command(&packet) { + debug!("{client} -> ET {command} ({} B)", packet.len()); + + // A player joining, not a browser query: kept in the journal, + // the ET logs only know the port. + if !connected && command.eq_ignore_ascii_case("connect") { + println!("connect {client} as port {port}"); + connected = true; + } + } + if let Err(e) = sock.send(&packet).await { + debug!("{client} -> ET send failed: {e}"); + } + sent += 1; + deadline = Instant::now() + SESSION_TIMEOUT; + } + res = sock.recv(&mut buf) => match res { + Ok(n) => { + if let Some(command) = et::command(&buf[..n]) { + debug!("{client} <- ET {command} ({n} B)"); + } + let _ = public.send_to(&buf[..n], client).await; + received += 1; + deadline = Instant::now() + SESSION_TIMEOUT; + } + // ICMP unreachable while the ET server is down: keep waiting. + Err(e) => debug!("{client} <- ET recv failed: {e}"), + }, + _ = sleep_until(deadline) => break, + } + } + + debug!("session - {client}: {sent} packets to ET, {received} from ET"); + }); + + Ok(Session { + tx, + port, + since: bans::now(), + }) + } + + /// Heartbeats masters while the ET server answers, sends one flatline when it stops. + async fn heartbeat(self: Arc) { + let mut ticker = interval(HEARTBEAT_INTERVAL); + let upstream = self.upstream; + + loop { + ticker.tick().await; + + let up = et::probe(upstream).await; + let alive = self.alive.swap(up, Ordering::Relaxed); + + debug!("probe {upstream}: {}", if up { "up" } else { "no answer" }); + if up != alive { + println!("ET server {upstream} is {}", if up { "up" } else { "down" }); + } + + match (up, alive) { + (true, _) => announce(&self.socket, &self.common.masters, HEARTBEAT_ALIVE).await, + (false, true) => announce(&self.socket, &self.common.masters, HEARTBEAT_DEAD).await, + (false, false) => {} + } + } + } +} + +/// Sends `heartbeat ` to every master from `socket`: the masters check the +/// address it came from. +async fn announce(socket: &UdpSocket, masters: &[String], message: &str) { + let packet = [OOB, format!("heartbeat {message}\n").as_bytes()].concat(); + + for master in masters { + match send_to_host(socket, &packet, master).await { + Ok(addr) => debug!("heartbeat {message} -> {master} ({addr})"), + Err(e) => eprintln!("heartbeat {master}: {e:#}"), + } + } +} + +/// Resolves `host` (DNS may change between heartbeats) and sends from `sock`. +async fn send_to_host(sock: &UdpSocket, packet: &[u8], host: &str) -> Result { + let ipv4 = sock.local_addr()?.is_ipv4(); + let addr = lookup_host(host) + .await? + .find(|a| a.is_ipv4() == ipv4) + .context("no address in the listen socket family")?; + + sock.send_to(packet, addr).await?; + Ok(addr) +}