#stack #address #protocols #networking #network-protocol #parser

stackaddr

Self-describing, layered network address representation, with flexible protocol stacks

5 releases (breaking)

new 0.4.0 Apr 21, 2025
0.3.0 Mar 31, 2025
0.2.0 Mar 28, 2025
0.1.0 Mar 25, 2025
0.0.1 Mar 22, 2025

#1077 in Network programming

Download history 81/week @ 2025-03-17 215/week @ 2025-03-24 134/week @ 2025-03-31 14/week @ 2025-04-07

444 downloads per month

MIT license

43KB
817 lines

stackaddr Crates.io License

Self-describing, layered address representation library, designed with flexibility and extensibility.

stackaddr provides a type-safe, composable, and future-proof way to represent complex address stacks, including transport protocols, cryptographic identities, metadata, and resource paths.

Features

  • Segment-based architecture: each address consists of typed Segments
    • Protocols like /ip4, /tcp, /tls, /http
    • Identities like /node/<base32>, /uuid/<uuid>
    • Metadata like /meta/env/production
    • Path-like entries like /foo/bar
  • Layered from L2 to L7: supports MAC, IP, TCP/UDP, TLS, HTTP, and more
    • /ip4/127.0.0.1/udp/4433/quic
    • /mac/aa:bb:cc:dd:ee:ff/ip4/192.168.1.1/tcp/80/http
  • serde support(optional): enable with features = ["serde"]
  • Easy parsing: implements FromStr, Display, and error types for easy parsing

Usage

Add stackaddr to your dependencies:

[dependencies]
stackaddr = "0.3"

To enable serde support:

[dependencies]
stackaddr = { version = "0.2", features = ["serde"] }

Example

Basic:

use stackaddr::{StackAddr, Protocol, Segment};

let addr = StackAddr::from_parts(&[
    Segment::Protocol(Protocol::Ip4("192.168.1.1".parse().unwrap())),
    Segment::Protocol(Protocol::Tcp(443)),
    Segment::Protocol(Protocol::Tls),
    Segment::Protocol(Protocol::Http),
]);

println!("{}", addr); 
// Output: /ip4/192.168.1.1/tcp/443/tls/http

From L2 to L4:

let s = "/mac/aa:bb:cc:dd:ee:ff/ip4/192.168.1.1/tcp/8080";
let addr: StackAddr = s.parse().expect("parse failed");

With identity:

let public_key: [u8; 32] = generate_public_key();
let id = Bytes::copy_from_slice(&public_key);
let addr = StackAddr::from_parts(&[
    Segment::Protocol(Protocol::Ip4("192.168.10.10".parse().unwrap())),
    Segment::Protocol(Protocol::Udp(4433)),
    Segment::Protocol(Protocol::Quic),
    Segment::Identity(Identity::NodeId(id)),
]);

With path:

let addr: StackAddr = "/dns/example.com/tcp/443/tls/http/images/logo.png".parse().unwrap();

With metadata:

let addr: StackAddr = "/meta/env/production".parse().unwrap();

Acknowledgment

Inspired by Multiaddr, StackAddr inherits its core ideas while embracing Rust’s flexibility to provide a more general-purpose and extensible address representation.

Dependencies

~0.6–7.5MB
~56K SLoC