This commit is contained in:
anlicheng 2026-02-13 16:50:29 +08:00
parent 9dad8b6ee8
commit 7a4ab39bc3
3 changed files with 51 additions and 48 deletions

View File

@ -141,7 +141,7 @@ handle_event(info, {frame, <<PacketId:32, ?PACKET_REGISTER_SUPER, Body/binary>>}
%% network的对应关系 %% network的对应关系
case sdlan_network:get_pid(NetworkId) of case sdlan_network:get_pid(NetworkId) of
NetworkPid when is_pid(NetworkPid) -> NetworkPid when is_pid(NetworkPid) ->
{ok, AesKey, SessionToken} = sdlan_network:attach(NetworkPid, {ClientIp, ClientPort}, ClientId, Mac, Ip, HostName), {ok, AesKey, SessionToken} = sdlan_network:attach(NetworkPid, self(), ClientId, Mac, Ip, HostName),
RsaPubKey = sdlan_cipher:rsa_pem_decode(PubKey), RsaPubKey = sdlan_cipher:rsa_pem_decode(PubKey),
EncodedAesKey = rsa_encode(AesKey, RsaPubKey), EncodedAesKey = rsa_encode(AesKey, RsaPubKey),

View File

@ -21,7 +21,7 @@
%% API %% API
-export([start_link/2]). -export([start_link/2]).
-export([get_name/1, get_pid/1, peer_info/3, unregister/3, debug_info/1, get_network_id/1, attach/6]). -export([get_name/1, get_pid/1, lookup_pid/1, peer_info/3, unregister/3, debug_info/1, get_network_id/1, attach/6]).
-export([forward/5, update_hole/6, disable_client/2, get_channel/2]). -export([forward/5, update_hole/6, disable_client/2, get_channel/2]).
-export([test_event/1]). -export([test_event/1]).
@ -79,6 +79,15 @@ test_event(Pid) ->
get_pid(Id) when is_integer(Id) -> get_pid(Id) when is_integer(Id) ->
whereis(get_name(Id)). whereis(get_name(Id)).
-spec lookup_pid(Id :: integer()) -> {ok, Pid :: pid()} | error.
lookup_pid(Id) when is_integer(Id) ->
case whereis(get_name(Id)) of
undefined ->
error;
Pid ->
{ok, Pid}
end.
-spec get_name(Id :: integer()) -> atom(). -spec get_name(Id :: integer()) -> atom().
get_name(Id) when is_integer(Id) -> get_name(Id) when is_integer(Id) ->
list_to_atom("sdlan_network:" ++ integer_to_list(Id)). list_to_atom("sdlan_network:" ++ integer_to_list(Id)).
@ -87,7 +96,8 @@ get_name(Id) when is_integer(Id) ->
get_network_id(Pid) when is_pid(Pid) -> get_network_id(Pid) when is_pid(Pid) ->
gen_server:call(Pid, get_network_id). gen_server:call(Pid, get_network_id).
-spec attach(Pid :: pid(), ChannelPid :: pid(), ClientId :: binary(), Mac :: binary(), Ip :: integer(), Hostname :: binary()) -> any(). -spec attach(Pid :: pid(), ChannelPid :: pid(), ClientId :: binary(), Mac :: binary(), Ip :: integer(), Hostname :: binary()) ->
{ok, AesKey :: binary(), SessionToken :: binary()}.
attach(Pid, ChannelPid, ClientId, Mac, Ip, Hostname) when is_pid(Pid), is_pid(ChannelPid), is_binary(ClientId), is_binary(Mac), is_integer(Ip), is_binary(Hostname) -> attach(Pid, ChannelPid, ClientId, Mac, Ip, Hostname) when is_pid(Pid), is_pid(ChannelPid), is_binary(ClientId), is_binary(Mac), is_integer(Ip), is_binary(Hostname) ->
gen_server:call(Pid, {attach, ChannelPid, ClientId, Mac, Ip, Hostname}). gen_server:call(Pid, {attach, ChannelPid, ClientId, Mac, Ip, Hostname}).

View File

@ -99,35 +99,32 @@ handle_cast({stun_relay, Ip, Port, Reply}, State = #state{socket = Sock}) ->
{stop, Reason :: term(), NewState :: #state{}}). {stop, Reason :: term(), NewState :: #state{}}).
handle_info({udp, Sock, Ip, Port, <<?PACKET_STUN_REQUEST:8, Body/binary>>}, State = #state{socket = Sock}) -> handle_info({udp, Sock, Ip, Port, <<?PACKET_STUN_REQUEST:8, Body/binary>>}, State = #state{socket = Sock}) ->
#sdl_stun_request{cookie = Cookie, client_id = ClientId, network_id = NetworkId, mac = Mac, nat_type = NatType, v6_info = V6Info} = sdlan_pb:decode_msg(Body, sdl_stun_request), StunRequest = catch sdlan_pb:decode_msg(Body, sdl_stun_request),
%% ip对应的nat的映射关系 %% ip对应的nat的映射关系
maybe
case sdlan_network:get_pid(NetworkId) of #sdl_stun_request{cookie = Cookie, client_id = ClientId, network_id = NetworkId, mac = Mac, nat_type = NatType, v6_info = V6Info} ?= StunRequest,
undefined -> {ok, NetworkPid} ?= sdlan_network:lookup_pid(NetworkId),
logger:debug("[sdlan_stun] stun_request network_id: ~p, client_id: ~p, not found", [NetworkId, ClientId]),
{noreply, State};
NetworkPid when is_pid(NetworkPid) ->
sdlan_network:update_hole(NetworkPid, ClientId, Mac, {Ip, Port}, NatType, V6Info), sdlan_network:update_hole(NetworkPid, ClientId, Mac, {Ip, Port}, NatType, V6Info),
StunReply = sdlan_pb:encode_msg(#sdl_stun_reply{ StunReply = sdlan_pb:encode_msg(#sdl_stun_reply{
cookie = Cookie cookie = Cookie
}), }),
ok = gen_udp:send(Sock, Ip, Port, <<?PACKET_STUN_REPLY, StunReply/binary>>), ok = gen_udp:send(Sock, Ip, Port, <<?PACKET_STUN_REPLY, StunReply/binary>>),
logger:debug("[sdlan_stun] stun_request network_id: ~p, client_id: ~p, hole: ~p", [NetworkId, ClientId, {Ip, Port}]), logger:debug("[sdlan_stun] stun_request network_id: ~p, client_id: ~p, hole: ~p", [NetworkId, ClientId, {Ip, Port}])
{noreply, State} end,
end; {noreply, State};
%% nat类型的探测机制, %% nat类型的探测机制,
%% assist的配置attr = 2 %% assist的配置attr = 2
handle_info({udp, Sock, ClientIp, ClientPort, <<?PACKET_STUN_PROBE:8, Body/binary>>}, State = #state{socket = Sock}) -> handle_info({udp, Sock, ClientIp, ClientPort, <<?PACKET_STUN_PROBE:8, Body/binary>>}, State = #state{socket = Sock}) ->
#sdl_stun_probe{cookie = Cookie, attr = Attr} = sdlan_pb:decode_msg(Body, sdl_stun_probe), StunProbe = catch sdlan_pb:decode_msg(Body, sdl_stun_probe),
maybe
#sdl_stun_probe{cookie = Cookie, attr = Attr} ?= StunProbe,
logger:debug("[sdlan_stun] get stun_probe request, att: ~p", [Attr]), logger:debug("[sdlan_stun] get stun_probe request, att: ~p", [Attr]),
ProbeReplyPkt = sdlan_pb:encode_msg(#sdl_stun_probe_reply { ProbeReplyPkt = sdlan_pb:encode_msg(#sdl_stun_probe_reply {
cookie = Cookie, cookie = Cookie,
port = ClientPort, port = ClientPort,
ip = int_ip(ClientIp) ip = int_ip(ClientIp)
}), }),
case Attr of case Attr of
?STUN_ATTR_CHANGE_NONE -> ?STUN_ATTR_CHANGE_NONE ->
ok = gen_udp:send(Sock, ClientIp, ClientPort, <<?PACKET_STUN_PROBE_REPLY, ProbeReplyPkt/binary>>); ok = gen_udp:send(Sock, ClientIp, ClientPort, <<?PACKET_STUN_PROBE_REPLY, ProbeReplyPkt/binary>>);
@ -137,6 +134,7 @@ handle_info({udp, Sock, ClientIp, ClientPort, <<?PACKET_STUN_PROBE:8, Body/binar
?STUN_ATTR_CHANGE_PEER -> ?STUN_ATTR_CHANGE_PEER ->
%% %%
sdlan_stun_port_assist:stun_relay(ClientIp, ClientPort, ProbeReplyPkt) sdlan_stun_port_assist:stun_relay(ClientIp, ClientPort, ProbeReplyPkt)
end
end, end,
{noreply, State}; {noreply, State};
@ -147,19 +145,14 @@ handle_info({udp, Sock, _, _, <<?PACKET_STUN_PROBE_RELAY:8, Ip0, Ip1, Ip2, Ip3,
{noreply, State}; {noreply, State};
handle_info({udp, _, _Ip, _Port, <<?PACKET_STUN_DATA, Body/binary>>}, State = #state{socket = Sock}) -> handle_info({udp, _, _Ip, _Port, <<?PACKET_STUN_DATA, Body/binary>>}, State = #state{socket = Sock}) ->
Data = #sdl_data{network_id = NetworkId, src_mac = SrcMac, dst_mac = DstMac, ttl = TTL} = sdlan_pb:decode_msg(Body, sdl_data), Data = catch sdlan_pb:decode_msg(Body, sdl_data),
maybe
logger:debug("[sdlan_stun] stun data, src_mac: ~p, dst_mac: ~p", [sdlan_util:format_mac(SrcMac), sdlan_util:format_mac(DstMac)]), #sdl_data{network_id = NetworkId, src_mac = SrcMac, dst_mac = DstMac, ttl = TTL} ?= Data,
{ok, NetworkPid} ?= sdlan_network:lookup_pid(NetworkId),
%% ttl需要减1 %% ttl需要减1
case sdlan_network:get_pid(NetworkId) of
NetworkPid when is_pid(NetworkPid) ->
NData = sdlan_pb:encode_msg(Data#sdl_data{ttl = TTL - 1, is_p2p = false}), NData = sdlan_pb:encode_msg(Data#sdl_data{ttl = TTL - 1, is_p2p = false}),
sdlan_network:forward(NetworkPid, Sock, SrcMac, DstMac, <<?PACKET_STUN_DATA, NData/binary>>); sdlan_network:forward(NetworkPid, Sock, SrcMac, DstMac, <<?PACKET_STUN_DATA, NData/binary>>)
_ ->
ok
end, end,
{noreply, State}; {noreply, State};
handle_info(Info, State) -> handle_info(Info, State) ->