This commit is contained in:
anlicheng 2026-01-26 22:48:03 +08:00
parent a4efafd484
commit 672da8d7b1
7 changed files with 52 additions and 41 deletions

View File

@ -19,13 +19,7 @@
%%
handle_request("POST", "/test/auth_token", _, PostParams) ->
logger:debug("[test_handler] get post params: ~p", [PostParams]),
Data = #{
<<"network_id">> => 8,
<<"upgrade_type">> => 0,
<<"upgrade_prompt">> => <<"simple upgrade">>,
<<"upgrade_address">> => <<"upgrade_address">>
},
{ok, 200, sdlan_util:json_data(Data)};
{ok, 200, sdlan_util:json_data(<<"ok">>)};
handle_request("POST", "/test/upgrade", _, PostParams) ->
logger:debug("[test_handler] get post params: ~p", [PostParams]),

View File

@ -27,11 +27,11 @@ lookup(FullHostname) when is_binary(FullHostname) ->
end.
-spec insert(any(), Domain :: binary(), Ip :: integer()) -> no_return().
insert(<<>>, _Domain, _Ip) ->
ok;
insert(HostName, Domain, Ip) when is_integer(HostName), is_binary(Domain), is_integer(Ip) ->
insert(HostName, Domain, Ip) when is_binary(HostName), is_binary(Domain), is_integer(Ip), HostName /= <<>> ->
FullHostname = <<HostName/binary, ".", Domain/binary>>,
insert(FullHostname, Ip).
insert(FullHostname, Ip);
insert(_, _, _) ->
ok.
-spec insert(FullHostname :: binary(), Ip :: integer()) -> no_return().
insert(FullHostname, Ip) when is_binary(FullHostname), is_integer(Ip) ->

View File

