mctx-core is a runtime-agnostic multicast sender library for IPv4 and IPv6
ASM/SSM-style traffic.
The default API focuses on lightweight UDP multicast send with explicit socket ownership, deterministic source/interface control, and non-blocking operation. Optional features add Tokio integration, metrics, multicast raw-IP forwarding, generic raw-IP control transmit, and Python bindings without changing the default UDP send path.
- IPv4 and IPv6 multicast send support
- Explicit separation between sender source address and outgoing interface
- Exact IPv4 or IPv6 local bind control for announce-style senders
- Predictable IPv6 destination scope handling for
ff31/ff32vsff35/ff38/ff3e - Non-blocking send API with caller-owned context and socket extraction
- Caller-provided socket support
- Optional
tokio,metrics,raw-packets, andraw-ipfeatures - Optional Python bindings in the sibling
mctx-core-pycrate
cargo add mctx-coreThe minimum supported Rust version is 1.88.
Optional feature examples:
cargo add mctx-core --features tokio
cargo add mctx-core --features metrics
cargo add mctx-core --features raw-packets
cargo add mctx-core --features raw-ipPython bindings are covered in the Python Bindings guide; the
binding crate lives in the repository's mctx-core-py workspace directory.
use mctx_core::{Context, PublicationConfig};
use std::net::Ipv4Addr;
let mut ctx = Context::new();
let id = ctx.add_publication(
PublicationConfig::new(Ipv4Addr::new(239, 1, 2, 3), 5000)
.with_source_addr(Ipv4Addr::new(192, 168, 1, 10))
.with_ttl(8),
)?;
let report = ctx.send(id, b"hello multicast")?;
println!("sent {} bytes to {}", report.bytes_sent, report.destination);
println!("wire source {:?}", report.source_addr);For IPv6 examples, source/interface rules, and CLI commands, see IPv6 Multicast and Demo Binaries.
tokio: async send wrapper for extracted publications.metrics: snapshots, deltas, samplers, and Heimdall-style JSONL helpers.raw-packets: complete multicast IP datagram transmit for AMT-style use cases.raw-ip: complete unicast or multicast IP datagram transmit for caller-built control traffic such as ICMP Packet Too Big.mctx-core-py: sibling workspace crate with Python and asyncio bindings.
- Usage Guide: core Rust sender API flow.
- IPv6 Multicast: source vs interface, scopes, and SSM group rules.
- Raw Packet Transmit:
raw-packetsAPI and platform limits. - Raw IP Control Transmit:
raw-ipAPI and platform limits. - Demo Binaries: sender CLI commands and metrics examples.
- Metrics: snapshot, delta, and JSONL semantics.
- Python Bindings: Python API and asyncio helper.
- Architecture: main types and module layout.
- Design Decisions: why the API is shaped this way.
| OS | IPv4 send | IPv6 ASM send | IPv6 SSM-style send | Notes |
|---|---|---|---|---|
| macOS | ✅ | ✅ | ✅ | ff32::/16 should use a fe80:: source |
| Linux | ✅ | ✅ | ✅ | intended support |
| Windows | ✅ | ✅ | ✅ | keep scope ID only for ff31 / ff32 |
The default UDP send path supports IPv4 and IPv6 multicast on the same platforms.
Raw multicast IP datagram transmit is available behind the raw-packets
feature. Linux and macOS support raw IPv4 and IPv6 transmit. Windows currently
supports raw IPv4 transmit only. Linux uses packet-socket injection when an
IPv6 datagram source differs from the configured local bind, preserving the
complete header for AMT forwarding. Linux and macOS use the host raw-IPv6 path
for matching local sources; that path preserves the source/group tuple and
transport header while the kernel rebuilds the base IPv6 header. macOS returns
an explicit unsupported error for remote-source IPv6 injection.
Generic raw-IP control transmit is available behind the independent raw-ip
feature. It accepts a complete caller-supplied unicast or multicast datagram.
Linux and macOS support IPv4 IP_HDRINCL-style transmit and an explicit
kernel-built IPv6 base-header path. Windows supports IPv4 only; raw IPv6
returns an explicit unsupported error. See Raw IP Control Transmit
for source-preservation and privilege requirements.
BSD 2-Clause