fix host name
This commit is contained in:
parent
067d425595
commit
99752ddd2e
@ -13,6 +13,7 @@
|
||||
client_id :: binary(),
|
||||
mac :: binary(),
|
||||
ip :: integer(),
|
||||
host_name :: binary(),
|
||||
%% 当前状态
|
||||
status = normal :: normal | disabled
|
||||
}).
|
||||
@ -45,8 +45,8 @@ handle_request("POST", "/node/move", _, #{<<"client_id">> := ClientId, <<"from_n
|
||||
case {sdlan_network:get_pid(FromNetworkId), sdlan_network:get_pid(ToNetworkId)} of
|
||||
{FromPid, ToPid} when is_pid(FromPid), is_pid(ToPid) ->
|
||||
case sdlan_network:dropout_client(FromPid, ClientId) of
|
||||
{ok, ChannelPid} ->
|
||||
Ref = sdlan_channel:move_network(ChannelPid, self(), ToPid),
|
||||
{ok, ChannelPid, HostName} ->
|
||||
Ref = sdlan_channel:move_network(ChannelPid, self(), ToPid, HostName),
|
||||
receive
|
||||
{command_reply, Ref, {error, Reason}} ->
|
||||
lager:warning("[node_handler] client_id: ~p, move network from: ~p, to: ~p, get error: ~p", [ClientId, FromPid, ToPid, Reason]),
|
||||
|
||||
@ -13,7 +13,7 @@
|
||||
|
||||
%% API
|
||||
-export([create_table/1, get_table_name/1]).
|
||||
-export([get_clients/1, get_client/2, 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/6]).
|
||||
-export([debug/1]).
|
||||
|
||||
create_table(Tab) when is_atom(Tab) ->
|
||||
@ -58,12 +58,23 @@ delete_clients(NetworkId) when is_integer(NetworkId) ->
|
||||
{error, Reason}
|
||||
end.
|
||||
|
||||
-spec delete_client(NetworkId :: integer(), ClientId :: binary()) -> ok | {error, Reason :: any()}.
|
||||
-spec delete_client(NetworkId :: integer(), ClientId :: binary()) -> {ok, Client :: #client{}} | {error, Reason :: any()}.
|
||||
delete_client(NetworkId, ClientId) when is_integer(NetworkId), is_binary(ClientId) ->
|
||||
Tab = get_table_name(NetworkId),
|
||||
case mnesia:transaction(fun() -> mnesia:delete(Tab, ClientId, write) end) of
|
||||
{'atomic', ok} ->
|
||||
ok;
|
||||
|
||||
Fun = fun() ->
|
||||
case mnesia:read(Tab, ClientId, write) of
|
||||
[] ->
|
||||
mnesia:abort(not_found);
|
||||
[Record] ->
|
||||
mnesia:delete(Tab, ClientId, write),
|
||||
{ok, Record}
|
||||
end
|
||||
end,
|
||||
|
||||
case mnesia:transaction(Fun) of
|
||||
{'atomic', {ok, Client}} ->
|
||||
{ok, Client};
|
||||
{'aborted', Reason} ->
|
||||
{error, Reason}
|
||||
end.
|
||||
@ -88,16 +99,16 @@ disable_client(NetworkId, ClientId) when is_integer(NetworkId), is_binary(Client
|
||||
end.
|
||||
|
||||
%% 分配ip地址的时候,以mac地址为唯一基准
|
||||
-spec alloc_ip(NetworkId :: integer(), Ips :: list(), ClientId :: binary(), Mac :: binary(), NetAddr0 :: integer()) ->
|
||||
-spec alloc_ip(NetworkId :: integer(), Ips :: list(), ClientId :: binary(), Mac :: binary(), NetAddr0 :: integer(), HostName :: binary()) ->
|
||||
{ok, Ip :: integer()} | {error, Reason :: any()}.
|
||||
alloc_ip(NetworkId, Ips, ClientId, Mac, NetAddr0) when is_binary(ClientId), is_integer(NetAddr0), is_binary(Mac) ->
|
||||
case mnesia:transaction(fun() -> alloc_ip0(NetworkId, Ips, ClientId, Mac, NetAddr0) end) of
|
||||
alloc_ip(NetworkId, Ips, ClientId, Mac, NetAddr0, HostName) when is_binary(ClientId), is_integer(NetAddr0), is_binary(Mac), is_binary(HostName) ->
|
||||
case mnesia:transaction(fun() -> alloc_ip0(NetworkId, Ips, ClientId, Mac, NetAddr0, HostName) end) of
|
||||
{'atomic', Res} ->
|
||||
{ok, Res};
|
||||
{'aborted', Reason} ->
|
||||
{error, Reason}
|
||||
end.
|
||||
alloc_ip0(NetworkId, Ips, ClientId, Mac, NetAddr0) ->
|
||||
alloc_ip0(NetworkId, Ips, ClientId, Mac, NetAddr0, HostName) ->
|
||||
Tab = get_table_name(NetworkId),
|
||||
|
||||
case mnesia:read(Tab, ClientId) of
|
||||
@ -107,21 +118,28 @@ alloc_ip0(NetworkId, Ips, ClientId, Mac, NetAddr0) ->
|
||||
[#client{status = disabled}] ->
|
||||
mnesia:abort(client_disabled);
|
||||
[] ->
|
||||
UsedIps = mnesia:foldl(fun(#client{ip = Ip0}, Acc) -> [Ip0|Acc] end, [], Tab),
|
||||
case lists:member(NetAddr0, Ips) andalso not lists:member(NetAddr0, UsedIps) of
|
||||
{UsedIps, UsedHostNames} = mnesia:foldl(fun(#client{ip = Ip0, host_name = HostName0}, {IpAcc, HostNameAcc}) ->
|
||||
{[Ip0|IpAcc], [HostName0|HostNameAcc]}
|
||||
end, {[], []}, Tab),
|
||||
case HostName =/= <<>> andalso lists:member(HostName, UsedHostNames) of
|
||||
true ->
|
||||
%% 如果ip没有被占用,则分配給当前请求
|
||||
Client = #client{client_id = ClientId, mac = Mac, ip = NetAddr0},
|
||||
ok = mnesia:write(Tab, Client, write),
|
||||
NetAddr0;
|
||||
mnesia:abort(host_name_used);
|
||||
false ->
|
||||
case Ips -- UsedIps of
|
||||
[] ->
|
||||
mnesia:abort(no_ip);
|
||||
[Ip|_] ->
|
||||
Client = #client{client_id = ClientId, mac = Mac, ip = Ip, status = normal},
|
||||
case lists:member(NetAddr0, Ips) andalso not lists:member(NetAddr0, UsedIps) of
|
||||
true ->
|
||||
%% 如果ip没有被占用,则分配給当前请求
|
||||
Client = #client{client_id = ClientId, mac = Mac, ip = NetAddr0, host_name = HostName, status = normal},
|
||||
ok = mnesia:write(Tab, Client, write),
|
||||
Ip
|
||||
NetAddr0;
|
||||
false ->
|
||||
case Ips -- UsedIps of
|
||||
[] ->
|
||||
mnesia:abort(no_ip);
|
||||
[Ip|_] ->
|
||||
Client = #client{client_id = ClientId, mac = Mac, ip = Ip, host_name = HostName, status = normal},
|
||||
ok = mnesia:write(Tab, Client, write),
|
||||
Ip
|
||||
end
|
||||
end
|
||||
end
|
||||
end.
|
||||
|
||||
@ -28,6 +28,8 @@
|
||||
-define(NAK_NETWORK_FAULT, 4).
|
||||
%% 内部错误
|
||||
-define(NAK_INTERNAL_FAULT, 5).
|
||||
%% hostname被占用
|
||||
-define(NAK_HOSTNAME_USED, 6).
|
||||
|
||||
%% 升级策略
|
||||
-define(UPGRADE_NONE, 0).
|
||||
@ -36,7 +38,7 @@
|
||||
|
||||
%% API
|
||||
-export([start_link/4]).
|
||||
-export([publish_command/4, send_event/3, stop/2, move_network/3]).
|
||||
-export([publish_command/4, send_event/3, stop/2, move_network/4]).
|
||||
|
||||
-export([init/1, handle_call/3, handle_cast/2, handle_info/2, terminate/2, code_change/3]).
|
||||
|
||||
@ -75,10 +77,10 @@ publish_command(Pid, ReceiverPid, CommandType, Msg) when is_pid(Pid), is_pid(Rec
|
||||
Ref.
|
||||
|
||||
%% 网络迁移是一种特殊的指令信息,需要单独处理
|
||||
-spec move_network(Pid :: pid(), ReceiverPid :: pid(), NetworkPid :: pid()) -> Ref :: reference().
|
||||
move_network(Pid, ReceiverPid, NetworkPid) when is_pid(Pid), is_pid(ReceiverPid), is_pid(NetworkPid) ->
|
||||
-spec move_network(Pid :: pid(), ReceiverPid :: pid(), NetworkPid :: pid(), HostName :: binary()) -> Ref :: reference().
|
||||
move_network(Pid, ReceiverPid, NetworkPid, HostName) when is_pid(Pid), is_pid(ReceiverPid), is_pid(NetworkPid), is_binary(HostName) ->
|
||||
Ref = make_ref(),
|
||||
Pid ! {move_network, ReceiverPid, Ref, NetworkPid},
|
||||
Pid ! {move_network, ReceiverPid, Ref, NetworkPid, HostName},
|
||||
Ref.
|
||||
|
||||
%% 向通道中写入消息
|
||||
@ -177,6 +179,10 @@ handle_info({tcp, Sock, <<PacketId:32, ?PACKET_REGISTER_SUPER, Body/binary>>}, S
|
||||
lager:warning("[sdlan_channel] client_id: ~p, token: ~p, register get error: no_ip", [ClientId, Token]),
|
||||
Transport:send(Sock, register_nak_reply(PacketId, ?NAK_NO_IP, <<"No Ip address">>)),
|
||||
{stop, normal, State};
|
||||
{error, host_name_used} ->
|
||||
lager:warning("[sdlan_channel] client_id: ~p, token: ~p, register get error: host_name_used", [ClientId, Token]),
|
||||
Transport:send(Sock, register_nak_reply(PacketId, ?NAK_HOSTNAME_USED, <<"Host Name Used">>)),
|
||||
{stop, normal, State};
|
||||
{error, client_disabled} ->
|
||||
lager:warning("[sdlan_channel] client_id: ~p, token: ~p, register get error: client_disabled", [ClientId, Token]),
|
||||
Transport:send(Sock, register_nak_reply(PacketId, ?NAK_NODE_DISABLE, <<"Client Connection Disable">>)),
|
||||
@ -249,11 +255,11 @@ handle_info({timeout, _, ping_ticker}, State = #state{client_id = ClientId, ping
|
||||
end;
|
||||
|
||||
%% 重新加入网络
|
||||
handle_info({move_network, ReceiverPid, Ref, NetworkPid},
|
||||
handle_info({move_network, ReceiverPid, Ref, NetworkPid, HostName},
|
||||
State = #state{transport = Transport, socket = Sock, client_id = ClientId, mac = Mac, pub_key = PubKey, packet_id = PacketId, inflight = Inflight, is_registered = true}) ->
|
||||
|
||||
%% 建立到network的对应关系
|
||||
case sdlan_network:assign_ip_addr(NetworkPid, self(), ClientId, Mac, 0) of
|
||||
case sdlan_network:assign_ip_addr(NetworkPid, self(), ClientId, Mac, 0, HostName) of
|
||||
{ok, Domain, NetAddr, NetBitLen, AesKey} ->
|
||||
RsaPubKey = sdlan_cipher:rsa_pem_decode(PubKey),
|
||||
EncodedAesKey = rsa_encode(AesKey, RsaPubKey),
|
||||
|
||||
@ -124,7 +124,7 @@ get_channel(Pid, ClientId) when is_pid(Pid), is_binary(ClientId) ->
|
||||
gen_server:call(Pid, {get_channel, ClientId}).
|
||||
|
||||
%% 剔除client_id,channel不关闭; channel会被重新绑定到其他的network里面
|
||||
-spec dropout_client(Pid :: pid(), ClientId :: binary()) -> {ok, ChannelPid :: pid()} | error.
|
||||
-spec dropout_client(Pid :: pid(), ClientId :: binary()) -> {ok, ChannelPid :: pid(), HostName :: binary()} | error.
|
||||
dropout_client(Pid, ClientId) when is_pid(Pid), is_binary(ClientId) ->
|
||||
gen_server:call(Pid, {dropout_client, ClientId}).
|
||||
|
||||
@ -226,7 +226,7 @@ handle_call({assign_ip_addr, ChannelPid, ClientId, Mac, NetAddr0, HostName}, _Fr
|
||||
lager:debug("[sdlan_network] alloc_ip, network_id: ~p, ips: ~p, client_id: ~p, mac: ~p, net_addr: ~p",
|
||||
[NetworkId, Ips, ClientId, sdlan_util:format_mac(Mac), sdlan_ipaddr:int_to_ipv4(NetAddr0)]),
|
||||
|
||||
case client_model:alloc_ip(NetworkId, Ips, ClientId, Mac, NetAddr0) of
|
||||
case client_model:alloc_ip(NetworkId, Ips, ClientId, Mac, NetAddr0, HostName) of
|
||||
{ok, Ip} ->
|
||||
%% 关闭之前的channel
|
||||
maybe_close_channel(maps:get(Mac, UsedMap, undefined)),
|
||||
@ -296,9 +296,12 @@ handle_call({dropout_client, ClientId}, _From, State = #state{network_id = Netwo
|
||||
is_reference(MRef) andalso demonitor(MRef),
|
||||
NUsedMap = maps:remove(Mac, UsedMap),
|
||||
%% 从数据库删除
|
||||
client_model:delete_client(NetworkId, ClientId),
|
||||
|
||||
{reply, {ok, ChannelPid}, State#state{used_map = NUsedMap}};
|
||||
case client_model:delete_client(NetworkId, ClientId) of
|
||||
{ok, #client{host_name = HostName}} ->
|
||||
{reply, {ok, ChannelPid, HostName}, State#state{used_map = NUsedMap}};
|
||||
{error, _} ->
|
||||
{reply, error, State}
|
||||
end;
|
||||
false ->
|
||||
{reply, error, State}
|
||||
end;
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user