fix network
This commit is contained in:
parent
a597ecbf2e
commit
e2fd4f18cb
@ -64,7 +64,7 @@
|
|||||||
aes_key :: binary(),
|
aes_key :: binary(),
|
||||||
|
|
||||||
%% 记录已经使用了的ip, #{mac :: integer() => #endpoint{}}
|
%% 记录已经使用了的ip, #{mac :: integer() => #endpoint{}}
|
||||||
used_map = #{}
|
endpoints = #{}
|
||||||
}).
|
}).
|
||||||
|
|
||||||
%%%===================================================================
|
%%%===================================================================
|
||||||
@ -184,7 +184,7 @@ init([Id]) when is_integer(Id) ->
|
|||||||
{stop, Reason :: term(), NewState :: #state{}}).
|
{stop, Reason :: term(), NewState :: #state{}}).
|
||||||
%% 给客户端分配ip地址
|
%% 给客户端分配ip地址
|
||||||
handle_call({assign_ip_addr, ChannelPid, ClientId, Mac}, _From,
|
handle_call({assign_ip_addr, ChannelPid, ClientId, Mac}, _From,
|
||||||
State = #state{network_id = NetworkId, domain = Domain, used_map = UsedMap, mask_len = MaskLen, aes_key = AesKey}) ->
|
State = #state{network_id = NetworkId, domain = Domain, endpoints = Endpoints, mask_len = MaskLen, aes_key = AesKey}) ->
|
||||||
|
|
||||||
case sdlan_api:assign_ip_address(NetworkId, ClientId, Mac) of
|
case sdlan_api:assign_ip_address(NetworkId, ClientId, Mac) of
|
||||||
{ok, #{<<"ip">> := Ip, <<"host_name">> := HostName}} ->
|
{ok, #{<<"ip">> := Ip, <<"host_name">> := HostName}} ->
|
||||||
@ -192,20 +192,20 @@ handle_call({assign_ip_addr, ChannelPid, ClientId, Mac}, _From,
|
|||||||
lager:debug("[sdlan_network] alloc_ip, network_id: ~p, client_id: ~p, mac: ~p, net_addr: ~p",
|
lager:debug("[sdlan_network] alloc_ip, network_id: ~p, client_id: ~p, mac: ~p, net_addr: ~p",
|
||||||
[NetworkId, ClientId, sdlan_util:format_mac(Mac), sdlan_ipaddr:int_to_ipv4(Ip)]),
|
[NetworkId, ClientId, sdlan_util:format_mac(Mac), sdlan_ipaddr:int_to_ipv4(Ip)]),
|
||||||
%% 关闭之前的channel
|
%% 关闭之前的channel
|
||||||
maybe_close_channel(maps:get(Mac, UsedMap, undefined)),
|
maybe_close_channel(maps:get(Mac, Endpoints, undefined)),
|
||||||
%% 添加域名->ip的映射关系
|
%% 添加域名->ip的映射关系
|
||||||
sdlan_hostname_regedit:insert(HostName, Domain, Ip),
|
sdlan_hostname_regedit:insert(HostName, Domain, Ip),
|
||||||
|
|
||||||
%% 建立到新的channel之间的关系
|
%% 建立到新的channel之间的关系
|
||||||
MRef = monitor(process, ChannelPid),
|
MRef = monitor(process, ChannelPid),
|
||||||
NUsedMap = maps:put(Mac, #endpoint{client_id = ClientId, ip = Ip, channel_pid = ChannelPid, monitor_ref = MRef}, UsedMap),
|
NEndpoints = maps:put(Mac, #endpoint{client_id = ClientId, ip = Ip, channel_pid = ChannelPid, monitor_ref = MRef}, Endpoints),
|
||||||
|
|
||||||
{reply, {ok, Domain, Ip, MaskLen, AesKey}, State#state{used_map = NUsedMap}};
|
{reply, {ok, Domain, Ip, MaskLen, AesKey}, State#state{endpoints = NEndpoints}};
|
||||||
{error, Reason} ->
|
{error, Reason} ->
|
||||||
{reply, {error, Reason}, State}
|
{reply, {error, Reason}, State}
|
||||||
end;
|
end;
|
||||||
|
|
||||||
handle_call(get_used_map, _From, State = #state{used_map = UsedMap}) ->
|
handle_call(get_used_map, _From, State = #state{endpoints = Endpoints}) ->
|
||||||
UsedInfos = maps:map(fun(_, #endpoint{hole = Hole, v6_info = V6Info}) ->
|
UsedInfos = maps:map(fun(_, #endpoint{hole = Hole, v6_info = V6Info}) ->
|
||||||
HoleMap = case Hole of
|
HoleMap = case Hole of
|
||||||
#hole{peer = {NatIp, NatPort}} ->
|
#hole{peer = {NatIp, NatPort}} ->
|
||||||
@ -227,24 +227,23 @@ handle_call(get_used_map, _From, State = #state{used_map = UsedMap}) ->
|
|||||||
#{}
|
#{}
|
||||||
end,
|
end,
|
||||||
#{<<"hole">> => HoleMap, <<"v6_info">> => V6Map}
|
#{<<"hole">> => HoleMap, <<"v6_info">> => V6Map}
|
||||||
end, UsedMap),
|
end, Endpoints),
|
||||||
|
|
||||||
{reply, {ok, UsedInfos}, State};
|
{reply, {ok, UsedInfos}, State};
|
||||||
|
|
||||||
%% client设置为禁止状态,不允许重连
|
%% client设置为禁止状态,不允许重连
|
||||||
handle_call({disable_client, ClientId}, _From, State = #state{network_id = NetworkId, used_map = UsedMap}) ->
|
handle_call({disable_client, ClientId}, _From, State = #state{endpoints = Endpoints}) ->
|
||||||
case lists:search(fun({_, #endpoint{client_id = ClientId0}}) -> ClientId =:= ClientId0 end, maps:to_list(UsedMap)) of
|
case lists:search(fun({_, #endpoint{client_id = ClientId0}}) -> ClientId =:= ClientId0 end, maps:to_list(Endpoints)) of
|
||||||
{value, {Mac, #endpoint{channel_pid = ChannelPid, monitor_ref = MRef}}} ->
|
{value, {Mac, #endpoint{channel_pid = ChannelPid, monitor_ref = MRef}}} ->
|
||||||
is_reference(MRef) andalso demonitor(MRef),
|
is_reference(MRef) andalso demonitor(MRef),
|
||||||
sdlan_channel:stop(ChannelPid, disable),
|
sdlan_channel:stop(ChannelPid, disable),
|
||||||
NUsedMap = maps:remove(Mac, UsedMap),
|
{reply, ok, State#state{endpoints = maps:remove(Mac, Endpoints)}};
|
||||||
{reply, ok, State#state{used_map = NUsedMap}};
|
|
||||||
false ->
|
false ->
|
||||||
{reply, error, State}
|
{reply, error, State}
|
||||||
end;
|
end;
|
||||||
|
|
||||||
handle_call({get_channel, ClientId}, _From, State = #state{used_map = UsedMap}) ->
|
handle_call({get_channel, ClientId}, _From, State = #state{endpoints = Endpoints}) ->
|
||||||
case lists:search(fun({_, #endpoint{client_id = ClientId0}}) -> ClientId =:= ClientId0 end, maps:to_list(UsedMap)) of
|
case lists:search(fun({_, #endpoint{client_id = ClientId0}}) -> ClientId =:= ClientId0 end, maps:to_list(Endpoints)) of
|
||||||
{value, {_Ip, #endpoint{channel_pid = ChannelPid}}} ->
|
{value, {_Ip, #endpoint{channel_pid = ChannelPid}}} ->
|
||||||
{reply, {ok, ChannelPid}, State};
|
{reply, {ok, ChannelPid}, State};
|
||||||
false ->
|
false ->
|
||||||
@ -252,12 +251,11 @@ handle_call({get_channel, ClientId}, _From, State = #state{used_map = UsedMap})
|
|||||||
end;
|
end;
|
||||||
|
|
||||||
%% 区别在于是否关闭掉channel, 这里是在网络迁移中的功能; drop的时候需要从当前网络中移除
|
%% 区别在于是否关闭掉channel, 这里是在网络迁移中的功能; drop的时候需要从当前网络中移除
|
||||||
handle_call({dropout_client, ClientId}, _From, State = #state{used_map = UsedMap}) ->
|
handle_call({dropout_client, ClientId}, _From, State = #state{endpoints = Endpoints}) ->
|
||||||
case lists:search(fun({_, #endpoint{client_id = ClientId0}}) -> ClientId =:= ClientId0 end, maps:to_list(UsedMap)) of
|
case lists:search(fun({_, #endpoint{client_id = ClientId0}}) -> ClientId =:= ClientId0 end, maps:to_list(Endpoints)) of
|
||||||
{value, {Mac, #endpoint{channel_pid = ChannelPid, monitor_ref = MRef}}} ->
|
{value, {Mac, #endpoint{channel_pid = ChannelPid, monitor_ref = MRef}}} ->
|
||||||
is_reference(MRef) andalso demonitor(MRef),
|
is_reference(MRef) andalso demonitor(MRef),
|
||||||
NUsedMap = maps:remove(Mac, UsedMap),
|
{reply, {ok, ChannelPid}, State#state{endpoints = maps:remove(Mac, Endpoints)}};
|
||||||
{reply, {ok, ChannelPid}, State#state{used_map = NUsedMap}};
|
|
||||||
false ->
|
false ->
|
||||||
{reply, error, State}
|
{reply, error, State}
|
||||||
end;
|
end;
|
||||||
@ -266,11 +264,11 @@ handle_call(get_network_id, _From, State = #state{network_id = NetworkId}) ->
|
|||||||
{reply, {ok, NetworkId}, State};
|
{reply, {ok, NetworkId}, State};
|
||||||
|
|
||||||
%% 网络存在的nat_peer信息
|
%% 网络存在的nat_peer信息
|
||||||
handle_call({peer_info, SrcMac, DstMac}, _From, State = #state{used_map = UsedMap}) ->
|
handle_call({peer_info, SrcMac, DstMac}, _From, State = #state{endpoints = Endpoints}) ->
|
||||||
case maps:find(DstMac, UsedMap) of
|
case maps:find(DstMac, Endpoints) of
|
||||||
{ok, #endpoint{channel_pid = DstChannelPid, hole = #hole{peer = DstNatPeer, nat_type = DstNatType}, v6_info = DstV6Info}} ->
|
{ok, #endpoint{channel_pid = DstChannelPid, hole = #hole{peer = DstNatPeer, nat_type = DstNatType}, v6_info = DstV6Info}} ->
|
||||||
%% 让目标服务器发送sendRegister事件(2024-06-25 新增,提高打洞的成功率)
|
%% 让目标服务器发送sendRegister事件(2024-06-25 新增,提高打洞的成功率)
|
||||||
case maps:get(SrcMac, UsedMap, undefined) of
|
case maps:get(SrcMac, Endpoints, undefined) of
|
||||||
#endpoint{hole = #hole{peer = {SrcNatIp, SrcNatPort}, nat_type = NatType}, v6_info = SrcV6Info} ->
|
#endpoint{hole = #hole{peer = {SrcNatIp, SrcNatPort}, nat_type = NatType}, v6_info = SrcV6Info} ->
|
||||||
Event = sdlan_pb:encode_msg(#sdl_send_register_event {
|
Event = sdlan_pb:encode_msg(#sdl_send_register_event {
|
||||||
dst_mac = SrcMac,
|
dst_mac = SrcMac,
|
||||||
@ -288,13 +286,13 @@ handle_call({peer_info, SrcMac, DstMac}, _From, State = #state{used_map = UsedMa
|
|||||||
{reply, error, State}
|
{reply, error, State}
|
||||||
end;
|
end;
|
||||||
|
|
||||||
handle_call(debug_info, _From, State = #state{network_id = NetworkId, ipaddr = IpAddr, mask_len = MaskLen, owner_id = OwnerId, used_map = UsedMap}) ->
|
handle_call(debug_info, _From, State = #state{network_id = NetworkId, ipaddr = IpAddr, mask_len = MaskLen, owner_id = OwnerId, endpoints = Endpoints}) ->
|
||||||
Reply = #{
|
Reply = #{
|
||||||
<<"network_id">> => NetworkId,
|
<<"network_id">> => NetworkId,
|
||||||
<<"ipaddr">> => IpAddr,
|
<<"ipaddr">> => IpAddr,
|
||||||
<<"mask_len">> => MaskLen,
|
<<"mask_len">> => MaskLen,
|
||||||
<<"owner_id">> => OwnerId,
|
<<"owner_id">> => OwnerId,
|
||||||
<<"used_ips">> => lists:map(fun format_endpoint/1, maps:to_list(UsedMap))
|
<<"used_ips">> => lists:map(fun format_endpoint/1, maps:to_list(Endpoints))
|
||||||
},
|
},
|
||||||
{reply, Reply, State}.
|
{reply, Reply, State}.
|
||||||
|
|
||||||
@ -305,11 +303,11 @@ handle_call(debug_info, _From, State = #state{network_id = NetworkId, ipaddr = I
|
|||||||
{noreply, NewState :: #state{}, timeout() | hibernate} |
|
{noreply, NewState :: #state{}, timeout() | hibernate} |
|
||||||
{stop, Reason :: term(), NewState :: #state{}}).
|
{stop, Reason :: term(), NewState :: #state{}}).
|
||||||
%% 网络数据转发, mac地址单播
|
%% 网络数据转发, mac地址单播
|
||||||
handle_cast({forward, Sock, SrcMac, DstMac, Packet}, State = #state{network_id = NetworkId, used_map = UsedMap, throttle_key = ThrottleKey, forward_bytes = ForwardBytes})
|
handle_cast({forward, Sock, SrcMac, DstMac, Packet}, State = #state{network_id = NetworkId, endpoints = Endpoints, throttle_key = ThrottleKey, forward_bytes = ForwardBytes})
|
||||||
when is_map_key(SrcMac, UsedMap), is_map_key(DstMac, UsedMap) ->
|
when is_map_key(SrcMac, Endpoints), is_map_key(DstMac, Endpoints) ->
|
||||||
|
|
||||||
PacketBytes = byte_size(Packet),
|
PacketBytes = byte_size(Packet),
|
||||||
case maps:find(DstMac, UsedMap) of
|
case maps:find(DstMac, Endpoints) of
|
||||||
{ok, #endpoint{hole = #hole{peer = Peer = {Ip, Port}}}} ->
|
{ok, #endpoint{hole = #hole{peer = Peer = {Ip, Port}}}} ->
|
||||||
case limiting_check(ThrottleKey) of
|
case limiting_check(ThrottleKey) of
|
||||||
pass ->
|
pass ->
|
||||||
@ -336,8 +334,8 @@ handle_cast({forward, Sock, SrcMac, DstMac, Packet}, State = #state{network_id =
|
|||||||
|
|
||||||
%% 网络数据转发, ip广播或组播, 不限流
|
%% 网络数据转发, ip广播或组播, 不限流
|
||||||
%% TODO 需要处理arp请求,arp请求就不要广播出去了,network是知道目标的ip信息的
|
%% TODO 需要处理arp请求,arp请求就不要广播出去了,network是知道目标的ip信息的
|
||||||
handle_cast({forward, Sock, SrcMac, DstMac, Packet}, State = #state{network_id = NetworkId, used_map = UsedMap, forward_bytes = ForwardBytes})
|
handle_cast({forward, Sock, SrcMac, DstMac, Packet}, State = #state{network_id = NetworkId, endpoints = Endpoints, forward_bytes = ForwardBytes})
|
||||||
when is_map_key(SrcMac, UsedMap) ->
|
when is_map_key(SrcMac, Endpoints) ->
|
||||||
%% 广播地址和组播地址,需要转发到整个网络
|
%% 广播地址和组播地址,需要转发到整个网络
|
||||||
case sdlan_util:is_broadcast_mac(DstMac) orelse sdlan_util:is_multicast_mac(DstMac) of
|
case sdlan_util:is_broadcast_mac(DstMac) orelse sdlan_util:is_multicast_mac(DstMac) of
|
||||||
true ->
|
true ->
|
||||||
@ -349,7 +347,7 @@ handle_cast({forward, Sock, SrcMac, DstMac, Packet}, State = #state{network_id =
|
|||||||
|
|
||||||
TargetMac = <<>>,
|
TargetMac = <<>>,
|
||||||
ArpResponse = arp_packet:marshal(arp_packet:arp_response(ArpRequestPkt, TargetMac, TargetIp)),
|
ArpResponse = arp_packet:marshal(arp_packet:arp_response(ArpRequestPkt, TargetMac, TargetIp)),
|
||||||
#endpoint{hole = #hole{peer = {NatIp, NatPort}}} = maps:get(SrcMac, UsedMap),
|
#endpoint{hole = #hole{peer = {NatIp, NatPort}}} = maps:get(SrcMac, Endpoints),
|
||||||
gen_udp:send(Sock, NatIp, NatPort, ArpResponse);
|
gen_udp:send(Sock, NatIp, NatPort, ArpResponse);
|
||||||
|
|
||||||
error ->
|
error ->
|
||||||
@ -362,7 +360,7 @@ handle_cast({forward, Sock, SrcMac, DstMac, Packet}, State = #state{network_id =
|
|||||||
_ ->
|
_ ->
|
||||||
ok
|
ok
|
||||||
end
|
end
|
||||||
end, UsedMap),
|
end, Endpoints),
|
||||||
|
|
||||||
%% client和stun之间必须有心跳机制保持nat映射可用,并且通过服务转发的udp包肯定可以到达对端的nat
|
%% client和stun之间必须有心跳机制保持nat映射可用,并且通过服务转发的udp包肯定可以到达对端的nat
|
||||||
lager:debug("[sdlan_network] broadcast data networkd_id: ~p, src_mac: ~p, dst_mac: ~p",
|
lager:debug("[sdlan_network] broadcast data networkd_id: ~p, src_mac: ~p, dst_mac: ~p",
|
||||||
@ -382,20 +380,20 @@ handle_cast({forward, _Sock, SrcMac, DstMac, _Packet}, State = #state{network_id
|
|||||||
{noreply, State};
|
{noreply, State};
|
||||||
|
|
||||||
%% 删除ip的占用并关闭channel
|
%% 删除ip的占用并关闭channel
|
||||||
handle_cast({unregister, _ClientId, Mac}, State = #state{network_id = NetworkId, used_map = UsedMap}) ->
|
handle_cast({unregister, _ClientId, Mac}, State = #state{network_id = NetworkId, endpoints = Endpoints}) ->
|
||||||
lager:debug("[sdlan_network] networkd_id: ~p, unregister Mac: ~p", [NetworkId, sdlan_util:format_mac(Mac)]),
|
lager:debug("[sdlan_network] networkd_id: ~p, unregister Mac: ~p", [NetworkId, sdlan_util:format_mac(Mac)]),
|
||||||
case maps:take(Mac, UsedMap) of
|
case maps:take(Mac, Endpoints) of
|
||||||
error ->
|
error ->
|
||||||
{noreply, State};
|
{noreply, State};
|
||||||
{#endpoint{channel_pid = ChannelPid, monitor_ref = MRef}, NUsedMap} ->
|
{#endpoint{channel_pid = ChannelPid, monitor_ref = MRef}, NEndpoints} ->
|
||||||
is_reference(MRef) andalso demonitor(MRef),
|
is_reference(MRef) andalso demonitor(MRef),
|
||||||
sdlan_channel:stop(ChannelPid, normal),
|
sdlan_channel:stop(ChannelPid, normal),
|
||||||
{noreply, State#state{used_map = NUsedMap}}
|
{noreply, State#state{endpoints = NEndpoints}}
|
||||||
end;
|
end;
|
||||||
|
|
||||||
%% 需要判断,client是属于当前网络的
|
%% 需要判断,client是属于当前网络的
|
||||||
handle_cast({update_hole, ClientId, Mac, Peer, NatType, V6Info}, State = #state{used_map = UsedMap}) ->
|
handle_cast({update_hole, ClientId, Mac, Peer, NatType, V6Info}, State = #state{endpoints = Endpoints}) ->
|
||||||
case maps:find(Mac, UsedMap) of
|
case maps:find(Mac, Endpoints) of
|
||||||
{ok, Endpoint0 = #endpoint{client_id = ClientId0, ip = Ip, hole = OldHole}} when ClientId =:= ClientId0 ->
|
{ok, Endpoint0 = #endpoint{client_id = ClientId0, ip = Ip, hole = OldHole}} when ClientId =:= ClientId0 ->
|
||||||
case OldHole =:= undefined orelse (OldHole#hole.peer =/= Peer orelse OldHole#hole.nat_type =/= NatType) of
|
case OldHole =:= undefined orelse (OldHole#hole.peer =/= Peer orelse OldHole#hole.nat_type =/= NatType) of
|
||||||
true ->
|
true ->
|
||||||
@ -403,13 +401,13 @@ handle_cast({update_hole, ClientId, Mac, Peer, NatType, V6Info}, State = #state{
|
|||||||
mac = Mac,
|
mac = Mac,
|
||||||
ip = Ip
|
ip = Ip
|
||||||
}),
|
}),
|
||||||
broadcast(?PACKET_EVENT_NAT_CHANGED, NatChangedEvent, Mac, UsedMap);
|
broadcast(?PACKET_EVENT_NAT_CHANGED, NatChangedEvent, Mac, Endpoints);
|
||||||
false ->
|
false ->
|
||||||
ok
|
ok
|
||||||
end,
|
end,
|
||||||
Endpoint = Endpoint0#endpoint{hole = #hole{peer = Peer, nat_type = NatType}, v6_info = V6Info},
|
Endpoint = Endpoint0#endpoint{hole = #hole{peer = Peer, nat_type = NatType}, v6_info = V6Info},
|
||||||
|
|
||||||
{noreply, State#state{used_map = maps:put(Mac, Endpoint, UsedMap)}};
|
{noreply, State#state{endpoints = maps:put(Mac, Endpoint, Endpoints)}};
|
||||||
_ ->
|
_ ->
|
||||||
{noreply, State}
|
{noreply, State}
|
||||||
end.
|
end.
|
||||||
@ -425,15 +423,15 @@ handle_info({timeout, _, flow_report_ticker}, State = #state{network_id = Networ
|
|||||||
catch sdlan_api:network_forward_report(NetworkId, ForwardBytes),
|
catch sdlan_api:network_forward_report(NetworkId, ForwardBytes),
|
||||||
{noreply, State#state{forward_bytes = 0}};
|
{noreply, State#state{forward_bytes = 0}};
|
||||||
|
|
||||||
handle_info({'EXIT', _Pid, shutdown}, State = #state{network_id = NetworkId, used_map = UsedMap}) ->
|
handle_info({'EXIT', _Pid, shutdown}, State = #state{network_id = NetworkId, endpoints = UsedMap}) ->
|
||||||
lager:warning("[sdlan_network] network: ~p, get shutdown message", [NetworkId]),
|
lager:warning("[sdlan_network] network: ~p, get shutdown message", [NetworkId]),
|
||||||
broadcast_shutdown(UsedMap),
|
broadcast_shutdown(UsedMap),
|
||||||
{stop, shutdown, State};
|
{stop, shutdown, State};
|
||||||
%% Channel进程退出, hole里面的数据也需要清理
|
%% Channel进程退出, hole里面的数据也需要清理
|
||||||
handle_info({'DOWN', _MRef, process, ChannelPid, Reason}, State = #state{network_id = NetworkId, used_map = UsedMap}) ->
|
handle_info({'DOWN', _MRef, process, ChannelPid, Reason}, State = #state{network_id = NetworkId, endpoints = Endpoints}) ->
|
||||||
lager:notice("[sdlan_network] network_id: ~p, channel_pid: ~p, close with reason: ~p", [NetworkId, ChannelPid, Reason]),
|
lager:notice("[sdlan_network] network_id: ~p, channel_pid: ~p, close with reason: ~p", [NetworkId, ChannelPid, Reason]),
|
||||||
NUsedMap = maps:filter(fun(_, #endpoint{channel_pid = ChannelPid0}) -> ChannelPid =/= ChannelPid0 end, UsedMap),
|
NUsedMap = maps:filter(fun(_, #endpoint{channel_pid = ChannelPid0}) -> ChannelPid =/= ChannelPid0 end, Endpoints),
|
||||||
{noreply, State#state{used_map = NUsedMap}}.
|
{noreply, State#state{endpoints = NUsedMap}}.
|
||||||
|
|
||||||
%% @private
|
%% @private
|
||||||
%% @doc This function is called by a gen_server when it is about to
|
%% @doc This function is called by a gen_server when it is about to
|
||||||
@ -442,14 +440,14 @@ handle_info({'DOWN', _MRef, process, ChannelPid, Reason}, State = #state{network
|
|||||||
%% with Reason. The return value is ignored.
|
%% with Reason. The return value is ignored.
|
||||||
-spec(terminate(Reason :: (normal | shutdown | {shutdown, term()} | term()),
|
-spec(terminate(Reason :: (normal | shutdown | {shutdown, term()} | term()),
|
||||||
State :: #state{}) -> term()).
|
State :: #state{}) -> term()).
|
||||||
terminate(Reason, #state{network_id = NetworkId, used_map = UsedMap}) ->
|
terminate(Reason, #state{network_id = NetworkId, endpoints = Endpoints}) ->
|
||||||
lager:debug("[sdlan_network] network: ~p, will terminate with reason: ~p", [NetworkId, Reason]),
|
lager:debug("[sdlan_network] network: ~p, will terminate with reason: ~p", [NetworkId, Reason]),
|
||||||
broadcast_shutdown(UsedMap),
|
broadcast_shutdown(Endpoints),
|
||||||
%% 整个网络下的设备都需要重新连接
|
%% 整个网络下的设备都需要重新连接
|
||||||
maps:foreach(fun(_, #endpoint{channel_pid = ChannelPid, monitor_ref = MRef}) ->
|
maps:foreach(fun(_, #endpoint{channel_pid = ChannelPid, monitor_ref = MRef}) ->
|
||||||
is_reference(MRef) andalso demonitor(MRef),
|
is_reference(MRef) andalso demonitor(MRef),
|
||||||
is_process_alive(ChannelPid) andalso sdlan_channel:stop(ChannelPid, normal)
|
is_process_alive(ChannelPid) andalso sdlan_channel:stop(ChannelPid, normal)
|
||||||
end, UsedMap),
|
end, Endpoints),
|
||||||
ok.
|
ok.
|
||||||
|
|
||||||
%% @private
|
%% @private
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user