fix sdlan_session

This commit is contained in:
anlicheng 2026-05-03 16:00:03 +08:00
parent 58e59fec82
commit c2b2140a6b

View File

@ -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(<<?PACKET_REGISTER_SUPER, Body/binary>>, 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, [<<?PACKET_REGISTER_SUPER_ACK, RegisterSuperAck/binary>>]);
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(<<?PACKET_QUERY_INFO, Body/binary>>, 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, [<<?PACKET_REGISTER_SUPER_ACK, RegisterSuperAck/binary>>]);
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'{