@ -90,9 +90,9 @@ lookup_pid(Id) when is_integer(Id) ->
get_name(Id) when is_integer(Id) ->
list_to_atom("sdlan_network:" ++ integer_to_list(Id)).
-spec attach(Pid :: pid(), Peer :: {Ip :: inet:ip4_address(), Port :: integer()}, ClientId :: binary(), Mac :: binary(), Ip :: inet:ip4_address(), HostName :: binary()) ->
-spec attach(Pid :: pid(), Peer :: {Ip :: inet:ip4_address(), Port :: integer()}, ClientId :: binary(), Mac :: binary(), Ip :: integer(), HostName :: binary()) ->
{ok, Domain :: binary(), MaskLen :: integer(), AesKey :: binary()} | {error, Reason :: any()}.
attach(Pid, Peer, ClientId, Mac, Ip, HostName) when is_pid(Pid), is_binary(ClientId), is_binary(Mac) ->
attach(Pid, Peer, ClientId, Mac, Ip, HostName) when is_pid(Pid), is_binary(ClientId), is_binary(Mac), is_integer(Ip) ->
gen_server:call(Pid, {attach, Peer, ClientId, Mac, Ip, HostName}).
-spec get_network_id(Pid :: pid()) -> {ok, NetworkId :: integer()}.
@ -354,7 +354,7 @@ handle_cast({stun_request, Sock, Peer = {ClientIp, ClientPort}, #sdl_stun_reques
case maps:find(Mac, Endpoints) of
%% ClientId =:= ClientId0, SessionToken =:= SessionToken0
{ok, Endpoint0 = #endpoint{ip = Ip, client_id = ClientId, hole = OldHole, session_token = ST}} ->
{ok, Endpoint0 = #endpoint{ip = Ip, client_id = ClientId, hole = OldHole, session_token = ST}} when 1 == 2 ->
NHole = #hole{peer = Peer, nat_type = NatType},
maybe
%% hole changed -> notify peers
@ -364,11 +364,15 @@ handle_cast({stun_request, Sock, Peer = {ClientIp, ClientPort}, #sdl_stun_reques
ip = Ip
}),
EventPacket = <<?PACKET_EVENT, ?PACKET_EVENT_NAT_CHANGED, NatChangedEvent/binary>>,
EndpointPeers = endpoint_peers([Mac], Endpoints),
logger:debug("[sdlan_network] hole changed, mac: ~p, ip: ~p, notify peers: ~p", [Mac, Ip, EndpointPeers]),
sdlan_stun_pool:send_packets(EndpointPeers, EventPacket)
end,
{noreply, State#state{endpoints = maps:put(Mac, Endpoint0#endpoint{hole = NHole, v6_info = V6Info, last_seen = erlang:monotonic_time(second)}, Endpoints)}};
NEndpoint = Endpoint0#endpoint{hole = NHole, v6_info = V6Info, last_seen = erlang:monotonic_time(second)},
logger:debug("[sdlan_network] mac: ~p, ip: ~p, endpoint is: ~p", [Mac, Ip, NEndpoint]),
{noreply, State#state{endpoints = maps:put(Mac, NEndpoint, Endpoints)}};
_ ->
%%
RefreshAuthEvent = sdlan_pb:encode_msg(#sdl_refresh_auth_event{

View File

@ -31,14 +31,10 @@
start_link(Sock, Ip, Port, Packet) ->
{ok, erlang:spawn_link(?MODULE, do_register, [Sock, Ip, Port, Packet])}.
do_register(Sock, SrcIp, SrcPort, #sdl_register_super{
do_register(Sock, ClientIp, ClientPort, #sdl_register_super{
pkt_id = PktId, client_id = ClientId, network_id = NetworkId, mac = Mac, ip = Ip, mask_len = MaskLen,
hostname = HostName, pub_key = PubKey, access_token = AccessToken}) ->
%%
logger:debug("[sdlan_channel] client_id: ~p, ip: ~p, mac: ~p, host_name: ~p, access_token: ~p, network_id: ~p",
[ClientId, Ip, Mac, HostName, AccessToken, NetworkId]),
true = (Mac =/= <<>> andalso PubKey =/= <<>> andalso ClientId =/= <<>>),
%% Mac地址不能是广播地址
true = not (sdlan_util:is_multicast_mac(Mac) orelse sdlan_util:is_broadcast_mac(Mac)),
@ -53,12 +49,19 @@ do_register(Sock, SrcIp, SrcPort, #sdl_register_super{
<<"access_token">> => AccessToken
},
case sdlan_api:auth_access_token(Params) of
%%
logger:debug("[sdlan_register_worker] xyz client_id: ~p, ip: ~p, mac: ~p, host_name: ~p, access_token: ~p, network_id: ~p",
[ClientId, Ip, Mac, HostName, AccessToken, NetworkId]),
%% TODO
%AuthResult = sdlan_api:auth_access_token(Params),
AuthResult = {ok, #{<<"result">> => <<"ok">>}},
case AuthResult of
{ok, #{<<"result">> := <<"ok">>}} ->
%% network的对应关系
case sdlan_network:get_pid(NetworkId) of
NetworkPid when is_pid(NetworkPid) ->
case sdlan_network:attach(NetworkPid, {SrcIp, SrcPort}, ClientId, Mac, Ip, HostName) of
case sdlan_network:attach(NetworkPid, {ClientIp, ClientPort}, ClientId, Mac, Ip, HostName) of
{ok, AesKey, SessionToken} ->
RsaPubKey = sdlan_cipher:rsa_pem_decode(PubKey),
EncodedAesKey = rsa_encode(AesKey, RsaPubKey),
@ -71,31 +74,31 @@ do_register(Sock, SrcIp, SrcPort, #sdl_register_super{
%%
Reply = <<?PACKET_REGISTER_SUPER_ACK, RegisterSuperAck/binary>>,
gen_udp:send(Sock, SrcIp, SrcPort, Reply),
gen_udp:send(Sock, ClientIp, ClientPort, Reply),
%% 线
Result = sdlan_api:node_online(ClientId, NetworkId, sdlan_ipaddr:int_to_ipv4(Ip)),
logger:debug("[sdlan_channel] client_id: ~p, set none online result is: ~p", [ClientId, Result]);
logger:debug("[sdlan_register_worker] client_id: ~p, set none online result is: ~p", [ClientId, Result]);
{error, no_ip} ->
logger:warning("[sdlan_channel] client_id: ~p, register get error: no_ip", [ClientId]),
gen_udp:send(Sock, SrcIp, SrcPort, register_nak_reply(PktId, ?NAK_NO_IP, <<"No Ip address">>));
logger:warning("[sdlan_register_worker] client_id: ~p, register get error: no_ip", [ClientId]),
gen_udp:send(Sock, ClientIp, ClientPort, register_nak_reply(PktId, ?NAK_NO_IP, <<"No Ip address">>));
{error, host_name_used} ->
logger:warning("[sdlan_channel] client_id: ~p, register get error: host_name_used", [ClientId]),
gen_udp:send(Sock, SrcIp, SrcPort, register_nak_reply(PktId, ?NAK_HOSTNAME_USED, <<"Host Name Used">>));
logger:warning("[sdlan_register_worker] client_id: ~p, register get error: host_name_used", [ClientId]),
gen_udp:send(Sock, ClientIp, ClientPort, register_nak_reply(PktId, ?NAK_HOSTNAME_USED, <<"Host Name Used">>));
{error, client_disabled} ->
logger:warning("[sdlan_channel] client_id: ~p, register get error: client_disabled", [ClientId]),
gen_udp:send(Sock, SrcIp, SrcPort, register_nak_reply(PktId, ?NAK_NODE_DISABLE, <<"Client Connection Disable">>))
logger:warning("[sdlan_register_worker] client_id: ~p, register get error: client_disabled", [ClientId]),
gen_udp:send(Sock, ClientIp, ClientPort, register_nak_reply(PktId, ?NAK_NODE_DISABLE, <<"Client Connection Disable">>))
end;
undefined ->
logger:warning("[sdlan_channel] client_id: ~p, register get error: network not found", [ClientId]),
gen_udp:send(Sock, SrcIp, SrcPort, register_nak_reply(PktId, ?NAK_INTERNAL_FAULT, <<"Internal Error">>))
logger:warning("[sdlan_register_worker] client_id: ~p, register get error: network not found", [ClientId]),
gen_udp:send(Sock, ClientIp, ClientPort, register_nak_reply(PktId, ?NAK_INTERNAL_FAULT, <<"Internal Error">>))
end;
{ok, #{<<"error">> := #{<<"code">> := Code, <<"message">> := Message}}} ->
logger:warning("[sdlan_channel] network_id: ~p, client_id: ~p, register get error: ~ts, error_code: ~p", [NetworkId, ClientId, Message, Code]),
gen_udp:send(Sock, SrcIp, SrcPort, register_nak_reply(PktId, Code, Message));
logger:warning("[sdlan_register_worker] network_id: ~p, client_id: ~p, register get error: ~ts, error_code: ~p", [NetworkId, ClientId, Message, Code]),
gen_udp:send(Sock, ClientIp, ClientPort, register_nak_reply(PktId, Code, Message));
{error, Reason} ->
logger:warning("[sdlan_channel] network_id: ~p, client_id: ~p, register get error: ~p", [NetworkId, ClientId, Reason]),
gen_udp:send(Sock, SrcIp, SrcPort, register_nak_reply(PktId, ?NAK_NETWORK_FAULT, <<"Network Error">>))
logger:warning("[sdlan_register_worker] network_id: ~p, client_id: ~p, register get error: ~p", [NetworkId, ClientId, Reason]),
gen_udp:send(Sock, ClientIp, ClientPort, register_nak_reply(PktId, ?NAK_NETWORK_FAULT, <<"Network Error">>))
end,
exit(normal).

View File

@ -47,14 +47,16 @@ start_link() ->
init([]) ->
SupFlags = #{strategy => simple_one_for_one, intensity => 1000, period => 3600},
ChildSpec = #{id => sdlan_register_worker,
ChildSpec = #{
id => sdlan_register_worker,
start => {sdlan_register_worker, start_link, []},
restart => temporary,
shutdown => 2000,
type => worker,
modules => [sdlan_register_worker]},
modules => [sdlan_register_worker]
},
{ok, {SupFlags, ChildSpec}}.
{ok, {SupFlags, [ChildSpec]}}.
%%%===================================================================
%%% Internal functions

View File

@ -149,6 +149,12 @@ handle_info({udp, _Socket, _ServerIp, _ServerPort, <<?PACKET_REGISTER_SUPER_NAK,
logger:debug("[stun_client] get a register super nak: ~p", [SuperNak]),
{noreply, State#state{}};
%%
handle_info({udp, _Socket, _ServerIp, _ServerPort, <<?PACKET_EVENT, ?PACKET_EVENT_REFRESH_AUTH, Data/binary>>}, State) ->
Event = #sdl_refresh_auth_event{} = sdlan_pb:decode_msg(Data, sdl_refresh_auth_event),
logger:debug("[stun_client] get a refresh_auth_event: ~p", [Event]),
{stop, refresh_auth, State};
handle_info({timeout, _, stun_request_ticker}, State = #state{tun_socket = TunSocket, client_id = ClientId, mac = Mac, ip = Ip, session_token = SessionToken}) ->
Packet = sdlan_pb:encode_msg(#sdl_stun_request{
client_id = ClientId,
@ -158,6 +164,8 @@ handle_info({timeout, _, stun_request_ticker}, State = #state{tun_socket = TunSo
nat_type = 0,
session_token = SessionToken
}),
logger:debug("timer ticker will send packet: ~p", [Packet]),
gen_udp:send(TunSocket, ?SUPER_HOST, ?SUPER_PORT, <<?PACKET_STUN_REQUEST, Packet/binary>>),
erlang:start_timer(5000, self(), stun_request_ticker),

View File

@ -14,7 +14,7 @@
%% stun类型探测相当于有个类型
{stun_servers, [
{port, 1265},
{acceptor_nums, 5}
{acceptor_nums, 1}
]},
{stun_port_assist, [