guppy-protocol
Home:
mark-ik/serval, atcomponents/errand/protocols/guppy-protocol(adopted 2026-07). The former standalone repository is archived and links here.
A Rust implementation of the
Guppy protocol v0.4.4
(guppy://): an async UDP client and server with chunking, per-packet
acknowledgement, windowed transmission, and retransmission, plus a small CLI.
Guppy is dimkr's smolweb-over-UDP protocol, inspired by TFTP, DNS, and
Spartan, designed to be servable from a microcontroller over a single UDP
socket (default port 6775). A request is one datagram carrying a URL; the
response is a numbered packet sequence the client acknowledges packet by
packet, ended by an empty end-of-file packet. User input rides the URL query,
prompted by a 1 <prompt> packet; 3 redirects and 4 errors are
single-packet answers.
This crate is independent and unaffiliated with the protocol's author. The
crates.io name is qualified (guppy-protocol) because the bare guppy name
is used by an unrelated project.
Library
use ;
match fetch.await?
Serving is a Handler (any async closure) returning the same
GuppyResponse; the server owns chunking, the send window, retransmission,
session tracking, and duplicate-request suppression. FileHandler is the
built-in static-directory handler.
CLI
Spec coverage (v0.4.4)
| Spec point | State |
|---|---|
Request = one datagram url\r\n, ≤ 2048 bytes |
enforced both sides |
| Success / continuation / EOF packet forms, seq +1, random start in [6, 2³¹−1] | full; the "don't confuse seq 39/41 with 3/4" disambiguation is unit-tested |
| Per-packet acknowledgement; duplicate packets re-acked; duplicate acks ignored | client + server |
| Retransmission (request, acks, unacked response packets) | both sides, tunable intervals |
| Out-of-order transmission | server sends a configurable window ahead of acks; client caches and re-orders (tested against scrambled + duplicated delivery) |
| Sessions (source-addr keyed, duplicate requests ignored, timeout, DoS cap) | server, with a post-completion linger |
Input prompts (1), redirects (3), errors (4) |
full round trip; input decodes from the URL query |
| Chunk size ≥ 512 recommendation | default 512, configurable |
| One source port per session | client binds a fresh socket per fetch |
Not covered: encryption (the spec declares it out of scope).
License
MIT. The specification declares no license; this implementation is original code.