diff --git a/src/quic/sdlan_quic_transport.erl b/src/quic/sdlan_quic_transport.erl index 0f09b77..6ed166f 100644 --- a/src/quic/sdlan_quic_transport.erl +++ b/src/quic/sdlan_quic_transport.erl @@ -83,7 +83,7 @@ init([Conn, Limits]) -> MaxPacketSize = proplists:get_value(max_packet_size, Limits, 16384), HeartbeatSec = proplists:get_value(heartbeat_sec, Limits, 15), StreamActiveN = proplists:get_value(stream_active_n, Limits, ?STREAM_ACTIVE_N), - Session = sdlan_session:new(HeartbeatSec), + Session = sdlan_session:new(HeartbeatSec, ?MODULE), {ok, initializing, #state{ conn = Conn, max_packet_size = MaxPacketSize, diff --git a/src/sdlan_session.erl b/src/sdlan_session.erl index ef44ce8..fc008ae 100644 --- a/src/sdlan_session.erl +++ b/src/sdlan_session.erl @@ -11,7 +11,7 @@ -include("sdlan_pb.hrl"). %% API --export([new/1, handle_frame/2, handle_timeout/2]). +-export([new/2, handle_frame/2, handle_timeout/2]). -export([send_event/2, command/4, close/1, debug_info/1]). -export([welcome_packet/2]). -export([test_rules/2]). @@ -28,6 +28,7 @@ -define(NAK_INTERNAL_FAULT, 5). -record(session, { + transport :: atom(), status = initialized :: initialized | registered, %% 心跳间隔 heartbeat_sec = 15, @@ -58,9 +59,9 @@ %%% API %%%=================================================================== --spec new(HeartbeatSec :: integer()) -> #session{}. -new(HeartbeatSec) -> - #session{heartbeat_sec = HeartbeatSec}. +-spec new(HeartbeatSec :: integer(), Transport :: atom()) -> #session{}. +new(HeartbeatSec, Transport) -> + #session{heartbeat_sec = HeartbeatSec, transport = Transport}. %% 测试规则函数 -spec test_rules(SrcIdentityId :: integer(), DstIdentityId :: integer()) -> binary(). @@ -89,7 +90,7 @@ welcome_packet(MaxPacketSize, HeartbeatSec) -> -spec handle_frame(Frame :: binary(), Session :: #session{}) -> {ok, StateName :: initialized | registered, NewSession :: #session{}, Packets :: [binary()]} | {stop, Reason :: term(), StateName :: initialized | registered, NewSession :: #session{}, Packets :: [binary()]}. -handle_frame(<>, Session = #session{status = initialized}) -> +handle_frame(<>, Session = #session{status = initialized, transport = Transport}) -> #'SDLRegisterSuper'{ client_id = ClientId, network_id = NetworkId, mac = Mac, ip = Ip, mask_len = MaskLen, hostname = HostName, pub_key = PubKey, access_token = AccessToken} = sdlan_pb:decode_msg(Body, 'SDLRegisterSuper'), @@ -110,8 +111,8 @@ handle_frame(<>, Session = #session{status <<"access_token">> => AccessToken }, %% 参数检查 - logger:debug("[sdlan_session] client_id: ~p, ip: ~p, mac: ~p, host_name: ~p, access_token: ~p, network_id: ~p", - [ClientId, Ip, Mac, HostName, AccessToken, NetworkId]), + logger:debug("[sdlan_session] transport: ~p, client_id: ~p, ip: ~p, mac: ~p, host_name: ~p, access_token: ~p, network_id: ~p", + [Transport, ClientId, Ip, Mac, HostName, AccessToken, NetworkId]), case sdlan_api:auth_access_token(Params) of {ok, #{<<"result">> := <<"ok">>}} -> @@ -134,7 +135,7 @@ handle_frame(<>, Session = #session{status <<"access_token">> => AccessToken, <<"status">> => 1 }), - logger:debug("[sdlan_session] client_id: ~p, set none online result is: ~p", [ClientId, Result]), + logger:debug("[sdlan_session] tranport: ~p, client_id: ~p, set none online result is: ~p", [Transport, ClientId, Result]), OfflineCb = fun() -> sdlan_api:set_node_status(#{ @@ -155,23 +156,23 @@ handle_frame(<>, Session = #session{status }), ok_result(NSession, [<>]); undefined -> - logger:warning("[sdlan_session] client_id: ~p, register get error: network not found", [ClientId]), + logger:warning("[sdlan_session] transport: ~p, client_id: ~p, register get error: network not found", [Transport, ClientId]), stop_result(normal, Session, [register_nak_reply(?NAK_INTERNAL_FAULT, <<"Internal Error">>)]) end; {ok, #{<<"error">> := #{<<"code">> := Code, <<"message">> := Message}}} -> - logger:warning("[sdlan_session] network_id: ~p, client_id: ~p, register get error: ~ts, error_code: ~p", [NetworkId, ClientId, Message, Code]), + logger:warning("[sdlan_session] transport: ~p, network_id: ~p, client_id: ~p, register get error: ~ts, error_code: ~p", [Transport, NetworkId, ClientId, Message, Code]), stop_result(normal, Session, [register_nak_reply(Code, Message)]); {error, Reason} -> - logger:warning("[sdlan_session] network_id: ~p, client_id: ~p, register get error: ~p", [NetworkId, ClientId, Reason]), + logger:warning("[sdlan_session] transport: ~p, network_id: ~p, client_id: ~p, register get error: ~p", [Transport, NetworkId, ClientId, Reason]), stop_result(normal, Session, [register_nak_reply(?NAK_NETWORK_FAULT, <<"Network Error">>)]) end; -handle_frame(<>, Session = #session{status = registered, network_pid = NetworkPid, mac = SrcMac}) when is_pid(NetworkPid) -> +handle_frame(<>, Session = #session{status = registered, network_pid = NetworkPid, mac = SrcMac, transport = Transport}) when is_pid(NetworkPid) -> #'SDLQueryInfo'{dst_mac = DstMac} = sdlan_pb:decode_msg(Body, 'SDLQueryInfo'), case sdlan_network:peer_info(NetworkPid, SrcMac, DstMac) of error -> - logger:debug("[sdlan_session] query_info src_mac is: ~p, dst_mac: ~p, nat_peer not found", - [sdlan_util:format_mac(SrcMac), sdlan_util:format_mac(DstMac)]), + logger:debug("[sdlan_session] transport: ~p, query_info src_mac is: ~p, dst_mac: ~p, nat_peer not found", + [Transport, sdlan_util:format_mac(SrcMac), sdlan_util:format_mac(DstMac)]), EmptyResponse = sdlan_pb:encode_msg(#'SDLPeerInfo'{ dst_mac = DstMac, @@ -180,8 +181,8 @@ handle_frame(<>, Session = #session{status = re }), ok_result(Session, [<>]); {ok, {NatPeer = {{Ip0, Ip1, Ip2, Ip3}, NatPort}, NatType}, V6Info} -> - logger:debug("[sdlan_session] query_info src_mac is: ~p, dst_mac: ~p, nat_peer: ~p", - [sdlan_util:format_mac(SrcMac), sdlan_util:format_mac(DstMac), NatPeer]), + logger:debug("[sdlan_session] transport: ~p, query_info src_mac is: ~p, dst_mac: ~p, nat_peer: ~p", + [Transport, sdlan_util:format_mac(SrcMac), sdlan_util:format_mac(DstMac), NatPeer]), PeerInfo = sdlan_pb:encode_msg(#'SDLPeerInfo'{ dst_mac = DstMac, @@ -196,11 +197,15 @@ handle_frame(<>, Session = #session{status = re end; %% arp查询 -handle_frame(<>, Session = #session{status = registered, network_id = NetworkId, network_pid = NetworkPid}) when is_pid(NetworkPid) -> +handle_frame(<>, + Session = #session{status = registered, network_id = NetworkId, network_pid = NetworkPid, transport = Transport}) when is_pid(NetworkPid) -> + #'SDLArpRequest'{target_ip = TargetIp, origin_ip = OriginIp, context = Context} = sdlan_pb:decode_msg(Body, 'SDLArpRequest'), case sdlan_network:arp_request(NetworkPid, TargetIp) of error -> - logger:debug("[sdlan_session] network: ~p, arp_request target_ip: ~p, mac not found", [NetworkId, sdlan_util:int_to_ipv4(TargetIp)]), + logger:debug("[sdlan_session] transport: ~p, network: ~p, arp_request target_ip: ~p, mac not found", + [Transport, NetworkId, sdlan_util:int_to_ipv4(TargetIp)]), + EmptyArpResponsePkt = sdlan_pb:encode_msg(#'SDLArpResponse'{ target_ip = TargetIp, target_mac = <<>>, @@ -209,7 +214,8 @@ handle_frame(<>, Session = #session{status = r }), ok_result(Session, [<>]); {ok, Mac} -> - logger:debug("[sdlan_session] network: ~p, arp_request target_ip: ~p, mac: ~p", [NetworkId, sdlan_util:int_to_ipv4(TargetIp), sdlan_util:format_mac(Mac)]), + logger:debug("[sdlan_session] transport: ~p, network: ~p, arp_request target_ip: ~p, mac: ~p", + [Transport, NetworkId, sdlan_util:int_to_ipv4(TargetIp), sdlan_util:format_mac(Mac)]), ArpResponsePkt = sdlan_pb:encode_msg(#'SDLArpResponse'{ target_ip = TargetIp, target_mac = Mac, @@ -219,12 +225,13 @@ handle_frame(<>, Session = #session{status = r ok_result(Session, [<>]) end; -handle_frame(<>, Session = #session{status = registered, network_pid = NetworkPid}) when is_pid(NetworkPid) -> +handle_frame(<>, Session = #session{status = registered, network_pid = NetworkPid, transport = Transport}) when is_pid(NetworkPid) -> Packets = maybe #'SDLPolicyRequest'{src_identity_id = SrcIdentityId, dst_identity_id = DstIdentityId, version = Version} ?= sdlan_pb:decode_msg(Body, 'SDLPolicyRequest'), {ok, Rules} = get_rules(SrcIdentityId, DstIdentityId), - logger:debug("[sdlan_session] policy_request src_identity_id: ~p, dst_identity_id: ~p, rules: ~p", [SrcIdentityId, DstIdentityId, Rules]), + logger:debug("[sdlan_session] transport: ~p, policy_request src_identity_id: ~p, dst_identity_id: ~p, rules: ~p", + [Transport, SrcIdentityId, DstIdentityId, Rules]), RuleBin = iolist_to_binary(lists:map(fun({Proto, Port}) -> <> end, Rules)), PolicyResponsePkt = sdlan_pb:encode_msg(#'SDLPolicyResponse'{ @@ -240,8 +247,9 @@ handle_frame(<>, Session = #session{status ok_result(Session, Packets); %% 处理命令的响应逻辑 -handle_frame(<>, Session = #session{status = registered, pending_commands = PendingCommands}) -> - maybe +handle_frame(<>, Session = #session{status = registered, pending_commands = PendingCommands, transport = Transport}) -> + logger:debug("[sdlan_session] transport: ~p command_ack", [Transport]), + maybe CommandAck = sdlan_pb:decode_msg(Body, 'SDLCommandAck'), #'SDLCommandAck'{pkt_id = PktId} ?= CommandAck, @@ -257,29 +265,31 @@ handle_frame(<>, Session = #session{status = r ok_result(Session, []) end; -handle_frame(<>, Session = #session{ping_counter = PingCounter, client_id = ClientId}) -> - logger:warning("[sdlan_session] get ping: ~p", [ClientId]), +handle_frame(<>, Session = #session{ping_counter = PingCounter, client_id = ClientId, transport = Transport}) -> + logger:warning("[sdlan_session] transport: ~p, get ping: ~p", [Transport, ClientId]), ok_result(Session#session{ping_counter = PingCounter + 1}, [<>]); %% 取消注册 -handle_frame(<>, Session = #session{status = registered, client_id = ClientId, mac = Mac, network_pid = NetworkPid}) when is_pid(NetworkPid) -> - logger:warning("[sdlan_session] unregister client_id: ~p", [ClientId]), +handle_frame(<>, Session = #session{status = registered, client_id = ClientId, mac = Mac, network_pid = NetworkPid, transport = Transport}) + when is_pid(NetworkPid) -> + + logger:warning("[sdlan_session] transport: ~p, unregister client_id: ~p", [Transport, ClientId]), sdlan_network:unregister(NetworkPid, ClientId, Mac), stop_result(normal, Session, []); -handle_frame(Frame, Session) -> - logger:notice("[sdlan_session] unexpected frame: ~p, status: ~p", [Frame, Session#session.status]), +handle_frame(Frame, Session = #session{transport = Transport}) -> + logger:notice("[sdlan_session] transport: ~p, unexpected frame: ~p, status: ~p", [Transport, Frame, Session#session.status]), ok_result(Session, []). -spec handle_timeout(TimerRef :: reference(), Session :: #session{}) -> {ok, StateName :: initialized | registered, NewSession :: #session{}} | {stop, Reason :: term(), StateName :: initialized | registered, NewSession :: #session{}}. -handle_timeout(TimerRef, Session = #session{ping_timer = TimerRef, client_id = ClientId, ping_counter = PingCounter}) -> +handle_timeout(TimerRef, Session = #session{ping_timer = TimerRef, client_id = ClientId, ping_counter = PingCounter, transport = Transport}) -> case PingCounter > 0 of true -> ok_timeout_result(schedule_ping(Session#session{ping_counter = 0, ping_timer = undefined})); false -> - logger:debug("[sdlan_session] client_id: ~p, ping losted", [ClientId]), + logger:debug("[sdlan_session] transport: ~p, client_id: ~p, ping losted", [Transport, ClientId]), stop_timeout_result(heartbeat_timeout, Session#session{ping_counter = 0, ping_timer = undefined}) end; handle_timeout(_TimerRef, Session) -> @@ -294,13 +304,13 @@ send_event(_Event, _Session) -> -spec command(Ref :: reference(), ReceiverPid :: pid(), {Tag :: atom(), SubCommand :: any()}, Session :: #session{}) -> {ok, StateName :: initialized | registered, NewSession :: #session{}, Packets :: [binary()]} | {error, not_registered}. -command(Ref, ReceiverPid, SubCommand, Session = #session{status = registered, pkt_id = PktId, pending_commands = PendingCommands, client_id = ClientId}) +command(Ref, ReceiverPid, SubCommand, Session = #session{status = registered, pkt_id = PktId, pending_commands = PendingCommands, client_id = ClientId, transport = Transport}) when is_reference(Ref), is_pid(ReceiverPid) -> CommandPkt = sdlan_pb:encode_msg(#'SDLCommand'{ pkt_id = PktId, command = SubCommand }), - logger:debug("[sdlan_session] client_id: ~p, will send Command: ~p", [ClientId, SubCommand]), + logger:debug("[sdlan_session] transport: ~p, client_id: ~p, will send Command: ~p", [Transport, ClientId, SubCommand]), ok_result(Session#session{pkt_id = PktId + 1, pending_commands = maps:put(PktId, {Ref, ReceiverPid}, PendingCommands)}, [<>]); diff --git a/src/ssl/sdlan_ssl_transport.erl b/src/ssl/sdlan_ssl_transport.erl index 2beed21..90f425b 100644 --- a/src/ssl/sdlan_ssl_transport.erl +++ b/src/ssl/sdlan_ssl_transport.erl @@ -49,7 +49,7 @@ start_link(Ref, Socket, Transport, Limits) -> init([Ref, Socket, Transport, Limits]) -> MaxPacketSize = proplists:get_value(max_packet_size, Limits, 16384), HeartbeatSec = proplists:get_value(heartbeat_sec, Limits, 15), - Session = sdlan_session:new(HeartbeatSec), + Session = sdlan_session:new(HeartbeatSec, ?MODULE), {ok, handshaking, #state{ ref = Ref, socket = Socket,