macula_route_packet (macula v4.2.4)

View Source

Egress routing for macula-net packets.

Per the macula-net spec (PLAN_MACULA_NET.md §5.2), this slice owns the egress flow:

IPv6 packet from TUN → look up dst → encapsulate → send to station

Two modes:

static
Phase 1 default. Caller pre-populates an ETS table of {Address, StationId, SendFun}. Used by tests and the smoke / netns demos. Selected when configure/1 receives stations.
dht
Phase 2. On miss in macula_cache_route, calls macula_resolve_address:resolve/3 for the destination, caches the answer (TTL = record's expires_at), and dials the resolved host via the configured connect_fn. Selected when configure/1 receives resolver.

CBOR encoding uses macula_cbor_nif:pack/1.

Summary

Functions

Install routing. Two shapes

Egress dispatch. Takes a raw IPv6 packet, looks up its destination, wraps it in a macula-net envelope, sends to the hosting station. In dht mode performs a DHT resolve on cache miss and dials the resolved host via the configured connect_fn.

Forward a pre-built macula-net envelope toward Dst.

Build a macula-net envelope around an IPv6 packet. Public so other layers (e.g. daemon attachment) can craft envelopes directly.

Look up the route for Address.

Return the configured static stations (diagnostics; empty in dht mode).

Types

connect_fun/0

-type connect_fun() ::
          fun((StationId :: binary(), Host :: binary() | string(), Port :: 1..65535) ->
                  ok | {error, term()}).

own_address/0

-type own_address() :: <<_:128>>.

resolver/0

-type resolver() ::
          #{realm_pubkey := <<_:256>>,
            find_fn := macula_resolve_address:find_fn(),
            connect_fn := connect_fun(),
            send_fn := send_fun()}.

send_fun/0

-type send_fun() :: fun((StationId :: binary(), CborEnvelope :: binary()) -> ok | {error, term()}).

station_entry/0

-type station_entry() :: #{address := <<_:128>>, station := binary(), send := send_fun()}.

Functions

configure(_)

-spec configure(#{own_address := own_address(), stations => [station_entry()], resolver => resolver()}) ->
                   ok.

Install routing. Two shapes:

Static: #{own_address, stations} — Phase 1 / tests. DHT: #{own_address, resolver} — Phase 2.

Idempotent. Calling again replaces the previous configuration.

dispatch(Packet)

-spec dispatch(Packet :: binary()) ->
                  {ok, StationId :: binary()} | {error, no_route | malformed_packet | term()}.

Egress dispatch. Takes a raw IPv6 packet, looks up its destination, wraps it in a macula-net envelope, sends to the hosting station. In dht mode performs a DHT resolve on cache miss and dials the resolved host via the configured connect_fn.

dispatch_envelope(CborEnvelope, Dst)

-spec dispatch_envelope(CborEnvelope :: binary(), Dst :: <<_:128>>) ->
                           {ok, StationId :: binary()} | {error, term()}.

Forward a pre-built macula-net envelope toward Dst.

Same lookup + resolve + connect + send pipeline as dispatch/1, but skips the IPv6-to-CBOR encapsulation step. Used by macula_host_attach_controller when a hosted daemon emits a data envelope whose dst is neither hosted on the same station nor the station's own address — the host station forwards the same bytes onward, preserving the envelope's src so the routing is transparent at L3.

encapsulate(Payload, Src, Dst)

-spec encapsulate(Payload :: binary(), Src :: <<_:128>>, Dst :: <<_:128>>) -> binary().

Build a macula-net envelope around an IPv6 packet. Public so other layers (e.g. daemon attachment) can craft envelopes directly.

lookup(Address)

-spec lookup(<<_:128>>) -> {ok, #{station := binary(), send := send_fun()}} | not_found.

Look up the route for Address.

In static mode this is the synchronous lookup of Phase 1. In dht mode the lookup is cache-only — a cold miss returns not_found rather than triggering a DHT call (use dispatch/1 for the full resolve+connect+send path).

mode()

-spec mode() -> static | dht | undefined.

routes()

-spec routes() -> [#{address := <<_:128>>, station := binary()}].

Return the configured static stations (diagnostics; empty in dht mode).