Skip to content

Commit

Permalink
wip
Browse files Browse the repository at this point in the history
  • Loading branch information
RoadRunnr committed May 2, 2024
1 parent 75ccdf3 commit c6b5bb3
Show file tree
Hide file tree
Showing 4 changed files with 73 additions and 48 deletions.
10 changes: 6 additions & 4 deletions src/eradius.erl
Original file line number Diff line number Diff line change
Expand Up @@ -31,12 +31,14 @@ load_tables(Dir, Tables) ->
eradius_dict:load_tables(Dir, Tables).

start_server(IP, Port, #{handler := {_, _}, clients := #{}} = Opts)
when is_tuple(IP), is_integer(Port), Port >= 0, Port < 65536 ->
eradius_server:start_instance(eradius_server:config(IP, Port, Opts)).
when (IP =:= any orelse is_tuple(IP)) andalso
is_integer(Port) andalso Port >= 0 andalso Port < 65536 ->
eradius_server:start_instance(IP, Port, Opts).

start_server(ServerName, IP, Port, #{handler := {_, _}, clients := #{}} = Opts)
when is_tuple(IP), is_integer(Port), Port >= 0, Port < 65536 ->
eradius_server:start_instance(ServerName, eradius_server:config(IP, Port, Opts)).
when (IP =:= any orelse is_tuple(IP)) andalso
is_integer(Port) andalso Port >= 0 andalso Port < 65536 ->
eradius_server:start_instance(ServerName, IP, Port, Opts).

%%%===================================================================
%%% application callbacks
Expand Down
93 changes: 61 additions & 32 deletions src/eradius_server.erl
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,13 @@
%% SPDX-License-Identifier: MIT
%%
-module(eradius_server).
-feature(maybe_expr, enable).

-behaviour(gen_server).

%% API
-export([start_instance/1, start_instance/2, stop_instance/1]).
-export([config/3, start_link/1, start_link/2]).
-export([start_instance/3, start_instance/4, stop_instance/1]).
-export([start_link/3, start_link/4]).
-export_type([req_id/0]).

%% internal API
Expand All @@ -19,8 +20,8 @@
%% gen_server callbacks
-export([init/1, handle_call/3, handle_cast/2, handle_info/2, terminate/2, code_change/3]).

-ignore_xref([start_link/1, start_link/2]).
-ignore_xref([start_instance/1, start_instance/2, stop_instance/1]).
-ignore_xref([start_link/3, start_link/4]).
-ignore_xref([start_instance/3, start_instance/4, stop_instance/1]).

-include_lib("stdlib/include/ms_transform.hrl").
-include_lib("kernel/include/logger.hrl").
Expand Down Expand Up @@ -92,41 +93,46 @@
%%% API
%%%=========================================================================

start_instance(Opts) ->
eradius_server_sup:start_instance(Opts).
-spec start_instance(IP :: 'any' | inet:ip_address(), Port :: inet:port_number(),
Opts :: server_opts()) -> gen_server:start_ret().
start_instance(IP, Port, Opts)
when (IP =:= any orelse is_tuple(IP)) andalso
is_integer(Port) andalso Port >= 0 andalso Port < 65536 ->
eradius_server_sup:start_instance([IP, Port, Opts]).

start_instance(ServerName, Opts) ->
eradius_server_sup:start_instance(ServerName, Opts).
-spec start_instance(ServerName :: gen_server:server_name(),
IP :: 'any' | inet:ip_address(), Port :: inet:port_number(),
Opts :: server_opts()) -> gen_server:start_ret().
start_instance(ServerName, IP, Port, Opts)
when (IP =:= any orelse is_tuple(IP)) andalso
is_integer(Port) andalso Port >= 0 andalso Port < 65536 ->
eradius_server_sup:start_instance([ServerName, IP, Port, Opts]).

-spec stop_instance(Pid :: pid()) -> ok.
stop_instance(Pid) ->
eradius_server_sup:stop_instance(Pid).
try gen_server:call(Pid, stop)
catch exit:_ -> ok end.

-spec config(IP :: inet:ip_address() | any, inet:port_number(),
server_opts()) -> server_config().
config(IP, Port, #{handler := {_, _}, clients := Clients} = Opts)
-spec start_link(IP :: 'any' | inet:ip_address(), Port :: inet:port_number(),
Opts :: server_opts()) -> gen_server:start_ret().
start_link(IP, Port, #{handler := {_, _}, clients := #{}} = Opts)
when (IP =:= any orelse is_tuple(IP)) andalso
is_map(Clients) andalso
is_integer(Port) andalso Port >= 0 andalso Port < 65536 ->
SocketOpts0 = maps:get(socket_opts, Opts, #{}),
SocketOpts = #{family := Family, ifaddr := IfAddr} =
maps:merge(default_socket_opts(IP, Port), to_map(SocketOpts0)),

Opts#{server_name => server_name(IP, Port, Opts),
socket_opts => SocketOpts#{ifaddr := socket_ip(Family, IfAddr)},
metrics_callback => maps:get(metrics_callback, Opts, undefined),
clients =>
maps:fold(fun(K, V, M) -> M#{socket_ip(Family, K) => V} end, #{}, Clients)
}.

-spec start_link(server_config()) -> gen_server:start_ret().
start_link(#{socket_opts := #{ifaddr := IP, port := Port}} = Config) ->
ServerName = list_to_atom(lists:flatten(["eradius_server_", server_name(IP, Port)])),
start_link({local, ServerName}, Config).
maybe
{ok, Config} ?= config(IP, Port, Opts),
gen_server:start_link(?MODULE, [Config], [])
end.

-spec start_link(gen_server:server_name(),
server_config()) -> gen_server:start_ret().
start_link(ServerName, Config) ->
gen_server:start_link(ServerName, ?MODULE, [Config], []).
-spec start_link(ServerName :: gen_server:server_name(),
IP :: 'any' | inet:ip_address(), Port :: inet:port_number(),
Opts :: server_opts()) -> gen_server:start_ret().
start_link(ServerName, IP, Port, #{handler := {_, _}, clients := #{}} = Opts)
when (IP =:= any orelse is_tuple(IP)) andalso
is_integer(Port) andalso Port >= 0 andalso Port < 65536 ->
maybe
{ok, Config} ?= config(IP, Port, Opts),
gen_server:start_link(ServerName, ?MODULE, [Config], [])
end.

%%%===================================================================
%%% gen_server callbacks
Expand Down Expand Up @@ -167,6 +173,8 @@ init([#{server_name := ServerName,
end.

%% @private
handle_call(stop, _From, State) ->
{stop, normal, ok, State};
handle_call(_Call, _From, State) ->
{reply, ok, State}.

Expand Down Expand Up @@ -328,6 +336,25 @@ apply_handler_mod(HandlerMod, HandlerArg,
%%% internal functions
%%%=========================================================================

-spec config(IP :: inet:ip_address() | any, inet:port_number(),
server_opts()) -> {ok, server_config()}.
config(IP, Port, #{handler := {_, _}, clients := Clients} = Opts0)
when (IP =:= any orelse is_tuple(IP)) andalso
is_map(Clients) andalso
is_integer(Port) andalso Port >= 0 andalso Port < 65536 ->
SocketOpts0 = maps:get(socket_opts, Opts0, #{}),
SocketOpts = #{family := Family, ifaddr := IfAddr} =
maps:merge(default_socket_opts(IP, Port), to_map(SocketOpts0)),

Opts =
Opts0#{server_name => server_name(IP, Port, Opts0),
socket_opts => SocketOpts#{ifaddr := socket_ip(Family, IfAddr)},
metrics_callback => maps:get(metrics_callback, Opts0, undefined),
clients =>
maps:fold(fun(K, V, M) -> M#{socket_ip(Family, K) => V} end, #{}, Clients)
},
{ok, Opts}.

flow_control(#state{socket = Socket, active_n = once}) ->
inet:setopts(Socket, [{active, once}]);
flow_control(_) ->
Expand All @@ -347,6 +374,8 @@ to_map(Opts) when is_map(Opts) ->
Opts.

%% @private
socket_ip(_, any) ->
any;
socket_ip(inet, {_, _, _, _} = IP) ->
IP;
socket_ip(inet6, {_, _, _, _} = IP) ->
Expand Down
10 changes: 2 additions & 8 deletions src/eradius_server_sup.erl
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
-module(eradius_server_sup).
-behaviour(supervisor).

-export([start_link/0, start_instance/1, start_instance/2, stop_instance/1, all/0]).
-export([start_link/0, start_instance/1, all/0]).

-export([init/1]).
-import(eradius_lib, [printable_peer/2]).
Expand All @@ -20,13 +20,7 @@ start_link() ->
supervisor:start_link({local, ?SERVER}, ?MODULE, []).

start_instance(Opts) ->
supervisor:start_child(?SERVER, [Opts]).

start_instance(ServerName, Opts) ->
supervisor:start_child(?SERVER, [ServerName, Opts]).

stop_instance(Pid) ->
supervisor:terminate_child(?SERVER, Pid).
supervisor:start_child(?SERVER, Opts).

all() ->
lists:map(fun({_, Child, _, _}) -> Child end, supervisor:which_children(?SERVER)).
Expand Down
8 changes: 4 additions & 4 deletions test/eradius_test_handler.erl
Original file line number Diff line number Diff line change
Expand Up @@ -22,10 +22,10 @@ start(Backend, Family) ->
SrvOpts = #{handler => {?MODULE, []},
clients => #{eradius_test_lib:localhost(Family, tuple) =>
#{secret => "secret", client => <<"ONE">>}}},
eradius:start_server(
eradius_test_lib:localhost(Family, tuple), 1812, SrvOpts#{server_name => one}),
eradius:start_server(
eradius_test_lib:localhost(Family, tuple), 1813, SrvOpts#{server_name => two}),
{ok, _} = eradius:start_server(
eradius_test_lib:localhost(Family, tuple), 1812, SrvOpts#{server_name => one}),
{ok, _} = eradius:start_server(
eradius_test_lib:localhost(Family, tuple), 1813, SrvOpts#{server_name => two}),
ok.

stop() ->
Expand Down

0 comments on commit c6b5bb3

Please sign in to comment.