mctx-core 0.2.2

Runtime-agnostic and portable IPv4 and IPv6 multicast sender library.
Documentation
# Design Decisions

## No Join or Leave Lifecycle

The receiver crate needs explicit group membership management. The sender side
does not, so `mctx-core` collapses that complexity into immediate-ready
publications.

## Separate IPv4 and IPv6 Send Paths

`mctx-core` keeps the IPv4 and IPv6 socket configuration branches separate.

That avoids hiding important IPv6 behavior behind a single generic multicast
send implementation and keeps platform-specific fixes easy to audit.

## Connected UDP Sockets

Each publication connects its UDP socket to a single multicast destination.
That keeps repeated sends simple and avoids rebuilding the same destination
address on every call.

## Explicit Source Address vs Outgoing Interface

The sender source address and the outgoing interface are treated as distinct
configuration choices.

For IPv4 this preserves the expected bind-vs-`IP_MULTICAST_IF` split.

For IPv6:

- binding the exact source matters for SSM-style receiver verification
- selecting the outgoing interface still matters independently
- an IPv6 address used as the sender selector also resolves to an interface
  index and sets `IPV6_MULTICAST_IF`

## IPv6 Destination Scope IDs

`mctx-core` only keeps a destination scope ID for interface-local and
link-local IPv6 multicast groups.

For wider scopes such as `ff35::/16`, `ff38::/16`, and `ff3e::/16`, the
destination scope ID is cleared and the bound source plus multicast interface
socket option drive the route selection instead. This matches the practical
Windows behavior observed in `mcrx-core`.

## Optional Add-Ons

The base crate keeps only the essentials:

- `socket2`
- `thiserror`
- lightweight OS support for IPv6 interface resolution

Async support and metrics are gated behind features so lightweight embeddings do
not pay for them by default.