fix network
This commit is contained in:
parent
c3c5873cc0
commit
4844e32b6c
@ -161,10 +161,11 @@ debug_info(Pid) when is_pid(Pid) ->
|
||||
gen_server:call(Pid, debug_info).
|
||||
|
||||
%% @doc Spawns the server and registers the local name (unique)
|
||||
-spec(start_link(Name :: atom(), Id :: integer()) ->
|
||||
-spec(start_link(Name :: atom(), NetworkData :: tuple()) ->
|
||||
{ok, Pid :: pid()} | ignore | {error, Reason :: term()}).
|
||||
start_link(Name, Id) when is_atom(Name), is_integer(Id) ->
|
||||
gen_server:start_link({local, Name}, ?MODULE, [Id], []).
|
||||
start_link(Name, NetworkData = {network, Id, _NetworkName, _Domain, _IpAddr, _MaskLen, _OwnerId, _Algorithm})
|
||||
when is_atom(Name), is_integer(Id) ->
|
||||
gen_server:start_link({local, Name}, ?MODULE, [NetworkData], []).
|
||||
|
||||
%%%===================================================================
|
||||
%%% gen_server callbacks
|
||||
@ -175,32 +176,22 @@ start_link(Name, Id) when is_atom(Name), is_integer(Id) ->
|
||||
-spec(init(Args :: term()) ->
|
||||
{ok, State :: #state{}} | {ok, State :: #state{}, timeout() | hibernate} |
|
||||
{stop, Reason :: term()} | ignore).
|
||||
init([Id]) when is_integer(Id) ->
|
||||
init([{network, Id, Name, Domain, IpAddr, MaskLen, OwnerId, Algorithm0}]) ->
|
||||
erlang:process_flag(trap_exit, true),
|
||||
case sdlan_api:get_network(Id) of
|
||||
{ok, #{<<"ipaddr">> := Null}} when Null == <<"null">>; Null == <<"NULL">> ->
|
||||
{stop, <<"ipaddrr is null">>};
|
||||
{ok, NetworkInfo = #{<<"id">> := Id, <<"name">> := Name, <<"domain">> := Domain, <<"algorithm">> := Algorithm0, <<"ipaddr">> := IpAddr0, <<"owner_id">> := OwnerId}} ->
|
||||
logger:debug("[sdlan_network] load network info: ~p", [NetworkInfo]),
|
||||
{IpAddr, MaskLen} = parse_ipaddr(IpAddr0),
|
||||
%% 限流key
|
||||
ThrottleKey = list_to_atom("network_throttle:" ++ integer_to_list(Id)),
|
||||
%% 绑定到资源协调器
|
||||
sdlan_network_coordinator:attach(self(), ThrottleKey),
|
||||
%% 限流key
|
||||
ThrottleKey = list_to_atom("network_throttle:" ++ integer_to_list(Id)),
|
||||
%% 绑定到资源协调器
|
||||
sdlan_network_coordinator:attach(self(), ThrottleKey),
|
||||
|
||||
sdlan_domain_regedit:insert(Domain),
|
||||
sdlan_domain_regedit:insert(Domain),
|
||||
|
||||
%% 处理加密算法
|
||||
Algorithm = normalization_algorithm(Algorithm0),
|
||||
Key = gen_key(Algorithm),
|
||||
EndpointTable = new_endpoint_table(Id),
|
||||
%% 处理加密算法
|
||||
Algorithm = normalization_algorithm(Algorithm0),
|
||||
Key = gen_key(Algorithm),
|
||||
EndpointTable = new_endpoint_table(Id),
|
||||
|
||||
{ok, #state{network_id = Id, name = Name, domain = Domain, ipaddr = IpAddr, algorithm = Algorithm,
|
||||
owner_id = OwnerId, mask_len = MaskLen, key = Key, throttle_key = ThrottleKey, endpoint_table = EndpointTable}};
|
||||
{error, Reason} ->
|
||||
logger:warning("[sdlan_network] load network: ~p, get error: ~p", [Id, Reason]),
|
||||
{stop, Reason}
|
||||
end.
|
||||
{ok, #state{network_id = Id, name = Name, domain = Domain, ipaddr = IpAddr, algorithm = Algorithm,
|
||||
owner_id = OwnerId, mask_len = MaskLen, key = Key, throttle_key = ThrottleKey, endpoint_table = EndpointTable}}.
|
||||
|
||||
%% @private
|
||||
%% @doc Handling call messages
|
||||
@ -426,17 +417,6 @@ code_change(_OldVsn, State = #state{}, _Extra) ->
|
||||
%%% Internal functions
|
||||
%%%===================================================================
|
||||
|
||||
%% 解析IpAddr: <<"192.168.172/24">>
|
||||
-spec parse_ipaddr(IpAddr0 :: binary()) -> {IpAddr :: binary(), MaskLen :: integer()}.
|
||||
parse_ipaddr(IpAddr0) when is_binary(IpAddr0) ->
|
||||
case binary:split(IpAddr0, <<"/">>) of
|
||||
[IpAddr, MaskLen] ->
|
||||
MaskLen1 = binary_to_integer(MaskLen),
|
||||
{IpAddr, MaskLen1};
|
||||
_ ->
|
||||
{IpAddr0, 24}
|
||||
end.
|
||||
|
||||
-spec limiting_check(ThrottleKey :: any()) -> pass | denied.
|
||||
limiting_check(ThrottleKey) ->
|
||||
case throttle:check(sdlan_network, ThrottleKey) of
|
||||
|
||||
@ -40,11 +40,16 @@ start_link() ->
|
||||
%% specifications.
|
||||
init([]) ->
|
||||
SupFlags = #{strategy => one_for_one, intensity => 1000, period => 3600},
|
||||
{ok, NetworkIds} = sdlan_api:get_all_networks(),
|
||||
Specs = lists:map(fun child_spec/1, NetworkIds),
|
||||
set_network_bind(length(Specs)),
|
||||
case sdlan_api:get_all_networks() of
|
||||
{ok, NetworkIds} ->
|
||||
Specs = lists:filtermap(fun load_child_spec/1, NetworkIds),
|
||||
set_network_bind(length(Specs)),
|
||||
|
||||
{ok, {SupFlags, Specs}}.
|
||||
{ok, {SupFlags, Specs}};
|
||||
{error, Reason} ->
|
||||
logger:warning("[sdlan_network_sup] load all networks error: ~p", [Reason]),
|
||||
{stop, {load_networks_failed, Reason}}
|
||||
end.
|
||||
|
||||
%%%===================================================================
|
||||
%%% Internal functions
|
||||
@ -54,15 +59,11 @@ init([]) ->
|
||||
ensure_network_started(Id) when is_integer(Id) ->
|
||||
case sdlan_network:get_pid(Id) of
|
||||
undefined ->
|
||||
case supervisor:start_child(?MODULE, child_spec(Id)) of
|
||||
{ok, Pid} when is_pid(Pid) ->
|
||||
{ok, Pid};
|
||||
{ok, undefined} ->
|
||||
{error, ignored};
|
||||
{error, {'already_started', Pid}} when is_pid(Pid) ->
|
||||
{ok, Pid};
|
||||
{error, Error} ->
|
||||
{error, Error}
|
||||
case child_spec(Id) of
|
||||
{ok, Spec} ->
|
||||
start_child(Spec);
|
||||
{error, Reason} ->
|
||||
{error, Reason}
|
||||
end;
|
||||
Pid when is_pid(Pid) ->
|
||||
{ok, Pid}
|
||||
@ -70,9 +71,20 @@ ensure_network_started(Id) when is_integer(Id) ->
|
||||
|
||||
-spec start_network(Id :: integer()) -> {ok, Pid :: pid()} | {error, Reason :: any()}.
|
||||
start_network(Id) when is_integer(Id) ->
|
||||
case supervisor:start_child(?MODULE, child_spec(Id)) of
|
||||
case child_spec(Id) of
|
||||
{ok, Spec} ->
|
||||
start_child(Spec);
|
||||
{error, Reason} ->
|
||||
{error, Reason}
|
||||
end.
|
||||
|
||||
-spec start_child(Spec :: map()) -> {ok, Pid :: pid()} | {error, Reason :: any()}.
|
||||
start_child(Spec) ->
|
||||
case supervisor:start_child(?MODULE, Spec) of
|
||||
{ok, Pid} when is_pid(Pid) ->
|
||||
{ok, Pid};
|
||||
{ok, undefined} ->
|
||||
{error, ignored};
|
||||
{error, {'already_started', Pid}} when is_pid(Pid) ->
|
||||
{ok, Pid};
|
||||
{error, Error} ->
|
||||
@ -99,17 +111,72 @@ delete_network(NetworkId) when is_integer(NetworkId) ->
|
||||
Error
|
||||
end.
|
||||
|
||||
-spec child_spec(Id :: integer()) -> map().
|
||||
-spec child_spec(Id :: integer()) -> {ok, map()} | {error, Reason :: any()}.
|
||||
child_spec(Id) when is_integer(Id) ->
|
||||
Name = sdlan_network:get_name(Id),
|
||||
#{
|
||||
id => Name,
|
||||
start => {sdlan_network, start_link, [Name, Id]},
|
||||
restart => permanent,
|
||||
shutdown => 2000,
|
||||
type => worker,
|
||||
modules => ['sdlan_network']
|
||||
}.
|
||||
case load_network_data(Id) of
|
||||
{ok, NetworkData} ->
|
||||
Name = sdlan_network:get_name(Id),
|
||||
{ok, #{
|
||||
id => Name,
|
||||
start => {sdlan_network, start_link, [Name, NetworkData]},
|
||||
restart => permanent,
|
||||
shutdown => 2000,
|
||||
type => worker,
|
||||
modules => ['sdlan_network']
|
||||
}};
|
||||
{error, Reason} ->
|
||||
{error, Reason}
|
||||
end.
|
||||
|
||||
-spec load_child_spec(Id :: integer()) -> {true, map()} | false.
|
||||
load_child_spec(Id) ->
|
||||
case child_spec(Id) of
|
||||
{ok, Spec} ->
|
||||
{true, Spec};
|
||||
{error, Reason} ->
|
||||
logger:warning("[sdlan_network_sup] skip network: ~p, reason: ~p", [Id, Reason]),
|
||||
false
|
||||
end.
|
||||
|
||||
-spec load_network_data(Id :: integer()) -> {ok, tuple()} | {error, Reason :: any()}.
|
||||
load_network_data(Id) when is_integer(Id) ->
|
||||
case sdlan_api:get_network(Id) of
|
||||
{ok, #{<<"ipaddr">> := Null}} when Null == <<"null">>; Null == <<"NULL">> ->
|
||||
{error, <<"ipaddrr is null">>};
|
||||
{ok, #{<<"id">> := NetworkId}} when NetworkId =/= Id ->
|
||||
{error, {network_id_mismatch, Id, NetworkId}};
|
||||
{ok, NetworkInfo = #{<<"id">> := Id, <<"name">> := Name, <<"domain">> := Domain,
|
||||
<<"algorithm">> := Algorithm, <<"ipaddr">> := IpAddr0, <<"owner_id">> := OwnerId}} ->
|
||||
logger:debug("[sdlan_network_sup] load network info: ~p", [NetworkInfo]),
|
||||
case parse_ipaddr(IpAddr0) of
|
||||
{ok, IpAddr, MaskLen} ->
|
||||
{ok, {network, Id, Name, Domain, IpAddr, MaskLen, OwnerId, Algorithm}};
|
||||
{error, Reason} ->
|
||||
{error, Reason}
|
||||
end;
|
||||
{ok, NetworkInfo} ->
|
||||
{error, {invalid_network_info, NetworkInfo}};
|
||||
{error, Reason} ->
|
||||
logger:warning("[sdlan_network_sup] load network: ~p, get error: ~p", [Id, Reason]),
|
||||
{error, Reason}
|
||||
end.
|
||||
|
||||
%% 解析IpAddr: <<"192.168.172/24">>
|
||||
-spec parse_ipaddr(IpAddr0 :: binary()) -> {ok, IpAddr :: binary(), MaskLen :: integer()} | {error, Reason :: any()}.
|
||||
parse_ipaddr(IpAddr0) when is_binary(IpAddr0) ->
|
||||
try
|
||||
case binary:split(IpAddr0, <<"/">>) of
|
||||
[IpAddr, MaskLen] ->
|
||||
{ok, IpAddr, binary_to_integer(MaskLen)};
|
||||
_ ->
|
||||
{ok, IpAddr0, 24}
|
||||
end
|
||||
catch
|
||||
_:_ ->
|
||||
{error, {invalid_ipaddr, IpAddr0}}
|
||||
end;
|
||||
parse_ipaddr(IpAddr0) ->
|
||||
{error, {invalid_ipaddr, IpAddr0}}.
|
||||
|
||||
set_network_bind(0) ->
|
||||
ok;
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user