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

stackaddr

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

3 releases (breaking)

new 0.2.0 Mar 28, 2025
0.1.0 Mar 25, 2025
0.0.1 Mar 22, 2025

#1329 in Network programming

Download history 176/week @ 2025-03-20

176 downloads per month

MIT license

29KB
533 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 network addresses and protocol stacks.

Features

  • Layered protocol stack: supports multiple encapsulated protocols (e.g. /ip4/127.0.0.1/udp/4433/quic)
    • Supports from L2 (MAC) to application-level protocols (e.g. /mac/aa:bb:cc:dd:ee:ff/ip4/192.168.1.1/tcp/80/http)
  • Identity aware: supports cryptographic identities like NodeId, PeerId, and UUID
  • Strong typing: no ambiguity between TCP/UDP/DNS/etc.
  • 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.1"

To enable serde support:

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

Example

Basic:

use stackaddr::{StackAddr, Protocol};

let addr = StackAddr::new(&[
    Protocol::Ip4("192.168.10.1".parse().unwrap()),
    Protocol::Tcp(443),
    Protocol::Https,
]);

println!("{}", addr); 
// Output: /ip4/192.168.10.1/tcp/443/https

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");

let expected = StackAddr::new(&[
    Protocol::Mac("aa:bb:cc:dd:ee:ff".parse().unwrap()),
    Protocol::Ip4("192.168.1.1".parse().unwrap()),
    Protocol::Tcp(8080),
]);

assert_eq!(addr, expected);

Parsing from string:

let parsed: StackAddr = "/ip6/::1/tcp/8443".parse().unwrap();
assert_eq!(parsed.port(), Some(8443));

With identity:

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

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

~1–8.5MB
~73K SLoC