summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--p11p-daemon/src/p11p_listener.erl73
-rw-r--r--p11p-daemon/src/p11p_server.erl58
-rw-r--r--p11p-daemon/src/p11p_server_sup.erl42
-rw-r--r--p11p-daemon/src/p11p_sup.erl2
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)
]}}.