diff options
-rw-r--r-- | p11p-daemon/src/p11p_listener.erl | 73 | ||||
-rw-r--r-- | p11p-daemon/src/p11p_server.erl | 58 | ||||
-rw-r--r-- | p11p-daemon/src/p11p_server_sup.erl | 42 | ||||
-rw-r--r-- | p11p-daemon/src/p11p_sup.erl | 2 |
4 files changed, 101 insertions, 74 deletions
diff --git a/p11p-daemon/src/p11p_listener.erl b/p11p-daemon/src/p11p_listener.erl deleted file mode 100644 index 8efb7d8..0000000 --- a/p11p-daemon/src/p11p_listener.erl +++ /dev/null @@ -1,73 +0,0 @@ -%% Create an AF_UNIX socket and accept connections. On connect, spawn -%% a p11p_server process. - --module(p11p_listener). --behaviour(gen_server). - -%% API. --export([start_link/0]). - -%% Genserver callbacks. --export([init/1, handle_call/3, handle_cast/2, handle_info/2, terminate/2, - code_change/3]). - -%% Records and types. --include("p11p_defs.hrl"). --record(state, {tokens}). - -%% API. --spec start_link() -> {ok, pid()} | {error, term()}. -start_link() -> - gen_server:start_link({local, ?MODULE}, ?MODULE, [], []). - -%% Genserver callbacks. -%%-spec init([[token()]]) -> {ok, #state{}}. -init([]) -> - TokensCfg = p11p_config:tokens(), - lager:debug("TokensCfg: ~p", [TokensCfg]), - {ok, Tokens} = init_tokens(TokensCfg, []), - {ok, #state{tokens = Tokens}}. - -handle_call(Request, _From, State) -> - lager:debug("Unhandled call: ~p~n", [Request]), - {reply, unhandled, State}. - -handle_cast(Request, State) -> - lager:debug("Unhandled cast: ~p~n", [Request]), - {noreply, State}. - -handle_info(Info, State) -> - lager:debug("Unhandled info: ~p~n", [Info]), - {noreply, State}. - -terminate(_Reason, _State) -> - ok. - -code_change(_OldVersion, State, _Extra) -> - {ok, State}. - -%% Private functions. -init_tokens([], Acc) -> - {ok, lists:reverse(Acc)}; -init_tokens([TokenCfg | T], Acc) -> - #token{name = Name} = TokenCfg, - SocketPath = socket_path(mkdir_socket_basepath(), Name), - file:delete(SocketPath), - {ok, ListenSocket} = gen_udp:open(0, [{ifaddr, {local, SocketPath}}]), - init_tokens(T, [ListenSocket | Acc]). - -mkdir_socket_basepath() -> - Path = "/run/user/1000/p11p", - ok = case file:make_dir(Path) of - ok -> ok; - {error, eexist} -> ok; - Err -> - lager:error("~s: unable to create directory: ~p", [Path, Err]), - err - end, - Path. - --spec socket_path(string(), string()) -> string(). -socket_path(BasePath, Name) -> - %%"/run/user/$UID/p11p/$TokenCfg-$UNIXPID" - BasePath ++ "/" ++ Name. diff --git a/p11p-daemon/src/p11p_server.erl b/p11p-daemon/src/p11p_server.erl new file mode 100644 index 0000000..726e97b --- /dev/null +++ b/p11p-daemon/src/p11p_server.erl @@ -0,0 +1,58 @@ +%% Create an AF_UNIX socket and accept connections. On connect, spawn +%% a p11p_server process. + +%% FIXME: Run _one_ socket per instance of this server! + +-module(p11p_server). +-behaviour(gen_server). + +%% API. +-export([start_link/1]). + +%% Genserver callbacks. +-export([init/1, handle_call/3, handle_cast/2, handle_info/2, terminate/2, + code_change/3]). + +%% Records and types. +-include("p11p_defs.hrl"). +-record(state, {socket :: gen_tcp:socket()}). + +%% API. +-spec start_link(gen_tcp:socket()) -> {ok, pid()} | {error, term()}. +start_link(Socket) -> + gen_server:start_link(?MODULE, Socket, []). + +%% Genserver callbacks. +init(Socket) -> + gen_server:cast(self(), accept), % Perform accept in gen-server loop. + {ok, #state{socket = Socket}}. + +handle_call(Request, _From, State) -> + lager:debug("Unhandled call: ~p~n", [Request]), + {reply, unhandled, State}. + +handle_cast(accept, State = #state{socket = ListenSocket}) -> + {ok, Sock} = gen_tcp:accept(ListenSocket), + %% TODO: authz + lager:debug("new connection accepted: ~p", [Sock]), + p11p_server_sup:start_server(), % New acceptor. + {noreply, State#state{socket = Sock}}; +handle_cast(Request, State) -> + lager:debug("Unhandled cast: ~p~n", [Request]), + {noreply, State}. + +handle_info({tcp, _Socket, Data}, State) -> + lager:debug("~p: received: ~s", [self(), Data]), + {noreply, State}; +handle_info(Info, State) -> + lager:debug("Unhandled info: ~p~n", [Info]), + {noreply, State}. + +terminate(_Reason, #state{socket = Socket}) -> + gen_tcp:close(Socket), % FIXME: correct? + ok. + +code_change(_OldVersion, State, _Extra) -> + {ok, State}. + +%% Private functions. diff --git a/p11p-daemon/src/p11p_server_sup.erl b/p11p-daemon/src/p11p_server_sup.erl new file mode 100644 index 0000000..15398bc --- /dev/null +++ b/p11p-daemon/src/p11p_server_sup.erl @@ -0,0 +1,42 @@ +-module(p11p_server_sup). +-behaviour(supervisor). + +-export([start_link/0, start_server/0]). +-export([init/1]). + +start_link() -> + supervisor:start_link({local, ?MODULE}, ?MODULE, []). + +init([]) -> + Name = "vtoken0", % FIXME + SocketPath = socket_path(mkdir_socket_basepath(), Name), + file:delete(SocketPath), + % TODO: consider flow control through {active, once} + {ok, ListenSocket} = gen_tcp:listen(0, [{ifaddr, {local, SocketPath}}, + binary]), + spawn_link(fun start_server/0), + {ok, {{simple_one_for_one, 60, 3600}, + [{sock_server, + {p11p_server, start_link, [ListenSocket]}, + temporary, 1000, worker, [p11p_server]} + ]}}. + +start_server() -> + supervisor:start_child(?MODULE, []). + +%% Private functions. +mkdir_socket_basepath() -> + Path = "/run/user/1000/p11p", + ok = case file:make_dir(Path) of + ok -> ok; + {error, eexist} -> ok; + Err -> + lager:error("~s: unable to create directory: ~p", [Path, Err]), + err + end, + Path. + +-spec socket_path(string(), string()) -> string(). +socket_path(BasePath, Name) -> + %%"/run/user/$UID/p11p/$TokenCfg-$UNIXPID" + BasePath ++ "/" ++ Name. diff --git a/p11p-daemon/src/p11p_sup.erl b/p11p-daemon/src/p11p_sup.erl index 76c7551..9ea5ae6 100644 --- a/p11p-daemon/src/p11p_sup.erl +++ b/p11p-daemon/src/p11p_sup.erl @@ -21,5 +21,5 @@ start_link() -> init([]) -> {ok, {{one_for_all, 10, 10}, [ ?CHILD(p11p_config, worker), - ?CHILD(p11p_listener, worker) + ?CHILD(p11p_server_sup, supervisor) ]}}. |