simple network used_maps

This commit is contained in:
anlicheng 2025-12-13 18:39:46 +08:00
parent 989dfae542
commit 067d425595
3 changed files with 34 additions and 19 deletions

View File

@ -13,7 +13,7 @@
%% API
-export([create_table/1, get_table_name/1]).
-export([get_clients/1, delete_clients/1, delete_client/2, disable_client/2, alloc_ip/5]).
-export([get_clients/1, get_client/2, delete_clients/1, delete_client/2, disable_client/2, alloc_ip/5]).
-export([debug/1]).
create_table(Tab) when is_atom(Tab) ->
@ -28,6 +28,16 @@ create_table(Tab) when is_atom(Tab) ->
get_table_name(NetworkId) when is_integer(NetworkId) ->
list_to_atom("client_" ++ integer_to_list(NetworkId)).
-spec get_client(NetworkId :: integer(), ClientId :: binary()) -> error | {ok, Client :: #client{}} .
get_client(NetworkId, ClientId) when is_integer(NetworkId), is_binary(ClientId) ->
Tab = get_table_name(NetworkId),
case mnesia:dirty_read(Tab, ClientId) of
[] ->
error;
[Client|_] ->
{ok, Client}
end.
-spec get_clients(NetworkId :: integer()) -> [Client :: #client{}].
get_clients(NetworkId) when is_integer(NetworkId) ->
Tab = get_table_name(NetworkId),

View File

@ -138,7 +138,7 @@ handle_info({tcp, Sock, <<PacketId:32, ?PACKET_REGISTER_SUPER, Body/binary>>}, S
%% network的对应关系
case sdlan_network:get_pid(NetworkId) of
NetworkPid when is_pid(NetworkPid) ->
try sdlan_network:assign_ip_addr(NetworkPid, self(), ClientId, Mac, NetAddr0) of
try sdlan_network:assign_ip_addr(NetworkPid, self(), ClientId, Mac, NetAddr0, HostName) of
{ok, Domain, NetAddr, NetBitLen, AesKey} ->
RsaPubKey = sdlan_cipher:rsa_pem_decode(PubKey),
EncodedAesKey = rsa_encode(AesKey, RsaPubKey),

View File

@ -21,7 +21,7 @@
%% API
-export([start_link/2]).
-export([get_name/1, get_pid/1, assign_ip_addr/5, peer_info/3, unregister/3, debug_info/1, get_network_id/1, get_used_map/1]).
-export([get_name/1, get_pid/1, assign_ip_addr/6, peer_info/3, unregister/3, debug_info/1, get_network_id/1, get_used_map/1]).
-export([forward/5, update_hole/6, disable_client/2, get_channel/2, dropout_client/2, reload/1]).
-export([test_event/1]).
@ -33,11 +33,9 @@
nat_type :: integer()
}).
%% ip的使用信息
%% ip的使用信息,
-record(host, {
client_id :: binary(),
mac :: binary(),
ip :: integer(),
channel_pid :: undefined | pid(),
monitor_ref :: undefined | reference(),
hole :: undefined | #hole{},
@ -90,10 +88,10 @@ get_name(Id) when is_integer(Id) ->
reload(Pid) when is_pid(Pid) ->
gen_server:call(Pid, reload).
-spec assign_ip_addr(Pid :: pid(), ChannelPid :: pid(), ClientId :: binary(), Mac :: binary(), NetAddr :: integer()) ->
-spec assign_ip_addr(Pid :: pid(), ChannelPid :: pid(), ClientId :: binary(), Mac :: binary(), NetAddr :: integer(), HostName :: binary()) ->
{ok, Domain :: binary(), NetAddr :: integer(), MaskLen :: integer(), AesKey :: binary()} | {error, Reason :: any()}.
assign_ip_addr(Pid, ChannelPid, ClientId, Mac, NetAddr) when is_pid(Pid), is_pid(ChannelPid), is_binary(ClientId), is_binary(Mac), is_integer(NetAddr) ->
gen_server:call(Pid, {assign_ip_addr, ChannelPid, ClientId, Mac, NetAddr}).
assign_ip_addr(Pid, ChannelPid, ClientId, Mac, NetAddr, HostName) when is_pid(Pid), is_pid(ChannelPid), is_binary(ClientId), is_binary(Mac), is_integer(NetAddr) ->
gen_server:call(Pid, {assign_ip_addr, ChannelPid, ClientId, Mac, NetAddr, HostName}).
-spec get_network_id(Pid :: pid()) -> {ok, NetworkId :: integer()}.
get_network_id(Pid) when is_pid(Pid) ->
@ -221,7 +219,7 @@ handle_call(reload, _From, State = #state{network_id = Id, ipaddr = OldIpAddr, m
end;
%% ip地址
handle_call({assign_ip_addr, ChannelPid, ClientId, Mac, NetAddr0}, _From,
handle_call({assign_ip_addr, ChannelPid, ClientId, Mac, NetAddr0, HostName}, _From,
State = #state{network_id = NetworkId, domain = Domain, ips = Ips, used_map = UsedMap, mask_len = MaskLen, aes_key = AesKey}) ->
%% ip地址的时候mac地址为唯一基准
@ -235,7 +233,7 @@ handle_call({assign_ip_addr, ChannelPid, ClientId, Mac, NetAddr0}, _From,
%% channel之间的关系
MRef = monitor(process, ChannelPid),
NUsedMap = maps:put(Mac, #host{client_id = ClientId, mac = Mac, ip = Ip, channel_pid = ChannelPid, monitor_ref = MRef}, UsedMap),
NUsedMap = maps:put(Mac, #host{client_id = ClientId, channel_pid = ChannelPid, monitor_ref = MRef}, UsedMap),
{reply, {ok, Domain, Ip, MaskLen, AesKey}, State#state{used_map = NUsedMap}};
{error, Reason} ->
@ -338,7 +336,14 @@ handle_call(debug_info, _From, State = #state{network_id = NetworkId, ipaddr = I
<<"mask_len">> => MaskLen,
<<"owner_id">> => OwnerId,
<<"ips">> => lists:map(fun sdlan_ipaddr:int_to_ipv4/1, Ips),
<<"used_ips">> => lists:map(fun({_, Host}) -> format_host(Host) end, maps:to_list(UsedMap))
<<"used_ips">> => lists:map(fun({_, Host = #host{client_id = ClientId}}) ->
case client_model:get_client(NetworkId, ClientId) of
error ->
#{};
{ok, #client{mac = Mac, ip = Ip}} ->
format_host(Host, Ip, Mac)
end
end, maps:to_list(UsedMap))
},
{reply, Reply, State}.
@ -435,12 +440,12 @@ handle_cast({unregister, _ClientId, Mac}, State = #state{network_id = NetworkId,
end;
%% client是属于当前网络的
handle_cast({update_hole, _ClientId, Mac, Peer, NatType, V6Info}, State = #state{used_map = UsedMap}) ->
case maps:find(Mac, UsedMap) of
{ok, Host0 = #host{hole = OldHole, ip = Ip}} ->
handle_cast({update_hole, ClientId, Mac, Peer, NatType, V6Info}, State = #state{network_id = NetworkId, used_map = UsedMap}) ->
case {maps:find(Mac, UsedMap), client_model:get_client(NetworkId, ClientId)} of
{{ok, Host0 = #host{client_id = ClientId0, hole = OldHole}}, {ok, #client{ip = Ip}}} when ClientId =:= ClientId0 ->
case OldHole =:= undefined orelse (OldHole#hole.peer =/= Peer orelse OldHole#hole.nat_type =/= NatType) of
true ->
NatChangedEvent = sdlan_pb:encode_msg(#sdl_nat_changed_event {
NatChangedEvent = sdlan_pb:encode_msg(#sdl_nat_changed_event{
mac = Mac,
ip = Ip
}),
@ -451,7 +456,7 @@ handle_cast({update_hole, _ClientId, Mac, Peer, NatType, V6Info}, State = #state
Host = Host0#host{hole = #hole{peer = Peer, nat_type = NatType}, v6_info = V6Info},
{noreply, State#state{used_map = maps:put(Mac, Host, UsedMap)}};
error ->
_ ->
{noreply, State}
end.
@ -561,8 +566,8 @@ parse_ipaddr(IpAddr0) when is_binary(IpAddr0) ->
{IpAddr0, 24}
end.
-spec format_host(Host :: #host{}) -> map().
format_host(#host{client_id = ClientId, mac = Mac, ip = Ip, hole = Hole, v6_info = V6Info}) ->
-spec format_host(Host :: #host{}, Ip :: integer(), Mac :: binary()) -> map().
format_host(#host{client_id = ClientId, hole = Hole, v6_info = V6Info}, Ip, Mac) when is_integer(Ip), is_binary(Mac) ->
HoleMap = case Hole of
undefined ->
#{};