fix network
This commit is contained in:
parent
48cf77b0d7
commit
342b27211d
@ -216,10 +216,10 @@ handle_call({attach, ChannelPid, ClientId, Mac, Ip, Hostname}, _From,
|
|||||||
%% 添加域名->ip的映射关系
|
%% 添加域名->ip的映射关系
|
||||||
sdlan_hostname_regedit:insert(Hostname, Domain, Ip),
|
sdlan_hostname_regedit:insert(Hostname, Domain, Ip),
|
||||||
|
|
||||||
|
OldEndpoint = maps:get(Mac, Endpoints, undefined),
|
||||||
%% mac对应的Endpoint存在,并且对应的ip变了,需要通知端上清理arp
|
%% mac对应的Endpoint存在,并且对应的ip变了,需要通知端上清理arp
|
||||||
%% 重复attach需要清理之前的绑定信息
|
|
||||||
maybe
|
maybe
|
||||||
{ok, #endpoint{ip = OldIp, channel_pid = OldChannelPid, channel_ref = OldChannelRef}} ?= maps:find(Mac, Endpoints),
|
#endpoint{ip = OldIp} ?= OldEndpoint,
|
||||||
true ?= OldIp =/= Ip,
|
true ?= OldIp =/= Ip,
|
||||||
|
|
||||||
Event = sdlan_pb:encode_msg(#'SDLEvent'{
|
Event = sdlan_pb:encode_msg(#'SDLEvent'{
|
||||||
@ -232,17 +232,10 @@ handle_call({attach, ChannelPid, ClientId, Mac, Ip, Hostname}, _From,
|
|||||||
|
|
||||||
broadcast(fun(#endpoint{channel_pid = ChannelPid0}) ->
|
broadcast(fun(#endpoint{channel_pid = ChannelPid0}) ->
|
||||||
sdlan_quic_channel:send_event(ChannelPid0, Event)
|
sdlan_quic_channel:send_event(ChannelPid0, Event)
|
||||||
end, [Mac], Endpoints),
|
end, [Mac], Endpoints)
|
||||||
|
|
||||||
%% 清理就的绑定关系
|
|
||||||
is_reference(OldChannelRef) andalso demonitor(OldChannelRef),
|
|
||||||
case OldChannelPid /= undefined andalso is_process_alive(OldChannelPid) of
|
|
||||||
true ->
|
|
||||||
sdlan_quic_channel:stop(OldChannelPid, rebind);
|
|
||||||
false ->
|
|
||||||
ok
|
|
||||||
end
|
|
||||||
end,
|
end,
|
||||||
|
%% 重复attach需要清理之前的绑定信息;即使IP未变化,也不能保留旧channel。
|
||||||
|
cleanup_endpoint(OldEndpoint, ChannelPid, rebind),
|
||||||
|
|
||||||
ChannelRef = monitor(process, ChannelPid),
|
ChannelRef = monitor(process, ChannelPid),
|
||||||
SessionToken = gen_session_token(),
|
SessionToken = gen_session_token(),
|
||||||
@ -257,7 +250,8 @@ handle_call({attach, ChannelPid, ClientId, Mac, Ip, Hostname}, _From,
|
|||||||
%% client设置为禁止状态,不允许重连
|
%% client设置为禁止状态,不允许重连
|
||||||
handle_call({disable_client, ClientId}, _From, State = #state{endpoints = Endpoints}) ->
|
handle_call({disable_client, ClientId}, _From, State = #state{endpoints = Endpoints}) ->
|
||||||
case search_endpoint(fun(_, #endpoint{client_id = ClientId0}) -> ClientId =:= ClientId0 end, Endpoints) of
|
case search_endpoint(fun(_, #endpoint{client_id = ClientId0}) -> ClientId =:= ClientId0 end, Endpoints) of
|
||||||
{ok, Mac, _} ->
|
{ok, Mac, Endpoint} ->
|
||||||
|
cleanup_endpoint(Endpoint, undefined, disabled),
|
||||||
{reply, ok, State#state{endpoints = maps:remove(Mac, Endpoints)}};
|
{reply, ok, State#state{endpoints = maps:remove(Mac, Endpoints)}};
|
||||||
error ->
|
error ->
|
||||||
{reply, ok, State}
|
{reply, ok, State}
|
||||||
@ -317,7 +311,7 @@ handle_call({command, ReceiverPid, ClientId, SubCommand}, _From, State = #state{
|
|||||||
sdlan_quic_channel:command(ChannelPid, Ref, ReceiverPid, SubCommand),
|
sdlan_quic_channel:command(ChannelPid, Ref, ReceiverPid, SubCommand),
|
||||||
{reply, {ok, Ref}, State};
|
{reply, {ok, Ref}, State};
|
||||||
error ->
|
error ->
|
||||||
{reply, {error, <<"目标Node不在线"/utf8>>}}
|
{reply, {error, <<"目标Node不在线"/utf8>>}, State}
|
||||||
end;
|
end;
|
||||||
|
|
||||||
handle_call(debug_info, _From, State = #state{network_id = NetworkId, ipaddr = IpAddr, mask_len = MaskLen, owner_id = OwnerId, endpoints = Endpoints}) ->
|
handle_call(debug_info, _From, State = #state{network_id = NetworkId, ipaddr = IpAddr, mask_len = MaskLen, owner_id = OwnerId, endpoints = Endpoints}) ->
|
||||||
@ -375,8 +369,11 @@ handle_cast({forward, Sock, SrcMac, DstMac, Packet}, State = #state{network_id =
|
|||||||
true ->
|
true ->
|
||||||
PacketBytes = byte_size(Packet),
|
PacketBytes = byte_size(Packet),
|
||||||
%% 消息广播
|
%% 消息广播
|
||||||
broadcast(fun(#endpoint{hole = #hole{peer = {NatIp, NatPort}}}) ->
|
broadcast(fun
|
||||||
gen_udp:send(Sock, NatIp, NatPort, Packet)
|
(#endpoint{hole = #hole{peer = {NatIp, NatPort}}}) ->
|
||||||
|
gen_udp:send(Sock, NatIp, NatPort, Packet);
|
||||||
|
(#endpoint{}) ->
|
||||||
|
ok
|
||||||
end, [SrcMac], Endpoints),
|
end, [SrcMac], Endpoints),
|
||||||
%% client和stun之间必须有心跳机制保持nat映射可用,并且通过服务转发的udp包肯定可以到达对端的nat
|
%% client和stun之间必须有心跳机制保持nat映射可用,并且通过服务转发的udp包肯定可以到达对端的nat
|
||||||
logger:debug("[sdlan_network] broadcast data networkd_id: ~p, src_mac: ~p, dst_mac: ~p",
|
logger:debug("[sdlan_network] broadcast data networkd_id: ~p, src_mac: ~p, dst_mac: ~p",
|
||||||
@ -397,7 +394,13 @@ handle_cast({forward, _Sock, SrcMac, DstMac, _Packet}, State = #state{network_id
|
|||||||
%% 删除ip的占用并关闭channel
|
%% 删除ip的占用并关闭channel
|
||||||
handle_cast({unregister, _ClientId, Mac}, State = #state{network_id = NetworkId, endpoints = Endpoints}) ->
|
handle_cast({unregister, _ClientId, Mac}, State = #state{network_id = NetworkId, endpoints = Endpoints}) ->
|
||||||
logger:debug("[sdlan_network] networkd_id: ~p, unregister Mac: ~p", [NetworkId, sdlan_util:format_mac(Mac)]),
|
logger:debug("[sdlan_network] networkd_id: ~p, unregister Mac: ~p", [NetworkId, sdlan_util:format_mac(Mac)]),
|
||||||
{noreply, State#state{endpoints = maps:remove(Mac, Endpoints)}};
|
case maps:take(Mac, Endpoints) of
|
||||||
|
{Endpoint, NEndpoints} ->
|
||||||
|
cleanup_endpoint(Endpoint, Endpoint#endpoint.channel_pid, unregister),
|
||||||
|
{noreply, State#state{endpoints = NEndpoints}};
|
||||||
|
error ->
|
||||||
|
{noreply, State}
|
||||||
|
end;
|
||||||
|
|
||||||
%% 需要判断,client是属于当前网络的
|
%% 需要判断,client是属于当前网络的
|
||||||
handle_cast({update_hole, SessionToken, ClientId, Mac, Peer, NatType, V6Info}, State = #state{endpoints = Endpoints}) ->
|
handle_cast({update_hole, SessionToken, ClientId, Mac, Peer, NatType, V6Info}, State = #state{endpoints = Endpoints}) ->
|
||||||
@ -455,7 +458,7 @@ handle_info({'DOWN', _MRef, process, ChannelPid, Reason}, State = #state{network
|
|||||||
State :: #state{}) -> none()).
|
State :: #state{}) -> none()).
|
||||||
terminate(Reason, #state{network_id = NetworkId, endpoints = Endpoints}) ->
|
terminate(Reason, #state{network_id = NetworkId, endpoints = Endpoints}) ->
|
||||||
broadcast(fun(#endpoint{channel_pid = ChannelPid}) ->
|
broadcast(fun(#endpoint{channel_pid = ChannelPid}) ->
|
||||||
case is_process_alive(ChannelPid) of
|
case is_pid(ChannelPid) andalso is_process_alive(ChannelPid) of
|
||||||
true ->
|
true ->
|
||||||
NetworkShutdownEvent = sdlan_pb:encode_msg(#'SDLEvent'{
|
NetworkShutdownEvent = sdlan_pb:encode_msg(#'SDLEvent'{
|
||||||
event = {shutdown, #'SDLEvent.NetworkShutdown'{
|
event = {shutdown, #'SDLEvent.NetworkShutdown'{
|
||||||
@ -512,6 +515,23 @@ limiting_check(ThrottleKey) ->
|
|||||||
end
|
end
|
||||||
end.
|
end.
|
||||||
|
|
||||||
|
cleanup_endpoint(undefined, _KeepChannelPid, _Reason) ->
|
||||||
|
ok;
|
||||||
|
cleanup_endpoint(#endpoint{channel_ref = ChannelRef, channel_pid = ChannelPid}, KeepChannelPid, Reason) ->
|
||||||
|
is_reference(ChannelRef) andalso erlang:demonitor(ChannelRef, [flush]),
|
||||||
|
case should_stop_channel(ChannelPid, KeepChannelPid) of
|
||||||
|
true ->
|
||||||
|
catch sdlan_quic_channel:stop(ChannelPid, Reason),
|
||||||
|
ok;
|
||||||
|
false ->
|
||||||
|
ok
|
||||||
|
end.
|
||||||
|
|
||||||
|
should_stop_channel(ChannelPid, KeepChannelPid) when is_pid(ChannelPid), ChannelPid =/= KeepChannelPid ->
|
||||||
|
is_process_alive(ChannelPid);
|
||||||
|
should_stop_channel(_, _) ->
|
||||||
|
false.
|
||||||
|
|
||||||
-spec broadcast(Fun :: fun((#endpoint{}) -> no_return()), ExcludeMacs :: [binary()], Endpoints :: map()) -> no_return().
|
-spec broadcast(Fun :: fun((#endpoint{}) -> no_return()), ExcludeMacs :: [binary()], Endpoints :: map()) -> no_return().
|
||||||
broadcast(Fun, ExcludeMacs, Endpoints) when is_function(Fun, 1), is_map(Endpoints), is_list(ExcludeMacs) ->
|
broadcast(Fun, ExcludeMacs, Endpoints) when is_function(Fun, 1), is_map(Endpoints), is_list(ExcludeMacs) ->
|
||||||
maps:foreach(fun(Mac, Endpoint) ->
|
maps:foreach(fun(Mac, Endpoint) ->
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user