In my spare time I built a small experimental P2P protocol stack in Go called Envelop.
Instead of thinking in terms of “connections” and “streams”, it treats every message as:
a piece of paper (the real payload),
that always travels inside one or more envelopes.
On the outside of an envelope you have DestPeerID, ReturnPeerID, TTL, Flags. Inside you have either:
the next Envelope (for onion-style nesting), or
the final paper (application payload).
So you can literally do “envelope in envelope in envelope”:
C gets the innermost envelope and sees the paper.
B only sees “an envelope to C”.
A only sees “an envelope to B”.
If inner layers are encrypted, A and B never see the paper; they just see:
“this layer is for me”
“next recipient is X”
“these are my flags/TTL”.
The stack looks like:
QUIC → Frame v2 → Envelope v2 → Router → Strategy → Socket → Host
Each QUIC stream carries one Frame; each Frame carries one Envelope.
Strategy: where the fun is
All “how to deliver” behavior lives behind a Strategy interface.
The built-in SimpleStrategy is just a single-layer demo. You can plug in your own strategy to turn Envelop into:
an I2P-style onion/garlic router (multi-layer envelopes, per-hop keys),
a private invite-only mesh with custom trust/delivery rules,
or any weird store-and-forward / delay / mixing scheme you want to experiment with.
The core stack doesn’t change – it still just sees envelopes and peer IDs.
Code (AGPLv3, Go) is here:
https://github.com/DarkMagier/envelop
There is both an English and a Chinese README. The code is heavily commented and meant more as an experimental protocol skeleton / learning resource than a production library.