← starla · 03
03 · architecture
Architecture.
How starla connects to the RIPE Atlas controller infrastructure, where the data flows, and which Rust crate owns which slice of the pipeline.
01Overview
One probe, one outbound SSH connection, one in-memory queue, one upload channel per batch.
02Connection flow
- Registration. starla SSHes to a registration server (e.g.
reg03.atlas.ripe.net:443), runsINITwith probe identity on stdin, and receives a controller assignment. - Controller INIT. Connects to the assigned controller via SSH, sends another
INIT(no stdin), and receives aSESSION_ID+REMOTE_PORT. - KEEP session. Opens a long-lived SSH connection running the
KEEPcommand. This connection carries both measurement commands (inbound) and result uploads (outbound).
03No local ports
All communication flows through the SSH tunnel; starla binds no local TCP ports.
- Measurement commands arrive via SSH reverse tunnel (
forwarded-tcpip). The SSH handler pipes them straight to the telnet command parser through an in-processDuplexStreambridge. - Result uploads go out via SSH
direct-tcpipchannels. Each upload opens a fresh channel to127.0.0.1:8080on the controller side and writes a raw HTTP/1.1POSTwith the measurement results.
One outbound socket. No listeners. No exposed surface.
04Crate structure
| Crate | Role |
|---|---|
starla-probe | Main binary; orchestrates everything. |
starla-common | Shared types, config, paths, logging. |
starla-controller | SSH connection, telnet parser, channel streams. |
starla-measurements | Ping, DNS, traceroute, HTTP, TLS, NTP implementations. |
starla-scheduler | Measurement scheduling and concurrent execution. |
starla-results | Result formatting, in-memory upload queue, upload transport. |
starla-network | Raw sockets, source address detection. |
starla-metrics | Prometheus metrics export (optional). |
05Measurement execution
The controller sends measurement schedules as CRONLINE or JSON commands over the telnet interface. The scheduler parses these into MeasurementJobs and executes them concurrently via tokio::spawn.
Each measurement type implements the Measurement trait:
ruststarla-measurementspub trait Measurement: Send + Sync { async fn execute(&self) -> anyhow::Result<MeasurementResult>; }
Results are formatted to match the official C probe's JSON output exactly — field order, spacing, numeric precision — and queued in a bounded in-memory buffer for upload. The queue size is configurable; oldest entries are dropped when the buffer is full.
06Result upload
The result handler periodically drains the queue and uploads batches via the UploadTransport trait. In production, this opens SSH direct-tcpip channels and writes raw HTTP/1.1:
httpPOST · over SSH channelPOST /?PROBE_ID=12345&SESSION_ID=abc HTTP/1.1 Content-Type: application/x-www-form-urlencoded P_TO_C_REPORT RESULT { "id":"1001", "fw":5120, ... } RESULT { "id":"1002", "fw":5120, ... } SESSION_ID abc
Failed uploads are re-queued with exponential backoff. Results older than one hour or with more than five failed attempts are dropped.
07State & directories
treestate layoutState directory (persistent): probe_key // SSH private key (generated on first run) probe_key.pub // SSH public key (register at atlas.ripe.net) probe_id // assigned probe ID known_hosts // controller SSH host keys (TOFU) Runtime directory (ephemeral): starla.sock // status socket for tray-app communication
Path resolution priority: CLI flag > systemd env > container paths (/state, /config) > XDG > standard Linux paths. See the paths module for details.
For the full protocol specification — every command format, result-line quirk, and known issue — see the Protocol Reference →