From c2b2140a6bb729a9b5c020d1560a7fe0c999d1e6 Mon Sep 17 00:00:00 2001 From: anlicheng <244108715@qq.com> Date: Sun, 3 May 2026 16:00:03 +0800 Subject: [PATCH] fix sdlan_session --- src/sdlan_session.erl | 158 ++++++++++++++++++++---------------------- 1 file changed, 76 insertions(+), 82 deletions(-) diff --git a/src/sdlan_session.erl b/src/sdlan_session.erl index 202047a..ef44ce8 100644 --- a/src/sdlan_session.erl +++ b/src/sdlan_session.erl @@ -73,10 +73,7 @@ test_rules(SrcIdentityId, DstIdentityId) when is_integer(SrcIdentityId), is_inte welcome_packet(MaxPacketSize, HeartbeatSec) -> Ipv6Assist = case application:get_env(sdlan, ipv6_assist_info) of {ok, {V6Bytes, Port}} -> - #'SDLV6Info' { - v6 = V6Bytes, - port = Port - }; + #'SDLV6Info'{v6 = V6Bytes, port = Port}; _ -> undefined end, @@ -93,7 +90,81 @@ welcome_packet(MaxPacketSize, HeartbeatSec) -> {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_register_super(Body, Session); + #'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'), + + true = (Mac =/= <<>> andalso PubKey =/= <<>> andalso ClientId =/= <<>>), + %% Mac地址不能是广播地址 + true = not (sdlan_util:is_multicast_mac(Mac) orelse sdlan_util:is_broadcast_mac(Mac)), + + MacBinStr = sdlan_util:format_mac(Mac), + IpAddr = sdlan_util:int_to_ipv4(Ip), + Params = #{ + <<"network_id">> => NetworkId, + <<"client_id">> => ClientId, + <<"mac">> => MacBinStr, + <<"ip">> => IpAddr, + <<"mask_len">> => MaskLen, + <<"hostname">> => HostName, + <<"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]), + + case sdlan_api:auth_access_token(Params) of + {ok, #{<<"result">> := <<"ok">>}} -> + %% 建立到network的对应关系 + case sdlan_network:get_pid(NetworkId) of + NetworkPid when is_pid(NetworkPid) -> + {ok, Algorithm, Key, RegionId, SessionToken} = sdlan_network:attach(NetworkPid, self(), ClientId, Mac, Ip, HostName), + RsaPubKey = sdlan_cipher:rsa_pem_decode(PubKey), + RegisterSuperAck = sdlan_pb:encode_msg(#'SDLRegisterSuperAck'{ + algorithm = Algorithm, + key = rsa_encode(Key, RsaPubKey), + region_id = RegionId, + session_token = SessionToken + }), + + %% 设置节点的在线状态 + Result = sdlan_api:set_node_status(#{ + <<"network_id">> => NetworkId, + <<"client_id">> => ClientId, + <<"access_token">> => AccessToken, + <<"status">> => 1 + }), + logger:debug("[sdlan_session] client_id: ~p, set none online result is: ~p", [ClientId, Result]), + + OfflineCb = fun() -> + sdlan_api:set_node_status(#{ + <<"network_id">> => NetworkId, + <<"client_id">> => ClientId, + <<"access_token">> => AccessToken, + <<"status">> => 0 + }) + end, + NSession = schedule_ping(Session#session{ + status = registered, + network_id = NetworkId, + network_pid = NetworkPid, + client_id = ClientId, + mac = Mac, + ip = Ip, + offline_cb = OfflineCb + }), + ok_result(NSession, [<>]); + undefined -> + logger:warning("[sdlan_session] client_id: ~p, register get error: network not found", [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]), + 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]), + 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) -> #'SDLQueryInfo'{dst_mac = DstMac} = sdlan_pb:decode_msg(Body, 'SDLQueryInfo'), @@ -260,83 +331,6 @@ debug_info(#session{ status = Status, client_id = ClientId, network_id = Network %%% Internal functions %%%=================================================================== -handle_register_super(Body, Session) -> - #'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'), - - true = (Mac =/= <<>> andalso PubKey =/= <<>> andalso ClientId =/= <<>>), - %% Mac地址不能是广播地址 - true = not (sdlan_util:is_multicast_mac(Mac) orelse sdlan_util:is_broadcast_mac(Mac)), - - MacBinStr = sdlan_util:format_mac(Mac), - IpAddr = sdlan_util:int_to_ipv4(Ip), - Params = #{ - <<"network_id">> => NetworkId, - <<"client_id">> => ClientId, - <<"mac">> => MacBinStr, - <<"ip">> => IpAddr, - <<"mask_len">> => MaskLen, - <<"hostname">> => HostName, - <<"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]), - - case sdlan_api:auth_access_token(Params) of - {ok, #{<<"result">> := <<"ok">>}} -> - %% 建立到network的对应关系 - case sdlan_network:get_pid(NetworkId) of - NetworkPid when is_pid(NetworkPid) -> - {ok, Algorithm, Key, RegionId, SessionToken} = sdlan_network:attach(NetworkPid, self(), ClientId, Mac, Ip, HostName), - RsaPubKey = sdlan_cipher:rsa_pem_decode(PubKey), - RegisterSuperAck = sdlan_pb:encode_msg(#'SDLRegisterSuperAck'{ - algorithm = Algorithm, - key = rsa_encode(Key, RsaPubKey), - region_id = RegionId, - session_token = SessionToken - }), - - %% 设置节点的在线状态 - Result = sdlan_api:set_node_status(#{ - <<"network_id">> => NetworkId, - <<"client_id">> => ClientId, - <<"access_token">> => AccessToken, - <<"status">> => 1 - }), - logger:debug("[sdlan_session] client_id: ~p, set none online result is: ~p", [ClientId, Result]), - - OfflineCb = fun() -> - sdlan_api:set_node_status(#{ - <<"network_id">> => NetworkId, - <<"client_id">> => ClientId, - <<"access_token">> => AccessToken, - <<"status">> => 0 - }) - end, - NSession = schedule_ping(Session#session{ - status = registered, - network_id = NetworkId, - network_pid = NetworkPid, - client_id = ClientId, - mac = Mac, - ip = Ip, - offline_cb = OfflineCb - }), - ok_result(NSession, [<>]); - undefined -> - logger:warning("[sdlan_session] client_id: ~p, register get error: network not found", [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]), - 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]), - stop_result(normal, Session, [register_nak_reply(?NAK_NETWORK_FAULT, <<"Network Error">>)]) - end. - -spec register_nak_reply(ErrorCode :: integer(), ErrorMsg :: binary()) -> binary(). register_nak_reply(ErrorCode, ErrorMsg) when is_integer(ErrorCode), is_binary(ErrorMsg) -> RegisterNakReply = sdlan_pb:encode_msg(#'SDLRegisterSuperNak'{