Packages

macula

0.12.3
7.0.0 6.0.0 5.2.2 5.2.1 5.2.0 5.1.0 5.0.0 4.8.0 4.7.1 4.7.0 4.6.0 4.5.0 4.4.10 4.4.9 4.4.8 4.4.7 4.4.6 4.4.5 4.4.4 4.4.3 4.4.2 4.4.1 4.4.0 4.3.1 4.3.0 4.2.9 4.2.8 4.2.7 4.2.6 4.2.5 4.2.4 4.2.3 4.2.2 4.2.1 4.2.0 4.1.1 4.1.0 4.0.0 3.16.0 3.15.3 3.15.2 3.15.1 3.14.0 3.13.0 3.12.1 3.12.0 3.11.1 3.11.0 3.10.3 3.10.2 3.10.1 3.9.0 3.8.0 3.7.0 3.5.0 3.4.0 3.3.0 3.2.0 3.1.0 3.0.0 2.1.1 2.1.0 2.0.0 1.5.2 1.5.1 1.4.30 1.4.29 1.4.28 1.4.27 1.4.26 1.4.25 1.4.24 1.4.23 1.4.22 1.4.21 1.4.20 1.4.19 1.4.18 1.4.17 1.4.16 1.4.15 1.4.14 1.4.13 1.4.11 1.4.10 1.4.9 1.4.8 1.4.7 1.4.6 1.4.5 1.4.4 1.4.3 1.4.2 1.4.1 1.4.0 1.3.1 1.3.0 1.2.0 1.1.0 1.0.10 1.0.9 1.0.8 1.0.7 1.0.6 1.0.5 1.0.4 1.0.3 1.0.2 1.0.1 1.0.0 0.48.6 0.48.5 0.48.4 0.48.3 0.48.2 0.48.1 0.48.0 0.47.1 0.47.0 0.46.3 0.46.1 0.46.0 0.45.3 0.45.2 0.45.1 0.45.0 0.44.2 0.44.1 0.44.0 0.43.3 0.43.2 0.43.1 0.43.0 0.42.9 0.42.8 0.42.7 0.42.6 0.42.5 0.42.4 0.42.3 0.42.2 0.42.1 0.42.0 0.41.1 0.41.0 0.40.1 0.40.0 0.39.9 0.39.8 0.39.7 0.39.6 0.39.5 0.39.4 0.39.3 0.39.2 0.39.1 0.39.0 0.38.8 0.38.7 0.38.6 0.38.5 0.38.4 0.38.3 0.38.2 0.38.1 0.38.0 0.37.7 0.37.6 0.37.5 0.37.4 0.37.3 0.37.2 0.37.1 0.37.0 0.36.6 0.36.5 0.36.4 0.36.3 0.36.2 0.36.1 0.36.0 0.35.4 0.35.3 0.35.2 0.35.1 0.35.0 0.34.1 0.34.0 0.33.1 0.33.0 0.32.5 0.32.4 0.32.3 0.32.2 0.32.1 0.32.0 0.31.9 0.31.8 0.31.7 0.31.6 0.31.5 0.31.4 0.31.3 0.31.2 0.31.1 0.31.0 0.30.10 0.30.9 0.30.8 0.30.7 0.30.6 0.30.5 0.30.4 0.30.3 0.30.2 0.30.1 0.30.0 0.29.0 0.28.3 0.28.2 0.28.1 0.28.0 0.27.1 0.27.0 0.26.1 0.26.0 0.25.6 0.25.5 0.25.4 0.25.3 0.25.2 0.25.1 0.25.0 0.24.6 0.24.5 0.24.4 0.24.3 0.24.2 0.24.1 0.24.0 0.23.3 0.23.2 0.23.1 0.23.0 0.22.12 0.22.11 0.22.10 0.22.9 0.22.8 0.22.7 0.22.6 0.22.5 0.22.4 0.22.3 0.22.2 0.22.1 0.22.0 0.21.7 0.21.6 0.21.5 0.21.4 0.21.2 0.21.1 0.21.0 0.20.25 0.20.24 0.20.23 0.20.22 0.20.21 0.20.20 0.20.19 0.20.18 0.20.17 0.20.16 0.20.15 0.20.14 0.20.13 0.20.12 0.20.11 0.20.10 0.20.9 0.20.8 0.20.7 0.20.6 0.20.5 0.20.3 0.20.2 0.20.1 0.20.0 0.19.2 0.19.1 0.19.0 0.18.1 0.18.0 0.17.4 0.17.3 0.17.2 0.17.1 0.17.0 0.16.6 0.16.5 0.16.4 0.16.3 0.16.2 0.16.1 0.16.0 0.15.1 0.15.0 0.14.3 0.14.2 0.14.1 0.14.0 0.12.6 0.12.5 0.12.3 0.11.3 0.10.2 0.10.1 0.10.0 0.9.2 0.9.1 0.9.0 0.8.25 0.8.24 0.8.23 0.8.22 0.8.21 0.8.20 0.8.19 0.8.18 0.8.17 0.8.16 0.8.15 0.8.14 0.8.13 0.8.12 0.8.11 0.8.10 0.8.9 0.8.8 0.8.7 0.8.6 0.8.5 0.8.4 0.8.3 0.8.2 0.8.1 0.8.0 0.7.30 0.7.29 0.7.28 0.7.27 0.7.26 0.7.25 0.7.24 0.7.23 0.7.22 0.7.21 0.7.20 0.7.19 0.7.18 0.7.17 0.7.16 0.7.15 0.7.14 0.7.13 0.7.12 0.7.11 0.7.10 0.7.9 0.7.8 0.7.7 0.7.6 0.7.5 0.7.4 0.7.3 0.7.2 0.7.1 0.7.0 0.6.7 0.6.6 0.6.5 0.6.4 0.6.3 0.6.2 0.6.1 0.6.0 0.5.0 0.4.4 0.4.3 0.4.2 0.4.1 0.4.0 0.3.4 0.3.3 0.3.2 0.3.1

