fix events
This commit is contained in:
parent
eb11c05ba5
commit
eb35558fe7
@ -33,7 +33,7 @@
|
||||
|
||||
%% 定义事件信息
|
||||
-define(PACKET_EVENT_KNOWN_IP, 16#01).
|
||||
-define(PACKET_EVENT_DROP_IP, 16#02).
|
||||
-define(PACKET_EVENT_DROP_IPS, 16#02).
|
||||
-define(PACKET_EVENT_NAT_CHANGED, 16#03).
|
||||
-define(PACKET_EVENT_SEND_REGISTER, 16#04).
|
||||
|
||||
|
||||
@ -16,7 +16,8 @@
|
||||
|
||||
-behaviour(gen_server).
|
||||
|
||||
-define(FLOW_REPORT_INTERVAL, 60 * 1000).
|
||||
-define(FLOW_REPORT_INTERVAL, 60_000).
|
||||
-define(ENDPOINT_GC_INTERVAL, 30_000).
|
||||
|
||||
%% broadcast, "FF-FF-FF-FF-FF-FF"
|
||||
-define(BROADCAST_MAC, <<16#FF,16#FF,16#FF,16#FF,16#FF,16#FF>>).
|
||||
@ -43,7 +44,9 @@
|
||||
hostname :: binary(),
|
||||
hole :: #hole{},
|
||||
%% 记录ip和ip_v6的映射关系, #{ip_addr :: integer() => {}}
|
||||
v6_info :: undefined | #sdl_v6_info{}
|
||||
v6_info :: undefined | #sdl_v6_info{},
|
||||
|
||||
last_seen :: integer() %% monotonic_time(second)
|
||||
}).
|
||||
|
||||
-record(state, {
|
||||
@ -161,6 +164,10 @@ init([Id]) when is_integer(Id) ->
|
||||
|
||||
%% 每分钟汇报一次转发的流量
|
||||
erlang:start_timer(?FLOW_REPORT_INTERVAL, self(), flow_report_ticker),
|
||||
|
||||
%% endpoint定时扫描器
|
||||
erlang:start_timer(?ENDPOINT_GC_INTERVAL, self(), endpoint_gc),
|
||||
|
||||
sdlan_domain_regedit:insert(Domain),
|
||||
|
||||
{ok, #state{network_id = Id, name = Name, domain = Domain, ipaddr = IpAddr, mask_len = MaskLen, aes_key = AesKey, throttle_key = ThrottleKey}};
|
||||
@ -187,7 +194,23 @@ handle_call({attach, Peer, ClientId, Mac, Ip, Hostname}, _From,
|
||||
[NetworkId, ClientId, sdlan_util:format_mac(Mac), sdlan_ipaddr:int_to_ipv4(Ip)]),
|
||||
%% 添加域名->ip的映射关系
|
||||
sdlan_hostname_regedit:insert(Hostname, Domain, Ip),
|
||||
Endpoint = #endpoint{client_id = ClientId, mac = Mac, ip = Ip, hostname = Hostname, hole = #hole{peer = Peer, nat_type = 0}},
|
||||
|
||||
%% mac对应的Endpoint存在,并且对应的ip变了,需要通知端上清理arp
|
||||
maybe
|
||||
{ok, #endpoint{ip = OldIp}} ?= maps:find(Mac, Endpoints),
|
||||
true ?= OldIp =/= Ip,
|
||||
NatChangedEvent = sdlan_pb:encode_msg(#sdl_nat_changed_event{
|
||||
mac = Mac,
|
||||
ip = Ip
|
||||
}),
|
||||
EventPacket = <<?PACKET_EVENT, ?PACKET_EVENT_NAT_CHANGED, NatChangedEvent/binary>>,
|
||||
|
||||
EndpointPeers = endpoint_peers([Mac], Endpoints),
|
||||
sdlan_stun_pool:send_packets(EndpointPeers, EventPacket)
|
||||
end,
|
||||
|
||||
Endpoint = #endpoint{client_id = ClientId, mac = Mac, ip = Ip, hostname = Hostname,
|
||||
hole = #hole{peer = Peer, nat_type = 0}, last_seen = erlang:monotonic_time(second)},
|
||||
|
||||
{reply, {ok, Domain, MaskLen, AesKey}, State#state{endpoints = maps:put(Mac, Endpoint, Endpoints)}};
|
||||
|
||||
@ -313,6 +336,7 @@ handle_cast({unregister, _ClientId, Mac}, State = #state{network_id = NetworkId,
|
||||
{noreply, State#state{endpoints = maps:remove(Mac, Endpoints)}};
|
||||
|
||||
%% 需要判断,client是属于当前网络的
|
||||
%% TODO 被拒绝的endpoint需要通知其重新验证
|
||||
handle_cast({update_hole, ClientId, Mac, Peer, NatType, V6Info}, State = #state{endpoints = Endpoints}) ->
|
||||
case maps:find(Mac, Endpoints) of
|
||||
{ok, Endpoint0 = #endpoint{ip = Ip, client_id = ClientId0, hole = OldHole}} when ClientId =:= ClientId0 ->
|
||||
@ -328,7 +352,7 @@ handle_cast({update_hole, ClientId, Mac, Peer, NatType, V6Info}, State = #state{
|
||||
EndpointPeers = endpoint_peers([Mac], Endpoints),
|
||||
sdlan_stun_pool:send_packets(EndpointPeers, EventPacket)
|
||||
end,
|
||||
{noreply, State#state{endpoints = maps:put(Mac, Endpoint0#endpoint{hole = NHole, v6_info = V6Info}, Endpoints)}};
|
||||
{noreply, State#state{endpoints = maps:put(Mac, Endpoint0#endpoint{hole = NHole, v6_info = V6Info, last_seen = erlang:monotonic_time(second)}, Endpoints)}};
|
||||
_ ->
|
||||
{noreply, State}
|
||||
end.
|
||||
@ -342,7 +366,35 @@ handle_cast({update_hole, ClientId, Mac, Peer, NatType, V6Info}, State = #state{
|
||||
handle_info({timeout, _, flow_report_ticker}, State = #state{network_id = NetworkId, forward_bytes = ForwardBytes}) ->
|
||||
erlang:start_timer(?FLOW_REPORT_INTERVAL, self(), flow_report_ticker),
|
||||
catch sdlan_api:network_forward_report(NetworkId, ForwardBytes),
|
||||
{noreply, State#state{forward_bytes = 0}}.
|
||||
{noreply, State#state{forward_bytes = 0}};
|
||||
|
||||
handle_info({timeout, _, endpoint_gc}, State = #state{endpoints = Endpoints}) ->
|
||||
erlang:start_timer(?ENDPOINT_GC_INTERVAL, self(), endpoint_gc),
|
||||
|
||||
Now = erlang:monotonic_time(second),
|
||||
|
||||
{AliveEndpoints, ExpiredEndpoints} = maps:fold(fun(Mac, Ep = #endpoint{last_seen = Last}, {Alive, Expired}) ->
|
||||
case Now - Last =< ?ENDPOINT_GC_INTERVAL of
|
||||
true ->
|
||||
{maps:put(Mac, Ep, Alive), Expired};
|
||||
false ->
|
||||
{Alive, maps:put(Mac, Ep, Expired)}
|
||||
end
|
||||
end,
|
||||
{#{}, #{}}, Endpoints),
|
||||
|
||||
ExpiredIps = lists:map(fun(#endpoint{ip = Ip0}) -> Ip0 end, maps:values(ExpiredEndpoints)),
|
||||
%% 通知活着的Endpoints
|
||||
NatChangedEvent = sdlan_pb:encode_msg(#sdl_nat_changed_event{
|
||||
mac = Mac,
|
||||
ip = Ip
|
||||
}),
|
||||
EventPacket = <<?PACKET_EVENT, ?PACKET_EVENT_NAT_CHANGED, NatChangedEvent/binary>>,
|
||||
|
||||
EndpointPeers = endpoint_peers([Mac], Endpoints),
|
||||
sdlan_stun_pool:send_packets(EndpointPeers, EventPacket),
|
||||
|
||||
{noreply, State#state{endpoints = AliveEndpoints}}.
|
||||
|
||||
%% @private
|
||||
%% @doc This function is called by a gen_server when it is about to
|
||||
|
||||
@ -64,6 +64,12 @@ message SDLNatChangedEvent {
|
||||
uint32 ip = 3;
|
||||
}
|
||||
|
||||
// 被清理掉的Endpoints
|
||||
message SDLDropMacsEvent {
|
||||
uint32 network_id = 1;
|
||||
repeated bytes mac = 2;
|
||||
}
|
||||
|
||||
message SDLSendRegisterEvent {
|
||||
uint32 network_id = 1;
|
||||
bytes dst_mac = 2;
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user