From 04ea746065f5ad9603a9b64502d42781497b0f75 Mon Sep 17 00:00:00 2001 From: Andreas Schultz Date: Fri, 26 Apr 2024 14:03:33 +0200 Subject: [PATCH] wip --- src/eradius.erl | 15 +-- src/eradius_auth.erl | 3 + src/eradius_client.erl | 143 ------------------------- src/eradius_client_mngr.erl | 17 +-- src/eradius_counter_aggregator.erl | 161 ----------------------------- src/eradius_lib.erl | 28 +---- src/eradius_metrics_prometheus.erl | 12 ++- src/eradius_req.erl | 3 + src/eradius_server.erl | 138 +------------------------ 9 files changed, 25 insertions(+), 495 deletions(-) delete mode 100644 src/eradius_counter_aggregator.erl diff --git a/src/eradius.erl b/src/eradius.erl index a3fc225..d6357e4 100644 --- a/src/eradius.erl +++ b/src/eradius.erl @@ -4,9 +4,9 @@ -behaviour(application). %% API --export([load_tables/1, load_tables/2, statistics/1, +-export([load_tables/1, load_tables/2, start_server/3, start_server/4]). --ignore_xref([load_tables/1, load_tables/2, statistics/1, +-ignore_xref([load_tables/1, load_tables/2, start_server/3, start_server/4]). %% application callbacks @@ -30,17 +30,6 @@ load_tables(Tables) -> load_tables(Dir, Tables) -> eradius_dict:load_tables(Dir, Tables). -%% @doc manipulate server statistics -%% * reset: reset all counters to zero -%% * pull: read counters and reset to zero -%% * read: read counters -statistics(reset) -> - eradius_counter_aggregator:reset(); -statistics(pull) -> - eradius_counter_aggregator:pull(); -statistics(read) -> - eradius_counter_aggregator:read(). - start_server(IP, Port, #{handler := {_, _}, clients := #{}} = Opts) when is_tuple(IP), is_integer(Port), Port >= 0, Port < 65536 -> eradius_server_sup:start_instance(eradius_server:config(IP, Port, Opts)). diff --git a/src/eradius_auth.erl b/src/eradius_auth.erl index 43eb0fc..f59eae3 100644 --- a/src/eradius_auth.erl +++ b/src/eradius_auth.erl @@ -21,6 +21,9 @@ -export([nt_hash/1, v2_generate_nt_response/4, mppe_get_master_key/2, mppe_generate_session_keys/3, mppe_get_asymetric_send_start_key/2, v2_generate_authenticator_response/5]). +-ignore_xref([nt_hash/1, v2_generate_nt_response/4, mppe_get_master_key/2, + mppe_generate_session_keys/3, mppe_get_asymetric_send_start_key/2, + v2_generate_authenticator_response/5]). -endif. -include("eradius_lib.hrl"). diff --git a/src/eradius_client.erl b/src/eradius_client.erl index cb35a80..7a1ebb3 100644 --- a/src/eradius_client.erl +++ b/src/eradius_client.erl @@ -100,20 +100,13 @@ proceed_response(_Tried, Req, {ok, Resp0}, _ServerName, _, TS1, _Opts) -> Resp = eradius_req:record_metric( reply, #{request => Req, duration => erlang:monotonic_time() - TS1}, Resp0), - %% update_client_request(Req, erlang:monotonic_time() - TS1), - %% update_client_responses(MetricsInfo), {{ok, Resp}, Req}; proceed_response(Tried, Req0, Response, ServerName, #{ip := ServerIP, port := Port}, TS1, Opts) -> Req = eradius_req:record_metric( Response, #{request => Req0, duration => erlang:monotonic_time() - TS1}, Req0), - %% update_client_responses(MetricsInfo), - %% update_client_request(Req, erlang:monotonic_time() - TS1), - eradius_client_mngr:request_failed(ServerName), - %% update_server_status_metric(ServerIP, Port, false, Opts), - maybe_failover(Tried, Req, Response, Opts). maybe_failover(Tried, Req, _Response, #{failover := [_|_] = FailOver} = Opts) -> @@ -131,8 +124,6 @@ send_request_loop(Socket, ReqId, Req0, Opts) -> %% send_request_loop/8 send_request_loop(_Socket, _ReqId, _Packet, #{timeout := Timeout, retries := 0}, Req) -> - %% TS = erlang:convert_time_unit(Timeout, millisecond, native), - %% update_client_request(timeout, TS), {{error, timeout}, Req}; send_request_loop(Socket, ReqId, Packet, #{timeout := Timeout, retries := RetryN} = Opts, @@ -152,143 +143,9 @@ send_request_loop(Socket, ReqId, Packet, {error, close} -> {{error, socket_down}, Req}; {error, timeout} -> - %% TS = erlang:convert_time_unit(Timeout, millisecond, native), - %% update_client_request(retransmission, TS), ReqN = eradius_req:record_metric(retransmission, #{}, Req), send_request_loop(Socket, ReqId, Packet, Opts#{retries := RetryN - 1}, ReqN); {error, _} = Error -> {Error, Req} end. - -%% @private -update_client_requests(MetricsInfo) -> - eradius_counter:inc_counter(requests, MetricsInfo). - -%% @private -update_client_request(pending, MetricsInfo, Pending) -> - if Pending =< 0 -> eradius_counter:dec_counter(pending, MetricsInfo); - true -> eradius_counter:inc_counter(pending, MetricsInfo) - end; -update_client_request(#{cmd := Cmd} = Req, MetricsInfo, Ms) -> - eradius_counter:observe(eradius_client_request_duration_milliseconds, MetricsInfo, Ms, "Execution time of a RADIUS request"), - update_client_request_by_type(Cmd, MetricsInfo, Ms, Req). - -%% @private -update_client_request_by_type(request, MetricsInfo, Ms, _) -> - eradius_counter:observe(eradius_client_access_request_duration_milliseconds, MetricsInfo, Ms, "Access-Request execution time"), - eradius_counter:inc_counter(accessRequests, MetricsInfo); -update_client_request_by_type(accreq, MetricsInfo, Ms, Req) -> - eradius_counter:observe(eradius_client_accounting_request_duration_milliseconds, MetricsInfo, Ms, "Accounting-Request execution time"), - inc_request_counter_accounting(MetricsInfo, Req); -update_client_request_by_type(coareq, MetricsInfo, Ms, _) -> - eradius_counter:observe(eradius_client_coa_request_duration_milliseconds, MetricsInfo, Ms, "Coa request execution time"), - eradius_counter:inc_counter(coaRequests, MetricsInfo); -update_client_request_by_type(discreq, MetricsInfo, Ms, _) -> - eradius_counter:observe(eradius_client_disconnect_request_duration_milliseconds, MetricsInfo, Ms, "Disconnect execution time"), - eradius_counter:inc_counter(discRequests, MetricsInfo); -update_client_request_by_type(retransmission, MetricsInfo, _Ms, _) -> - eradius_counter:inc_counter(retransmissions, MetricsInfo); -update_client_request_by_type(timeout, MetricsInfo, _Ms, _) -> - eradius_counter:inc_counter(timeouts, MetricsInfo); -update_client_request_by_type(_, _, _, _) -> ok. - -%% @private -update_client_responses(MetricsInfo) -> eradius_counter:inc_counter(replies, MetricsInfo). - -%% @private -update_client_response(accept, MetricsInfo, _) -> eradius_counter:inc_counter(accessAccepts, MetricsInfo); -update_client_response(reject, MetricsInfo, _) -> eradius_counter:inc_counter(accessRejects, MetricsInfo); -update_client_response(challenge, MetricsInfo, _) -> eradius_counter:inc_counter(accessChallenges, MetricsInfo); -update_client_response(accresp, MetricsInfo, Request) -> inc_responses_counter_accounting(MetricsInfo, Request); -update_client_response(coanak, MetricsInfo, _) -> eradius_counter:inc_counter(coaNaks, MetricsInfo); -update_client_response(coaack, MetricsInfo, _) -> eradius_counter:inc_counter(coaAcks, MetricsInfo); -update_client_response(discnak, MetricsInfo, _) -> eradius_counter:inc_counter(discNaks, MetricsInfo); -update_client_response(discack, MetricsInfo, _) -> eradius_counter:inc_counter(discAcks, MetricsInfo); -update_client_response(dropped, MetricsInfo, _) -> eradius_counter:inc_counter(packetsDropped, MetricsInfo); -update_client_response(bad_authenticator, MetricsInfo, _) -> eradius_counter:inc_counter(badAuthenticators, MetricsInfo); -update_client_response(unknown_req_type, MetricsInfo, _) -> eradius_counter:inc_counter(unknownTypes, MetricsInfo); -update_client_response(_, _, _) -> ok. - -%%%========================================================================= -%%% internal functions -%%%========================================================================= - -make_metrics_info(ServerName, #{ip := ServerIP, port := ServerPort}, {ClientName, ClientIP}) -> - ClientAddrInfo = eradius_lib:make_addr_info({ClientName, {ClientIP, undefined}}), - ServerAddrInfo = eradius_lib:make_addr_info({ServerName, {ServerIP, ServerPort}}), - {ClientAddrInfo, ServerAddrInfo}. - -inc_request_counter_accounting(MetricsInfo, #{attrs := Attrs}) -> - Requests = ets:match_spec_run(Attrs, client_request_counter_account_match_spec_compile()), - [eradius_counter:inc_counter(Type, MetricsInfo) || Type <- Requests], - ok; -inc_request_counter_accounting(_, _) -> - ok. - -inc_responses_counter_accounting(MetricsInfo, #{attrs := Attrs}) -> - Responses = ets:match_spec_run(Attrs, client_response_counter_account_match_spec_compile()), - [eradius_counter:inc_counter(Type, MetricsInfo) || Type <- Responses], - ok; -inc_responses_counter_accounting(_, _) -> - ok. - -update_server_status_metric(IP, Port, false, _Options) -> - eradius_counter:set_boolean_metric(server_status, [IP, Port], false); -update_server_status_metric(IP, Port, true, Options) -> - UpstreamServers = proplists:get_value(failover, Options, []), - %% set all servesr from pool as inactive - if is_list(UpstreamServers) -> - lists:foreach( - fun (Server) -> - case Server of - {ServerIP, ServerPort, _} -> - eradius_counter:set_boolean_metric(server_status, [ServerIP, ServerPort], false); - {ServerIP, ServerPort, _, _} -> - eradius_counter:set_boolean_metric(server_status, [ServerIP, ServerPort], false); - _ -> - ok - end - - end, UpstreamServers); - true -> - ok - end, - %% set current service as active - eradius_counter:set_boolean_metric(server_status, [IP, Port], true). - -client_request_counter_account_match_spec_compile() -> - case persistent_term:get({?MODULE, ?FUNCTION_NAME}, undefined) of - undefined -> - MatchSpecCompile = - ets:match_spec_compile( - ets:fun2ms( - fun ({?RStatus_Type, ?RStatus_Type_Start}) -> accountRequestsStart; - ({?RStatus_Type, ?RStatus_Type_Stop}) -> accountRequestsStop; - ({?RStatus_Type, ?RStatus_Type_Update}) -> accountRequestsUpdate; - ({#attribute{id = ?RStatus_Type}, ?RStatus_Type_Start}) -> accountRequestsStart; - ({#attribute{id = ?RStatus_Type}, ?RStatus_Type_Stop}) -> accountRequestsStop; - ({#attribute{id = ?RStatus_Type}, ?RStatus_Type_Update}) -> accountRequestsUpdate end)), - persistent_term:put({?MODULE, ?FUNCTION_NAME}, MatchSpecCompile), - MatchSpecCompile; - MatchSpecCompile -> - MatchSpecCompile - end. - -client_response_counter_account_match_spec_compile() -> - case persistent_term:get({?MODULE, ?FUNCTION_NAME}, undefined) of - undefined -> - MatchSpecCompile = - ets:match_spec_compile( - ets:fun2ms( - fun ({?RStatus_Type, ?RStatus_Type_Start}) -> accountResponsesStart; - ({?RStatus_Type, ?RStatus_Type_Stop}) -> accountResponsesStop; - ({?RStatus_Type, ?RStatus_Type_Update}) -> accountResponsesUpdate; - ({#attribute{id = ?RStatus_Type}, ?RStatus_Type_Start}) -> accountResponsesStart; - ({#attribute{id = ?RStatus_Type}, ?RStatus_Type_Stop}) -> accountResponsesStop; - ({#attribute{id = ?RStatus_Type}, ?RStatus_Type_Update}) -> accountResponsesUpdate end)), - persistent_term:put({?MODULE, ?FUNCTION_NAME}, MatchSpecCompile), - MatchSpecCompile; - MatchSpecCompile -> - MatchSpecCompile - end. diff --git a/src/eradius_client_mngr.erl b/src/eradius_client_mngr.erl index a72144c..fe5b27a 100644 --- a/src/eradius_client_mngr.erl +++ b/src/eradius_client_mngr.erl @@ -20,7 +20,8 @@ -export([init/1, handle_call/3, handle_cast/2, handle_info/2, terminate/2, code_change/3]). -ifdef(TEST). --export([get_state/0, servers/0, server/1, get_socket_count/0, init_server_status_metrics/0]). +-export([get_state/0, servers/0, server/1, get_socket_count/0]). +-ignore_xref([get_state/0, servers/0, server/1, get_socket_count/0]). -endif. -ignore_xref([start_default_client/1, start_client/1, start_client/2]). @@ -474,17 +475,3 @@ find_socket_process(PortIdx, Sockets, #state{owner = Owner, config = Config}) -> Socket -> {Socket, Sockets} end. - -%% @private -init_server_status_metrics() -> - case application:get_env(eradius, server_status_metrics_enabled, false) of - false -> - ok; - true -> - %% That will be called at eradius startup and we must be sure that prometheus - %% application already started if server status metrics supposed to be used - application:ensure_all_started(prometheus), - ets:foldl(fun ({{Addr, Port}, _, _}, _Acc) -> - eradius_counter:set_boolean_metric(server_status, [Addr, Port], false) - end, [], ?MODULE) - end. diff --git a/src/eradius_counter_aggregator.erl b/src/eradius_counter_aggregator.erl deleted file mode 100644 index 44f444c..0000000 --- a/src/eradius_counter_aggregator.erl +++ /dev/null @@ -1,161 +0,0 @@ --module(eradius_counter_aggregator). - --behaviour(gen_server). --export([init/1, handle_call/3, handle_cast/2, handle_info/2, terminate/2, code_change/3]). --export([start_link/0, reset/0, pull/0, read/0]). - --include("eradius_lib.hrl"). - --define(INIT_HB, 1000). --define(INTERVAL_HB, 5000). - --record(state, { - me :: reference(), - reset :: erlang:timestamp() - }). - -%% @doc reset all counters to zero -reset() -> - gen_server:call(?MODULE, reset). -%% @doc read counters and reset to zero --spec pull() -> eradius_counter:stats(). -pull() -> - gen_server:call(?MODULE, pull). -%% @doc read counters --spec read() -> eradius_counter:stats(). -read() -> - gen_server:call(?MODULE, read). - -%% @private --spec start_link() -> {ok, pid()} | {error, term()}. -start_link() -> - gen_server:start_link({local, ?MODULE}, ?MODULE, [], []). - -%% ------------------------------------------------------------------------------------------ -%% -- gen_server Callbacks -%% @private -init([]) -> - ets:new(?MODULE, [ordered_set, protected, named_table, {keypos, #nas_counter.key}, {write_concurrency,true}]), - EnableAggregator = application:get_env(eradius, counter_aggregator, false), - if EnableAggregator == true -> - erlang:send_after(?INIT_HB, self(), heartbeat); - true -> - ok - end, - {ok, #state{me = make_ref(), reset = eradius_lib:timestamp()}}. - -%% @private -handle_call(pull, _From, State) -> - Nass = read_stats(State), - Servers = server_stats(pull), - ets:delete_all_objects(?MODULE), - {reply, {Servers, Nass}, State#state{reset = eradius_lib:timestamp()}}; -handle_call(read, _From, State) -> - Nass = read_stats(State), - Servers = server_stats(read), - {reply, {Servers, Nass}, State}; -handle_call(reset, _From, State) -> - server_stats(reset), - ets:delete_all_objects(?MODULE), - {reply, ok, State#state{reset = eradius_lib:timestamp()}}. - -%% @private -handle_info(heartbeat, State) -> - eradius_counter:collect(State#state.me, self()), - erlang:send_after(?INTERVAL_HB, self(), heartbeat), - {noreply, State}; -handle_info({collect, Ref, Stats}, State = #state{me = Ref}) -> - lists:foreach(fun update_stats/1, Stats), - {noreply, State}; -handle_info({collect, Ref, Stats}, State) -> - io:format("invalid stats answer: ~p~n", [{collect, Ref, Stats}]), - {noreply, State}. - -%% -- unused callbacks -%% @private -handle_cast(_Msg, State) -> {noreply, State}. -%% @private -code_change(_OldVsn, State, _Extra) -> {ok, State}. -%% @private -terminate(_Reason, _State) -> ok. - -%% ------------------------------------------------------------------------------------------ -%% -- helper functions -%% @private - -read_stats(State) -> - {State#state.reset, ets:tab2list(?MODULE)}. - -server_stats(Func) -> - lists:foldl(fun(S, Acc) -> [eradius_server:stats(S, Func)|Acc] end, [], eradius_server_sup:all()). - -update_stats(Rec = #nas_counter{key = Key}) -> - Cnt0 = case ets:lookup(?MODULE, Key) of - [] -> #nas_counter{key = Key}; - [Cnt] -> Cnt - end, - ets:insert(?MODULE, add_counter(Cnt0, Rec)); -update_stats(Rec = #client_counter{key = Key}) -> - Cnt0 = case ets:lookup(?MODULE, Key) of - [] -> #client_counter{key = Key}; - [Cnt] -> Cnt - end, - ets:insert(?MODULE, add_counter(Cnt0, Rec)). - -add_counter(Cnt1 = #nas_counter{}, Cnt2 = #nas_counter{}) -> - #nas_counter{ - key = Cnt1#nas_counter.key, - requests = Cnt1#nas_counter.requests + Cnt2#nas_counter.requests, - replies = Cnt1#nas_counter.replies + Cnt2#nas_counter.replies, - dupRequests = Cnt1#nas_counter.dupRequests + Cnt2#nas_counter.dupRequests, - malformedRequests = Cnt1#nas_counter.malformedRequests + Cnt2#nas_counter.malformedRequests, - accessRequests = Cnt1#nas_counter.accessRequests + Cnt2#nas_counter.accessRequests, - accessAccepts = Cnt1#nas_counter.accessAccepts + Cnt2#nas_counter.accessAccepts, - accessRejects = Cnt1#nas_counter.accessRejects + Cnt2#nas_counter.accessRejects, - accessChallenges = Cnt1#nas_counter.accessChallenges + Cnt2#nas_counter.accessChallenges, - accountRequestsStart = Cnt1#nas_counter.accountRequestsStart + Cnt2#nas_counter.accountRequestsStart, - accountRequestsStop = Cnt1#nas_counter.accountRequestsStop + Cnt2#nas_counter.accountRequestsStop, - accountRequestsUpdate = Cnt1#nas_counter.accountRequestsUpdate + Cnt2#nas_counter.accountRequestsUpdate, - accountResponsesStart = Cnt1#nas_counter.accountResponsesStart + Cnt2#nas_counter.accountResponsesStart, - accountResponsesStop = Cnt1#nas_counter.accountResponsesStop + Cnt2#nas_counter.accountResponsesStop, - accountResponsesUpdate = Cnt1#nas_counter.accountResponsesUpdate + Cnt2#nas_counter.accountResponsesUpdate, - noRecords = Cnt1#nas_counter.noRecords + Cnt2#nas_counter.noRecords, - badAuthenticators = Cnt1#nas_counter.badAuthenticators + Cnt2#nas_counter.badAuthenticators, - packetsDropped = Cnt1#nas_counter.packetsDropped + Cnt2#nas_counter.packetsDropped, - unknownTypes = Cnt1#nas_counter.unknownTypes + Cnt2#nas_counter.unknownTypes, - handlerFailure = Cnt1#nas_counter.handlerFailure + Cnt2#nas_counter.handlerFailure, - coaRequests = Cnt1#nas_counter.coaRequests + Cnt2#nas_counter.coaRequests, - coaAcks = Cnt1#nas_counter.coaAcks + Cnt2#nas_counter.coaAcks, - coaNaks = Cnt1#nas_counter.coaNaks + Cnt2#nas_counter.coaNaks, - discRequests = Cnt1#nas_counter.discRequests + Cnt2#nas_counter.discRequests, - discAcks = Cnt1#nas_counter.discAcks + Cnt2#nas_counter.discAcks, - discNaks = Cnt1#nas_counter.discNaks + Cnt2#nas_counter.discNaks - }; -add_counter(Cnt1 = #client_counter{}, Cnt2 = #client_counter{}) -> - #client_counter{ - key = Cnt1#client_counter.key, - requests = Cnt1#client_counter.requests + Cnt2#client_counter.requests, - replies = Cnt1#client_counter.replies + Cnt2#client_counter.replies, - accessRequests = Cnt1#client_counter.accessRequests + Cnt2#client_counter.accessRequests, - accessAccepts = Cnt1#client_counter.accessAccepts + Cnt2#client_counter.accessAccepts, - accessRejects = Cnt1#client_counter.accessRejects + Cnt2#client_counter.accessRejects, - accessChallenges = Cnt1#client_counter.accessChallenges + Cnt2#client_counter.accessChallenges, - accountRequestsStart = Cnt1#client_counter.accountRequestsStart + Cnt2#client_counter.accountRequestsStart, - accountRequestsStop = Cnt1#client_counter.accountRequestsStop + Cnt2#client_counter.accountRequestsStop, - accountRequestsUpdate = Cnt1#client_counter.accountRequestsUpdate + Cnt2#client_counter.accountRequestsUpdate, - accountResponsesStart = Cnt1#client_counter.accountResponsesStart + Cnt2#client_counter.accountResponsesStart, - accountResponsesStop = Cnt1#client_counter.accountResponsesStop + Cnt2#client_counter.accountResponsesStop, - accountResponsesUpdate = Cnt1#client_counter.accountResponsesUpdate + Cnt2#client_counter.accountResponsesUpdate, - badAuthenticators = Cnt1#client_counter.badAuthenticators + Cnt2#client_counter.badAuthenticators, - packetsDropped = Cnt1#client_counter.packetsDropped + Cnt2#client_counter.packetsDropped, - unknownTypes = Cnt1#client_counter.unknownTypes + Cnt2#client_counter.unknownTypes, - coaRequests = Cnt1#client_counter.coaRequests + Cnt2#client_counter.coaRequests, - coaAcks = Cnt1#client_counter.coaAcks + Cnt2#client_counter.coaAcks, - coaNaks = Cnt1#client_counter.coaNaks + Cnt2#client_counter.coaNaks, - discRequests = Cnt1#client_counter.discRequests + Cnt2#client_counter.discRequests, - discAcks = Cnt1#client_counter.discAcks + Cnt2#client_counter.discAcks, - discNaks = Cnt1#client_counter.discNaks + Cnt2#client_counter.discNaks, - retransmissions = Cnt1#client_counter.retransmissions + Cnt2#client_counter.retransmissions, - timeouts = Cnt1#client_counter.timeouts + Cnt2#client_counter.timeouts, - pending = Cnt1#client_counter.pending + Cnt2#client_counter.pending - }. diff --git a/src/eradius_lib.erl b/src/eradius_lib.erl index 7c77f48..ae349f5 100644 --- a/src/eradius_lib.erl +++ b/src/eradius_lib.erl @@ -1,6 +1,6 @@ -module(eradius_lib). -export([pad_to/2]). --export([timestamp/0, printable_peer/1, printable_peer/2, make_addr_info/1]). +-export([timestamp/0, printable_peer/1, printable_peer/2]). %% -compile(bin_opt_info). @@ -28,32 +28,6 @@ pad_to(Width, Binary) -> timestamp() -> erlang:system_time(milli_seconds). --spec make_addr_info({term(), {inet:ip_address(), integer()}}) -> atom_address(). -make_addr_info({undefined, {IP, Port}}) -> - {socket_to_atom(IP, Port), ip_to_atom(IP), port_to_atom(Port)}; -make_addr_info({Name, {IP, Port}}) -> - {to_atom(Name), ip_to_atom(IP), port_to_atom(Port)}. - -to_atom(Value) when is_atom(Value) -> Value; -to_atom(Value) when is_binary(Value) -> binary_to_atom(Value, latin1); -to_atom(Value) when is_list(Value) -> list_to_atom(Value). - -socket_to_atom(IP, undefined) -> - ip_to_atom(IP); -socket_to_atom(IP, Port) when is_tuple(IP) -> - list_to_atom(inet:ntoa(IP) ++ ":" ++ integer_to_list(Port)); -socket_to_atom(IP, Port) when is_binary(IP) -> - binary_to_atom(erlang:iolist_to_binary([IP, <<":">>, Port]), latin1); -socket_to_atom(IP, Port) when is_atom(IP) -> - binary_to_atom(erlang:iolist_to_binary([atom_to_binary(IP, latin1), <<":">>, Port]), latin1). - -ip_to_atom(IP) when is_atom(IP) -> IP; -ip_to_atom(IP) -> list_to_atom(inet:ntoa(IP)). - -port_to_atom(undefined) -> undefined; -port_to_atom(Port) when is_atom(Port) -> Port; -port_to_atom(Port) -> list_to_atom(integer_to_list(Port)). - -spec printable_peer({inet:ip_address() | any, eradius_server:port_number()}) -> io_lib:chars(). printable_peer({IP, Port}) -> printable_peer(IP, Port). diff --git a/src/eradius_metrics_prometheus.erl b/src/eradius_metrics_prometheus.erl index 0a0c385..a36646c 100644 --- a/src/eradius_metrics_prometheus.erl +++ b/src/eradius_metrics_prometheus.erl @@ -6,6 +6,9 @@ -export([init/1, reset/0]). -export([client_metrics_callback/3, server_metrics_callback/3]). +-ignore_xref([init/1, reset/0]). +-ignore_xref([client_metrics_callback/3, server_metrics_callback/3]). + -include("dictionary.hrl"). -include("eradius_lib.hrl"). -include("eradius_dict.hrl"). @@ -406,18 +409,18 @@ server_metrics_callback(Event, MetaData, prometheus_counter:inc(eradius_retransmissions_total, [Server], 1); drop -> prometheus_counter:inc(eradius_requests_total, [Server], 1), + prometheus_counter:inc(eradius_packets_dropped_total, [Server], 1), case MetaData of #{reason := duplicate} -> prometheus_counter:inc(eradius_duplicated_requests_total, [Server], 1); _ -> ok end; + %% invalid_request -> + %% prometheus_counter:inc(eradius_invalid_requests_total, [Server], 1); %% eradius_malformed_requests_total %% eradius_invalid_requests_total - %% eradius_retransmissions_total - %% eradius_duplicated_requests_total %% eradius_pending_requests_total - %% eradius_packets_dropped_total %% eradius_bad_authenticator_request_total reply -> prometheus_counter:inc(eradius_replies_total, [Server], 1), @@ -447,6 +450,9 @@ server_metrics_callback(Event, MetaData, ok end, Req; +server_metrics_callback(invalid_request, #{server := Server} = _MetaData, _) -> + prometheus_counter:inc(eradius_invalid_requests_total, [Server], 1), + ok; server_metrics_callback(Event, MetaData, Req) -> ct:pal("BROKEN Server-Metric:~nEvent: ~p~nMetaData: ~p~nReq: ~p~n", [Event, MetaData, Req]), diff --git a/src/eradius_req.erl b/src/eradius_req.erl index 5e4f9fb..cc0c1fd 100644 --- a/src/eradius_req.erl +++ b/src/eradius_req.erl @@ -52,7 +52,10 @@ -ifdef(TEST). -export([encode_value/2, decode_value/2, scramble/3, ascend/3]). -export([salt_encrypt/4, salt_decrypt/3, encode_attribute/3, decode_attribute/4]). +-ignore_xref([encode_value/2, decode_value/2, scramble/3, ascend/3]). +-ignore_xref([salt_encrypt/4, salt_decrypt/3, encode_attribute/3, decode_attribute/4]). -endif. + -include("eradius_lib.hrl"). -include("eradius_dict.hrl"). diff --git a/src/eradius_server.erl b/src/eradius_server.erl index 8794e55..0bffa10 100644 --- a/src/eradius_server.erl +++ b/src/eradius_server.erl @@ -187,7 +187,6 @@ handle_info({udp, Socket, FromIP, FromPortNo, <>} server => ServerName, nas => {FromIP, FromPortNo}}, ReqKey = {FromIP, FromPortNo, ReqId}, - %% eradius_counter:inc_counter(requests, Req), case ets:lookup(Transacts, ReqKey) of [] -> @@ -206,7 +205,6 @@ handle_info({udp, Socket, FromIP, FromPortNo, <>} " duplicate request (being handled) ~p", [printable_peer(Server), printable_peer(FromIP, FromPortNo), HandlerPid, ReqKey]), - %% eradius_counter:inc_counter(dupRequests, Req); eradius_req:record_metric(drop, #{reason => duplicate}, Req1); [{_ReqKey, {replied, HandlerPid}}] -> %% handler process waiting for resend message @@ -215,18 +213,16 @@ handle_info({udp, Socket, FromIP, FromPortNo, <>} "duplicate request (resent) ~p", [printable_peer(Server), printable_peer(FromIP, FromPortNo), HandlerPid, ReqKey]), - %% eradius_counter:inc_counter(dupRequests, Req), - %% eradius_counter:inc_counter(retransmissions, Req) eradius_req:record_metric(retransmissions, #{reason => duplicate}, Req1) end, flow_control(State), {noreply, State}; handle_info({udp, _Socket, _FromIP, _FromPortNo, _Packet} = Msg, - #state{metrics_callback = MetricsCallback} = State) -> + #state{name = ServerName, metrics_callback = MetricsCallback} = State) -> %% TBD: this should go into a malformed counter ct:pal("Invalid-UDP: ~p", [Msg]), - eradius_req:metrics_callback(MetricsCallback, invalidRequests, #{}), + eradius_req:metrics_callback(MetricsCallback, invalid_request, #{server => ServerName}), flow_control(State), {noreply, State}; %% NewState = State#state{counter = eradius_counter:inc_counter(invalidRequests, State#state.counter)}, @@ -261,12 +257,11 @@ code_change(_OldVsn, State, _Extra) -> {ok, State}. %% @private -spec do_radius(pid(), eradius_server_mon:handler(), term(), eradius_req:req()) -> any(). do_radius(ServerPid, {HandlerMod, HandlerArg}, ReqKey, - #{cmd := ReqCmd, - arrival_time := TS1, socket := Socket, server := Server, + #{arrival_time := TS1, socket := Socket, server := Server, nas := {NasIP, NasPort} = Nas} = Req0) -> ct:pal("do_radius: ~p", [Req0]), case apply_handler_mod(HandlerMod, HandlerArg, Req0) of - {reply, Packet, #{cmd := RespCmd} = Resp0, Req} -> + {reply, Packet, Resp0, Req} -> ?LOG(debug, "~s From: ~s INF: Sending response for request ~0p", [printable_peer(Server), printable_peer(Nas), ReqKey]), %% TS2 = erlang:monotonic_time(), @@ -280,7 +275,7 @@ do_radius(ServerPid, {HandlerMod, HandlerArg}, ReqKey, wait_resend_init(ServerPid, ReqKey, Resp, Packet, ResendTimeout, ?RESEND_RETRIES); _ -> ok end; - {discard, Reason} = Discard -> + {discard, Reason} -> ?LOG(debug, "~s From: ~s INF: Handler discarded the request ~p for reason ~1000.p", [printable_peer(Server), printable_peer(Nas), Reason, ReqKey]), eradius_req:record_metric(discard, #{reason => Reason}, Req0); @@ -338,129 +333,6 @@ apply_handler_mod(HandlerMod, HandlerArg, {exit, {Class, Reason}} end. -%%%========================================================================= -%%% metrics functions -%%%========================================================================= - -inc_counter({ReqCmd, RespCmd}, Req, Ms, Request) -> - inc_request_counter(ReqCmd, Req, Ms, Request), - inc_reply_counter(RespCmd, Req, Request). - -inc_request_counter(request, Req, Ms, _) -> - eradius_counter:observe(eradius_request_duration_milliseconds, - Req, Ms, "RADIUS request exeuction time"), - eradius_counter:observe(eradius_access_request_duration_milliseconds, - Req, Ms, "Access-Request execution time"), - eradius_counter:inc_request_counter(accessRequests, Req); -inc_request_counter(accreq, Req, Ms, Request) -> - eradius_counter:observe(eradius_request_duration_milliseconds, - Req, Ms, "RADIUS request exeuction time"), - eradius_counter:observe(eradius_accounting_request_duration_milliseconds, - Req, Ms, "Accounting-Request execution time"), - inc_request_counter_accounting(Req, Request); -inc_request_counter(coareq, Req, Ms, _) -> - eradius_counter:observe(eradius_request_duration_milliseconds, - Req, Ms, "RADIUS request exeuction time"), - eradius_counter:observe(eradius_coa_request_duration_milliseconds, - Req, Ms, "Coa-Request execution time"), - eradius_counter:inc_request_counter(coaRequests, Req); -inc_request_counter(discreq, Req, Ms, _) -> - eradius_counter:observe(eradius_request_duration_milliseconds, - Req, Ms, "RADIUS request exeuction time"), - eradius_counter:observe(eradius_disconnect_request_duration_milliseconds, - Req, Ms, "Disconnect-Request execution time"), - eradius_counter:inc_request_counter(discRequests, Req); -inc_request_counter(_Cmd, _Req, _Ms, _Request) -> - ok. - -inc_reply_counter(accept, Req, _) -> - eradius_counter:inc_counter(replies, Req), - eradius_counter:inc_reply_counter(accessAccepts, Req); -inc_reply_counter(reject, Req, _) -> - eradius_counter:inc_counter(replies, Req), - eradius_counter:inc_reply_counter(accessRejects, Req); -inc_reply_counter(challenge, Req, _) -> - eradius_counter:inc_counter(replies, Req), - eradius_counter:inc_reply_counter(accessChallenges, Req); -inc_reply_counter(accresp, Req, Request) -> - eradius_counter:inc_counter(replies, Req), - inc_response_counter_accounting(Req, Request); -inc_reply_counter(coaack, Req, _) -> - eradius_counter:inc_counter(replies, Req), - eradius_counter:inc_reply_counter(coaAcks, Req); -inc_reply_counter(coanak, Req, _) -> - eradius_counter:inc_counter(replies, Req), - eradius_counter:inc_reply_counter(coaNaks, Req); -inc_reply_counter(discack, Req, _) -> - eradius_counter:inc_counter(replies, Req), - eradius_counter:inc_reply_counter(discAcks, Req); -inc_reply_counter(discnak, Req, _) -> - eradius_counter:inc_counter(replies, Req), - eradius_counter:inc_reply_counter(discNaks, Req); -inc_reply_counter(_Cmd, _Req, _Request) -> - ok. - -inc_request_counter_accounting(Req, #{attrs := Attrs}) -> - Requests = ets:match_spec_run(Attrs, server_request_counter_account_match_spec_compile()), - [eradius_counter:inc_request_counter(Type, Req) || Type <- Requests], - ok; -inc_request_counter_accounting(_, _) -> - ok. - -inc_response_counter_accounting(Req, #{attrs := Attrs}) -> - Responses = ets:match_spec_run(Attrs, server_response_counter_account_match_spec_compile()), - [eradius_counter:inc_reply_counter(Type, Req) || Type <- Responses], - ok; -inc_response_counter_accounting(_, _) -> - ok. - -inc_discard_counter(bad_authenticator, Req) -> - eradius_counter:inc_counter(badAuthenticators, Req); -inc_discard_counter(unknown_req_type, Req) -> - eradius_counter:inc_counter(unknownTypes, Req); -inc_discard_counter(malformed, Req) -> - eradius_counter:inc_counter(malformedRequests, Req); -inc_discard_counter(_Reason, Req) -> - eradius_counter:inc_counter(packetsDropped, Req). - -server_request_counter_account_match_spec_compile() -> - case persistent_term:get({?MODULE, ?FUNCTION_NAME}, undefined) of - undefined -> - MatchSpecCompile = - ets:match_spec_compile( - ets:fun2ms( - fun ({#attribute{id = ?RStatus_Type}, ?RStatus_Type_Start}) -> - accountRequestsStart; - ({#attribute{id = ?RStatus_Type}, ?RStatus_Type_Stop}) -> - accountRequestsStop; - ({#attribute{id = ?RStatus_Type}, ?RStatus_Type_Update}) -> - accountRequestsUpdate - end)), - persistent_term:put({?MODULE, ?FUNCTION_NAME}, MatchSpecCompile), - MatchSpecCompile; - MatchSpecCompile -> - MatchSpecCompile - end. - -server_response_counter_account_match_spec_compile() -> - case persistent_term:get({?MODULE, ?FUNCTION_NAME}, undefined) of - undefined -> - MatchSpecCompile = - ets:match_spec_compile( - ets:fun2ms( - fun ({#attribute{id = ?RStatus_Type}, ?RStatus_Type_Start}) -> - accountResponsesStart; - ({#attribute{id = ?RStatus_Type}, ?RStatus_Type_Stop}) -> - accountResponsesStop; - ({#attribute{id = ?RStatus_Type}, ?RStatus_Type_Update}) -> - accountResponsesUpdate - end)), - persistent_term:put({?MODULE, ?FUNCTION_NAME}, MatchSpecCompile), - MatchSpecCompile; - MatchSpecCompile -> - MatchSpecCompile - end. - %%%========================================================================= %%% internal functions %%%=========================================================================