Macula HTTP/3 Mesh SDK — connect, subscribe, publish, call, advertise

Current section

Files

Jump to
macula src macula_quic_conn_callback.erl
Raw

src/macula_quic_conn_callback.erl

%%%-------------------------------------------------------------------
%%% @doc
%%% QUIC connection callback module for Macula.
%%% Implements quicer_connection behavior to handle connection lifecycle.
%%% @end
%%%-------------------------------------------------------------------
-module(macula_quic_conn_callback).
-behaviour(quicer_connection).
-include_lib("kernel/include/logger.hrl").
%% Callback init
-export([init/1]).
%% Connection Callbacks
-export([
new_conn/3,
connected/3,
transport_shutdown/3,
shutdown/3,
closed/3,
local_address_changed/3,
peer_address_changed/3,
streams_available/3,
peer_needs_streams/3,
resumed/3,
nst_received/3,
new_stream/3
]).
-export([handle_info/2]).
%%%===================================================================
%%% Callback Implementation
%%%===================================================================
%% @doc Initialize connection callback state
init(ConnOpts) when is_map(ConnOpts) ->
?LOG_DEBUG("Initializing with opts: ~p", [maps:keys(ConnOpts)]),
{ok, ConnOpts};
init(ConnOpts) when is_list(ConnOpts) ->
init(maps:from_list(ConnOpts)).
%% @doc Handle new connection
%% With quicer_server, streams are delivered automatically via new_stream/3
new_conn(Conn, #{version := Vsn}, #{gateway_pid := GatewayPid} = State) ->
?LOG_INFO("New connection: ~p (QUIC v~p)", [Conn, Vsn]),
?LOG_DEBUG("Gateway PID: ~p", [GatewayPid]),
%% quicer_server will automatically deliver streams via new_stream/3 callback
%% No need to spawn stream acceptor - quicer_server handles it
?LOG_DEBUG("Using quicer_server automatic stream delivery"),
%% Store connection and gateway_pid in state
{ok, State#{
conn => Conn,
gateway_pid => GatewayPid
}};
new_conn(Conn, ConnProps, State) ->
%% Fallback if gateway_pid not provided
?LOG_WARNING("New connection without gateway_pid: ~p", [Conn]),
new_conn(Conn, ConnProps, State#{gateway_pid => whereis(macula_gateway)}).
%% @doc Handle connection established
connected(_Conn, _Flags, State) ->
?LOG_INFO("Connection established"),
{ok, State}.
%% @doc Handle transport shutdown
transport_shutdown(Conn, #{error := Error, status := Status}, State) ->
?LOG_WARNING("Transport shutdown: Conn=~p, Error=~p, Status=~p",
[Conn, Error, Status]),
{ok, State}.
%% @doc Handle connection shutdown
shutdown(Conn, Reason, State) ->
?LOG_INFO("Connection shutdown: Conn=~p, Reason=~p", [Conn, Reason]),
{ok, State}.
%% @doc Handle connection closed
closed(_Conn, _Flags, State) ->
?LOG_INFO("Connection closed"),
{stop, normal, State}.
%% @doc Handle local address changed
local_address_changed(_Conn, _NewAddr, State) ->
{ok, State}.
%% @doc Handle peer address changed (NAT rebinding)
%% This callback is triggered when the peer's observed address changes,
%% typically due to NAT rebinding. We need to:
%% 1. Log the address change
%% 2. Invalidate cached NAT profile for the peer
%% 3. Update connection tracking
peer_address_changed(Conn, NewAddr, #{gateway_pid := GatewayPid} = State) ->
?LOG_WARNING("Peer address changed!"),
?LOG_INFO(" Connection: ~p", [Conn]),
?LOG_INFO(" New address: ~p", [NewAddr]),
%% Notify gateway of address change (it can update client tracking)
GatewayPid ! {peer_address_changed, Conn, NewAddr},
%% If we have a node_id for this connection, invalidate its NAT profile
%% The new address means NAT rebinding occurred - cached profile is stale
case maps:get(node_id, State, undefined) of
undefined ->
?LOG_DEBUG("No node_id in state, skipping NAT cache invalidation");
NodeId ->
?LOG_INFO("Invalidating NAT cache for node ~s", [NodeId]),
case whereis(macula_nat_cache) of
undefined ->
?LOG_DEBUG("NAT cache not running");
_Pid ->
macula_nat_cache:invalidate(NodeId)
end
end,
{ok, State#{last_peer_address => NewAddr}};
peer_address_changed(Conn, NewAddr, State) ->
%% Fallback without gateway_pid
?LOG_WARNING("Peer address changed (no gateway): ~p -> ~p", [Conn, NewAddr]),
{ok, State#{last_peer_address => NewAddr}}.
%% @doc Handle streams available
streams_available(_Conn, #{bidi_streams := Bidi, unidi_streams := Unidi}, State) ->
?LOG_DEBUG("Streams available: Bidi=~p, Unidi=~p", [Bidi, Unidi]),
{ok, State}.
%% @doc Handle peer needs streams
peer_needs_streams(_Conn, _Undefined, State) ->
{ok, State}.
%% @doc Handle connection resumed
resumed(_Conn, _Data, State) ->
{ok, State}.
%% @doc Handle NST received (not used for server)
nst_received(_Conn, _Data, State) ->
{stop, no_nst_for_server, State}.
%% @doc Handle new stream
%% With quicer_server, ALL streams are delivered here (not just orphans)
%% Forward them to the gateway for processing
new_stream(Stream, Props, #{gateway_pid := GatewayPid} = State) ->
?LOG_DEBUG("========================================"),
?LOG_INFO("NEW STREAM RECEIVED!"),
?LOG_DEBUG("Stream: ~p", [Stream]),
?LOG_DEBUG("Props: ~p", [Props]),
?LOG_DEBUG("========================================"),
%% Forward stream to gateway
?LOG_DEBUG("Forwarding stream to gateway: ~p", [GatewayPid]),
GatewayPid ! {quic_stream, Stream, Props},
{ok, State};
new_stream(Stream, Props, State) ->
%% Fallback if no gateway_pid in state
?LOG_WARNING("Stream received but no gateway_pid in state"),
?LOG_WARNING("Stream: ~p, Props: ~p", [Stream, Props]),
{ok, State}.
%% @doc Handle other messages
handle_info(Info, State) ->
?LOG_WARNING("Unhandled info: ~p", [Info]),
{ok, State}.